# HG changeset patch # User Doug Simon # Date 1368436884 -7200 # Node ID 18632807db02b682d477d7fc9c26787ba6efb313 # Parent 36e12fbbefdf2b1be03e3ed4544e3a262b887cd0 RuntimeStub installation support is now more distinct from normal nmethod installation diff -r 36e12fbbefdf -r 18632807db02 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotCompilationResult.java --- 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 { public int compare(Site s1, Site s2) { diff -r 36e12fbbefdf -r 18632807db02 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotInstalledCode.java --- 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); } diff -r 36e12fbbefdf -r 18632807db02 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/SnippetStub.java --- 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()) + ">"; } } diff -r 36e12fbbefdf -r 18632807db02 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/Stub.java --- 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() { @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; diff -r 36e12fbbefdf -r 18632807db02 src/share/vm/graal/graalCodeInstaller.cpp --- 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); diff -r 36e12fbbefdf -r 18632807db02 src/share/vm/graal/graalCodeInstaller.hpp --- 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 diff -r 36e12fbbefdf -r 18632807db02 src/share/vm/graal/graalCompilerToVM.cpp --- 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"); } diff -r 36e12fbbefdf -r 18632807db02 src/share/vm/graal/graalJavaAccess.hpp --- 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;") \