# HG changeset patch # User Doug Simon # Date 1398983787 -7200 # Node ID a20be10ad437e8037dec7712dab8a8718332d4ac # Parent 05d3f069cff2df3723e2fcb5eef3950f93f3873b made Graal work with the HotSpot compiler queue and compiler threads, enabled by -XX:-UseGraalCompilationQueue diff -r 05d3f069cff2 -r a20be10ad437 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/CompilationTask.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/CompilationTask.java Fri May 02 00:17:40 2014 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/CompilationTask.java Fri May 02 00:36:27 2014 +0200 @@ -26,6 +26,7 @@ import static com.oracle.graal.api.code.CodeUtil.*; import static com.oracle.graal.compiler.GraalCompiler.*; import static com.oracle.graal.compiler.common.GraalOptions.*; +import static com.oracle.graal.compiler.common.UnsafeAccess.*; import static com.oracle.graal.hotspot.bridge.VMToCompilerImpl.*; import static com.oracle.graal.nodes.StructuredGraph.*; import static com.oracle.graal.phases.common.InliningUtil.*; @@ -117,11 +118,23 @@ */ private final com.sun.management.ThreadMXBean threadMXBean = (com.sun.management.ThreadMXBean) ManagementFactory.getThreadMXBean(); - public CompilationTask(HotSpotBackend backend, HotSpotResolvedJavaMethod method, int entryBCI, boolean blocking) { + /** + * The address of the native CompileTask associated with this compilation. If 0L, then this + * compilation is being managed by a Graal compilation queue otherwise its managed by a native + * HotSpot compilation queue. + */ + private final long ctask; + + public CompilationTask(HotSpotBackend backend, HotSpotResolvedJavaMethod method, int entryBCI, long ctask, boolean blocking) { this.backend = backend; this.method = method; this.entryBCI = entryBCI; - this.id = method.allocateCompileId(entryBCI); + if (ctask == 0L) { + this.id = method.allocateCompileId(entryBCI); + } else { + this.id = unsafe.getInt(ctask + backend.getRuntime().getConfig().compileTaskCompileIdOffset); + } + this.ctask = ctask; this.blocking = blocking; this.taskId = uniqueTaskIds.incrementAndGet(); this.status = new AtomicReference<>(CompilationStatus.Queued); @@ -337,13 +350,17 @@ System.exit(-1); } } finally { + int processedBytes = (int) (InlinedBytecodes.getCurrentValue() - previousInlinedBytecodes); + if (ctask != 0L) { + unsafe.putInt(ctask + config.compileTaskNumInlinedBytecodesOffset, processedBytes); + } if ((config.ciTime || config.ciTimeEach || PrintCompRate.getValue() != 0) && installedCode != null) { - long processedBytes = InlinedBytecodes.getCurrentValue() - previousInlinedBytecodes; + long time = CompilationTime.getCurrentValue() - previousCompilationTime; TimeUnit timeUnit = CompilationTime.getTimeUnit(); long timeUnitsPerSecond = timeUnit.convert(1, TimeUnit.SECONDS); CompilerToVM c2vm = backend.getRuntime().getCompilerToVM(); - c2vm.notifyCompilationStatistics(id, method, entryBCI != INVOCATION_ENTRY_BCI, (int) processedBytes, time, timeUnitsPerSecond, installedCode); + c2vm.notifyCompilationStatistics(id, method, entryBCI != INVOCATION_ENTRY_BCI, processedBytes, time, timeUnitsPerSecond, installedCode); } if (clearFromCompilationQueue) { @@ -388,7 +405,7 @@ final HotSpotCodeCacheProvider codeCache = backend.getProviders().getCodeCache(); InstalledCode installedCode = null; try (Scope s = Debug.scope("CodeInstall", new DebugDumpScope(String.valueOf(id), true), codeCache, method)) { - installedCode = codeCache.installMethod(method, compResult); + installedCode = codeCache.installMethod(method, compResult, ctask); } catch (Throwable e) { throw Debug.handle(e); } diff -r 05d3f069cff2 -r a20be10ad437 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/CompileTheWorld.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/CompileTheWorld.java Fri May 02 00:17:40 2014 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/CompileTheWorld.java Fri May 02 00:36:27 2014 +0200 @@ -317,7 +317,7 @@ class CTWCompilationTask extends CompilationTask { CTWCompilationTask(HotSpotBackend backend, HotSpotResolvedJavaMethod method) { - super(backend, method, INVOCATION_ENTRY_BCI, false); + super(backend, method, INVOCATION_ENTRY_BCI, 0L, false); } /** diff -r 05d3f069cff2 -r a20be10ad437 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotCompiledNmethod.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotCompiledNmethod.java Fri May 02 00:17:40 2014 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotCompiledNmethod.java Fri May 02 00:36:27 2014 +0200 @@ -34,11 +34,17 @@ public final HotSpotResolvedJavaMethod method; public final int entryBCI; public final int id; + public final long ctask; public HotSpotCompiledNmethod(TargetDescription target, HotSpotResolvedJavaMethod method, CompilationResult compResult) { + this(target, method, compResult, 0L); + } + + public HotSpotCompiledNmethod(TargetDescription target, HotSpotResolvedJavaMethod method, CompilationResult compResult, long ctask) { super(target, compResult); this.method = method; this.entryBCI = compResult.getEntryBCI(); this.id = compResult.getId(); + this.ctask = ctask; } } diff -r 05d3f069cff2 -r a20be10ad437 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotVMConfig.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotVMConfig.java Fri May 02 00:17:40 2014 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotVMConfig.java Fri May 02 00:36:27 2014 +0200 @@ -170,7 +170,7 @@ String name = annotation.name(); Flags.Flag entry = flags.get(name); if (entry == null) { - if (!isRequired(currentArch, annotation.archs())) { + if (annotation.optional() || !isRequired(currentArch, annotation.archs())) { continue; } throw new IllegalArgumentException("flag not found: " + name); @@ -716,6 +716,7 @@ @HotSpotVMFlag(name = "CIPrintCompilerName") @Stable public boolean printCompilerName; @HotSpotVMFlag(name = "PrintInlining") @Stable public boolean printInlining; @HotSpotVMFlag(name = "GraalUseFastLocking") @Stable public boolean useFastLocking; + @HotSpotVMFlag(name = "UseGraalCompilationQueue", optional = true) @Stable public boolean useGraalCompilationQueue; @HotSpotVMFlag(name = "ForceUnreachable") @Stable public boolean forceUnreachable; @HotSpotVMFlag(name = "GPUOffload") @Stable public boolean gpuOffload; @HotSpotVMFlag(name = "TieredCompilation") @Stable public boolean tieredCompilation; @@ -1067,6 +1068,9 @@ @HotSpotVMConstant(name = "JVM_ACC_MONITOR_MATCH") @Stable public int jvmAccMonitorMatch; @HotSpotVMConstant(name = "JVM_ACC_HAS_MONITOR_BYTECODES") @Stable public int jvmAccHasMonitorBytecodes; + @HotSpotVMField(name = "CompileTask::_compile_id", type = "uint", get = HotSpotVMField.Type.OFFSET) @Stable public int compileTaskCompileIdOffset; + @HotSpotVMField(name = "CompileTask::_num_inlined_bytecodes", type = "int", get = HotSpotVMField.Type.OFFSET) @Stable public int compileTaskNumInlinedBytecodesOffset; + /** * Value of Method::extra_stack_entries(). */ diff -r 05d3f069cff2 -r a20be10ad437 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotVMFlag.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotVMFlag.java Fri May 02 00:17:40 2014 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotVMFlag.java Fri May 02 00:36:27 2014 +0200 @@ -36,4 +36,6 @@ * required on all architectures. */ String[] archs() default {}; + + boolean optional() default false; } diff -r 05d3f069cff2 -r a20be10ad437 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/VMToCompiler.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/VMToCompiler.java Fri May 02 00:17:40 2014 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/VMToCompiler.java Fri May 02 00:36:27 2014 +0200 @@ -33,8 +33,10 @@ /** * Compiles a method to machine code. This method is called from the VM * (VMToCompiler::compileMethod). + * + * @param ctask the CompileTask pointer if this is a request from a HotSpot compiler thread */ - void compileMethod(long metaspaceMethod, int entryBCI, boolean blocking); + void compileMethod(long metaspaceMethod, int entryBCI, long ctask, boolean blocking); void shutdownCompiler() throws Exception; diff -r 05d3f069cff2 -r a20be10ad437 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/VMToCompilerImpl.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/VMToCompilerImpl.java Fri May 02 00:17:40 2014 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/VMToCompilerImpl.java Fri May 02 00:36:27 2014 +0200 @@ -192,55 +192,57 @@ } } - // Create compilation queue. - CompilerThreadFactory factory = new CompilerThreadFactory("GraalCompilerThread", new DebugConfigAccess() { - public GraalDebugConfig getDebugConfig() { - return Debug.isEnabled() ? DebugEnvironment.initialize(log) : null; - } - }); - compileQueue = new Queue(factory); + if (runtime.getConfig().useGraalCompilationQueue) { + + // Create compilation queue. + CompilerThreadFactory factory = new CompilerThreadFactory("GraalCompilerThread", new DebugConfigAccess() { + public GraalDebugConfig getDebugConfig() { + return Debug.isEnabled() ? DebugEnvironment.initialize(log) : null; + } + }); + compileQueue = new Queue(factory); - // Create queue status printing thread. - if (PrintQueue.getValue()) { - Thread t = new Thread() { + // Create queue status printing thread. + if (PrintQueue.getValue()) { + Thread t = new Thread() { - @Override - public void run() { - while (true) { - TTY.println(compileQueue.toString()); - try { - Thread.sleep(1000); - } catch (InterruptedException e) { + @Override + public void run() { + while (true) { + TTY.println(compileQueue.toString()); + try { + Thread.sleep(1000); + } catch (InterruptedException e) { + } } } - } - }; - t.setDaemon(true); - t.start(); - } - - if (PrintCompRate.getValue() != 0) { - if (runtime.getConfig().ciTime || runtime.getConfig().ciTimeEach) { - throw new GraalInternalError("PrintCompRate is incompatible with CITime and CITimeEach"); + }; + t.setDaemon(true); + t.start(); } - Thread t = new Thread() { + + if (PrintCompRate.getValue() != 0) { + if (runtime.getConfig().ciTime || runtime.getConfig().ciTimeEach) { + throw new GraalInternalError("PrintCompRate is incompatible with CITime and CITimeEach"); + } + Thread t = new Thread() { - @Override - public void run() { - while (true) { - runtime.getCompilerToVM().printCompilationStatistics(true, false); - runtime.getCompilerToVM().resetCompilationStatistics(); - try { - Thread.sleep(PrintCompRate.getValue()); - } catch (InterruptedException e) { + @Override + public void run() { + while (true) { + runtime.getCompilerToVM().printCompilationStatistics(true, false); + runtime.getCompilerToVM().resetCompilationStatistics(); + try { + Thread.sleep(PrintCompRate.getValue()); + } catch (InterruptedException e) { + } } } - } - }; - t.setDaemon(true); - t.start(); + }; + t.setDaemon(true); + t.start(); + } } - BenchmarkCounters.initialize(runtime.getCompilerToVM()); compilerStartTime = System.nanoTime(); @@ -346,23 +348,24 @@ private void enqueue(Method m) throws Throwable { JavaMethod javaMethod = runtime.getHostProviders().getMetaAccess().lookupJavaMethod(m); assert !((HotSpotResolvedJavaMethod) javaMethod).isAbstract() && !((HotSpotResolvedJavaMethod) javaMethod).isNative() : javaMethod; - compileMethod((HotSpotResolvedJavaMethod) javaMethod, StructuredGraph.INVOCATION_ENTRY_BCI, false); + compileMethod((HotSpotResolvedJavaMethod) javaMethod, StructuredGraph.INVOCATION_ENTRY_BCI, 0L, false); } public void shutdownCompiler() throws Exception { - try (Enqueueing enqueueing = new Enqueueing()) { - // We have to use a privileged action here because shutting down the compiler might be - // called from user code which very likely contains unprivileged frames. - AccessController.doPrivileged(new PrivilegedExceptionAction() { - public Void run() throws Exception { - if (compileQueue != null) { - compileQueue.shutdown(); + if (runtime.getConfig().useGraalCompilationQueue) { + try (Enqueueing enqueueing = new Enqueueing()) { + // We have to use a privileged action here because shutting down the compiler might + // be called from user code which very likely contains unprivileged frames. + AccessController.doPrivileged(new PrivilegedExceptionAction() { + public Void run() throws Exception { + if (compileQueue != null) { + compileQueue.shutdown(); + } + return null; } - return null; - } - }); + }); + } } - printDebugValues(ResetDebugValuesAfterBootstrap.getValue() ? "application" : null, false); phaseTransition("final"); @@ -537,22 +540,34 @@ } @Override - public void compileMethod(long metaspaceMethod, final int entryBCI, final boolean blocking) { + public void compileMethod(long metaspaceMethod, final int entryBCI, long ctask, final boolean blocking) { final HotSpotResolvedJavaMethod method = HotSpotResolvedJavaMethod.fromMetaspace(metaspaceMethod); - // We have to use a privileged action here because compilations are enqueued from user code - // which very likely contains unprivileged frames. - AccessController.doPrivileged(new PrivilegedAction() { - public Void run() { - compileMethod(method, entryBCI, blocking); - return null; - } - }); + if (ctask != 0L) { + // This is on a VM CompilerThread - no user frames exist + compileMethod(method, entryBCI, ctask, false); + } else { + // We have to use a privileged action here because compilations are + // enqueued from user code which very likely contains unprivileged frames. + AccessController.doPrivileged(new PrivilegedAction() { + public Void run() { + compileMethod(method, entryBCI, 0L, blocking); + return null; + } + }); + } } /** * Compiles a method to machine code. */ - void compileMethod(final HotSpotResolvedJavaMethod method, final int entryBCI, final boolean blocking) { + void compileMethod(final HotSpotResolvedJavaMethod method, final int entryBCI, long ctask, final boolean blocking) { + if (ctask != 0L) { + HotSpotBackend backend = runtime.getHostBackend(); + CompilationTask task = new CompilationTask(backend, method, entryBCI, ctask, false); + task.runCompilation(false); + return; + } + boolean osrCompilation = entryBCI != StructuredGraph.INVOCATION_ENTRY_BCI; if (osrCompilation && bootstrapRunning) { // no OSR compilations during bootstrap - the compiler is just too slow at this point, @@ -575,7 +590,7 @@ assert method.isQueuedForCompilation(); HotSpotBackend backend = runtime.getHostBackend(); - CompilationTask task = new CompilationTask(backend, method, entryBCI, block); + CompilationTask task = new CompilationTask(backend, method, entryBCI, ctask, block); try { compileQueue.execute(task); diff -r 05d3f069cff2 -r a20be10ad437 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotCodeCacheProvider.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotCodeCacheProvider.java Fri May 02 00:17:40 2014 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotCodeCacheProvider.java Fri May 02 00:36:27 2014 +0200 @@ -206,12 +206,12 @@ return installedCode; } - public InstalledCode installMethod(HotSpotResolvedJavaMethod method, CompilationResult compResult) { + public InstalledCode installMethod(HotSpotResolvedJavaMethod method, CompilationResult compResult, long ctask) { if (compResult.getId() == -1) { compResult.setId(method.allocateCompileId(compResult.getEntryBCI())); } HotSpotInstalledCode installedCode = new HotSpotNmethod(method, compResult.getName(), true); - runtime.getCompilerToVM().installCode(new HotSpotCompiledNmethod(target, method, compResult), installedCode, method.getSpeculationLog()); + runtime.getCompilerToVM().installCode(new HotSpotCompiledNmethod(target, method, compResult, ctask), installedCode, method.getSpeculationLog()); return logOrDump(installedCode, compResult); } @@ -236,7 +236,7 @@ @Override public InstalledCode setDefaultMethod(ResolvedJavaMethod method, CompilationResult compResult) { HotSpotResolvedJavaMethod hotspotMethod = (HotSpotResolvedJavaMethod) method; - return installMethod(hotspotMethod, compResult); + return installMethod(hotspotMethod, compResult, 0L); } public HotSpotNmethod addExternalMethod(ResolvedJavaMethod method, CompilationResult compResult) { diff -r 05d3f069cff2 -r a20be10ad437 src/share/vm/classfile/systemDictionary.cpp --- a/src/share/vm/classfile/systemDictionary.cpp Fri May 02 00:17:40 2014 +0200 +++ b/src/share/vm/classfile/systemDictionary.cpp Fri May 02 00:36:27 2014 +0200 @@ -216,7 +216,7 @@ // Forwards to resolve_instance_class_or_null Klass* SystemDictionary::resolve_or_null(Symbol* class_name, Handle class_loader, Handle protection_domain, TRAPS) { - assert(!THREAD->is_Compiler_thread(), + assert(THREAD->can_call_java(), err_msg("can not load classes with compiler thread: class=%s, classloader=%s", class_name->as_C_string(), class_loader.is_null() ? "null" : class_loader->klass()->name()->as_C_string())); @@ -2347,7 +2347,7 @@ TRAPS) { methodHandle empty; assert(EnableInvokeDynamic, ""); - assert(!THREAD->is_Compiler_thread(), ""); + assert(THREAD->can_call_java() ,""); Handle method_type = SystemDictionary::find_method_handle_type(signature, accessing_klass, CHECK_(empty)); if (false) { // FIXME: Decide if the Java upcall should resolve signatures. @@ -2400,7 +2400,7 @@ if (spe != NULL && spe->method_type() != NULL) { assert(java_lang_invoke_MethodType::is_instance(spe->method_type()), ""); return Handle(THREAD, spe->method_type()); - } else if (THREAD->is_Compiler_thread()) { + } else if (!THREAD->can_call_java()) { warning("SystemDictionary::find_method_handle_type called from compiler thread"); // FIXME return Handle(); // do not attempt from within compiler, unless it was cached } diff -r 05d3f069cff2 -r a20be10ad437 src/share/vm/classfile/vmSymbols.hpp --- a/src/share/vm/classfile/vmSymbols.hpp Fri May 02 00:17:40 2014 +0200 +++ b/src/share/vm/classfile/vmSymbols.hpp Fri May 02 00:36:27 2014 +0200 @@ -367,7 +367,7 @@ template(compileTheWorld_name, "compileTheWorld") \ template(shutdownCompiler_name, "shutdownCompiler") \ template(compileMethod_name, "compileMethod") \ - template(compileMethod_signature, "(JIZ)V") \ + template(compileMethod_signature, "(JIJZ)V") \ template(setOption_name, "setOption") \ template(setOption_signature, "(Ljava/lang/String;)Z") \ template(finalizeOptions_name, "finalizeOptions") \ diff -r 05d3f069cff2 -r a20be10ad437 src/share/vm/compiler/compileBroker.cpp --- a/src/share/vm/compiler/compileBroker.cpp Fri May 02 00:17:40 2014 +0200 +++ b/src/share/vm/compiler/compileBroker.cpp Fri May 02 00:36:27 2014 +0200 @@ -804,7 +804,7 @@ #if defined(COMPILERGRAAL) _compilers[1] = graal; - c2_count = 0; + c2_count = UseGraalCompilationQueue ? 0 : c2_count; #endif // COMPILERGRAAL #ifdef COMPILER2 @@ -1143,22 +1143,24 @@ return; } -#if defined(COMPILERGRAAL) - // In tiered mode we want to only handle highest tier compiles and - // in non-tiered mode the default level should be - // CompLevel_full_optimization which equals CompLevel_highest_tier. - assert(TieredCompilation || comp_level == CompLevel_full_optimization, "incorrect compile level"); - assert(CompLevel_full_optimization == CompLevel_highest_tier, "incorrect level definition"); - if (comp_level == CompLevel_full_optimization) { - if (!JavaThread::current()->is_graal_compiling()) { - bool blockingCompilation = is_compile_blocking(method, osr_bci); - GraalCompiler::instance()->compile_method(method, osr_bci, blockingCompilation); - } else { - // Can't enqueue this request because there would be no one to service it, so simply return. +#ifdef COMPILERGRAAL + if (UseGraalCompilationQueue) { + // In tiered mode we want to only handle highest tier compiles and + // in non-tiered mode the default level should be + // CompLevel_full_optimization which equals CompLevel_highest_tier. + assert(TieredCompilation || comp_level == CompLevel_full_optimization, "incorrect compile level"); + assert(CompLevel_full_optimization == CompLevel_highest_tier, "incorrect level definition"); + if (comp_level == CompLevel_full_optimization) { + if (!JavaThread::current()->is_graal_compiling()) { + bool blockingCompilation = is_compile_blocking(method, osr_bci); + GraalCompiler::instance()->compile_method(method, osr_bci, NULL, blockingCompilation); + } else { + // Can't enqueue this request because there would be no one to service it, so simply return. + } + return; } - return; + assert(TieredCompilation, "should only reach here in tiered mode"); } - assert(TieredCompilation, "should only reach here in tiered mode"); #endif // COMPILERGRAAL // Outputs from the following MutexLocker block: @@ -1881,6 +1883,35 @@ tty->print(s.as_string()); } +void CompileBroker::post_compile(CompilerThread* thread, CompileTask* task, EventCompilation& event, bool success, ciEnv* ci_env) { + + if (success) { + task->mark_success(); + if (ci_env != NULL) { + task->set_num_inlined_bytecodes(ci_env->num_inlined_bytecodes()); + } + if (_compilation_log != NULL) { + nmethod* code = task->code(); + if (code != NULL) { + _compilation_log->log_nmethod(thread, code); + } + } + } + + // simulate crash during compilation + assert(task->compile_id() != CICrashAt, "just as planned"); + if (event.should_commit()) { + event.set_method(task->method()); + event.set_compileID(task->compile_id()); + event.set_compileLevel(task->comp_level()); + event.set_succeded(task->is_success()); + event.set_isOsr(task->osr_bci() != CompileBroker::standard_entry_bci); + event.set_codeSize((task->code() == NULL) ? 0 : task->code()->total_size()); + event.set_inlinedBytes(task->num_inlined_bytecodes()); + event.commit(); + } +} + // ------------------------------------------------------------------ // CompileBroker::invoke_compiler_on_method // @@ -1929,6 +1960,21 @@ push_jni_handle_block(); Method* target_handle = task->method(); int compilable = ciEnv::MethodCompilable; + AbstractCompiler *comp = compiler(task_level); + +#ifdef COMPILERGRAAL + if (comp != NULL && comp->is_graal()) { + assert(!UseGraalCompilationQueue, "should not reach here"); + GraalCompiler* graal = (GraalCompiler*) comp; + + TraceTime t1("compilation", &time); + EventCompilation event; + + graal->compile_method(target_handle, osr_bci, task, false); + + post_compile(thread, task, event, task->code() != NULL, NULL); + } else +#endif // COMPILERGRAAL { int system_dictionary_modification_counter; { @@ -1960,7 +2006,6 @@ TraceTime t1("compilation", &time); EventCompilation event; - AbstractCompiler *comp = compiler(task_level); if (comp == NULL) { ci_env.record_method_not_compilable("no compiler", !TieredCompilation); } else { @@ -1988,28 +2033,9 @@ err_msg_res("COMPILE SKIPPED: %s", ci_env.failure_reason()); task->print_compilation(tty, msg); } - } else { - task->mark_success(); - task->set_num_inlined_bytecodes(ci_env.num_inlined_bytecodes()); - if (_compilation_log != NULL) { - nmethod* code = task->code(); - if (code != NULL) { - _compilation_log->log_nmethod(thread, code); - } - } } - // simulate crash during compilation - assert(task->compile_id() != CICrashAt, "just as planned"); - if (event.should_commit()) { - event.set_method(target->get_Method()); - event.set_compileID(compile_id); - event.set_compileLevel(task->comp_level()); - event.set_succeded(task->is_success()); - event.set_isOsr(is_osr); - event.set_codeSize((task->code() == NULL) ? 0 : task->code()->total_size()); - event.set_inlinedBytes(task->num_inlined_bytecodes()); - event.commit(); - } + + post_compile(thread, task, event, !ci_env.failing(), &ci_env); } pop_jni_handle_block(); diff -r 05d3f069cff2 -r a20be10ad437 src/share/vm/compiler/compileBroker.hpp --- a/src/share/vm/compiler/compileBroker.hpp Fri May 02 00:17:40 2014 +0200 +++ b/src/share/vm/compiler/compileBroker.hpp Fri May 02 00:36:27 2014 +0200 @@ -28,6 +28,7 @@ #include "ci/compilerInterface.hpp" #include "compiler/abstractCompiler.hpp" #include "runtime/perfData.hpp" +#include "trace/tracing.hpp" class nmethod; class nmethodLocker; @@ -339,6 +340,7 @@ static void wait_for_completion(CompileTask* task); static void invoke_compiler_on_method(CompileTask* task); + static void post_compile(CompilerThread* thread, CompileTask* task, EventCompilation& event, bool success, ciEnv* ci_env); static void set_last_compile(CompilerThread *thread, methodHandle method, bool is_osr, int comp_level); static void push_jni_handle_block(); static void pop_jni_handle_block(); diff -r 05d3f069cff2 -r a20be10ad437 src/share/vm/graal/graalCodeInstaller.cpp --- a/src/share/vm/graal/graalCodeInstaller.cpp Fri May 02 00:17:40 2014 +0200 +++ b/src/share/vm/graal/graalCodeInstaller.cpp Fri May 02 00:36:27 2014 +0200 @@ -422,12 +422,13 @@ methodHandle method = getMethodFromHotSpotMethod(HotSpotCompiledNmethod::method(compiled_code)); jint entry_bci = HotSpotCompiledNmethod::entryBCI(compiled_code); jint id = HotSpotCompiledNmethod::id(compiled_code); + CompileTask* task = (CompileTask*) (address) HotSpotCompiledNmethod::ctask(compiled_code); if (id == -1) { // Make sure a valid compile_id is associated with every compile id = CompileBroker::assign_compile_id_unlocked(Thread::current(), method, entry_bci); } 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, id, false, installed_code, speculation_log); + GraalCompiler::instance(), _debug_recorder, _dependencies, task, id, false, installed_code, speculation_log); cb = nm; } diff -r 05d3f069cff2 -r a20be10ad437 src/share/vm/graal/graalCompiler.cpp --- a/src/share/vm/graal/graalCompiler.cpp Fri May 02 00:17:40 2014 +0200 +++ b/src/share/vm/graal/graalCompiler.cpp Fri May 02 00:36:27 2014 +0200 @@ -44,7 +44,10 @@ // Initialization void GraalCompiler::initialize() { - + if (!should_perform_init()) { + return; + } + ThreadToNativeFromVM trans(JavaThread::current()); JavaThread* THREAD = JavaThread::current(); TRACE_graal_1("GraalCompiler::initialize"); @@ -100,7 +103,7 @@ if (UseCompiler) { _external_deopt_i2c_entry = create_external_deopt_i2c(); #ifdef COMPILERGRAAL - bool bootstrap = FLAG_IS_DEFAULT(BootstrapGraal) ? !TieredCompilation : BootstrapGraal; + bool bootstrap = UseGraalCompilationQueue && (FLAG_IS_DEFAULT(BootstrapGraal) ? !TieredCompilation : BootstrapGraal); #else bool bootstrap = false; #endif @@ -172,7 +175,7 @@ return buffer_blob; } -void GraalCompiler::compile_method(methodHandle method, int entry_bci, jboolean blocking) { +void GraalCompiler::compile_method(methodHandle method, int entry_bci, CompileTask* task, jboolean blocking) { GRAAL_EXCEPTION_CONTEXT if (!_initialized) { CompilationPolicy::policy()->delay_compilation(method()); @@ -182,7 +185,7 @@ assert(_initialized, "must already be initialized"); ResourceMark rm; thread->set_is_graal_compiling(true); - VMToCompiler::compileMethod(method(), entry_bci, blocking); + VMToCompiler::compileMethod(method(), entry_bci, (jlong) (address) task, blocking); thread->set_is_graal_compiling(false); } diff -r 05d3f069cff2 -r a20be10ad437 src/share/vm/graal/graalCompiler.hpp --- a/src/share/vm/graal/graalCompiler.hpp Fri May 02 00:17:40 2014 +0200 +++ b/src/share/vm/graal/graalCompiler.hpp Fri May 02 00:36:27 2014 +0200 @@ -60,7 +60,7 @@ // Compilation entry point for methods virtual void compile_method(ciEnv* env, ciMethod* target, int entry_bci); - void compile_method(methodHandle target, int entry_bci, jboolean blocking); + void compile_method(methodHandle target, int entry_bci, CompileTask* task, jboolean blocking); // Print compilation timers and statistics virtual void print_timers(); diff -r 05d3f069cff2 -r a20be10ad437 src/share/vm/graal/graalGlobals.hpp --- a/src/share/vm/graal/graalGlobals.hpp Fri May 02 00:17:40 2014 +0200 +++ b/src/share/vm/graal/graalGlobals.hpp Fri May 02 00:36:27 2014 +0200 @@ -52,6 +52,9 @@ COMPILERGRAAL_PRESENT(product(bool, BootstrapGraal, true, \ "Bootstrap Graal before running Java main method")) \ \ + COMPILERGRAAL_PRESENT(product(bool, UseGraalCompilationQueue, false, \ + "Use non-native compilation queue for Graal")) \ + \ product(bool, ForceGraalInitialization, false, \ "Force VM to initialize the compiler even if not used") \ \ diff -r 05d3f069cff2 -r a20be10ad437 src/share/vm/graal/graalJavaAccess.hpp --- a/src/share/vm/graal/graalJavaAccess.hpp Fri May 02 00:17:40 2014 +0200 +++ b/src/share/vm/graal/graalJavaAccess.hpp Fri May 02 00:36:27 2014 +0200 @@ -88,6 +88,7 @@ oop_field(HotSpotCompiledNmethod, method, "Lcom/oracle/graal/hotspot/meta/HotSpotResolvedJavaMethod;") \ int_field(HotSpotCompiledNmethod, entryBCI) \ int_field(HotSpotCompiledNmethod, id) \ + long_field(HotSpotCompiledNmethod, ctask) \ end_class \ start_class(HotSpotCompiledRuntimeStub) \ oop_field(HotSpotCompiledRuntimeStub, stubName, "Ljava/lang/String;") \ diff -r 05d3f069cff2 -r a20be10ad437 src/share/vm/graal/graalVMToCompiler.cpp --- a/src/share/vm/graal/graalVMToCompiler.cpp Fri May 02 00:17:40 2014 +0200 +++ b/src/share/vm/graal/graalVMToCompiler.cpp Fri May 02 00:36:27 2014 +0200 @@ -111,7 +111,7 @@ check_pending_exception("Error while calling finalizeOptions"); } -void VMToCompiler::compileMethod(Method* method, int entry_bci, jboolean blocking) { +void VMToCompiler::compileMethod(Method* method, int entry_bci, jlong ctask, jboolean blocking) { assert(method != NULL, "just checking"); Thread* THREAD = Thread::current(); JavaValue result(T_VOID); @@ -119,6 +119,7 @@ args.push_oop(instance()); args.push_long((jlong) (address) method); args.push_int(entry_bci); + args.push_long(ctask); args.push_int(blocking); JavaCalls::call_interface(&result, vmToCompilerKlass(), vmSymbols::compileMethod_name(), vmSymbols::compileMethod_signature(), &args, THREAD); check_pending_exception("Error while calling compileMethod"); diff -r 05d3f069cff2 -r a20be10ad437 src/share/vm/graal/graalVMToCompiler.hpp --- a/src/share/vm/graal/graalVMToCompiler.hpp Fri May 02 00:17:40 2014 +0200 +++ b/src/share/vm/graal/graalVMToCompiler.hpp Fri May 02 00:36:27 2014 +0200 @@ -60,8 +60,8 @@ // public static void HotSpotOptions.finalizeOptions(boolean ciTime); static void finalizeOptions(jboolean ciTime); - // public abstract boolean compileMethod(long vmId, int entry_bci, boolean blocking); - static void compileMethod(Method* method, int entry_bci, jboolean blocking); + // public abstract boolean compileMethod(long metaspaceMethod, int entryBCI, long ctask, boolean blocking); + static void compileMethod(Method* method, int entry_bci, jlong ctask, jboolean blocking); // public abstract void shutdownCompiler(); static void shutdownCompiler(); diff -r 05d3f069cff2 -r a20be10ad437 src/share/vm/interpreter/linkResolver.cpp --- a/src/share/vm/interpreter/linkResolver.cpp Fri May 02 00:17:40 2014 +0200 +++ b/src/share/vm/interpreter/linkResolver.cpp Fri May 02 00:36:27 2014 +0200 @@ -113,7 +113,7 @@ // Note: with several active threads, the must_be_compiled may be true // while can_be_compiled is false; remove assert // assert(CompilationPolicy::can_be_compiled(selected_method), "cannot compile"); - if (THREAD->is_Compiler_thread()) { + if (!THREAD->can_call_java()) { // don't force compilation, resolve was on behalf of compiler return; } @@ -364,7 +364,7 @@ return; } } else if (iid == vmIntrinsics::_invokeGeneric - && !THREAD->is_Compiler_thread() + && THREAD->can_call_java() && appendix_result_or_null != NULL) { // This is a method with type-checking semantics. // We will ask Java code to spin an adapter method for it. diff -r 05d3f069cff2 -r a20be10ad437 src/share/vm/oops/method.cpp --- a/src/share/vm/oops/method.cpp Fri May 02 00:17:40 2014 +0200 +++ b/src/share/vm/oops/method.cpp Fri May 02 00:36:27 2014 +0200 @@ -1314,7 +1314,7 @@ // These two methods are static since a GC may move the Method bool Method::load_signature_classes(methodHandle m, TRAPS) { - if (THREAD->is_Compiler_thread()) { + if (!THREAD->can_call_java()) { // There is nothing useful this routine can do from within the Compile thread. // Hopefully, the signature contains only well-known classes. // We could scan for this and return true/false, but the caller won't care. diff -r 05d3f069cff2 -r a20be10ad437 src/share/vm/prims/jni.cpp --- a/src/share/vm/prims/jni.cpp Fri May 02 00:17:40 2014 +0200 +++ b/src/share/vm/prims/jni.cpp Fri May 02 00:36:27 2014 +0200 @@ -5174,15 +5174,19 @@ *(JNIEnv**)penv = thread->jni_environment(); #ifdef GRAAL - // GraalCompiler needs to have been created in compileBroker.cpp - GraalCompiler* graal_compiler = GraalCompiler::instance(); - if (ForceGraalInitialization && graal_compiler == NULL) { - graal_compiler = new GraalCompiler(); - } - if (graal_compiler != NULL) { - graal_compiler->initialize(); + if (COMPILERGRAAL_PRESENT(UseGraalCompilationQueue) NOT_COMPILERGRAAL(true)) { + // GraalCompiler needs to have been created in compileBroker.cpp + GraalCompiler* graal_compiler = GraalCompiler::instance(); + if (ForceGraalInitialization && graal_compiler == NULL) { + graal_compiler = new GraalCompiler(); + } + if (graal_compiler != NULL) { + graal_compiler->initialize(); + } else { + assert(!UseCompiler, "why isn't there any compiler?"); + } } else { - assert(!UseCompiler, "why isn't there any compiler?"); + // Graal is initialized on a CompilerThread } #endif diff -r 05d3f069cff2 -r a20be10ad437 src/share/vm/runtime/javaCalls.cpp --- a/src/share/vm/runtime/javaCalls.cpp Fri May 02 00:17:40 2014 +0200 +++ b/src/share/vm/runtime/javaCalls.cpp Fri May 02 00:36:27 2014 +0200 @@ -52,7 +52,7 @@ guarantee(thread->is_Java_thread(), "crucial check - the VM thread cannot and must not escape to Java code"); assert(!thread->owns_locks(), "must release all locks when leaving VM"); - guarantee(!thread->is_Compiler_thread(), "cannot make java calls from the compiler"); + guarantee(thread->can_call_java(), "cannot make java calls from the compiler"); _result = result; // Allocate handle block for Java code. This must be done before we change thread_state to _thread_in_Java_or_stub, @@ -366,7 +366,7 @@ #endif - assert(!thread->is_Compiler_thread(), "cannot compile from the compiler"); + assert(thread->can_call_java(), "cannot compile from the compiler"); if (CompilationPolicy::must_be_compiled(method)) { CompileBroker::compile_method(method, InvocationEntryBci, CompilationPolicy::policy()->initial_compile_level(), diff -r 05d3f069cff2 -r a20be10ad437 src/share/vm/runtime/thread.cpp --- a/src/share/vm/runtime/thread.cpp Fri May 02 00:17:40 2014 +0200 +++ b/src/share/vm/runtime/thread.cpp Fri May 02 00:36:27 2014 +0200 @@ -2253,7 +2253,7 @@ // Do not throw asynchronous exceptions against the compiler thread // (the compiler thread should not be a Java thread -- fix in 1.4.2) - if (is_Compiler_thread()) return; + if (!can_call_java()) return; { // Actually throw the Throwable against the target Thread - however @@ -3311,6 +3311,12 @@ #endif } +#ifdef COMPILERGRAAL +bool CompilerThread::can_call_java() const { + return _compiler != NULL && _compiler->is_graal(); +} +#endif + void CompilerThread::oops_do(OopClosure* f, CLDToOopClosure* cld_f, CodeBlobClosure* cf) { JavaThread::oops_do(f, cld_f, cf); if (_scanned_nmethod != NULL && cf != NULL) { @@ -4334,7 +4340,7 @@ { MutexLockerEx ml(doLock ? Threads_lock : NULL); ALL_JAVA_THREADS(p) { - if (p->is_Compiler_thread()) continue; + if (!p->can_call_java()) continue; address pending = (address)p->current_pending_monitor(); if (pending == monitor) { // found a match diff -r 05d3f069cff2 -r a20be10ad437 src/share/vm/runtime/thread.hpp --- a/src/share/vm/runtime/thread.hpp Fri May 02 00:17:40 2014 +0200 +++ b/src/share/vm/runtime/thread.hpp Fri May 02 00:36:27 2014 +0200 @@ -321,6 +321,9 @@ virtual bool is_Named_thread() const { return false; } virtual bool is_Worker_thread() const { return false; } + // Can this thread make Java upcalls + virtual bool can_call_java() const { return true; } + // Casts virtual WorkerThread* as_Worker_thread() const { return NULL; } @@ -1876,8 +1879,13 @@ CompilerThread(CompileQueue* queue, CompilerCounters* counters); bool is_Compiler_thread() const { return true; } + +#ifdef COMPILERGRAAL + virtual bool can_call_java() const; +#endif + // Hide this compiler thread from external view. - bool is_hidden_from_external_view() const { return true; } + bool is_hidden_from_external_view() const { return !can_call_java(); } void set_compiler(AbstractCompiler* c) { _compiler = c; } AbstractCompiler* compiler() const { return _compiler; } diff -r 05d3f069cff2 -r a20be10ad437 src/share/vm/runtime/vmStructs.cpp --- a/src/share/vm/runtime/vmStructs.cpp Fri May 02 00:17:40 2014 +0200 +++ b/src/share/vm/runtime/vmStructs.cpp Fri May 02 00:36:27 2014 +0200 @@ -1307,6 +1307,7 @@ nonstatic_field(CompileTask, _osr_bci, int) \ nonstatic_field(CompileTask, _comp_level, int) \ nonstatic_field(CompileTask, _compile_id, uint) \ + nonstatic_field(CompileTask, _num_inlined_bytecodes, int) \ nonstatic_field(CompileTask, _next, CompileTask*) \ nonstatic_field(CompileTask, _prev, CompileTask*) \ \ diff -r 05d3f069cff2 -r a20be10ad437 src/share/vm/utilities/exceptions.cpp --- a/src/share/vm/utilities/exceptions.cpp Fri May 02 00:17:40 2014 +0200 +++ b/src/share/vm/utilities/exceptions.cpp Fri May 02 00:36:27 2014 +0200 @@ -84,7 +84,7 @@ #endif // ASSERT if (thread->is_VM_thread() - || thread->is_Compiler_thread() ) { + || !thread->can_call_java() ) { // We do not care what kind of exception we get for the vm-thread or a thread which // is compiling. We just install a dummy exception object thread->set_pending_exception(Universe::vm_exception(), file, line); @@ -107,7 +107,7 @@ } if (thread->is_VM_thread() - || thread->is_Compiler_thread() ) { + || !thread->can_call_java() ) { // We do not care what kind of exception we get for the vm-thread or a thread which // is compiling. We just install a dummy exception object thread->set_pending_exception(Universe::vm_exception(), file, line);