@@ -367,33 +367,31 @@ void CompileQueue::add(CompileTask* task) {
367367 */
368368void CompileQueue::delete_all () {
369369 MutexLocker mu (MethodCompileQueue_lock);
370- CompileTask* next = _first;
370+ CompileTask* current = _first;
371371
372372 // Iterate over all tasks in the compile queue
373- while (next != nullptr ) {
374- CompileTask* current = next;
375- next = current->next ();
376- bool found_waiter = false ;
377- {
378- MutexLocker ct_lock (CompileTaskWait_lock);
379- assert (current->waiting_for_completion_count () <= 1 , " more than one thread are waiting for task" );
380- if (current->waiting_for_completion_count () > 0 ) {
381- // If another thread waits for this task, we must wake them up
382- // so they will stop waiting and free the task.
383- CompileTaskWait_lock->notify_all ();
384- found_waiter = true ;
385- }
386- }
387- if (!found_waiter) {
388- // If no one was waiting for this task, we need to delete it ourselves.
389- // In this case, the task is also certainly unlocked, because, again, there is no waiter.
390- // Otherwise, by convention, it's the waiters responsibility to delete the task.
373+ while (current != nullptr ) {
374+ if (!current->is_blocking ()) {
375+ // Non-blocking task. No one is waiting for it, delete it now.
391376 delete current;
377+ } else {
378+ // Blocking task. By convention, it is the waiters responsibility
379+ // to delete the task. We cannot delete it here, because we do not
380+ // coordinate with waiters. We will notify the waiters later.
392381 }
382+ current = current->next ();
393383 }
394384 _first = nullptr ;
395385 _last = nullptr ;
396386
387+ // Wake up all blocking task waiters to deal with remaining blocking
388+ // tasks. This is not a performance sensitive path, so we do this
389+ // unconditionally to simplify coding/testing.
390+ {
391+ MonitorLocker ml (Thread::current (), CompileTaskWait_lock);
392+ ml.notify_all ();
393+ }
394+
397395 // Wake up all threads that block on the queue.
398396 MethodCompileQueue_lock->notify_all ();
399397}
@@ -1720,23 +1718,26 @@ void CompileBroker::wait_for_completion(CompileTask* task) {
17201718 } else
17211719#endif
17221720 {
1723- MonitorLocker ml (thread, CompileTaskWait_lock);
17241721 free_task = true ;
1725- task->inc_waiting_for_completion ();
1722+ // Wait until the task is complete or compilation is shut down.
1723+ MonitorLocker ml (thread, CompileTaskWait_lock);
17261724 while (!task->is_complete () && !is_compilation_disabled_forever ()) {
17271725 ml.wait ();
17281726 }
1729- task->dec_waiting_for_completion ();
17301727 }
17311728
1732- if (free_task) {
1733- if (is_compilation_disabled_forever ()) {
1734- delete task;
1735- return ;
1736- }
1729+ // It is harmless to check this status without the lock, because
1730+ // completion is a stable property.
1731+ if (!task->is_complete () && is_compilation_disabled_forever ()) {
1732+ // Task is not complete, and we are exiting for compilation shutdown.
1733+ // The task can still be executed by some compiler thread, therefore
1734+ // we cannot delete it. This will leave task allocated, which leaks it.
1735+ // At this (degraded) point, it is less risky to abandon the task,
1736+ // rather than attempting a more complicated deletion protocol.
1737+ free_task = false ;
1738+ }
17371739
1738- // It is harmless to check this status without the lock, because
1739- // completion is a stable property (until the task object is deleted).
1740+ if (free_task) {
17401741 assert (task->is_complete (), " Compilation should have completed" );
17411742
17421743 // By convention, the waiter is responsible for deleting a
0 commit comments