Skip to content

Commit 958383d

Browse files
committed
8364501: Compiler shutdown crashes on access to deleted CompileTask
Reviewed-by: kvn, mhaessig
1 parent e9e331b commit 958383d

File tree

3 files changed

+18
-8
lines changed

3 files changed

+18
-8
lines changed

src/hotspot/share/compiler/compileBroker.cpp

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -371,6 +371,7 @@ void CompileQueue::delete_all() {
371371

372372
// Iterate over all tasks in the compile queue
373373
while (current != nullptr) {
374+
CompileTask* next = current->next();
374375
if (!current->is_blocking()) {
375376
// Non-blocking task. No one is waiting for it, delete it now.
376377
delete current;
@@ -379,7 +380,7 @@ void CompileQueue::delete_all() {
379380
// to delete the task. We cannot delete it here, because we do not
380381
// coordinate with waiters. We will notify the waiters later.
381382
}
382-
current = current->next();
383+
current = next;
383384
}
384385
_first = nullptr;
385386
_last = nullptr;
@@ -504,6 +505,8 @@ void CompileQueue::remove(CompileTask* task) {
504505
assert(task == _last, "Sanity");
505506
_last = task->prev();
506507
}
508+
task->set_next(nullptr);
509+
task->set_prev(nullptr);
507510
--_size;
508511
++_total_removed;
509512
}
@@ -1728,17 +1731,22 @@ void CompileBroker::wait_for_completion(CompileTask* task) {
17281731

17291732
// It is harmless to check this status without the lock, because
17301733
// 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.
1734+
if (!task->is_complete()) {
1735+
// Task is not complete, likely because we are exiting for compilation
1736+
// shutdown. The task can still be reached through the queue, or executed
1737+
// by some compiler thread. There is no coordination with either MCQ lock
1738+
// holders or compilers, therefore we cannot delete the task.
1739+
//
1740+
// This will leave task allocated, which leaks it. At this (degraded) point,
1741+
// it is less risky to abandon the task, rather than attempting a more
1742+
// complicated deletion protocol.
17371743
free_task = false;
17381744
}
17391745

17401746
if (free_task) {
17411747
assert(task->is_complete(), "Compilation should have completed");
1748+
assert(task->next() == nullptr && task->prev() == nullptr,
1749+
"Completed task should not be in the queue");
17421750

17431751
// By convention, the waiter is responsible for deleting a
17441752
// blocking CompileTask. Since there is only one waiter ever

src/hotspot/share/compiler/compileTask.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@ CompileTask::CompileTask(int compile_id,
7474
_arena_bytes = 0;
7575

7676
_next = nullptr;
77+
_prev = nullptr;
7778

7879
Atomic::add(&_active_tasks, 1, memory_order_relaxed);
7980
}

src/hotspot/share/compiler/compileTask.hpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,8 @@ class CompileTask : public CHeapObj<mtCompiler> {
101101
#endif
102102
int _comp_level;
103103
int _num_inlined_bytecodes;
104-
CompileTask* _next, *_prev;
104+
CompileTask* _next;
105+
CompileTask* _prev;
105106
// Fields used for logging why the compilation was initiated:
106107
jlong _time_queued; // time when task was enqueued
107108
jlong _time_started; // time when compilation started

0 commit comments

Comments
 (0)