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) {