8023461: Thread holding lock at safepoint that vm can block on: MethodCompileQueue_lock

Reviewed-by: kvn, iveresov
This commit is contained in:
Vladimir Ivanov 2014-03-11 15:06:34 +04:00
parent 54db2c2d61
commit 38d80b03c4
5 changed files with 86 additions and 33 deletions

View file

@ -704,13 +704,39 @@ CompileTask* CompileQueue::get() {
return NULL;
}
CompileTask* task = CompilationPolicy::policy()->select_task(this);
CompileTask* task;
{
No_Safepoint_Verifier nsv;
task = CompilationPolicy::policy()->select_task(this);
}
remove(task);
purge_stale_tasks(); // may temporarily release MCQ lock
return task;
}
void CompileQueue::remove(CompileTask* task)
{
// Clean & deallocate stale compile tasks.
// Temporarily releases MethodCompileQueue lock.
void CompileQueue::purge_stale_tasks() {
assert(lock()->owned_by_self(), "must own lock");
if (_first_stale != NULL) {
// Stale tasks are purged when MCQ lock is released,
// but _first_stale updates are protected by MCQ lock.
// Once task processing starts and MCQ lock is released,
// other compiler threads can reuse _first_stale.
CompileTask* head = _first_stale;
_first_stale = NULL;
{
MutexUnlocker ul(lock());
for (CompileTask* task = head; task != NULL; ) {
CompileTask* next_task = task->next();
CompileTaskWrapper ctw(task); // Frees the task
task = next_task;
}
}
}
}
void CompileQueue::remove(CompileTask* task) {
assert(lock()->owned_by_self(), "must own lock");
if (task->prev() != NULL) {
task->prev()->set_next(task->next());
@ -730,6 +756,16 @@ void CompileQueue::remove(CompileTask* task)
--_size;
}
void CompileQueue::remove_and_mark_stale(CompileTask* task) {
assert(lock()->owned_by_self(), "must own lock");
remove(task);
// Enqueue the task for reclamation (should be done outside MCQ lock)
task->set_next(_first_stale);
task->set_prev(NULL);
_first_stale = task;
}
// methods in the compile queue need to be marked as used on the stack
// so that they don't get reclaimed by Redefine Classes
void CompileQueue::mark_on_stack() {
@ -2006,7 +2042,7 @@ void CompileBroker::invoke_compiler_on_method(CompileTask* task) {
// Note that the queued_for_compilation bits are cleared without
// protection of a mutex. [They were set by the requester thread,
// when adding the task to the complie queue -- at which time the
// when adding the task to the compile queue -- at which time the
// compile queue lock was held. Subsequently, we acquired the compile
// queue lock to get this task off the compile queue; thus (to belabour
// the point somewhat) our clearing of the bits must be occurring