src/share/vm/compiler/compileBroker.cpp
Index
Unified diffs
Context diffs
Sdiffs
Patch
New
Old
Previous File
Next File
hotspot Cdiff src/share/vm/compiler/compileBroker.cpp
src/share/vm/compiler/compileBroker.cpp
Print this page
rev 6404 : 8023461: Thread holding lock at safepoint that vm can block on: MethodCompileQueue_lock
Reviewed-by: kvn, iveresov
rev 6405 : imported patch stale_task
rev 6406 : [mq]: stale_task.1
*** 702,718 ****
if (CompileBroker::is_compilation_disabled_forever()) {
return NULL;
}
! CompileTask* task = CompilationPolicy::policy()->select_task(this);
remove(task);
return task;
}
! void CompileQueue::remove(CompileTask* task)
! {
assert(lock()->owned_by_self(), "must own lock");
if (task->prev() != NULL) {
task->prev()->set_next(task->next());
} else {
// max is the first element
--- 702,745 ----
if (CompileBroker::is_compilation_disabled_forever()) {
return NULL;
}
! CompileTask* task;
! {
! No_Safepoint_Verifier nsv;
! task = CompilationPolicy::policy()->select_task(this);
! }
remove(task);
+ purge_stale_tasks(); // may temporarily release MCQ lock
return 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->method()->clear_queued_for_compilation();
! 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());
} else {
// max is the first element
*** 728,737 ****
--- 755,774 ----
_last = task->prev();
}
--_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() {
CompileTask* task = _first;
while (task != NULL) {
*** 2004,2014 ****
break;
}
// 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
// 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
// only after the setting of the bits. See also 14012000 above.
method->clear_queued_for_compilation();
--- 2041,2051 ----
break;
}
// 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 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
// only after the setting of the bits. See also 14012000 above.
method->clear_queued_for_compilation();
src/share/vm/compiler/compileBroker.cpp
Index
Unified diffs
Context diffs
Sdiffs
Patch
New
Old
Previous File
Next File