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