src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp
Print this page
rev 2891 : 7120038: G1: ParallelGCThreads==0 is broken
Summary: Running G1 with ParallelGCThreads==0 results in various crashes and asserts. Most of these are caused by unguarded references to the worker threads array or an incorrect number of active workers.
Reviewed-by:
*** 3721,3732 ****
}
double end_time_sec = os::elapsedTime();
double pause_time_ms = (end_time_sec - start_time_sec) * MILLIUNITS;
g1_policy()->record_pause_time_ms(pause_time_ms);
! int active_gc_threads = workers()->active_workers();
! g1_policy()->record_collection_pause_end(active_gc_threads);
MemoryService::track_memory_usage();
// In prepare_for_verify() below we'll need to scan the deferred
// update buffers to bring the RSets up-to-date if
--- 3721,3733 ----
}
double end_time_sec = os::elapsedTime();
double pause_time_ms = (end_time_sec - start_time_sec) * MILLIUNITS;
g1_policy()->record_pause_time_ms(pause_time_ms);
! int active_workers = (G1CollectedHeap::use_parallel_gc_threads() ?
! workers()->active_workers() : 1);
! g1_policy()->record_collection_pause_end(active_workers);
MemoryService::track_memory_usage();
// In prepare_for_verify() below we'll need to scan the deferred
// update buffers to bring the RSets up-to-date if
*** 5246,5257 ****
// object discovered by the STW ref processor.
int active_workers = (G1CollectedHeap::use_parallel_gc_threads() ?
workers()->active_workers() : 1);
! assert(active_workers == workers()->active_workers(),
"Need to reset active_workers");
set_par_threads(active_workers);
G1ParPreserveCMReferentsTask keep_cm_referents(this, active_workers, _task_queues);
if (G1CollectedHeap::use_parallel_gc_threads()) {
workers()->run_task(&keep_cm_referents);
--- 5247,5260 ----
// object discovered by the STW ref processor.
int active_workers = (G1CollectedHeap::use_parallel_gc_threads() ?
workers()->active_workers() : 1);
! assert(!G1CollectedHeap::use_parallel_gc_threads() ||
! active_workers == workers()->active_workers(),
"Need to reset active_workers");
+
set_par_threads(active_workers);
G1ParPreserveCMReferentsTask keep_cm_referents(this, active_workers, _task_queues);
if (G1CollectedHeap::use_parallel_gc_threads()) {
workers()->run_task(&keep_cm_referents);
*** 5385,5401 ****
workers()->active_workers(),
Threads::number_of_non_daemon_threads());
assert(UseDynamicNumberOfGCThreads ||
n_workers == workers()->total_workers(),
"If not dynamic should be using all the workers");
set_par_threads(n_workers);
} else {
assert(n_par_threads() == 0,
"Should be the original non-parallel value");
n_workers = 1;
}
- workers()->set_active_workers(n_workers);
G1ParTask g1_par_task(this, _task_queues);
init_for_evac_failure(NULL);
--- 5388,5404 ----
workers()->active_workers(),
Threads::number_of_non_daemon_threads());
assert(UseDynamicNumberOfGCThreads ||
n_workers == workers()->total_workers(),
"If not dynamic should be using all the workers");
+ workers()->set_active_workers(n_workers);
set_par_threads(n_workers);
} else {
assert(n_par_threads() == 0,
"Should be the original non-parallel value");
n_workers = 1;
}
G1ParTask g1_par_task(this, _task_queues);
init_for_evac_failure(NULL);
*** 5413,5422 ****
--- 5416,5426 ----
workers()->active_workers() == workers()->total_workers(),
"If not dynamic should be using all the workers");
workers()->run_task(&g1_par_task);
} else {
StrongRootsScope srs(this);
+ g1_par_task.set_for_termination(n_workers);
g1_par_task.work(0);
}
double par_time = (os::elapsedTime() - start_par) * 1000.0;
g1_policy()->record_par_time(par_time);
*** 6070,6079 ****
--- 6074,6084 ----
}
void G1CollectedHeap::set_par_threads() {
// Don't change the number of workers. Use the value previously set
// in the workgroup.
+ assert(G1CollectedHeap::use_parallel_gc_threads(), "shouldn't be here otherwise");
int n_workers = workers()->active_workers();
assert(UseDynamicNumberOfGCThreads ||
n_workers == workers()->total_workers(),
"Otherwise should be using the total number of workers");
if (n_workers == 0) {