# HG changeset patch # User simonis # Date 1456511936 -3600 # Fri Feb 26 19:38:56 2016 +0100 # Node ID 062a8e67b92f7b798dbec75f536f757d3867f4be # Parent 8b9fdaeb8c57056656f7452f8e9ae586d677907f 8150646: Add support for blocking compiles through whitebox API diff --git a/src/share/vm/compiler/compileBroker.cpp b/src/share/vm/compiler/compileBroker.cpp --- a/src/share/vm/compiler/compileBroker.cpp +++ b/src/share/vm/compiler/compileBroker.cpp @@ -948,7 +948,7 @@ } // Should this thread wait for completion of the compile? - blocking = is_compile_blocking(); + blocking = is_compile_blocking(method, comp_level); #if INCLUDE_JVMCI if (UseJVMCICompiler) { @@ -1309,9 +1309,15 @@ * Should the current thread block until this compilation request * has been fulfilled? */ -bool CompileBroker::is_compile_blocking() { +bool CompileBroker::is_compile_blocking(const methodHandle& method, int comp_level) { assert(!InstanceRefKlass::owns_pending_list_lock(JavaThread::current()), "possible deadlock"); - return !BackgroundCompilation; + + bool backgroundCompilation; + DirectiveSet* directive = DirectivesStack::getMatchingDirective(method, compiler(comp_level)); + backgroundCompilation = directive->BackgroundCompilationOption; + DirectivesStack::release(directive); + + return !backgroundCompilation; } diff --git a/src/share/vm/compiler/compileBroker.hpp b/src/share/vm/compiler/compileBroker.hpp --- a/src/share/vm/compiler/compileBroker.hpp +++ b/src/share/vm/compiler/compileBroker.hpp @@ -223,7 +223,7 @@ static void init_compiler_sweeper_threads(int c1_compiler_count, int c2_compiler_count); static bool compilation_is_complete (const methodHandle& method, int osr_bci, int comp_level); static bool compilation_is_prohibited(const methodHandle& method, int osr_bci, int comp_level); - static bool is_compile_blocking(); + static bool is_compile_blocking (const methodHandle& method, int comp_level); static void preload_classes (const methodHandle& method, TRAPS); static CompileTask* create_compile_task(CompileQueue* queue, diff --git a/src/share/vm/compiler/compilerDirectives.hpp b/src/share/vm/compiler/compilerDirectives.hpp --- a/src/share/vm/compiler/compilerDirectives.hpp +++ b/src/share/vm/compiler/compilerDirectives.hpp @@ -42,6 +42,7 @@ cflags(PrintAssembly, bool, PrintAssembly, PrintAssembly) \ cflags(PrintInlining, bool, PrintInlining, PrintInlining) \ cflags(PrintNMethods, bool, PrintNMethods, PrintNMethods) \ + cflags(BackgroundCompilation, bool, BackgroundCompilation, BackgroundCompilation) \ cflags(ReplayInline, bool, false, ReplayInline) \ cflags(DumpReplay, bool, false, DumpReplay) \ cflags(DumpInline, bool, false, DumpInline) \ diff --git a/src/share/vm/prims/whitebox.cpp b/src/share/vm/prims/whitebox.cpp --- a/src/share/vm/prims/whitebox.cpp +++ b/src/share/vm/prims/whitebox.cpp @@ -30,6 +30,7 @@ #include "classfile/stringTable.hpp" #include "code/codeCache.hpp" #include "compiler/methodMatcher.hpp" +#include "compiler/directivesParser.hpp" #include "jvmtifiles/jvmtiEnv.hpp" #include "memory/metadataFactory.hpp" #include "memory/metaspaceShared.hpp" @@ -1502,6 +1503,18 @@ } } +WB_ENTRY(void, WB_AddCompilerDirective(JNIEnv* env, jobject o, jstring compDirect)) + // can't be in VM when we call JNI + ThreadToNativeFromVM ttnfv(thread); + const char* dir = env->GetStringUTFChars(compDirect, NULL); + DirectivesParser::parse_string(dir, tty); + env->ReleaseStringUTFChars(compDirect, dir); +WB_END + +WB_ENTRY(void, WB_RemoveCompilerDirective(JNIEnv* env, jobject o)) + DirectivesStack::pop(); +WB_END + #define CC (char*) static JNINativeMethod methods[] = { @@ -1677,6 +1690,9 @@ {CC"isShared", CC"(Ljava/lang/Object;)Z", (void*)&WB_IsShared }, {CC"areSharedStringsIgnored", CC"()Z", (void*)&WB_AreSharedStringsIgnored }, {CC"clearInlineCaches", CC"()V", (void*)&WB_ClearInlineCaches }, + {CC"addCompilerDirective", CC"(Ljava/lang/String;)V", + (void*)&WB_AddCompilerDirective }, + {CC"removeCompilerDirective", CC"()V", (void*)&WB_RemoveCompilerDirective }, }; #undef CC diff --git a/src/share/vm/runtime/advancedThresholdPolicy.cpp b/src/share/vm/runtime/advancedThresholdPolicy.cpp --- a/src/share/vm/runtime/advancedThresholdPolicy.cpp +++ b/src/share/vm/runtime/advancedThresholdPolicy.cpp @@ -24,6 +24,8 @@ #include "precompiled.hpp" #include "code/codeCache.hpp" +#include "compiler/compilerDirectives.hpp" +#include "compiler/compilerOracle.hpp" #include "compiler/compileTask.hpp" #include "runtime/advancedThresholdPolicy.hpp" #include "runtime/simpleThresholdPolicy.inline.hpp" @@ -179,10 +181,24 @@ max_task = task; max_method = method; } else { + // Prefer 'blocking' compilations to minimize waits on them. + // This also helps to prevent blocking compiles from getting stale. + CompLevel level = (CompLevel)task->comp_level(); + bool backgroundCompilation; + DirectiveSet* directive = + DirectivesStack::getMatchingDirective(methodHandle(method), + CompileBroker::compiler(level)); + backgroundCompilation = directive->BackgroundCompilationOption; + DirectivesStack::release(directive); + if (backgroundCompilation == false) { + max_task = task; + max_method = method; + break; + } // If a method has been stale for some time, remove it from the queue. if (is_stale(t, TieredCompileTaskTimeout, method) && !is_old(method)) { if (PrintTieredEvents) { - print_event(REMOVE_FROM_QUEUE, method, method, task->osr_bci(), (CompLevel)task->comp_level()); + print_event(REMOVE_FROM_QUEUE, method, method, task->osr_bci(), level); } task->log_task_dequeued("stale"); compile_queue->remove_and_mark_stale(task);