changeset 9654:18632807db02

RuntimeStub installation support is now more distinct from normal nmethod installation
author Doug Simon <doug.simon@oracle.com>
date Mon, 13 May 2013 11:21:24 +0200
parents 36e12fbbefdf
children 0a771345825b
files graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotCompilationResult.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotInstalledCode.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/SnippetStub.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/Stub.java src/share/vm/graal/graalCodeInstaller.cpp src/share/vm/graal/graalCodeInstaller.hpp src/share/vm/graal/graalCompilerToVM.cpp src/share/vm/graal/graalJavaAccess.hpp
diffstat 8 files changed, 107 insertions(+), 68 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotCompilationResult.java	Mon May 13 11:00:56 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotCompilationResult.java	Mon May 13 11:21:24 2013 +0200
@@ -27,12 +27,15 @@
 import java.util.*;
 
 import com.oracle.graal.api.code.*;
-import com.oracle.graal.api.code.CompilationResult.*;
+import com.oracle.graal.api.code.CompilationResult.Call;
+import com.oracle.graal.api.code.CompilationResult.DataPatch;
+import com.oracle.graal.api.code.CompilationResult.ExceptionHandler;
+import com.oracle.graal.api.code.CompilationResult.Infopoint;
+import com.oracle.graal.api.code.CompilationResult.Mark;
+import com.oracle.graal.api.code.CompilationResult.Site;
 import com.oracle.graal.api.meta.*;
-import com.oracle.graal.api.code.CompilationResult.ExceptionHandler;
 import com.oracle.graal.hotspot.meta.*;
 import com.oracle.graal.hotspot.stubs.*;
-import com.oracle.graal.replacements.*;
 
 /**
  * Augments a {@link CompilationResult} with HotSpot-specific information.
@@ -41,12 +44,15 @@
 
     private static final long serialVersionUID = 7807321392203253218L;
     public final CompilationResult comp;
-    public final HotSpotResolvedJavaMethod method; // used only for methods
-    public final int entryBCI; // used only for methods
 
     /**
-     * Name of the RuntimeStub to be installed for this compilation result. If null, then the
-     * compilation result will be installed as an nmethod.
+     * Non-null for installation of an nmethod.
+     */
+    public final HotSpotResolvedJavaMethod method;
+    public final int entryBCI;
+
+    /**
+     * Non-null for installation of a RuntimeStub.
      */
     public final String stubName;
 
@@ -55,23 +61,49 @@
 
     public HotSpotCompilationResult(HotSpotResolvedJavaMethod method, int entryBCI, CompilationResult comp) {
         this.method = method;
+        this.stubName = null;
         this.comp = comp;
         this.entryBCI = entryBCI;
 
-        if (graalRuntime().getRuntime().lookupJavaType(Stub.class).isAssignableFrom(method.getDeclaringClass()) && method.getAnnotation(Snippet.class) != null) {
-            this.stubName = MetaUtil.format("%h.%n", method);
-        } else {
-            this.stubName = null;
-        }
-
         sites = getSortedSites(comp);
-        if (comp.getExceptionHandlers() == null) {
+        if (comp.getExceptionHandlers().isEmpty()) {
             exceptionHandlers = null;
         } else {
             exceptionHandlers = comp.getExceptionHandlers().toArray(new ExceptionHandler[comp.getExceptionHandlers().size()]);
         }
     }
 
+    public HotSpotCompilationResult(Stub stub, CompilationResult comp) {
+        assert checkStubInvariants(comp);
+        this.method = null;
+        this.stubName = stub.toString();
+        this.comp = comp;
+        this.entryBCI = 0;
+
+        sites = getSortedSites(comp);
+        assert comp.getExceptionHandlers().isEmpty();
+        exceptionHandlers = null;
+    }
+
+    /**
+     * Checks the conditions a compilation must satisfy to be installed as a RuntimeStub.
+     */
+    private boolean checkStubInvariants(CompilationResult compResult) {
+        for (DataPatch data : compResult.getDataReferences()) {
+            Constant constant = data.constant;
+            assert constant.getKind() != Kind.Object : this + " cannot have embedded object constant: " + constant;
+            assert constant.getPrimitiveAnnotation() == null : this + " cannot have embedded metadata: " + constant;
+        }
+        for (Infopoint infopoint : compResult.getInfopoints()) {
+            assert infopoint instanceof Call : this + " cannot have non-call infopoint: " + infopoint;
+            Call call = (Call) infopoint;
+            assert call.target instanceof HotSpotRuntimeCallTarget : this + " cannot have non runtime call: " + call.target;
+            HotSpotRuntimeCallTarget callTarget = (HotSpotRuntimeCallTarget) call.target;
+            assert callTarget.getAddress() == graalRuntime().getConfig().uncommonTrapStub || callTarget.isCRuntimeCall() : this + "must only call C runtime or deoptimization stub, not " + call.target;
+        }
+        return true;
+    }
+
     static class SiteComparator implements Comparator<Site> {
 
         public int compare(Site s1, Site s2) {
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotInstalledCode.java	Mon May 13 11:00:56 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotInstalledCode.java	Mon May 13 11:21:24 2013 +0200
@@ -30,6 +30,7 @@
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.graph.*;
 import com.oracle.graal.hotspot.*;
+import com.oracle.graal.hotspot.stubs.*;
 
 /**
  * Implementation of {@link InstalledCode} for HotSpot. If the code is installed as an nmethod (as
@@ -46,18 +47,26 @@
     private static final long serialVersionUID = 156632908220561612L;
 
     private final HotSpotResolvedJavaMethod method;
+    private final Stub stub;
     private final boolean isDefault;
     private final Graph graph;
     long codeBlob;
     long start;
-    boolean isNmethod;
 
     public HotSpotInstalledCode(HotSpotResolvedJavaMethod method, Graph graph, boolean isDefault) {
         this.method = method;
+        this.stub = null;
         this.graph = graph;
         this.isDefault = isDefault;
     }
 
+    public HotSpotInstalledCode(Stub stub) {
+        this.method = null;
+        this.stub = stub;
+        this.graph = null;
+        this.isDefault = false;
+    }
+
     public boolean isDefault() {
         return isDefault;
     }
@@ -77,24 +86,27 @@
 
     @Override
     public boolean isValid() {
-        return !isNmethod || graalRuntime().getCompilerToVM().isInstalledCodeValid(codeBlob);
+        return stub != null || graalRuntime().getCompilerToVM().isInstalledCodeValid(codeBlob);
     }
 
     @Override
     public void invalidate() {
-        if (isNmethod) {
+        if (stub == null) {
             graalRuntime().getCompilerToVM().invalidateInstalledCode(codeBlob);
         }
     }
 
     @Override
     public String toString() {
-        return String.format("InstalledCode[method=%s, codeBlob=0x%x, isDefault=%b, isNmethod=%b]", method, codeBlob, isDefault, isNmethod);
+        if (stub != null) {
+            return String.format("InstalledCode[stub=%s, codeBlob=0x%x]", stub, codeBlob);
+        }
+        return String.format("InstalledCode[method=%s, codeBlob=0x%x, isDefault=%b]", method, codeBlob, isDefault);
     }
 
     @Override
     public Object execute(Object arg1, Object arg2, Object arg3) throws InvalidInstalledCodeException {
-        assert isNmethod;
+        assert stub == null;
         assert method.getSignature().getParameterCount(!Modifier.isStatic(method.getModifiers())) == 3;
         assert method.getSignature().getParameterKind(0) == Kind.Object;
         assert method.getSignature().getParameterKind(1) == Kind.Object;
@@ -118,7 +130,7 @@
 
     @Override
     public Object executeVarargs(Object... args) throws InvalidInstalledCodeException {
-        assert isNmethod;
+        assert stub == null;
         assert checkArgs(args);
         return graalRuntime().getCompilerToVM().executeCompiledMethodVarargs(args, codeBlob);
     }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/SnippetStub.java	Mon May 13 11:00:56 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/SnippetStub.java	Mon May 13 11:21:24 2013 +0200
@@ -82,13 +82,17 @@
     protected abstract Arguments makeArguments(SnippetInfo stub);
 
     @Override
+    protected Object debugScopeContext() {
+        return getInstalledCodeOwner();
+    }
+
+    @Override
     public ResolvedJavaMethod getInstalledCodeOwner() {
         return snippet.info.getMethod();
     }
 
     @Override
     public String toString() {
-        ResolvedJavaMethod method = getInstalledCodeOwner();
-        return "Stub<" + (method != null ? format("%h.%n", method) : linkage) + ">";
+        return "Stub<" + format("%h.%n", getInstalledCodeOwner()) + ">";
     }
 }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/Stub.java	Mon May 13 11:00:56 2013 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/Stub.java	Mon May 13 11:21:24 2013 +0200
@@ -28,15 +28,14 @@
 import java.util.concurrent.*;
 
 import com.oracle.graal.api.code.*;
-import com.oracle.graal.api.code.CompilationResult.Call;
-import com.oracle.graal.api.code.CompilationResult.DataPatch;
-import com.oracle.graal.api.code.CompilationResult.Infopoint;
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.compiler.*;
 import com.oracle.graal.compiler.target.*;
 import com.oracle.graal.debug.*;
 import com.oracle.graal.debug.internal.*;
+import com.oracle.graal.graph.*;
 import com.oracle.graal.hotspot.*;
+import com.oracle.graal.hotspot.bridge.CompilerToVM.CodeInstallResult;
 import com.oracle.graal.hotspot.meta.*;
 import com.oracle.graal.hotspot.nodes.*;
 import com.oracle.graal.java.*;
@@ -111,29 +110,12 @@
         return linkage;
     }
 
-    /**
-     * Checks the conditions a compilation must satisfy to be installed as a RuntimeStub.
-     */
-    private boolean checkStubInvariants(CompilationResult compResult) {
-        for (DataPatch data : compResult.getDataReferences()) {
-            Constant constant = data.constant;
-            assert constant.getKind() != Kind.Object : this + " cannot have embedded object constant: " + constant;
-            assert constant.getPrimitiveAnnotation() == null : this + " cannot have embedded metadata: " + constant;
-        }
-        for (Infopoint infopoint : compResult.getInfopoints()) {
-            assert infopoint instanceof Call : this + " cannot have non-call infopoint: " + infopoint;
-            Call call = (Call) infopoint;
-            assert call.target instanceof HotSpotRuntimeCallTarget : this + " cannot have non runtime call: " + call.target;
-            HotSpotRuntimeCallTarget callTarget = (HotSpotRuntimeCallTarget) call.target;
-            assert callTarget.getAddress() == graalRuntime().getConfig().uncommonTrapStub || callTarget.isCRuntimeCall() : this + "must only call C runtime or deoptimization stub, not " + call.target;
-        }
-        return true;
-    }
-
     protected abstract StructuredGraph getGraph();
 
     @Override
-    public abstract String toString();
+    public String toString() {
+        return "Stub<" + linkage.getDescriptor() + ">";
+    }
 
     /**
      * Gets the method the stub's code will be {@linkplain InstalledCode#getMethod() associated}
@@ -141,9 +123,10 @@
      */
     protected abstract ResolvedJavaMethod getInstalledCodeOwner();
 
-    protected Object debugScopeContext() {
-        return getInstalledCodeOwner();
-    }
+    /**
+     * Gets a context object for the debug scope created when producing the code for this stub.
+     */
+    protected abstract Object debugScopeContext();
 
     /**
      * Gets the code for this stub, compiling it first if necessary.
@@ -156,10 +139,11 @@
                 public void run() {
 
                     final StructuredGraph graph = getGraph();
-                    StubStartNode newStart = graph.add(new StubStartNode(Stub.this));
-                    newStart.setStateAfter(graph.start().stateAfter());
-                    graph.replaceFixed(graph.start(), newStart);
-                    graph.setStart(newStart);
+                    if (!(graph.start() instanceof StubStartNode)) {
+                        StubStartNode newStart = graph.add(new StubStartNode(Stub.this));
+                        newStart.setStateAfter(graph.start().stateAfter());
+                        graph.replaceFixed(graph.start(), newStart);
+                    }
 
                     PhasePlan phasePlan = new PhasePlan();
                     GraphBuilderPhase graphBuilderPhase = new GraphBuilderPhase(runtime, GraphBuilderConfiguration.getDefault(), OptimisticOptimizations.ALL);
@@ -168,23 +152,27 @@
                     final CompilationResult compResult = GraalCompiler.compileGraph(graph, cc, getInstalledCodeOwner(), runtime, replacements, backend, runtime.getTarget(), null, phasePlan,
                                     OptimisticOptimizations.ALL, new SpeculationLog());
 
-                    assert checkStubInvariants(compResult);
-
                     assert destroyedRegisters != null;
                     code = Debug.scope("CodeInstall", new Callable<InstalledCode>() {
 
                         @Override
                         public InstalledCode call() {
-                            InstalledCode installedCode = runtime.addMethod(getInstalledCodeOwner(), compResult);
-                            assert installedCode != null : "error installing stub " + this;
+                            Stub stub = Stub.this;
+                            HotSpotInstalledCode installedCode = new HotSpotInstalledCode(stub);
+                            HotSpotCompilationResult hsCompResult = new HotSpotCompilationResult(stub, compResult);
+                            CodeInstallResult result = graalRuntime().getCompilerToVM().installCode(hsCompResult, installedCode, null);
+                            if (result != CodeInstallResult.OK) {
+                                throw new GraalInternalError("Error installing stub %s: %s", Stub.this, result);
+                            }
                             if (Debug.isDumpEnabled()) {
                                 Debug.dump(new Object[]{compResult, installedCode}, "After code installation");
                             }
-                            // TTY.println(getMethod().toString());
-                            // TTY.println(runtime().disassemble(installedCode));
+                            // TTY.println(stub.toString());
+                            // TTY.println(runtime.disassemble(installedCode));
                             return installedCode;
                         }
                     });
+
                 }
             });
             assert code != null : "error installing stub " + this;
--- a/src/share/vm/graal/graalCodeInstaller.cpp	Mon May 13 11:00:56 2013 +0200
+++ b/src/share/vm/graal/graalCodeInstaller.cpp	Mon May 13 11:21:24 2013 +0200
@@ -351,7 +351,7 @@
 }
 
 // constructor used to create a method
-CodeInstaller::CodeInstaller(Handle& comp_result, methodHandle method, GraalEnv::CodeInstallResult& result, CodeBlob*& cb, Handle installed_code, Handle triggered_deoptimizations) {
+CodeInstaller::CodeInstaller(Handle& comp_result, GraalEnv::CodeInstallResult& result, CodeBlob*& cb, Handle installed_code, Handle triggered_deoptimizations) {
   GraalCompiler::initialize_buffer_blob();
   CodeBuffer buffer(JavaThread::current()->get_buffer_blob());
   jobject comp_result_obj = JNIHandles::make_local(comp_result());
@@ -360,7 +360,7 @@
 
   {
     No_Safepoint_Verifier no_safepoint;
-    initialize_fields(JNIHandles::resolve(comp_result_obj), method);
+    initialize_fields(JNIHandles::resolve(comp_result_obj));
     initialize_buffer(buffer);
     process_exception_handlers();
   }
@@ -379,17 +379,23 @@
     result = GraalEnv::ok;
   } else {
     nmethod* nm = NULL;
+    methodHandle method = getMethodFromHotSpotMethod(HotSpotCompilationResult::method(comp_result));
     result = GraalEnv::register_method(method, nm, entry_bci, &_offsets, _custom_stack_area_offset, &buffer, stack_slots, _debug_recorder->_oopmaps, &_exception_handler_table,
         GraalCompiler::instance(), _debug_recorder, _dependencies, NULL, -1, false, leaf_graph_ids, installed_code, triggered_deoptimizations);
     cb = nm;
   }
 }
 
-void CodeInstaller::initialize_fields(oop comp_result, methodHandle method) {
+void CodeInstaller::initialize_fields(oop comp_result) {
   _comp_result = HotSpotCompilationResult::comp(comp_result);
-  if (!method.is_null()) {
+  oop hotspotJavaMethod = HotSpotCompilationResult::method(comp_result);
+  if (hotspotJavaMethod != NULL) {
+    methodHandle method = getMethodFromHotSpotMethod(hotspotJavaMethod);
     _parameter_count = method->size_of_parameters();
     TRACE_graal_1("installing code for %s", method->name_and_sig_as_C_string());
+  } else {
+    // TODO (ds) not sure if this is correct - only used in OopMap constructor for non-product builds
+    _parameter_count = 0;
   }
   _stubName = HotSpotCompilationResult::stubName(comp_result);
   _sites = (arrayOop) HotSpotCompilationResult::sites(comp_result);
--- a/src/share/vm/graal/graalCodeInstaller.hpp	Mon May 13 11:00:56 2013 +0200
+++ b/src/share/vm/graal/graalCodeInstaller.hpp	Mon May 13 11:21:24 2013 +0200
@@ -76,13 +76,13 @@
 
 public:
 
-  CodeInstaller(Handle& comp_result, methodHandle method, GraalEnv::CodeInstallResult& result, CodeBlob*& cb, Handle installed_code, Handle triggered_deoptimizations);
+  CodeInstaller(Handle& comp_result, GraalEnv::CodeInstallResult& result, CodeBlob*& cb, Handle installed_code, Handle triggered_deoptimizations);
 
   static address runtime_call_target_address(oop runtime_call);
 
 private:
   // extract the fields of the CompilationResult
-  void initialize_fields(oop target_method, methodHandle method);
+  void initialize_fields(oop target_method);
   void initialize_assumptions(oop target_method);
 
   // perform data and call relocation on the CodeBuffer
--- a/src/share/vm/graal/graalCompilerToVM.cpp	Mon May 13 11:00:56 2013 +0200
+++ b/src/share/vm/graal/graalCompilerToVM.cpp	Mon May 13 11:21:24 2013 +0200
@@ -872,12 +872,11 @@
   HandleMark hm;
   Handle compResultHandle = JNIHandles::resolve(compResult);
   CodeBlob* cb = NULL;
-  methodHandle method = getMethodFromHotSpotMethod(HotSpotCompilationResult::method(compResult));
   Handle installed_code_handle = JNIHandles::resolve(installed_code);
   Handle triggered_deoptimizations_handle = JNIHandles::resolve(triggered_deoptimizations);
   GraalEnv::CodeInstallResult result;
 
-  CodeInstaller installer(compResultHandle, method, result, cb, installed_code_handle, triggered_deoptimizations_handle);
+  CodeInstaller installer(compResultHandle, result, cb, installed_code_handle, triggered_deoptimizations_handle);
 
   if (PrintCodeCacheOnCompilation) {
     stringStream s;
@@ -898,7 +897,6 @@
       HotSpotInstalledCode::set_codeBlob(installed_code_handle, (jlong) cb);
       HotSpotInstalledCode::set_method(installed_code_handle, HotSpotCompilationResult::method(compResult));
       HotSpotInstalledCode::set_start(installed_code_handle, (jlong) cb->code_begin());
-      HotSpotInstalledCode::set_isNmethod(installed_code_handle, cb->is_nmethod());
       nmethod* nm = cb->as_nmethod_or_null();
       assert(nm == NULL || !installed_code_handle->is_scavengable() || nm->on_scavenge_root_list(), "nm should be scavengable if installed_code is scavengable");
     }
--- a/src/share/vm/graal/graalJavaAccess.hpp	Mon May 13 11:00:56 2013 +0200
+++ b/src/share/vm/graal/graalJavaAccess.hpp	Mon May 13 11:21:24 2013 +0200
@@ -81,7 +81,6 @@
     oop_field(HotSpotInstalledCode, method, "Lcom/oracle/graal/hotspot/meta/HotSpotResolvedJavaMethod;")                                                       \
     long_field(HotSpotInstalledCode, start)                                                                                                                    \
     boolean_field(HotSpotInstalledCode, isDefault)                                                                                                             \
-    boolean_field(HotSpotInstalledCode, isNmethod)                                                                                                             \
   end_class                                                                                                                                                    \
   start_class(HotSpotCompilationResult)                                                                                                                        \
     oop_field(HotSpotCompilationResult, comp, "Lcom/oracle/graal/api/code/CompilationResult;")                                                                 \