提交 a360982b 编写于 作者: I iignatyev

8022832: Add WB APIs for OSR compilation

Reviewed-by: kvn
上级 abc7536a
...@@ -747,6 +747,7 @@ void Method::set_not_compilable(int comp_level, bool report, const char* reason) ...@@ -747,6 +747,7 @@ void Method::set_not_compilable(int comp_level, bool report, const char* reason)
set_not_c2_compilable(); set_not_c2_compilable();
} }
CompilationPolicy::policy()->disable_compilation(this); CompilationPolicy::policy()->disable_compilation(this);
assert(!CompilationPolicy::can_be_compiled(this, comp_level), "sanity check");
} }
bool Method::is_not_osr_compilable(int comp_level) const { bool Method::is_not_osr_compilable(int comp_level) const {
...@@ -773,6 +774,7 @@ void Method::set_not_osr_compilable(int comp_level, bool report, const char* rea ...@@ -773,6 +774,7 @@ void Method::set_not_osr_compilable(int comp_level, bool report, const char* rea
set_not_c2_osr_compilable(); set_not_c2_osr_compilable();
} }
CompilationPolicy::policy()->disable_compilation(this); CompilationPolicy::policy()->disable_compilation(this);
assert(!CompilationPolicy::can_be_osr_compiled(this, comp_level), "sanity check");
} }
// Revert to using the interpreter and clear out the nmethod // Revert to using the interpreter and clear out the nmethod
......
...@@ -196,12 +196,22 @@ WB_ENTRY(void, WB_DeoptimizeAll(JNIEnv* env, jobject o)) ...@@ -196,12 +196,22 @@ WB_ENTRY(void, WB_DeoptimizeAll(JNIEnv* env, jobject o))
VMThread::execute(&op); VMThread::execute(&op);
WB_END WB_END
WB_ENTRY(jint, WB_DeoptimizeMethod(JNIEnv* env, jobject o, jobject method)) WB_ENTRY(jint, WB_DeoptimizeMethod(JNIEnv* env, jobject o, jobject method, jboolean is_osr))
jmethodID jmid = reflected_method_to_jmid(thread, env, method); jmethodID jmid = reflected_method_to_jmid(thread, env, method);
MutexLockerEx mu(Compile_lock); MutexLockerEx mu(Compile_lock);
methodHandle mh(THREAD, Method::checked_resolve_jmethod_id(jmid)); methodHandle mh(THREAD, Method::checked_resolve_jmethod_id(jmid));
int result = 0; int result = 0;
nmethod* code = mh->code(); nmethod* code;
if (is_osr) {
int bci = InvocationEntryBci;
while ((code = mh->lookup_osr_nmethod_for(bci, CompLevel_none, false)) != NULL) {
code->mark_for_deoptimization();
++result;
bci = code->osr_entry_bci() + 1;
}
} else {
code = mh->code();
}
if (code != NULL) { if (code != NULL) {
code->mark_for_deoptimization(); code->mark_for_deoptimization();
++result; ++result;
...@@ -214,22 +224,26 @@ WB_ENTRY(jint, WB_DeoptimizeMethod(JNIEnv* env, jobject o, jobject method)) ...@@ -214,22 +224,26 @@ WB_ENTRY(jint, WB_DeoptimizeMethod(JNIEnv* env, jobject o, jobject method))
return result; return result;
WB_END WB_END
WB_ENTRY(jboolean, WB_IsMethodCompiled(JNIEnv* env, jobject o, jobject method)) WB_ENTRY(jboolean, WB_IsMethodCompiled(JNIEnv* env, jobject o, jobject method, jboolean is_osr))
jmethodID jmid = reflected_method_to_jmid(thread, env, method); jmethodID jmid = reflected_method_to_jmid(thread, env, method);
MutexLockerEx mu(Compile_lock); MutexLockerEx mu(Compile_lock);
methodHandle mh(THREAD, Method::checked_resolve_jmethod_id(jmid)); methodHandle mh(THREAD, Method::checked_resolve_jmethod_id(jmid));
nmethod* code = mh->code(); nmethod* code = is_osr ? mh->lookup_osr_nmethod_for(InvocationEntryBci, CompLevel_none, false) : mh->code();
if (code == NULL) { if (code == NULL) {
return JNI_FALSE; return JNI_FALSE;
} }
return (code->is_alive() && !code->is_marked_for_deoptimization()); return (code->is_alive() && !code->is_marked_for_deoptimization());
WB_END WB_END
WB_ENTRY(jboolean, WB_IsMethodCompilable(JNIEnv* env, jobject o, jobject method, jint comp_level)) WB_ENTRY(jboolean, WB_IsMethodCompilable(JNIEnv* env, jobject o, jobject method, jint comp_level, jboolean is_osr))
jmethodID jmid = reflected_method_to_jmid(thread, env, method); jmethodID jmid = reflected_method_to_jmid(thread, env, method);
MutexLockerEx mu(Compile_lock); MutexLockerEx mu(Compile_lock);
methodHandle mh(THREAD, Method::checked_resolve_jmethod_id(jmid)); methodHandle mh(THREAD, Method::checked_resolve_jmethod_id(jmid));
return CompilationPolicy::can_be_compiled(mh, comp_level); if (is_osr) {
return CompilationPolicy::can_be_osr_compiled(mh, comp_level);
} else {
return CompilationPolicy::can_be_compiled(mh, comp_level);
}
WB_END WB_END
WB_ENTRY(jboolean, WB_IsMethodQueuedForCompilation(JNIEnv* env, jobject o, jobject method)) WB_ENTRY(jboolean, WB_IsMethodQueuedForCompilation(JNIEnv* env, jobject o, jobject method))
...@@ -239,18 +253,28 @@ WB_ENTRY(jboolean, WB_IsMethodQueuedForCompilation(JNIEnv* env, jobject o, jobje ...@@ -239,18 +253,28 @@ WB_ENTRY(jboolean, WB_IsMethodQueuedForCompilation(JNIEnv* env, jobject o, jobje
return mh->queued_for_compilation(); return mh->queued_for_compilation();
WB_END WB_END
WB_ENTRY(jint, WB_GetMethodCompilationLevel(JNIEnv* env, jobject o, jobject method)) WB_ENTRY(jint, WB_GetMethodCompilationLevel(JNIEnv* env, jobject o, jobject method, jboolean is_osr))
jmethodID jmid = reflected_method_to_jmid(thread, env, method); jmethodID jmid = reflected_method_to_jmid(thread, env, method);
methodHandle mh(THREAD, Method::checked_resolve_jmethod_id(jmid)); methodHandle mh(THREAD, Method::checked_resolve_jmethod_id(jmid));
nmethod* code = mh->code(); nmethod* code = is_osr ? mh->lookup_osr_nmethod_for(InvocationEntryBci, CompLevel_none, false) : mh->code();
return (code != NULL ? code->comp_level() : CompLevel_none); return (code != NULL ? code->comp_level() : CompLevel_none);
WB_END WB_END
WB_ENTRY(void, WB_MakeMethodNotCompilable(JNIEnv* env, jobject o, jobject method, jint comp_level, jboolean is_osr))
jmethodID jmid = reflected_method_to_jmid(thread, env, method);
methodHandle mh(THREAD, Method::checked_resolve_jmethod_id(jmid));
if (is_osr) {
mh->set_not_osr_compilable(comp_level, true /* report */, "WhiteBox");
} else {
mh->set_not_compilable(comp_level, true /* report */, "WhiteBox");
}
WB_END
WB_ENTRY(void, WB_MakeMethodNotCompilable(JNIEnv* env, jobject o, jobject method, jint comp_level)) WB_ENTRY(jint, WB_GetMethodEntryBci(JNIEnv* env, jobject o, jobject method))
jmethodID jmid = reflected_method_to_jmid(thread, env, method); jmethodID jmid = reflected_method_to_jmid(thread, env, method);
methodHandle mh(THREAD, Method::checked_resolve_jmethod_id(jmid)); methodHandle mh(THREAD, Method::checked_resolve_jmethod_id(jmid));
mh->set_not_compilable(comp_level, true /* report */, "WhiteBox"); nmethod* code = mh->lookup_osr_nmethod_for(InvocationEntryBci, CompLevel_none, false);
return (code != NULL && code->is_osr_method() ? code->osr_entry_bci() : InvocationEntryBci);
WB_END WB_END
WB_ENTRY(jboolean, WB_TestSetDontInlineMethod(JNIEnv* env, jobject o, jobject method, jboolean value)) WB_ENTRY(jboolean, WB_TestSetDontInlineMethod(JNIEnv* env, jobject o, jobject method, jboolean value))
...@@ -261,12 +285,15 @@ WB_ENTRY(jboolean, WB_TestSetDontInlineMethod(JNIEnv* env, jobject o, jobject me ...@@ -261,12 +285,15 @@ WB_ENTRY(jboolean, WB_TestSetDontInlineMethod(JNIEnv* env, jobject o, jobject me
return result; return result;
WB_END WB_END
WB_ENTRY(jint, WB_GetCompileQueuesSize(JNIEnv* env, jobject o)) WB_ENTRY(jint, WB_GetCompileQueueSize(JNIEnv* env, jobject o, jint comp_level))
return CompileBroker::queue_size(CompLevel_full_optimization) /* C2 */ + if (comp_level == CompLevel_any) {
CompileBroker::queue_size(CompLevel_full_profile) /* C1 */; return CompileBroker::queue_size(CompLevel_full_optimization) /* C2 */ +
CompileBroker::queue_size(CompLevel_full_profile) /* C1 */;
} else {
return CompileBroker::queue_size(comp_level);
}
WB_END WB_END
WB_ENTRY(jboolean, WB_TestSetForceInlineMethod(JNIEnv* env, jobject o, jobject method, jboolean value)) WB_ENTRY(jboolean, WB_TestSetForceInlineMethod(JNIEnv* env, jobject o, jobject method, jboolean value))
jmethodID jmid = reflected_method_to_jmid(thread, env, method); jmethodID jmid = reflected_method_to_jmid(thread, env, method);
methodHandle mh(THREAD, Method::checked_resolve_jmethod_id(jmid)); methodHandle mh(THREAD, Method::checked_resolve_jmethod_id(jmid));
...@@ -275,10 +302,10 @@ WB_ENTRY(jboolean, WB_TestSetForceInlineMethod(JNIEnv* env, jobject o, jobject m ...@@ -275,10 +302,10 @@ WB_ENTRY(jboolean, WB_TestSetForceInlineMethod(JNIEnv* env, jobject o, jobject m
return result; return result;
WB_END WB_END
WB_ENTRY(jboolean, WB_EnqueueMethodForCompilation(JNIEnv* env, jobject o, jobject method, jint comp_level)) WB_ENTRY(jboolean, WB_EnqueueMethodForCompilation(JNIEnv* env, jobject o, jobject method, jint comp_level, jint bci))
jmethodID jmid = reflected_method_to_jmid(thread, env, method); jmethodID jmid = reflected_method_to_jmid(thread, env, method);
methodHandle mh(THREAD, Method::checked_resolve_jmethod_id(jmid)); methodHandle mh(THREAD, Method::checked_resolve_jmethod_id(jmid));
nmethod* nm = CompileBroker::compile_method(mh, InvocationEntryBci, comp_level, mh, mh->invocation_count(), "WhiteBox", THREAD); nmethod* nm = CompileBroker::compile_method(mh, bci, comp_level, mh, mh->invocation_count(), "WhiteBox", THREAD);
MutexLockerEx mu(Compile_lock); MutexLockerEx mu(Compile_lock);
return (mh->queued_for_compilation() || nm != NULL); return (mh->queued_for_compilation() || nm != NULL);
WB_END WB_END
...@@ -324,7 +351,6 @@ WB_ENTRY(jboolean, WB_IsInStringTable(JNIEnv* env, jobject o, jstring javaString ...@@ -324,7 +351,6 @@ WB_ENTRY(jboolean, WB_IsInStringTable(JNIEnv* env, jobject o, jstring javaString
return (StringTable::lookup(name, len) != NULL); return (StringTable::lookup(name, len) != NULL);
WB_END WB_END
WB_ENTRY(void, WB_FullGC(JNIEnv* env, jobject o)) WB_ENTRY(void, WB_FullGC(JNIEnv* env, jobject o))
Universe::heap()->collector_policy()->set_should_clear_all_soft_refs(true); Universe::heap()->collector_policy()->set_should_clear_all_soft_refs(true);
Universe::heap()->collect(GCCause::_last_ditch_collection); Universe::heap()->collect(GCCause::_last_ditch_collection);
...@@ -423,31 +449,32 @@ static JNINativeMethod methods[] = { ...@@ -423,31 +449,32 @@ static JNINativeMethod methods[] = {
{CC"NMTWaitForDataMerge", CC"()Z", (void*)&WB_NMTWaitForDataMerge}, {CC"NMTWaitForDataMerge", CC"()Z", (void*)&WB_NMTWaitForDataMerge},
#endif // INCLUDE_NMT #endif // INCLUDE_NMT
{CC"deoptimizeAll", CC"()V", (void*)&WB_DeoptimizeAll }, {CC"deoptimizeAll", CC"()V", (void*)&WB_DeoptimizeAll },
{CC"deoptimizeMethod", CC"(Ljava/lang/reflect/Executable;)I", {CC"deoptimizeMethod", CC"(Ljava/lang/reflect/Executable;Z)I",
(void*)&WB_DeoptimizeMethod }, (void*)&WB_DeoptimizeMethod },
{CC"isMethodCompiled", CC"(Ljava/lang/reflect/Executable;)Z", {CC"isMethodCompiled", CC"(Ljava/lang/reflect/Executable;Z)Z",
(void*)&WB_IsMethodCompiled }, (void*)&WB_IsMethodCompiled },
{CC"isMethodCompilable", CC"(Ljava/lang/reflect/Executable;I)Z", {CC"isMethodCompilable", CC"(Ljava/lang/reflect/Executable;IZ)Z",
(void*)&WB_IsMethodCompilable}, (void*)&WB_IsMethodCompilable},
{CC"isMethodQueuedForCompilation", {CC"isMethodQueuedForCompilation",
CC"(Ljava/lang/reflect/Executable;)Z", (void*)&WB_IsMethodQueuedForCompilation}, CC"(Ljava/lang/reflect/Executable;)Z", (void*)&WB_IsMethodQueuedForCompilation},
{CC"makeMethodNotCompilable", {CC"makeMethodNotCompilable",
CC"(Ljava/lang/reflect/Executable;I)V", (void*)&WB_MakeMethodNotCompilable}, CC"(Ljava/lang/reflect/Executable;IZ)V", (void*)&WB_MakeMethodNotCompilable},
{CC"testSetDontInlineMethod", {CC"testSetDontInlineMethod",
CC"(Ljava/lang/reflect/Executable;Z)Z", (void*)&WB_TestSetDontInlineMethod}, CC"(Ljava/lang/reflect/Executable;Z)Z", (void*)&WB_TestSetDontInlineMethod},
{CC"getMethodCompilationLevel", {CC"getMethodCompilationLevel",
CC"(Ljava/lang/reflect/Executable;)I", (void*)&WB_GetMethodCompilationLevel}, CC"(Ljava/lang/reflect/Executable;Z)I", (void*)&WB_GetMethodCompilationLevel},
{CC"getCompileQueuesSize", {CC"getMethodEntryBci",
CC"()I", (void*)&WB_GetCompileQueuesSize}, CC"(Ljava/lang/reflect/Executable;)I", (void*)&WB_GetMethodEntryBci},
{CC"getCompileQueueSize",
CC"(I)I", (void*)&WB_GetCompileQueueSize},
{CC"testSetForceInlineMethod", {CC"testSetForceInlineMethod",
CC"(Ljava/lang/reflect/Executable;Z)Z", (void*)&WB_TestSetForceInlineMethod}, CC"(Ljava/lang/reflect/Executable;Z)Z", (void*)&WB_TestSetForceInlineMethod},
{CC"enqueueMethodForCompilation", {CC"enqueueMethodForCompilation",
CC"(Ljava/lang/reflect/Executable;I)Z", (void*)&WB_EnqueueMethodForCompilation}, CC"(Ljava/lang/reflect/Executable;II)Z", (void*)&WB_EnqueueMethodForCompilation},
{CC"clearMethodState", {CC"clearMethodState",
CC"(Ljava/lang/reflect/Executable;)V", (void*)&WB_ClearMethodState}, CC"(Ljava/lang/reflect/Executable;)V", (void*)&WB_ClearMethodState},
{CC"isInStringTable", CC"(Ljava/lang/String;)Z", (void*)&WB_IsInStringTable }, {CC"isInStringTable", CC"(Ljava/lang/String;)Z", (void*)&WB_IsInStringTable },
{CC"fullGC", CC"()V", (void*)&WB_FullGC }, {CC"fullGC", CC"()V", (void*)&WB_FullGC },
{CC"readReservedMemory", CC"()V", (void*)&WB_ReadReservedMemory }, {CC"readReservedMemory", CC"()V", (void*)&WB_ReadReservedMemory },
}; };
......
...@@ -138,6 +138,23 @@ bool CompilationPolicy::can_be_compiled(methodHandle m, int comp_level) { ...@@ -138,6 +138,23 @@ bool CompilationPolicy::can_be_compiled(methodHandle m, int comp_level) {
return false; return false;
} }
// Returns true if m is allowed to be osr compiled
bool CompilationPolicy::can_be_osr_compiled(methodHandle m, int comp_level) {
bool result = false;
if (comp_level == CompLevel_all) {
if (TieredCompilation) {
// enough to be osr compilable at any level for tiered
result = !m->is_not_osr_compilable(CompLevel_simple) || !m->is_not_osr_compilable(CompLevel_full_optimization);
} else {
// must be osr compilable at available level for non-tiered
result = !m->is_not_osr_compilable(CompLevel_highest_tier);
}
} else if (is_compile(comp_level)) {
result = !m->is_not_osr_compilable(comp_level);
}
return (result && can_be_compiled(m, comp_level));
}
bool CompilationPolicy::is_compilation_enabled() { bool CompilationPolicy::is_compilation_enabled() {
// NOTE: CompileBroker::should_compile_new_jobs() checks for UseCompiler // NOTE: CompileBroker::should_compile_new_jobs() checks for UseCompiler
return !delay_compilation_during_startup() && CompileBroker::should_compile_new_jobs(); return !delay_compilation_during_startup() && CompileBroker::should_compile_new_jobs();
...@@ -458,7 +475,7 @@ void SimpleCompPolicy::method_back_branch_event(methodHandle m, int bci, JavaThr ...@@ -458,7 +475,7 @@ void SimpleCompPolicy::method_back_branch_event(methodHandle m, int bci, JavaThr
const int hot_count = m->backedge_count(); const int hot_count = m->backedge_count();
const char* comment = "backedge_count"; const char* comment = "backedge_count";
if (is_compilation_enabled() && !m->is_not_osr_compilable(comp_level) && can_be_compiled(m, comp_level)) { if (is_compilation_enabled() && can_be_osr_compiled(m, comp_level)) {
CompileBroker::compile_method(m, bci, comp_level, m, hot_count, comment, thread); CompileBroker::compile_method(m, bci, comp_level, m, hot_count, comment, thread);
NOT_PRODUCT(trace_osr_completion(m->lookup_osr_nmethod_for(bci, comp_level, true));) NOT_PRODUCT(trace_osr_completion(m->lookup_osr_nmethod_for(bci, comp_level, true));)
} }
...@@ -514,7 +531,7 @@ void StackWalkCompPolicy::method_back_branch_event(methodHandle m, int bci, Java ...@@ -514,7 +531,7 @@ void StackWalkCompPolicy::method_back_branch_event(methodHandle m, int bci, Java
const int hot_count = m->backedge_count(); const int hot_count = m->backedge_count();
const char* comment = "backedge_count"; const char* comment = "backedge_count";
if (is_compilation_enabled() && !m->is_not_osr_compilable(comp_level) && can_be_compiled(m, comp_level)) { if (is_compilation_enabled() && can_be_osr_compiled(m, comp_level)) {
CompileBroker::compile_method(m, bci, comp_level, m, hot_count, comment, thread); CompileBroker::compile_method(m, bci, comp_level, m, hot_count, comment, thread);
NOT_PRODUCT(trace_osr_completion(m->lookup_osr_nmethod_for(bci, comp_level, true));) NOT_PRODUCT(trace_osr_completion(m->lookup_osr_nmethod_for(bci, comp_level, true));)
} }
......
...@@ -52,6 +52,8 @@ public: ...@@ -52,6 +52,8 @@ public:
static bool must_be_compiled(methodHandle m, int comp_level = CompLevel_all); static bool must_be_compiled(methodHandle m, int comp_level = CompLevel_all);
// m is allowed to be compiled // m is allowed to be compiled
static bool can_be_compiled(methodHandle m, int comp_level = CompLevel_all); static bool can_be_compiled(methodHandle m, int comp_level = CompLevel_all);
// m is allowed to be osr compiled
static bool can_be_osr_compiled(methodHandle m, int comp_level = CompLevel_all);
static bool is_compilation_enabled(); static bool is_compilation_enabled();
static void set_policy(CompilationPolicy* policy) { _policy = policy; } static void set_policy(CompilationPolicy* policy) { _policy = policy; }
static CompilationPolicy* policy() { return _policy; } static CompilationPolicy* policy() { return _policy; }
......
...@@ -23,6 +23,7 @@ ...@@ -23,6 +23,7 @@
/* /*
* @test ClearMethodStateTest * @test ClearMethodStateTest
* @bug 8006683 8007288 8022832
* @library /testlibrary /testlibrary/whitebox * @library /testlibrary /testlibrary/whitebox
* @build ClearMethodStateTest * @build ClearMethodStateTest
* @run main ClassFileInstaller sun.hotspot.WhiteBox * @run main ClassFileInstaller sun.hotspot.WhiteBox
...@@ -59,16 +60,19 @@ public class ClearMethodStateTest extends CompilerWhiteBoxTest { ...@@ -59,16 +60,19 @@ public class ClearMethodStateTest extends CompilerWhiteBoxTest {
WHITE_BOX.clearMethodState(method); WHITE_BOX.clearMethodState(method);
checkCompiled(); checkCompiled();
WHITE_BOX.clearMethodState(method); WHITE_BOX.clearMethodState(method);
WHITE_BOX.deoptimizeMethod(method); deoptimize();
checkNotCompiled(); checkNotCompiled();
if (testCase.isOsr) {
// part test isn't applicable for OSR test case
return;
}
if (!TIERED_COMPILATION) { if (!TIERED_COMPILATION) {
WHITE_BOX.clearMethodState(method); WHITE_BOX.clearMethodState(method);
compile(COMPILE_THRESHOLD); compile(COMPILE_THRESHOLD);
checkCompiled(); checkCompiled();
WHITE_BOX.deoptimizeMethod(method); deoptimize();
checkNotCompiled(); checkNotCompiled();
WHITE_BOX.clearMethodState(method); WHITE_BOX.clearMethodState(method);
......
...@@ -44,8 +44,14 @@ public abstract class CompilerWhiteBoxTest { ...@@ -44,8 +44,14 @@ public abstract class CompilerWhiteBoxTest {
protected static int COMP_LEVEL_ANY = -1; protected static int COMP_LEVEL_ANY = -1;
/** {@code CompLevel::CompLevel_simple} -- C1 */ /** {@code CompLevel::CompLevel_simple} -- C1 */
protected static int COMP_LEVEL_SIMPLE = 1; protected static int COMP_LEVEL_SIMPLE = 1;
/** {@code CompLevel::CompLevel_limited_profile} -- C1, invocation & backedge counters */
protected static int COMP_LEVEL_LIMITED_PROFILE = 2;
/** {@code CompLevel::CompLevel_full_profile} -- C1, invocation & backedge counters + mdo */
protected static int COMP_LEVEL_FULL_PROFILE = 3;
/** {@code CompLevel::CompLevel_full_optimization} -- C2 or Shark */ /** {@code CompLevel::CompLevel_full_optimization} -- C2 or Shark */
protected static int COMP_LEVEL_FULL_OPTIMIZATION = 4; protected static int COMP_LEVEL_FULL_OPTIMIZATION = 4;
/** Maximal value for CompLeveL */
protected static int COMP_LEVEL_MAX = COMP_LEVEL_FULL_OPTIMIZATION;
/** Instance of WhiteBox */ /** Instance of WhiteBox */
protected static final WhiteBox WHITE_BOX = WhiteBox.getWhiteBox(); protected static final WhiteBox WHITE_BOX = WhiteBox.getWhiteBox();
...@@ -64,6 +70,21 @@ public abstract class CompilerWhiteBoxTest { ...@@ -64,6 +70,21 @@ public abstract class CompilerWhiteBoxTest {
/** Flag for verbose output, true if {@code -Dverbose} specified */ /** Flag for verbose output, true if {@code -Dverbose} specified */
protected static final boolean IS_VERBOSE protected static final boolean IS_VERBOSE
= System.getProperty("verbose") != null; = System.getProperty("verbose") != null;
/** count of invocation to triger compilation */
protected static final int THRESHOLD;
/** count of invocation to triger OSR compilation */
protected static final long BACKEDGE_THRESHOLD;
static {
if (TIERED_COMPILATION) {
THRESHOLD = 150000;
BACKEDGE_THRESHOLD = 0xFFFFFFFFL;
} else {
THRESHOLD = COMPILE_THRESHOLD;
BACKEDGE_THRESHOLD = COMPILE_THRESHOLD * Long.parseLong(getVMOption(
"OnStackReplacePercentage"));
}
}
/** /**
* Returns value of VM option. * Returns value of VM option.
...@@ -112,7 +133,7 @@ public abstract class CompilerWhiteBoxTest { ...@@ -112,7 +133,7 @@ public abstract class CompilerWhiteBoxTest {
/** tested method */ /** tested method */
protected final Executable method; protected final Executable method;
private final Callable<Integer> callable; protected final TestCase testCase;
/** /**
* Constructor. * Constructor.
...@@ -123,7 +144,7 @@ public abstract class CompilerWhiteBoxTest { ...@@ -123,7 +144,7 @@ public abstract class CompilerWhiteBoxTest {
Objects.requireNonNull(testCase); Objects.requireNonNull(testCase);
System.out.println("TEST CASE:" + testCase.name()); System.out.println("TEST CASE:" + testCase.name());
method = testCase.executable; method = testCase.executable;
callable = testCase.callable; this.testCase = testCase;
} }
/** /**
...@@ -169,12 +190,18 @@ public abstract class CompilerWhiteBoxTest { ...@@ -169,12 +190,18 @@ public abstract class CompilerWhiteBoxTest {
if (WHITE_BOX.isMethodQueuedForCompilation(method)) { if (WHITE_BOX.isMethodQueuedForCompilation(method)) {
throw new RuntimeException(method + " must not be in queue"); throw new RuntimeException(method + " must not be in queue");
} }
if (WHITE_BOX.isMethodCompiled(method)) { if (WHITE_BOX.isMethodCompiled(method, false)) {
throw new RuntimeException(method + " must be not compiled"); throw new RuntimeException(method + " must be not compiled");
} }
if (WHITE_BOX.getMethodCompilationLevel(method) != 0) { if (WHITE_BOX.getMethodCompilationLevel(method, false) != 0) {
throw new RuntimeException(method + " comp_level must be == 0"); throw new RuntimeException(method + " comp_level must be == 0");
} }
if (WHITE_BOX.isMethodCompiled(method, true)) {
throw new RuntimeException(method + " must be not osr_compiled");
}
if (WHITE_BOX.getMethodCompilationLevel(method, true) != 0) {
throw new RuntimeException(method + " osr_comp_level must be == 0");
}
} }
/** /**
...@@ -192,14 +219,46 @@ public abstract class CompilerWhiteBoxTest { ...@@ -192,14 +219,46 @@ public abstract class CompilerWhiteBoxTest {
method, System.currentTimeMillis() - start); method, System.currentTimeMillis() - start);
return; return;
} }
if (!WHITE_BOX.isMethodCompiled(method)) { if (!WHITE_BOX.isMethodCompiled(method, testCase.isOsr)) {
throw new RuntimeException(method + " must be compiled"); throw new RuntimeException(method + " must be "
+ (testCase.isOsr ? "osr_" : "") + "compiled");
} }
if (WHITE_BOX.getMethodCompilationLevel(method) == 0) { if (WHITE_BOX.getMethodCompilationLevel(method, testCase.isOsr) == 0) {
throw new RuntimeException(method + " comp_level must be != 0"); throw new RuntimeException(method
+ (testCase.isOsr ? " osr_" : " ")
+ "comp_level must be != 0");
}
}
protected final void deoptimize() {
WHITE_BOX.deoptimizeMethod(method, testCase.isOsr);
if (testCase.isOsr) {
WHITE_BOX.deoptimizeMethod(method, false);
} }
} }
protected final int getCompLevel() {
return WHITE_BOX.getMethodCompilationLevel(method, testCase.isOsr);
}
protected final boolean isCompilable() {
return WHITE_BOX.isMethodCompilable(method, COMP_LEVEL_ANY,
testCase.isOsr);
}
protected final boolean isCompilable(int compLevel) {
return WHITE_BOX.isMethodCompilable(method, compLevel, testCase.isOsr);
}
protected final void makeNotCompilable() {
WHITE_BOX.makeMethodNotCompilable(method, COMP_LEVEL_ANY,
testCase.isOsr);
}
protected final void makeNotCompilable(int compLevel) {
WHITE_BOX.makeMethodNotCompilable(method, compLevel, testCase.isOsr);
}
/** /**
* Waits for completion of background compilation of {@linkplain #method}. * Waits for completion of background compilation of {@linkplain #method}.
*/ */
...@@ -226,12 +285,18 @@ public abstract class CompilerWhiteBoxTest { ...@@ -226,12 +285,18 @@ public abstract class CompilerWhiteBoxTest {
protected final void printInfo() { protected final void printInfo() {
System.out.printf("%n%s:%n", method); System.out.printf("%n%s:%n", method);
System.out.printf("\tcompilable:\t%b%n", System.out.printf("\tcompilable:\t%b%n",
WHITE_BOX.isMethodCompilable(method)); WHITE_BOX.isMethodCompilable(method, COMP_LEVEL_ANY, false));
System.out.printf("\tcompiled:\t%b%n", System.out.printf("\tcompiled:\t%b%n",
WHITE_BOX.isMethodCompiled(method)); WHITE_BOX.isMethodCompiled(method, false));
System.out.printf("\tcomp_level:\t%d%n", System.out.printf("\tcomp_level:\t%d%n",
WHITE_BOX.getMethodCompilationLevel(method)); WHITE_BOX.getMethodCompilationLevel(method, false));
System.out.printf("\tin_queue:\t%b%n", System.out.printf("\tosr_compilable:\t%b%n",
WHITE_BOX.isMethodCompilable(method, COMP_LEVEL_ANY, true));
System.out.printf("\tosr_compiled:\t%b%n",
WHITE_BOX.isMethodCompiled(method, true));
System.out.printf("\tosr_comp_level:\t%d%n",
WHITE_BOX.getMethodCompilationLevel(method, true));
System.out.printf("\tin_queue:\t%b%n",
WHITE_BOX.isMethodQueuedForCompilation(method)); WHITE_BOX.isMethodQueuedForCompilation(method));
System.out.printf("compile_queues_size:\t%d%n%n", System.out.printf("compile_queues_size:\t%d%n%n",
WHITE_BOX.getCompileQueuesSize()); WHITE_BOX.getCompileQueuesSize());
...@@ -244,18 +309,22 @@ public abstract class CompilerWhiteBoxTest { ...@@ -244,18 +309,22 @@ public abstract class CompilerWhiteBoxTest {
/** /**
* Tries to trigger compilation of {@linkplain #method} by call * Tries to trigger compilation of {@linkplain #method} by call
* {@linkplain #callable} enough times. * {@linkplain #testCase.callable} enough times.
* *
* @return accumulated result * @return accumulated result
* @see #compile(int) * @see #compile(int)
*/ */
protected final int compile() { protected final int compile() {
return compile(Math.max(COMPILE_THRESHOLD, 150000)); if (testCase.isOsr) {
return compile(1);
} else {
return compile(THRESHOLD);
}
} }
/** /**
* Tries to trigger compilation of {@linkplain #method} by call * Tries to trigger compilation of {@linkplain #method} by call
* {@linkplain #callable} specified times. * {@linkplain #testCase.callable} specified times.
* *
* @param count invocation count * @param count invocation count
* @return accumulated result * @return accumulated result
...@@ -265,7 +334,7 @@ public abstract class CompilerWhiteBoxTest { ...@@ -265,7 +334,7 @@ public abstract class CompilerWhiteBoxTest {
Integer tmp; Integer tmp;
for (int i = 0; i < count; ++i) { for (int i = 0; i < count; ++i) {
try { try {
tmp = callable.call(); tmp = testCase.callable.call();
} catch (Exception e) { } catch (Exception e) {
tmp = null; tmp = null;
} }
...@@ -283,23 +352,36 @@ public abstract class CompilerWhiteBoxTest { ...@@ -283,23 +352,36 @@ public abstract class CompilerWhiteBoxTest {
*/ */
enum TestCase { enum TestCase {
/** constructor test case */ /** constructor test case */
CONSTRUCTOR_TEST(Helper.CONSTRUCTOR, Helper.CONSTRUCTOR_CALLABLE), CONSTRUCTOR_TEST(Helper.CONSTRUCTOR, Helper.CONSTRUCTOR_CALLABLE, false),
/** method test case */ /** method test case */
METOD_TEST(Helper.METHOD, Helper.METHOD_CALLABLE), METOD_TEST(Helper.METHOD, Helper.METHOD_CALLABLE, false),
/** static method test case */ /** static method test case */
STATIC_TEST(Helper.STATIC, Helper.STATIC_CALLABLE); STATIC_TEST(Helper.STATIC, Helper.STATIC_CALLABLE, false),
/** OSR constructor test case */
OSR_CONSTRUCTOR_TEST(Helper.OSR_CONSTRUCTOR,
Helper.OSR_CONSTRUCTOR_CALLABLE, true),
/** OSR method test case */
OSR_METOD_TEST(Helper.OSR_METHOD, Helper.OSR_METHOD_CALLABLE, true),
/** OSR static method test case */
OSR_STATIC_TEST(Helper.OSR_STATIC, Helper.OSR_STATIC_CALLABLE, true);
/** tested method */ /** tested method */
final Executable executable; final Executable executable;
/** object to invoke {@linkplain #executable} */ /** object to invoke {@linkplain #executable} */
final Callable<Integer> callable; final Callable<Integer> callable;
/** flag for OSR test case */
final boolean isOsr;
private TestCase(Executable executable, Callable<Integer> callable) { private TestCase(Executable executable, Callable<Integer> callable,
boolean isOsr) {
this.executable = executable; this.executable = executable;
this.callable = callable; this.callable = callable;
this.isOsr = isOsr;
} }
private static class Helper { private static class Helper {
private static final Callable<Integer> CONSTRUCTOR_CALLABLE private static final Callable<Integer> CONSTRUCTOR_CALLABLE
= new Callable<Integer>() { = new Callable<Integer>() {
@Override @Override
...@@ -326,9 +408,39 @@ enum TestCase { ...@@ -326,9 +408,39 @@ enum TestCase {
} }
}; };
private static final Callable<Integer> OSR_CONSTRUCTOR_CALLABLE
= new Callable<Integer>() {
@Override
public Integer call() throws Exception {
return new Helper(null).hashCode();
}
};
private static final Callable<Integer> OSR_METHOD_CALLABLE
= new Callable<Integer>() {
private final Helper helper = new Helper();
@Override
public Integer call() throws Exception {
return helper.osrMethod();
}
};
private static final Callable<Integer> OSR_STATIC_CALLABLE
= new Callable<Integer>() {
@Override
public Integer call() throws Exception {
return osrStaticMethod();
}
};
private static final Constructor CONSTRUCTOR; private static final Constructor CONSTRUCTOR;
private static final Constructor OSR_CONSTRUCTOR;
private static final Method METHOD; private static final Method METHOD;
private static final Method STATIC; private static final Method STATIC;
private static final Method OSR_METHOD;
private static final Method OSR_STATIC;
static { static {
try { try {
...@@ -338,17 +450,26 @@ enum TestCase { ...@@ -338,17 +450,26 @@ enum TestCase {
"exception on getting method Helper.<init>(int)", e); "exception on getting method Helper.<init>(int)", e);
} }
try { try {
METHOD = Helper.class.getDeclaredMethod("method"); OSR_CONSTRUCTOR = Helper.class.getDeclaredConstructor(
Object.class);
} catch (NoSuchMethodException | SecurityException e) { } catch (NoSuchMethodException | SecurityException e) {
throw new RuntimeException( throw new RuntimeException(
"exception on getting method Helper.method()", e); "exception on getting method Helper.<init>(Object)", e);
} }
METHOD = getMethod("method");
STATIC = getMethod("staticMethod");
OSR_METHOD = getMethod("osrMethod");
OSR_STATIC = getMethod("osrStaticMethod");
}
private static Method getMethod(String name) {
try { try {
STATIC = Helper.class.getDeclaredMethod("staticMethod"); return Helper.class.getDeclaredMethod(name);
} catch (NoSuchMethodException | SecurityException e) { } catch (NoSuchMethodException | SecurityException e) {
throw new RuntimeException( throw new RuntimeException(
"exception on getting method Helper.staticMethod()", e); "exception on getting method Helper." + name, e);
} }
} }
private static int staticMethod() { private static int staticMethod() {
...@@ -359,12 +480,39 @@ enum TestCase { ...@@ -359,12 +480,39 @@ enum TestCase {
return 42; return 42;
} }
private static int osrStaticMethod() {
int result = 0;
for (long i = 0; i < CompilerWhiteBoxTest.BACKEDGE_THRESHOLD; ++i) {
result += staticMethod();
}
return result;
}
private int osrMethod() {
int result = 0;
for (long i = 0; i < CompilerWhiteBoxTest.BACKEDGE_THRESHOLD; ++i) {
result += method();
}
return result;
}
private final int x; private final int x;
// for method and OSR method test case
public Helper() { public Helper() {
x = 0; x = 0;
} }
// for OSR constructor test case
private Helper(Object o) {
int result = 0;
for (long i = 0; i < CompilerWhiteBoxTest.BACKEDGE_THRESHOLD; ++i) {
result += method();
}
x = result;
}
// for constructor test case
private Helper(int x) { private Helper(int x) {
this.x = x; this.x = x;
} }
......
...@@ -23,6 +23,7 @@ ...@@ -23,6 +23,7 @@
/* /*
* @test DeoptimizeAllTest * @test DeoptimizeAllTest
* @bug 8006683 8007288 8022832
* @library /testlibrary /testlibrary/whitebox * @library /testlibrary /testlibrary/whitebox
* @build DeoptimizeAllTest * @build DeoptimizeAllTest
* @run main ClassFileInstaller sun.hotspot.WhiteBox * @run main ClassFileInstaller sun.hotspot.WhiteBox
......
...@@ -23,6 +23,7 @@ ...@@ -23,6 +23,7 @@
/* /*
* @test DeoptimizeMethodTest * @test DeoptimizeMethodTest
* @bug 8006683 8007288 8022832
* @library /testlibrary /testlibrary/whitebox * @library /testlibrary /testlibrary/whitebox
* @build DeoptimizeMethodTest * @build DeoptimizeMethodTest
* @run main ClassFileInstaller sun.hotspot.WhiteBox * @run main ClassFileInstaller sun.hotspot.WhiteBox
...@@ -54,7 +55,7 @@ public class DeoptimizeMethodTest extends CompilerWhiteBoxTest { ...@@ -54,7 +55,7 @@ public class DeoptimizeMethodTest extends CompilerWhiteBoxTest {
protected void test() throws Exception { protected void test() throws Exception {
compile(); compile();
checkCompiled(); checkCompiled();
WHITE_BOX.deoptimizeMethod(method); deoptimize();
checkNotCompiled(); checkNotCompiled();
} }
} }
...@@ -23,10 +23,11 @@ ...@@ -23,10 +23,11 @@
/* /*
* @test EnqueueMethodForCompilationTest * @test EnqueueMethodForCompilationTest
* @bug 8006683 8007288 8022832
* @library /testlibrary /testlibrary/whitebox * @library /testlibrary /testlibrary/whitebox
* @build EnqueueMethodForCompilationTest * @build EnqueueMethodForCompilationTest
* @run main ClassFileInstaller sun.hotspot.WhiteBox * @run main ClassFileInstaller sun.hotspot.WhiteBox
* @run main/othervm -Xbootclasspath/a:. -Xmixed -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -XX:CompileCommand=compileonly,TestCase$Helper::* EnqueueMethodForCompilationTest * @run main/othervm/timeout=600 -Xbootclasspath/a:. -Xmixed -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -XX:CompileCommand=compileonly,TestCase$Helper::* EnqueueMethodForCompilationTest
* @summary testing of WB::enqueueMethodForCompilation() * @summary testing of WB::enqueueMethodForCompilation()
* @author igor.ignatyev@oracle.com * @author igor.ignatyev@oracle.com
*/ */
...@@ -50,7 +51,7 @@ public class EnqueueMethodForCompilationTest extends CompilerWhiteBoxTest { ...@@ -50,7 +51,7 @@ public class EnqueueMethodForCompilationTest extends CompilerWhiteBoxTest {
// method can not be compiled on level 'none' // method can not be compiled on level 'none'
WHITE_BOX.enqueueMethodForCompilation(method, COMP_LEVEL_NONE); WHITE_BOX.enqueueMethodForCompilation(method, COMP_LEVEL_NONE);
if (WHITE_BOX.isMethodCompilable(method, COMP_LEVEL_NONE)) { if (isCompilable(COMP_LEVEL_NONE)) {
throw new RuntimeException(method throw new RuntimeException(method
+ " is compilable at level COMP_LEVEL_NONE"); + " is compilable at level COMP_LEVEL_NONE");
} }
...@@ -60,27 +61,29 @@ public class EnqueueMethodForCompilationTest extends CompilerWhiteBoxTest { ...@@ -60,27 +61,29 @@ public class EnqueueMethodForCompilationTest extends CompilerWhiteBoxTest {
WHITE_BOX.enqueueMethodForCompilation(method, COMP_LEVEL_ANY); WHITE_BOX.enqueueMethodForCompilation(method, COMP_LEVEL_ANY);
checkNotCompiled(); checkNotCompiled();
WHITE_BOX.enqueueMethodForCompilation(method, 5); // not existing comp level
if (!WHITE_BOX.isMethodCompilable(method, 5)) { WHITE_BOX.enqueueMethodForCompilation(method, 42);
checkNotCompiled();
compile();
checkCompiled();
} else {
checkCompiled();
}
int compLevel = WHITE_BOX.getMethodCompilationLevel(method);
WHITE_BOX.deoptimizeMethod(method);
checkNotCompiled(); checkNotCompiled();
WHITE_BOX.enqueueMethodForCompilation(method, compLevel); compile();
checkCompiled();
int compLevel = getCompLevel();
int bci = WHITE_BOX.getMethodEntryBci(method);
System.out.println("bci = " + bci);
printInfo();
deoptimize();
printInfo();
checkNotCompiled();
printInfo();
WHITE_BOX.enqueueMethodForCompilation(method, compLevel, bci);
checkCompiled(); checkCompiled();
WHITE_BOX.deoptimizeMethod(method); deoptimize();
checkNotCompiled(); checkNotCompiled();
compile(); compile();
checkCompiled(); checkCompiled();
WHITE_BOX.deoptimizeMethod(method); deoptimize();
checkNotCompiled(); checkNotCompiled();
} }
} }
...@@ -23,11 +23,11 @@ ...@@ -23,11 +23,11 @@
/* /*
* @test IsMethodCompilableTest * @test IsMethodCompilableTest
* @bug 8007270 * @bug 8007270 8006683 8007288 8022832
* @library /testlibrary /testlibrary/whitebox * @library /testlibrary /testlibrary/whitebox
* @build IsMethodCompilableTest * @build IsMethodCompilableTest
* @run main ClassFileInstaller sun.hotspot.WhiteBox * @run main ClassFileInstaller sun.hotspot.WhiteBox
* @run main/othervm/timeout=600 -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -XX:CompileCommand=compileonly,TestCase$Helper::* IsMethodCompilableTest * @run main/othervm/timeout=2400 -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -XX:CompileCommand=compileonly,TestCase$Helper::* IsMethodCompilableTest
* @summary testing of WB::isMethodCompilable() * @summary testing of WB::isMethodCompilable()
* @author igor.ignatyev@oracle.com * @author igor.ignatyev@oracle.com
*/ */
...@@ -68,7 +68,7 @@ public class IsMethodCompilableTest extends CompilerWhiteBoxTest { ...@@ -68,7 +68,7 @@ public class IsMethodCompilableTest extends CompilerWhiteBoxTest {
*/ */
@Override @Override
protected void test() throws Exception { protected void test() throws Exception {
if (!WHITE_BOX.isMethodCompilable(method)) { if (!isCompilable()) {
throw new RuntimeException(method + " must be compilable"); throw new RuntimeException(method + " must be compilable");
} }
System.out.println("PerMethodRecompilationCutoff = " System.out.println("PerMethodRecompilationCutoff = "
...@@ -83,7 +83,8 @@ public class IsMethodCompilableTest extends CompilerWhiteBoxTest { ...@@ -83,7 +83,8 @@ public class IsMethodCompilableTest extends CompilerWhiteBoxTest {
for (long i = 0L, n = PER_METHOD_RECOMPILATION_CUTOFF - 1; i < n; ++i) { for (long i = 0L, n = PER_METHOD_RECOMPILATION_CUTOFF - 1; i < n; ++i) {
compileAndDeoptimize(); compileAndDeoptimize();
} }
if (!WHITE_BOX.isMethodCompilable(method)) { if (!testCase.isOsr && !isCompilable()) {
// in osr test case count of deopt maybe more than iterations
throw new RuntimeException(method + " is not compilable after " throw new RuntimeException(method + " is not compilable after "
+ (PER_METHOD_RECOMPILATION_CUTOFF - 1) + " iterations"); + (PER_METHOD_RECOMPILATION_CUTOFF - 1) + " iterations");
} }
...@@ -92,15 +93,16 @@ public class IsMethodCompilableTest extends CompilerWhiteBoxTest { ...@@ -92,15 +93,16 @@ public class IsMethodCompilableTest extends CompilerWhiteBoxTest {
// deoptimize 'PerMethodRecompilationCutoff' + 1 times // deoptimize 'PerMethodRecompilationCutoff' + 1 times
long i; long i;
for (i = 0L; i < PER_METHOD_RECOMPILATION_CUTOFF for (i = 0L; i < PER_METHOD_RECOMPILATION_CUTOFF
&& WHITE_BOX.isMethodCompilable(method); ++i) { && isCompilable(); ++i) {
compileAndDeoptimize(); compileAndDeoptimize();
} }
if (i != PER_METHOD_RECOMPILATION_CUTOFF) { if (!testCase.isOsr && i != PER_METHOD_RECOMPILATION_CUTOFF) {
// in osr test case count of deopt maybe more than iterations
throw new RuntimeException(method + " is not compilable after " throw new RuntimeException(method + " is not compilable after "
+ i + " iterations, but must only after " + i + " iterations, but must only after "
+ PER_METHOD_RECOMPILATION_CUTOFF); + PER_METHOD_RECOMPILATION_CUTOFF);
} }
if (WHITE_BOX.isMethodCompilable(method)) { if (isCompilable()) {
throw new RuntimeException(method + " is still compilable after " throw new RuntimeException(method + " is still compilable after "
+ PER_METHOD_RECOMPILATION_CUTOFF + " iterations"); + PER_METHOD_RECOMPILATION_CUTOFF + " iterations");
} }
...@@ -109,7 +111,7 @@ public class IsMethodCompilableTest extends CompilerWhiteBoxTest { ...@@ -109,7 +111,7 @@ public class IsMethodCompilableTest extends CompilerWhiteBoxTest {
// WB.clearMethodState() must reset no-compilable flags // WB.clearMethodState() must reset no-compilable flags
WHITE_BOX.clearMethodState(method); WHITE_BOX.clearMethodState(method);
if (!WHITE_BOX.isMethodCompilable(method)) { if (!isCompilable()) {
throw new RuntimeException(method throw new RuntimeException(method
+ " is not compilable after clearMethodState()"); + " is not compilable after clearMethodState()");
} }
...@@ -120,6 +122,6 @@ public class IsMethodCompilableTest extends CompilerWhiteBoxTest { ...@@ -120,6 +122,6 @@ public class IsMethodCompilableTest extends CompilerWhiteBoxTest {
private void compileAndDeoptimize() throws Exception { private void compileAndDeoptimize() throws Exception {
compile(); compile();
waitBackgroundCompilation(); waitBackgroundCompilation();
WHITE_BOX.deoptimizeMethod(method); deoptimize();
} }
} }
...@@ -23,16 +23,16 @@ ...@@ -23,16 +23,16 @@
/* /*
* @test MakeMethodNotCompilableTest * @test MakeMethodNotCompilableTest
* @bug 8012322 * @bug 8012322 8006683 8007288 8022832
* @library /testlibrary /testlibrary/whitebox * @library /testlibrary /testlibrary/whitebox
* @build MakeMethodNotCompilableTest * @build MakeMethodNotCompilableTest
* @run main ClassFileInstaller sun.hotspot.WhiteBox * @run main ClassFileInstaller sun.hotspot.WhiteBox
* @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -XX:CompileCommand=compileonly,TestCase$Helper::* MakeMethodNotCompilableTest * @run main/othervm/timeout=2400 -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -XX:CompileCommand=compileonly,TestCase$Helper::* MakeMethodNotCompilableTest
* @summary testing of WB::makeMethodNotCompilable() * @summary testing of WB::makeMethodNotCompilable()
* @author igor.ignatyev@oracle.com * @author igor.ignatyev@oracle.com
*/ */
public class MakeMethodNotCompilableTest extends CompilerWhiteBoxTest { public class MakeMethodNotCompilableTest extends CompilerWhiteBoxTest {
private int bci;
public static void main(String[] args) throws Exception { public static void main(String[] args) throws Exception {
if (args.length == 0) { if (args.length == 0) {
for (TestCase test : TestCase.values()) { for (TestCase test : TestCase.values()) {
...@@ -63,25 +63,27 @@ public class MakeMethodNotCompilableTest extends CompilerWhiteBoxTest { ...@@ -63,25 +63,27 @@ public class MakeMethodNotCompilableTest extends CompilerWhiteBoxTest {
@Override @Override
protected void test() throws Exception { protected void test() throws Exception {
checkNotCompiled(); checkNotCompiled();
if (!WHITE_BOX.isMethodCompilable(method)) { if (!isCompilable()) {
throw new RuntimeException(method + " must be compilable"); throw new RuntimeException(method + " must be compilable");
} }
bci = getBci();
if (TIERED_COMPILATION) { if (TIERED_COMPILATION) {
final int tierLimit = TIERED_STOP_AT_LEVEL + 1; final int tierLimit = TIERED_STOP_AT_LEVEL + 1;
for (int testedTier = 1; testedTier < tierLimit; ++testedTier) { for (int testedTier = 1; testedTier < tierLimit; ++testedTier) {
testTier(testedTier); testTier(testedTier);
} }
for (int testedTier = 1; testedTier < tierLimit; ++testedTier) { for (int testedTier = 1; testedTier < tierLimit; ++testedTier) {
WHITE_BOX.makeMethodNotCompilable(method, testedTier); makeNotCompilable(testedTier);
if (WHITE_BOX.isMethodCompilable(method, testedTier)) { if (isCompilable(testedTier)) {
throw new RuntimeException(method throw new RuntimeException(method
+ " must be not compilable at level" + testedTier); + " must be not compilable at level" + testedTier);
} }
WHITE_BOX.enqueueMethodForCompilation(method, testedTier); WHITE_BOX.enqueueMethodForCompilation(method, testedTier, bci);
checkNotCompiled(); checkNotCompiled();
if (!WHITE_BOX.isMethodCompilable(method)) { if (!isCompilable()) {
System.out.println(method System.out.println(method
+ " is not compilable after level " + testedTier); + " is not compilable after level " + testedTier);
} }
...@@ -89,15 +91,20 @@ public class MakeMethodNotCompilableTest extends CompilerWhiteBoxTest { ...@@ -89,15 +91,20 @@ public class MakeMethodNotCompilableTest extends CompilerWhiteBoxTest {
} else { } else {
compile(); compile();
checkCompiled(); checkCompiled();
int compLevel = WHITE_BOX.getMethodCompilationLevel(method); int compLevel = getCompLevel();
WHITE_BOX.deoptimizeMethod(method); deoptimize();
WHITE_BOX.makeMethodNotCompilable(method, compLevel); makeNotCompilable(compLevel);
if (WHITE_BOX.isMethodCompilable(method, COMP_LEVEL_ANY)) { if (isCompilable(COMP_LEVEL_ANY)) {
throw new RuntimeException(method throw new RuntimeException(method
+ " must be not compilable at CompLevel::CompLevel_any," + " must be not compilable at CompLevel::CompLevel_any,"
+ " after it is not compilable at " + compLevel); + " after it is not compilable at " + compLevel);
} }
WHITE_BOX.clearMethodState(method); WHITE_BOX.clearMethodState(method);
if (!isCompilable()) {
throw new RuntimeException(method
+ " is not compilable after clearMethodState()");
}
// nocompilable at opposite level must make no sense // nocompilable at opposite level must make no sense
int oppositeLevel; int oppositeLevel;
...@@ -106,16 +113,16 @@ public class MakeMethodNotCompilableTest extends CompilerWhiteBoxTest { ...@@ -106,16 +113,16 @@ public class MakeMethodNotCompilableTest extends CompilerWhiteBoxTest {
} else { } else {
oppositeLevel = COMP_LEVEL_SIMPLE; oppositeLevel = COMP_LEVEL_SIMPLE;
} }
WHITE_BOX.makeMethodNotCompilable(method, oppositeLevel); makeNotCompilable(oppositeLevel);
if (!WHITE_BOX.isMethodCompilable(method, COMP_LEVEL_ANY)) { if (!isCompilable(COMP_LEVEL_ANY)) {
throw new RuntimeException(method throw new RuntimeException(method
+ " must be compilable at CompLevel::CompLevel_any," + " must be compilable at CompLevel::CompLevel_any,"
+ " even it is not compilable at opposite level [" + " even it is not compilable at opposite level ["
+ compLevel + "]"); + compLevel + "]");
} }
if (!WHITE_BOX.isMethodCompilable(method, compLevel)) { if (!isCompilable(compLevel)) {
throw new RuntimeException(method throw new RuntimeException(method
+ " must be compilable at level " + compLevel + " must be compilable at level " + compLevel
+ ", even it is not compilable at opposite level [" + ", even it is not compilable at opposite level ["
...@@ -126,24 +133,24 @@ public class MakeMethodNotCompilableTest extends CompilerWhiteBoxTest { ...@@ -126,24 +133,24 @@ public class MakeMethodNotCompilableTest extends CompilerWhiteBoxTest {
// clearing after tiered/non-tiered tests // clearing after tiered/non-tiered tests
// WB.clearMethodState() must reset no-compilable flags // WB.clearMethodState() must reset no-compilable flags
WHITE_BOX.clearMethodState(method); WHITE_BOX.clearMethodState(method);
if (!WHITE_BOX.isMethodCompilable(method)) { if (!isCompilable()) {
throw new RuntimeException(method throw new RuntimeException(method
+ " is not compilable after clearMethodState()"); + " is not compilable after clearMethodState()");
} }
WHITE_BOX.makeMethodNotCompilable(method); makeNotCompilable();
if (WHITE_BOX.isMethodCompilable(method)) { if (isCompilable()) {
throw new RuntimeException(method + " must be not compilable"); throw new RuntimeException(method + " must be not compilable");
} }
compile(); compile();
checkNotCompiled(); checkNotCompiled();
if (WHITE_BOX.isMethodCompilable(method)) { if (isCompilable()) {
throw new RuntimeException(method + " must be not compilable"); throw new RuntimeException(method + " must be not compilable");
} }
// WB.clearMethodState() must reset no-compilable flags // WB.clearMethodState() must reset no-compilable flags
WHITE_BOX.clearMethodState(method); WHITE_BOX.clearMethodState(method);
if (!WHITE_BOX.isMethodCompilable(method)) { if (!isCompilable()) {
throw new RuntimeException(method throw new RuntimeException(method
+ " is not compilable after clearMethodState()"); + " is not compilable after clearMethodState()");
} }
...@@ -153,24 +160,23 @@ public class MakeMethodNotCompilableTest extends CompilerWhiteBoxTest { ...@@ -153,24 +160,23 @@ public class MakeMethodNotCompilableTest extends CompilerWhiteBoxTest {
// separately tests each tier // separately tests each tier
private void testTier(int testedTier) { private void testTier(int testedTier) {
if (!WHITE_BOX.isMethodCompilable(method, testedTier)) { if (!isCompilable(testedTier)) {
throw new RuntimeException(method throw new RuntimeException(method
+ " is not compilable on start"); + " is not compilable on start");
} }
WHITE_BOX.makeMethodNotCompilable(method, testedTier); makeNotCompilable(testedTier);
// tests for all other tiers // tests for all other tiers
for (int anotherTier = 1, tierLimit = TIERED_STOP_AT_LEVEL + 1; for (int anotherTier = 1, tierLimit = TIERED_STOP_AT_LEVEL + 1;
anotherTier < tierLimit; ++anotherTier) { anotherTier < tierLimit; ++anotherTier) {
boolean isCompilable = WHITE_BOX.isMethodCompilable(method, boolean isCompilable = isCompilable(anotherTier);
anotherTier);
if (sameCompile(testedTier, anotherTier)) { if (sameCompile(testedTier, anotherTier)) {
if (isCompilable) { if (isCompilable) {
throw new RuntimeException(method throw new RuntimeException(method
+ " must be not compilable at level " + anotherTier + " must be not compilable at level " + anotherTier
+ ", if it is not compilable at " + testedTier); + ", if it is not compilable at " + testedTier);
} }
WHITE_BOX.enqueueMethodForCompilation(method, anotherTier); WHITE_BOX.enqueueMethodForCompilation(method, anotherTier, bci);
checkNotCompiled(); checkNotCompiled();
} else { } else {
if (!isCompilable) { if (!isCompilable) {
...@@ -179,12 +185,12 @@ public class MakeMethodNotCompilableTest extends CompilerWhiteBoxTest { ...@@ -179,12 +185,12 @@ public class MakeMethodNotCompilableTest extends CompilerWhiteBoxTest {
+ ", even if it is not compilable at " + ", even if it is not compilable at "
+ testedTier); + testedTier);
} }
WHITE_BOX.enqueueMethodForCompilation(method, anotherTier); WHITE_BOX.enqueueMethodForCompilation(method, anotherTier, bci);
checkCompiled(); checkCompiled();
WHITE_BOX.deoptimizeMethod(method); deoptimize();
} }
if (!WHITE_BOX.isMethodCompilable(method, COMP_LEVEL_ANY)) { if (!isCompilable(COMP_LEVEL_ANY)) {
throw new RuntimeException(method throw new RuntimeException(method
+ " must be compilable at 'CompLevel::CompLevel_any'" + " must be compilable at 'CompLevel::CompLevel_any'"
+ ", if it is not compilable only at " + testedTier); + ", if it is not compilable only at " + testedTier);
...@@ -193,7 +199,7 @@ public class MakeMethodNotCompilableTest extends CompilerWhiteBoxTest { ...@@ -193,7 +199,7 @@ public class MakeMethodNotCompilableTest extends CompilerWhiteBoxTest {
// clear state after test // clear state after test
WHITE_BOX.clearMethodState(method); WHITE_BOX.clearMethodState(method);
if (!WHITE_BOX.isMethodCompilable(method, testedTier)) { if (!isCompilable(testedTier)) {
throw new RuntimeException(method throw new RuntimeException(method
+ " is not compilable after clearMethodState()"); + " is not compilable after clearMethodState()");
} }
...@@ -211,4 +217,13 @@ public class MakeMethodNotCompilableTest extends CompilerWhiteBoxTest { ...@@ -211,4 +217,13 @@ public class MakeMethodNotCompilableTest extends CompilerWhiteBoxTest {
} }
return false; return false;
} }
private int getBci() {
compile();
checkCompiled();
int result = WHITE_BOX.getMethodEntryBci(method);
deoptimize();
WHITE_BOX.clearMethodState(method);
return result;
}
} }
...@@ -23,6 +23,7 @@ ...@@ -23,6 +23,7 @@
/* /*
* @test SetDontInlineMethodTest * @test SetDontInlineMethodTest
* @bug 8006683 8007288 8022832
* @library /testlibrary /testlibrary/whitebox * @library /testlibrary /testlibrary/whitebox
* @build SetDontInlineMethodTest * @build SetDontInlineMethodTest
* @run main ClassFileInstaller sun.hotspot.WhiteBox * @run main ClassFileInstaller sun.hotspot.WhiteBox
......
...@@ -23,6 +23,7 @@ ...@@ -23,6 +23,7 @@
/* /*
* @test SetForceInlineMethodTest * @test SetForceInlineMethodTest
* @bug 8006683 8007288 8022832
* @library /testlibrary /testlibrary/whitebox * @library /testlibrary /testlibrary/whitebox
* @build SetForceInlineMethodTest * @build SetForceInlineMethodTest
* @run main ClassFileInstaller sun.hotspot.WhiteBox * @run main ClassFileInstaller sun.hotspot.WhiteBox
......
...@@ -93,23 +93,45 @@ public class WhiteBox { ...@@ -93,23 +93,45 @@ public class WhiteBox {
// Compiler // Compiler
public native void deoptimizeAll(); public native void deoptimizeAll();
public native boolean isMethodCompiled(Executable method); public boolean isMethodCompiled(Executable method) {
public boolean isMethodCompilable(Executable method) { return isMethodCompiled(method, false /*not osr*/);
return isMethodCompilable(method, -1 /*any*/);
} }
public native boolean isMethodCompilable(Executable method, int compLevel); public native boolean isMethodCompiled(Executable method, boolean isOsr);
public boolean isMethodCompilable(Executable method) {
return isMethodCompilable(method, -1 /*any*/);
}
public boolean isMethodCompilable(Executable method, int compLevel) {
return isMethodCompilable(method, compLevel, false /*not osr*/);
}
public native boolean isMethodCompilable(Executable method, int compLevel, boolean isOsr);
public native boolean isMethodQueuedForCompilation(Executable method); public native boolean isMethodQueuedForCompilation(Executable method);
public native int deoptimizeMethod(Executable method); public int deoptimizeMethod(Executable method) {
public void makeMethodNotCompilable(Executable method) { return deoptimizeMethod(method, false /*not osr*/);
makeMethodNotCompilable(method, -1 /*any*/); }
public native int deoptimizeMethod(Executable method, boolean isOsr);
public void makeMethodNotCompilable(Executable method) {
makeMethodNotCompilable(method, -1 /*any*/);
}
public void makeMethodNotCompilable(Executable method, int compLevel) {
makeMethodNotCompilable(method, compLevel, false /*not osr*/);
} }
public native void makeMethodNotCompilable(Executable method, int compLevel); public native void makeMethodNotCompilable(Executable method, int compLevel, boolean isOsr);
public native int getMethodCompilationLevel(Executable method); public int getMethodCompilationLevel(Executable method) {
return getMethodCompilationLevel(method, false /*not ost*/);
}
public native int getMethodCompilationLevel(Executable method, boolean isOsr);
public native boolean testSetDontInlineMethod(Executable method, boolean value); public native boolean testSetDontInlineMethod(Executable method, boolean value);
public native int getCompileQueuesSize(); public int getCompileQueuesSize() {
return getCompileQueueSize(-1 /*any*/);
}
public native int getCompileQueueSize(int compLevel);
public native boolean testSetForceInlineMethod(Executable method, boolean value); public native boolean testSetForceInlineMethod(Executable method, boolean value);
public native boolean enqueueMethodForCompilation(Executable method, int compLevel); public boolean enqueueMethodForCompilation(Executable method, int compLevel) {
return enqueueMethodForCompilation(method, compLevel, -1 /*InvocationEntryBci*/);
}
public native boolean enqueueMethodForCompilation(Executable method, int compLevel, int entry_bci);
public native void clearMethodState(Executable method); public native void clearMethodState(Executable method);
public native int getMethodEntryBci(Executable method);
// Intered strings // Intered strings
public native boolean isInStringTable(String str); public native boolean isInStringTable(String str);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册