8153013: BlockingCompilation test times out
Summary: Task has no invocation count and get stale at once
Reviewed-by: kvn, iveresov, twisti
--- a/hotspot/src/share/vm/ci/ciReplay.cpp Mon Apr 18 11:30:10 2016 +0200
+++ b/hotspot/src/share/vm/ci/ciReplay.cpp Wed Apr 13 14:48:22 2016 +0200
@@ -552,7 +552,7 @@
}
replay_state = this;
CompileBroker::compile_method(method, entry_bci, comp_level,
- methodHandle(), 0, "replay", THREAD);
+ methodHandle(), 0, CompileTask::Reason_Replay, THREAD);
replay_state = NULL;
reset();
}
--- a/hotspot/src/share/vm/classfile/classLoader.cpp Mon Apr 18 11:30:10 2016 +0200
+++ b/hotspot/src/share/vm/classfile/classLoader.cpp Wed Apr 13 14:48:22 2016 +0200
@@ -1642,7 +1642,7 @@
}
// Force compilation
CompileBroker::compile_method(m, InvocationEntryBci, comp_level,
- methodHandle(), 0, "CTW", THREAD);
+ methodHandle(), 0, CompileTask::Reason_CTW, THREAD);
if (HAS_PENDING_EXCEPTION) {
clear_pending_exception_if_not_oom(CHECK);
tty->print_cr("CompileTheWorld (%d) : Skipping method: %s", _compile_the_world_class_counter, m->name_and_sig_as_C_string());
@@ -1658,7 +1658,7 @@
m->clear_code();
}
CompileBroker::compile_method(m, InvocationEntryBci, CompLevel_full_optimization,
- methodHandle(), 0, "CTW", THREAD);
+ methodHandle(), 0, CompileTask::Reason_CTW, THREAD);
if (HAS_PENDING_EXCEPTION) {
clear_pending_exception_if_not_oom(CHECK);
tty->print_cr("CompileTheWorld (%d) : Skipping method: %s", _compile_the_world_class_counter, m->name_and_sig_as_C_string());
--- a/hotspot/src/share/vm/compiler/compileBroker.cpp Mon Apr 18 11:30:10 2016 +0200
+++ b/hotspot/src/share/vm/compiler/compileBroker.cpp Wed Apr 13 14:48:22 2016 +0200
@@ -169,6 +169,8 @@
CompileQueue* CompileBroker::_c2_compile_queue = NULL;
CompileQueue* CompileBroker::_c1_compile_queue = NULL;
+
+
class CompilationLog : public StringEventLog {
public:
CompilationLog() : StringEventLog("Compilation events") {
@@ -844,7 +846,7 @@
int comp_level,
const methodHandle& hot_method,
int hot_count,
- const char* comment,
+ CompileTask::CompileReason compile_reason,
bool blocking,
Thread* thread) {
guarantee(!method->is_abstract(), "cannot compile abstract methods");
@@ -860,7 +862,7 @@
if (osr_bci != InvocationEntryBci) {
tty->print(" osr_bci: %d", osr_bci);
}
- tty->print(" level: %d comment: %s count: %d", comp_level, comment, hot_count);
+ tty->print(" level: %d comment: %s count: %d", comp_level, CompileTask::reason_name(compile_reason), hot_count);
if (!hot_method.is_null()) {
tty->print(" hot: ");
if (hot_method() != method()) {
@@ -1024,7 +1026,7 @@
task = create_compile_task(queue,
compile_id, method,
osr_bci, comp_level,
- hot_method, hot_count, comment,
+ hot_method, hot_count, compile_reason,
blocking);
}
@@ -1036,7 +1038,8 @@
nmethod* CompileBroker::compile_method(const methodHandle& method, int osr_bci,
int comp_level,
const methodHandle& hot_method, int hot_count,
- const char* comment, Thread* THREAD) {
+ CompileTask::CompileReason compile_reason,
+ Thread* THREAD) {
// Do nothing if compilebroker is not initalized or compiles are submitted on level none
if (!_initialized || comp_level == CompLevel_none) {
return NULL;
@@ -1046,7 +1049,7 @@
assert(comp != NULL, "Ensure we have a compiler");
DirectiveSet* directive = DirectivesStack::getMatchingDirective(method, comp);
- nmethod* nm = CompileBroker::compile_method(method, osr_bci, comp_level, hot_method, hot_count, comment, directive, THREAD);
+ nmethod* nm = CompileBroker::compile_method(method, osr_bci, comp_level, hot_method, hot_count, compile_reason, directive, THREAD);
DirectivesStack::release(directive);
return nm;
}
@@ -1054,7 +1057,8 @@
nmethod* CompileBroker::compile_method(const methodHandle& method, int osr_bci,
int comp_level,
const methodHandle& hot_method, int hot_count,
- const char* comment, DirectiveSet* directive,
+ CompileTask::CompileReason compile_reason,
+ DirectiveSet* directive,
Thread* THREAD) {
// make sure arguments make sense
@@ -1180,7 +1184,7 @@
return NULL;
}
bool is_blocking = !directive->BackgroundCompilationOption || CompileTheWorld || ReplayCompiles;
- compile_method_base(method, osr_bci, comp_level, hot_method, hot_count, comment, is_blocking, THREAD);
+ compile_method_base(method, osr_bci, comp_level, hot_method, hot_count, compile_reason, is_blocking, THREAD);
}
// return requested nmethod
@@ -1344,11 +1348,11 @@
int comp_level,
const methodHandle& hot_method,
int hot_count,
- const char* comment,
+ CompileTask::CompileReason compile_reason,
bool blocking) {
CompileTask* new_task = CompileTask::allocate();
new_task->initialize(compile_id, method, osr_bci, comp_level,
- hot_method, hot_count, comment,
+ hot_method, hot_count, compile_reason,
blocking);
queue->add(new_task);
return new_task;
--- a/hotspot/src/share/vm/compiler/compileBroker.hpp Mon Apr 18 11:30:10 2016 +0200
+++ b/hotspot/src/share/vm/compiler/compileBroker.hpp Wed Apr 13 14:48:22 2016 +0200
@@ -232,7 +232,7 @@
int comp_level,
const methodHandle& hot_method,
int hot_count,
- const char* comment,
+ CompileTask::CompileReason compile_reason,
bool blocking);
static void wait_for_completion(CompileTask* task);
#if INCLUDE_JVMCI
@@ -251,7 +251,7 @@
int comp_level,
const methodHandle& hot_method,
int hot_count,
- const char* comment,
+ CompileTask::CompileReason compile_reason,
bool blocking,
Thread* thread);
@@ -289,14 +289,15 @@
int comp_level,
const methodHandle& hot_method,
int hot_count,
- const char* comment, Thread* thread);
+ CompileTask::CompileReason compile_reason,
+ Thread* thread);
static nmethod* compile_method(const methodHandle& method,
int osr_bci,
int comp_level,
const methodHandle& hot_method,
int hot_count,
- const char* comment,
+ CompileTask::CompileReason compile_reason,
DirectiveSet* directive,
Thread* thread);
--- a/hotspot/src/share/vm/compiler/compileTask.cpp Mon Apr 18 11:30:10 2016 +0200
+++ b/hotspot/src/share/vm/compiler/compileTask.cpp Wed Apr 13 14:48:22 2016 +0200
@@ -82,7 +82,7 @@
int comp_level,
const methodHandle& hot_method,
int hot_count,
- const char* comment,
+ CompileTask::CompileReason compile_reason,
bool is_blocking) {
assert(!_lock->is_locked(), "bad locking");
@@ -104,7 +104,7 @@
_hot_method_holder = NULL;
_hot_count = hot_count;
_time_queued = 0; // tidy
- _comment = comment;
+ _compile_reason = compile_reason;
_failure_reason = NULL;
if (LogCompilation) {
@@ -309,9 +309,9 @@
xtty->begin_elem("task_queued");
log_task(xtty);
- if (_comment != NULL) {
- xtty->print(" comment='%s'", _comment);
- }
+ assert(_compile_reason > CompileTask::Reason_None && _compile_reason < CompileTask::Reason_Count, "Valid values");
+ xtty->print(" comment='%s'", reason_name(_compile_reason));
+
if (_hot_method != NULL) {
methodHandle hot(thread, _hot_method);
methodHandle method(thread, _method);
@@ -440,3 +440,5 @@
}
st->cr();
}
+
+
--- a/hotspot/src/share/vm/compiler/compileTask.hpp Mon Apr 18 11:30:10 2016 +0200
+++ b/hotspot/src/share/vm/compiler/compileTask.hpp Wed Apr 13 14:48:22 2016 +0200
@@ -40,6 +40,39 @@
friend class VMStructs;
friend class JVMCIVMStructs;
+ public:
+ // Different reasons for a compilation
+ // The order is important - Reason_Whitebox and higher can not become
+ // stale, see CompileTask::can_become_stale()
+ // Also mapped to reason_names[]
+ enum CompileReason {
+ Reason_None,
+ Reason_InvocationCount, // Simple/StackWalk-policy
+ Reason_BackedgeCount, // Simple/StackWalk-policy
+ Reason_Tiered, // Tiered-policy
+ Reason_CTW, // Compile the world
+ Reason_Replay, // ciReplay
+ Reason_Whitebox, // Whitebox API
+ Reason_MustBeCompiled, // Java callHelper, LinkResolver
+ Reason_Bootstrap, // JVMCI bootstrap
+ Reason_Count
+ };
+
+ static const char* reason_name(CompileTask::CompileReason compile_reason) {
+ static const char* reason_names[] = {
+ "no_reason",
+ "count",
+ "backedge_count",
+ "tiered",
+ "CTW",
+ "replay",
+ "whitebox",
+ "must_be_compiled",
+ "bootstrap"
+ };
+ return reason_names[compile_reason];
+ }
+
private:
static CompileTask* _task_free_list;
#ifdef ASSERT
@@ -69,7 +102,7 @@
Method* _hot_method; // which method actually triggered this task
jobject _hot_method_holder;
int _hot_count; // information about its invocation counter
- const char* _comment; // more info about the task
+ CompileReason _compile_reason; // more info about the task
const char* _failure_reason;
public:
@@ -78,8 +111,8 @@
}
void initialize(int compile_id, const methodHandle& method, int osr_bci, int comp_level,
- const methodHandle& hot_method, int hot_count, const char* comment,
- bool is_blocking);
+ const methodHandle& hot_method, int hot_count,
+ CompileTask::CompileReason compile_reason, bool is_blocking);
static CompileTask* allocate();
static void free(CompileTask* task);
@@ -91,6 +124,15 @@
bool is_complete() const { return _is_complete; }
bool is_blocking() const { return _is_blocking; }
bool is_success() const { return _is_success; }
+ bool can_become_stale() const {
+ switch (_compile_reason) {
+ case Reason_BackedgeCount:
+ case Reason_InvocationCount:
+ case Reason_Tiered:
+ return !_is_blocking;
+ }
+ return false;
+ }
#if INCLUDE_JVMCI
bool has_waiter() const { return _has_waiter; }
void clear_waiter() { _has_waiter = false; }
--- a/hotspot/src/share/vm/jvmci/jvmciCompiler.cpp Mon Apr 18 11:30:10 2016 +0200
+++ b/hotspot/src/share/vm/jvmci/jvmciCompiler.cpp Wed Apr 13 14:48:22 2016 +0200
@@ -85,7 +85,7 @@
if (!mh->is_native() && !mh->is_static() && !mh->is_initializer()) {
ResourceMark rm;
int hot_count = 10; // TODO: what's the appropriate value?
- CompileBroker::compile_method(mh, InvocationEntryBci, CompLevel_full_optimization, mh, hot_count, "bootstrap", THREAD);
+ CompileBroker::compile_method(mh, InvocationEntryBci, CompLevel_full_optimization, mh, hot_count, CompileTask::Reason_Bootstrap, THREAD);
}
}
--- a/hotspot/src/share/vm/prims/whitebox.cpp Mon Apr 18 11:30:10 2016 +0200
+++ b/hotspot/src/share/vm/prims/whitebox.cpp Wed Apr 13 14:48:22 2016 +0200
@@ -646,7 +646,7 @@
return false;
}
methodHandle mh(THREAD, method);
- nmethod* nm = CompileBroker::compile_method(mh, bci, comp_level, mh, mh->invocation_count(), "WhiteBox", THREAD);
+ nmethod* nm = CompileBroker::compile_method(mh, bci, comp_level, mh, mh->invocation_count(), CompileTask::Reason_Whitebox, THREAD);
MutexLockerEx mu(Compile_lock);
return (mh->queued_for_compilation() || nm != NULL);
}
--- a/hotspot/src/share/vm/runtime/advancedThresholdPolicy.cpp Mon Apr 18 11:30:10 2016 +0200
+++ b/hotspot/src/share/vm/runtime/advancedThresholdPolicy.cpp Wed Apr 13 14:48:22 2016 +0200
@@ -191,8 +191,8 @@
max_method = method;
} else {
// If a method has been stale for some time, remove it from the queue.
- // Blocking tasks don't become stale
- if (!task->is_blocking() && is_stale(t, TieredCompileTaskTimeout, method) && !is_old(method)) {
+ // Blocking tasks and tasks submitted from whitebox API don't become stale
+ if (task->can_become_stale() && is_stale(t, TieredCompileTaskTimeout, method) && !is_old(method)) {
if (PrintTieredEvents) {
print_event(REMOVE_FROM_QUEUE, method, method, task->osr_bci(), (CompLevel)task->comp_level());
}
@@ -491,7 +491,7 @@
void AdvancedThresholdPolicy::submit_compile(const methodHandle& mh, int bci, CompLevel level, JavaThread* thread) {
int hot_count = (bci == InvocationEntryBci) ? mh->invocation_count() : mh->backedge_count();
update_rate(os::javaTimeMillis(), mh());
- CompileBroker::compile_method(mh, bci, level, mh, hot_count, "tiered", thread);
+ CompileBroker::compile_method(mh, bci, level, mh, hot_count, CompileTask::Reason_Tiered, thread);
}
// Handle the invocation event.
--- a/hotspot/src/share/vm/runtime/compilationPolicy.cpp Mon Apr 18 11:30:10 2016 +0200
+++ b/hotspot/src/share/vm/runtime/compilationPolicy.cpp Wed Apr 13 14:48:22 2016 +0200
@@ -130,7 +130,7 @@
}
CompileBroker::compile_method(selected_method, InvocationEntryBci,
CompilationPolicy::policy()->initial_compile_level(),
- methodHandle(), 0, "must_be_compiled", CHECK);
+ methodHandle(), 0, CompileTask::Reason_MustBeCompiled, CHECK);
}
}
@@ -508,12 +508,11 @@
const int comp_level = CompLevel_highest_tier;
const int hot_count = m->invocation_count();
reset_counter_for_invocation_event(m);
- const char* comment = "count";
if (is_compilation_enabled() && can_be_compiled(m, comp_level)) {
CompiledMethod* nm = m->code();
if (nm == NULL ) {
- CompileBroker::compile_method(m, InvocationEntryBci, comp_level, m, hot_count, comment, thread);
+ CompileBroker::compile_method(m, InvocationEntryBci, comp_level, m, hot_count, CompileTask::Reason_InvocationCount, thread);
}
}
}
@@ -521,10 +520,9 @@
void SimpleCompPolicy::method_back_branch_event(const methodHandle& m, int bci, JavaThread* thread) {
const int comp_level = CompLevel_highest_tier;
const int hot_count = m->backedge_count();
- const char* comment = "backedge_count";
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, CompileTask::Reason_BackedgeCount, thread);
NOT_PRODUCT(trace_osr_completion(m->lookup_osr_nmethod_for(bci, comp_level, true));)
}
}
@@ -539,7 +537,6 @@
const int comp_level = CompLevel_highest_tier;
const int hot_count = m->invocation_count();
reset_counter_for_invocation_event(m);
- const char* comment = "count";
if (is_compilation_enabled() && m->code() == NULL && can_be_compiled(m, comp_level)) {
ResourceMark rm(thread);
@@ -569,7 +566,7 @@
assert(top != NULL, "findTopInlinableFrame returned null");
if (TraceCompilationPolicy) top->print();
CompileBroker::compile_method(top->top_method(), InvocationEntryBci, comp_level,
- m, hot_count, comment, thread);
+ m, hot_count, CompileTask::Reason_InvocationCount, thread);
}
}
}
@@ -577,10 +574,9 @@
void StackWalkCompPolicy::method_back_branch_event(const methodHandle& m, int bci, JavaThread* thread) {
const int comp_level = CompLevel_highest_tier;
const int hot_count = m->backedge_count();
- const char* comment = "backedge_count";
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, CompileTask::Reason_BackedgeCount, thread);
NOT_PRODUCT(trace_osr_completion(m->lookup_osr_nmethod_for(bci, comp_level, true));)
}
}
--- a/hotspot/src/share/vm/runtime/simpleThresholdPolicy.cpp Mon Apr 18 11:30:10 2016 +0200
+++ b/hotspot/src/share/vm/runtime/simpleThresholdPolicy.cpp Wed Apr 13 14:48:22 2016 +0200
@@ -265,7 +265,7 @@
// Tell the broker to compile the method
void SimpleThresholdPolicy::submit_compile(const methodHandle& mh, int bci, CompLevel level, JavaThread* thread) {
int hot_count = (bci == InvocationEntryBci) ? mh->invocation_count() : mh->backedge_count();
- CompileBroker::compile_method(mh, bci, level, mh, hot_count, "tiered", thread);
+ CompileBroker::compile_method(mh, bci, level, mh, hot_count, CompileTask::Reason_Tiered, thread);
}
// Call and loop predicates determine whether a transition to a higher
--- a/hotspot/test/compiler/whitebox/BlockingCompilation.java Mon Apr 18 11:30:10 2016 +0200
+++ b/hotspot/test/compiler/whitebox/BlockingCompilation.java Wed Apr 13 14:48:22 2016 +0200
@@ -23,14 +23,13 @@
/*
* @test
- * @bug 8150646
+ * @bug 8150646 8153013
* @summary Add support for blocking compiles through whitebox API
* @library /testlibrary /test/lib /
* @build sun.hotspot.WhiteBox
* compiler.testlibrary.CompilerUtils
- * @run main ClassFileInstaller sun.hotspot.WhiteBox
- * sun.hotspot.WhiteBox$WhiteBoxPermission
- *
+ * @run driver ClassFileInstaller sun.hotspot.WhiteBox
+ * sun.hotspot.WhiteBox$WhiteBoxPermission
* @run main/othervm/timeout=60
* -Xbootclasspath/a:.
* -Xmixed
@@ -40,11 +39,10 @@
* BlockingCompilation
*/
+import compiler.testlibrary.CompilerUtils;
import java.lang.reflect.Method;
import java.util.Random;
-
import sun.hotspot.WhiteBox;
-import compiler.testlibrary.CompilerUtils;
public class BlockingCompilation {
private static final WhiteBox WB = WhiteBox.getWhiteBox();
@@ -77,7 +75,13 @@
// If the compiles are blocking, this call will block until the test time out,
// Progress == success
// (Don't run with -Xcomp since that can cause long timeouts due to many compiles)
- WB.enqueueMethodForCompilation(m, highest_level);
+ if (!WB.enqueueMethodForCompilation(m, highest_level)) {
+ throw new Exception("Failed to enqueue method on level: " + highest_level);
+ }
+
+ if (!WB.isMethodQueuedForCompilation(m)) {
+ throw new Exception("Must be enqueued because of locked compilation");
+ }
// restore state
WB.unlockCompilation();