8080110: Remove usage of CollectedHeap::n_par_threads() from root processing
Reviewed-by: jmasa, kbarrett
This commit is contained in:
parent
e13e75547c
commit
c13872f88d
@ -2428,14 +2428,18 @@ void CMSCollector::verify_after_remark_work_1() {
|
||||
MarkRefsIntoClosure notOlder(_span, verification_mark_bm());
|
||||
gch->rem_set()->prepare_for_younger_refs_iterate(false); // Not parallel.
|
||||
|
||||
gch->gen_process_roots(_cmsGen->level(),
|
||||
true, // younger gens are roots
|
||||
true, // activate StrongRootsScope
|
||||
GenCollectedHeap::ScanningOption(roots_scanning_options()),
|
||||
should_unload_classes(),
|
||||
¬Older,
|
||||
NULL,
|
||||
NULL); // SSS: Provide correct closure
|
||||
{
|
||||
StrongRootsScope srs(1);
|
||||
|
||||
gch->gen_process_roots(&srs,
|
||||
_cmsGen->level(),
|
||||
true, // younger gens are roots
|
||||
GenCollectedHeap::ScanningOption(roots_scanning_options()),
|
||||
should_unload_classes(),
|
||||
¬Older,
|
||||
NULL,
|
||||
NULL);
|
||||
}
|
||||
|
||||
// Now mark from the roots
|
||||
MarkFromRootsClosure markFromRootsClosure(this, _span,
|
||||
@ -2496,14 +2500,18 @@ void CMSCollector::verify_after_remark_work_2() {
|
||||
|
||||
gch->rem_set()->prepare_for_younger_refs_iterate(false); // Not parallel.
|
||||
|
||||
gch->gen_process_roots(_cmsGen->level(),
|
||||
true, // younger gens are roots
|
||||
true, // activate StrongRootsScope
|
||||
GenCollectedHeap::ScanningOption(roots_scanning_options()),
|
||||
should_unload_classes(),
|
||||
¬Older,
|
||||
NULL,
|
||||
&cld_closure);
|
||||
{
|
||||
StrongRootsScope srs(1);
|
||||
|
||||
gch->gen_process_roots(&srs,
|
||||
_cmsGen->level(),
|
||||
true, // younger gens are roots
|
||||
GenCollectedHeap::ScanningOption(roots_scanning_options()),
|
||||
should_unload_classes(),
|
||||
¬Older,
|
||||
NULL,
|
||||
&cld_closure);
|
||||
}
|
||||
|
||||
// Now mark from the roots
|
||||
MarkFromRootsVerifyClosure markFromRootsClosure(this, _span,
|
||||
@ -2913,10 +2921,11 @@ class CMSParMarkTask : public AbstractGangTask {
|
||||
|
||||
// Parallel initial mark task
|
||||
class CMSParInitialMarkTask: public CMSParMarkTask {
|
||||
StrongRootsScope* _strong_roots_scope;
|
||||
public:
|
||||
CMSParInitialMarkTask(CMSCollector* collector, uint n_workers) :
|
||||
CMSParMarkTask("Scan roots and young gen for initial mark in parallel",
|
||||
collector, n_workers) {}
|
||||
CMSParInitialMarkTask(CMSCollector* collector, StrongRootsScope* strong_roots_scope, uint n_workers) :
|
||||
CMSParMarkTask("Scan roots and young gen for initial mark in parallel", collector, n_workers),
|
||||
_strong_roots_scope(strong_roots_scope) {}
|
||||
void work(uint worker_id);
|
||||
};
|
||||
|
||||
@ -3004,14 +3013,15 @@ void CMSCollector::checkpointRootsInitialWork() {
|
||||
FlexibleWorkGang* workers = gch->workers();
|
||||
assert(workers != NULL, "Need parallel worker threads.");
|
||||
uint n_workers = workers->active_workers();
|
||||
CMSParInitialMarkTask tsk(this, n_workers);
|
||||
|
||||
StrongRootsScope srs(n_workers);
|
||||
|
||||
CMSParInitialMarkTask tsk(this, &srs, n_workers);
|
||||
gch->set_par_threads(n_workers);
|
||||
initialize_sequential_subtasks_for_young_gen_rescan(n_workers);
|
||||
if (n_workers > 1) {
|
||||
StrongRootsScope srs;
|
||||
workers->run_task(&tsk);
|
||||
} else {
|
||||
StrongRootsScope srs;
|
||||
tsk.work(0);
|
||||
}
|
||||
gch->set_par_threads(0);
|
||||
@ -3019,9 +3029,12 @@ void CMSCollector::checkpointRootsInitialWork() {
|
||||
// The serial version.
|
||||
CLDToOopClosure cld_closure(¬Older, true);
|
||||
gch->rem_set()->prepare_for_younger_refs_iterate(false); // Not parallel.
|
||||
gch->gen_process_roots(_cmsGen->level(),
|
||||
|
||||
StrongRootsScope srs(1);
|
||||
|
||||
gch->gen_process_roots(&srs,
|
||||
_cmsGen->level(),
|
||||
true, // younger gens are roots
|
||||
true, // activate StrongRootsScope
|
||||
GenCollectedHeap::ScanningOption(roots_scanning_options()),
|
||||
should_unload_classes(),
|
||||
¬Older,
|
||||
@ -4452,9 +4465,9 @@ void CMSParInitialMarkTask::work(uint worker_id) {
|
||||
|
||||
CLDToOopClosure cld_closure(&par_mri_cl, true);
|
||||
|
||||
gch->gen_process_roots(_collector->_cmsGen->level(),
|
||||
gch->gen_process_roots(_strong_roots_scope,
|
||||
_collector->_cmsGen->level(),
|
||||
false, // yg was scanned above
|
||||
false, // this is parallel code
|
||||
GenCollectedHeap::ScanningOption(_collector->CMSCollector::roots_scanning_options()),
|
||||
_collector->should_unload_classes(),
|
||||
&par_mri_cl,
|
||||
@ -4478,6 +4491,7 @@ class CMSParRemarkTask: public CMSParMarkTask {
|
||||
// The per-thread work queues, available here for stealing.
|
||||
OopTaskQueueSet* _task_queues;
|
||||
ParallelTaskTerminator _term;
|
||||
StrongRootsScope* _strong_roots_scope;
|
||||
|
||||
public:
|
||||
// A value of 0 passed to n_workers will cause the number of
|
||||
@ -4485,12 +4499,14 @@ class CMSParRemarkTask: public CMSParMarkTask {
|
||||
CMSParRemarkTask(CMSCollector* collector,
|
||||
CompactibleFreeListSpace* cms_space,
|
||||
uint n_workers, FlexibleWorkGang* workers,
|
||||
OopTaskQueueSet* task_queues):
|
||||
OopTaskQueueSet* task_queues,
|
||||
StrongRootsScope* strong_roots_scope):
|
||||
CMSParMarkTask("Rescan roots and grey objects in parallel",
|
||||
collector, n_workers),
|
||||
_cms_space(cms_space),
|
||||
_task_queues(task_queues),
|
||||
_term(n_workers, task_queues) { }
|
||||
_term(n_workers, task_queues),
|
||||
_strong_roots_scope(strong_roots_scope) { }
|
||||
|
||||
OopTaskQueueSet* task_queues() { return _task_queues; }
|
||||
|
||||
@ -4588,9 +4604,9 @@ void CMSParRemarkTask::work(uint worker_id) {
|
||||
// ---------- remaining roots --------------
|
||||
_timer.reset();
|
||||
_timer.start();
|
||||
gch->gen_process_roots(_collector->_cmsGen->level(),
|
||||
gch->gen_process_roots(_strong_roots_scope,
|
||||
_collector->_cmsGen->level(),
|
||||
false, // yg was scanned above
|
||||
false, // this is parallel code
|
||||
GenCollectedHeap::ScanningOption(_collector->CMSCollector::roots_scanning_options()),
|
||||
_collector->should_unload_classes(),
|
||||
&par_mrias_cl,
|
||||
@ -5068,9 +5084,9 @@ void CMSCollector::do_remark_parallel() {
|
||||
}
|
||||
CompactibleFreeListSpace* cms_space = _cmsGen->cmsSpace();
|
||||
|
||||
CMSParRemarkTask tsk(this,
|
||||
cms_space,
|
||||
n_workers, workers, task_queues());
|
||||
StrongRootsScope srs(n_workers);
|
||||
|
||||
CMSParRemarkTask tsk(this, cms_space, n_workers, workers, task_queues(), &srs);
|
||||
|
||||
// Set up for parallel process_roots work.
|
||||
gch->set_par_threads(n_workers);
|
||||
@ -5105,11 +5121,9 @@ void CMSCollector::do_remark_parallel() {
|
||||
// necessarily be so, since it's possible that we are doing
|
||||
// ST marking.
|
||||
ReferenceProcessorMTDiscoveryMutator mt(ref_processor(), true);
|
||||
StrongRootsScope srs;
|
||||
workers->run_task(&tsk);
|
||||
} else {
|
||||
ReferenceProcessorMTDiscoveryMutator mt(ref_processor(), false);
|
||||
StrongRootsScope srs;
|
||||
tsk.work(0);
|
||||
}
|
||||
|
||||
@ -5177,11 +5191,11 @@ void CMSCollector::do_remark_non_parallel() {
|
||||
verify_work_stacks_empty();
|
||||
|
||||
gch->rem_set()->prepare_for_younger_refs_iterate(false); // Not parallel.
|
||||
StrongRootsScope srs;
|
||||
StrongRootsScope srs(1);
|
||||
|
||||
gch->gen_process_roots(_cmsGen->level(),
|
||||
gch->gen_process_roots(&srs,
|
||||
_cmsGen->level(),
|
||||
true, // younger gens as roots
|
||||
false, // use the local StrongRootsScope
|
||||
GenCollectedHeap::ScanningOption(roots_scanning_options()),
|
||||
should_unload_classes(),
|
||||
&mrias_cl,
|
||||
|
@ -567,11 +567,13 @@ void ParEvacuateFollowersClosure::do_void() {
|
||||
}
|
||||
|
||||
ParNewGenTask::ParNewGenTask(ParNewGeneration* gen, Generation* old_gen,
|
||||
HeapWord* young_old_boundary, ParScanThreadStateSet* state_set) :
|
||||
HeapWord* young_old_boundary, ParScanThreadStateSet* state_set,
|
||||
StrongRootsScope* strong_roots_scope) :
|
||||
AbstractGangTask("ParNewGeneration collection"),
|
||||
_gen(gen), _old_gen(old_gen),
|
||||
_young_old_boundary(young_old_boundary),
|
||||
_state_set(state_set)
|
||||
_state_set(state_set),
|
||||
_strong_roots_scope(strong_roots_scope)
|
||||
{}
|
||||
|
||||
// Reset the terminator for the given number of
|
||||
@ -603,10 +605,10 @@ void ParNewGenTask::work(uint worker_id) {
|
||||
false);
|
||||
|
||||
par_scan_state.start_strong_roots();
|
||||
gch->gen_process_roots(_gen->level(),
|
||||
gch->gen_process_roots(_strong_roots_scope,
|
||||
_gen->level(),
|
||||
true, // Process younger gens, if any,
|
||||
// as strong roots.
|
||||
false, // no scope; this is parallel code
|
||||
GenCollectedHeap::SO_ScavengeCodeCache,
|
||||
GenCollectedHeap::StrongAndWeakRoots,
|
||||
&par_scan_state.to_space_root_closure(),
|
||||
@ -952,20 +954,23 @@ void ParNewGeneration::collect(bool full,
|
||||
*to(), *this, *_old_gen, *task_queues(),
|
||||
_overflow_stacks, desired_plab_sz(), _term);
|
||||
|
||||
ParNewGenTask tsk(this, _old_gen, reserved().end(), &thread_state_set);
|
||||
gch->set_par_threads(n_workers);
|
||||
gch->rem_set()->prepare_for_younger_refs_iterate(true);
|
||||
// It turns out that even when we're using 1 thread, doing the work in a
|
||||
// separate thread causes wide variance in run times. We can't help this
|
||||
// in the multi-threaded case, but we special-case n=1 here to get
|
||||
// repeatable measurements of the 1-thread overhead of the parallel code.
|
||||
if (n_workers > 1) {
|
||||
StrongRootsScope srs;
|
||||
workers->run_task(&tsk);
|
||||
} else {
|
||||
StrongRootsScope srs;
|
||||
tsk.work(0);
|
||||
{
|
||||
StrongRootsScope srs(n_workers);
|
||||
|
||||
ParNewGenTask tsk(this, _old_gen, reserved().end(), &thread_state_set, &srs);
|
||||
gch->set_par_threads(n_workers);
|
||||
gch->rem_set()->prepare_for_younger_refs_iterate(true);
|
||||
// It turns out that even when we're using 1 thread, doing the work in a
|
||||
// separate thread causes wide variance in run times. We can't help this
|
||||
// in the multi-threaded case, but we special-case n=1 here to get
|
||||
// repeatable measurements of the 1-thread overhead of the parallel code.
|
||||
if (n_workers > 1) {
|
||||
workers->run_task(&tsk);
|
||||
} else {
|
||||
tsk.work(0);
|
||||
}
|
||||
}
|
||||
|
||||
thread_state_set.reset(0 /* Bad value in debug if not reset */,
|
||||
promotion_failed());
|
||||
|
||||
|
@ -39,6 +39,7 @@ class ParScanWithBarrierClosure;
|
||||
class ParRootScanWithoutBarrierClosure;
|
||||
class ParRootScanWithBarrierTwoGensClosure;
|
||||
class ParEvacuateFollowersClosure;
|
||||
class StrongRootsScope;
|
||||
|
||||
// It would be better if these types could be kept local to the .cpp file,
|
||||
// but they must be here to allow ParScanClosure::do_oop_work to be defined
|
||||
@ -237,12 +238,14 @@ class ParNewGenTask: public AbstractGangTask {
|
||||
Generation* _old_gen;
|
||||
HeapWord* _young_old_boundary;
|
||||
class ParScanThreadStateSet* _state_set;
|
||||
StrongRootsScope* _strong_roots_scope;
|
||||
|
||||
public:
|
||||
ParNewGenTask(ParNewGeneration* gen,
|
||||
Generation* old_gen,
|
||||
HeapWord* young_old_boundary,
|
||||
ParScanThreadStateSet* state_set);
|
||||
ParScanThreadStateSet* state_set,
|
||||
StrongRootsScope* strong_roots_scope);
|
||||
|
||||
HeapWord* young_old_boundary() { return _young_old_boundary; }
|
||||
|
||||
|
@ -2608,7 +2608,6 @@ void ConcurrentMark::checkpointRootsFinalWork() {
|
||||
|
||||
g1h->ensure_parsability(false);
|
||||
|
||||
StrongRootsScope srs;
|
||||
// this is remark, so we'll use up all active threads
|
||||
uint active_workers = g1h->workers()->active_workers();
|
||||
if (active_workers == 0) {
|
||||
@ -2622,13 +2621,17 @@ void ConcurrentMark::checkpointRootsFinalWork() {
|
||||
// constructor and pass values of the active workers
|
||||
// through the gang in the task.
|
||||
|
||||
CMRemarkTask remarkTask(this, active_workers);
|
||||
// We will start all available threads, even if we decide that the
|
||||
// active_workers will be fewer. The extra ones will just bail out
|
||||
// immediately.
|
||||
g1h->set_par_threads(active_workers);
|
||||
g1h->workers()->run_task(&remarkTask);
|
||||
g1h->set_par_threads(0);
|
||||
{
|
||||
StrongRootsScope srs(active_workers);
|
||||
|
||||
CMRemarkTask remarkTask(this, active_workers);
|
||||
// We will start all available threads, even if we decide that the
|
||||
// active_workers will be fewer. The extra ones will just bail out
|
||||
// immediately.
|
||||
g1h->set_par_threads(active_workers);
|
||||
g1h->workers()->run_task(&remarkTask);
|
||||
g1h->set_par_threads(0);
|
||||
}
|
||||
|
||||
SATBMarkQueueSet& satb_mq_set = JavaThread::satb_mark_queue_set();
|
||||
guarantee(has_overflown() ||
|
||||
|
@ -3021,7 +3021,7 @@ void G1CollectedHeap::verify(bool silent, VerifyOption vo) {
|
||||
G1VerifyCodeRootBlobClosure blobsCl(&codeRootsCl);
|
||||
|
||||
{
|
||||
G1RootProcessor root_processor(this);
|
||||
G1RootProcessor root_processor(this, 1);
|
||||
root_processor.process_all_roots(&rootsCl,
|
||||
&cldCl,
|
||||
&blobsCl);
|
||||
@ -5393,7 +5393,7 @@ void G1CollectedHeap::evacuate_collection_set(EvacuationInfo& evacuation_info) {
|
||||
double end_par_time_sec;
|
||||
|
||||
{
|
||||
G1RootProcessor root_processor(this);
|
||||
G1RootProcessor root_processor(this, n_workers);
|
||||
G1ParTask g1_par_task(this, _task_queues, &root_processor);
|
||||
// InitialMark needs claim bits to keep track of the marked-through CLDs.
|
||||
if (g1_policy()->during_initial_mark_pause()) {
|
||||
|
@ -127,7 +127,7 @@ void G1MarkSweep::mark_sweep_phase1(bool& marked_for_unloading,
|
||||
|
||||
MarkingCodeBlobClosure follow_code_closure(&GenMarkSweep::follow_root_closure, !CodeBlobToOopClosure::FixRelocations);
|
||||
{
|
||||
G1RootProcessor root_processor(g1h);
|
||||
G1RootProcessor root_processor(g1h, 1);
|
||||
root_processor.process_strong_roots(&GenMarkSweep::follow_root_closure,
|
||||
&GenMarkSweep::follow_cld_closure,
|
||||
&follow_code_closure);
|
||||
@ -237,7 +237,7 @@ void G1MarkSweep::mark_sweep_phase3() {
|
||||
|
||||
CodeBlobToOopClosure adjust_code_closure(&GenMarkSweep::adjust_pointer_closure, CodeBlobToOopClosure::FixRelocations);
|
||||
{
|
||||
G1RootProcessor root_processor(g1h);
|
||||
G1RootProcessor root_processor(g1h, 1);
|
||||
root_processor.process_all_roots(&GenMarkSweep::adjust_pointer_closure,
|
||||
&GenMarkSweep::adjust_cld_closure,
|
||||
&adjust_code_closure);
|
||||
|
@ -90,11 +90,10 @@ public:
|
||||
|
||||
|
||||
void G1RootProcessor::worker_has_discovered_all_strong_classes() {
|
||||
uint n_workers = _g1h->n_par_threads();
|
||||
assert(ClassUnloadingWithConcurrentMark, "Currently only needed when doing G1 Class Unloading");
|
||||
|
||||
uint new_value = (uint)Atomic::add(1, &_n_workers_discovered_strong_classes);
|
||||
if (new_value == n_workers) {
|
||||
if (new_value == n_workers()) {
|
||||
// This thread is last. Notify the others.
|
||||
MonitorLockerEx ml(&_lock, Mutex::_no_safepoint_check_flag);
|
||||
_lock.notify_all();
|
||||
@ -102,21 +101,20 @@ void G1RootProcessor::worker_has_discovered_all_strong_classes() {
|
||||
}
|
||||
|
||||
void G1RootProcessor::wait_until_all_strong_classes_discovered() {
|
||||
uint n_workers = _g1h->n_par_threads();
|
||||
assert(ClassUnloadingWithConcurrentMark, "Currently only needed when doing G1 Class Unloading");
|
||||
|
||||
if ((uint)_n_workers_discovered_strong_classes != n_workers) {
|
||||
if ((uint)_n_workers_discovered_strong_classes != n_workers()) {
|
||||
MonitorLockerEx ml(&_lock, Mutex::_no_safepoint_check_flag);
|
||||
while ((uint)_n_workers_discovered_strong_classes != n_workers) {
|
||||
while ((uint)_n_workers_discovered_strong_classes != n_workers()) {
|
||||
_lock.wait(Mutex::_no_safepoint_check_flag, 0, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
G1RootProcessor::G1RootProcessor(G1CollectedHeap* g1h) :
|
||||
G1RootProcessor::G1RootProcessor(G1CollectedHeap* g1h, uint n_workers) :
|
||||
_g1h(g1h),
|
||||
_process_strong_tasks(new SubTasksDone(G1RP_PS_NumElements)),
|
||||
_srs(),
|
||||
_srs(n_workers),
|
||||
_lock(Mutex::leaf, "G1 Root Scanning barrier lock", false, Monitor::_safepoint_check_never),
|
||||
_n_workers_discovered_strong_classes(0) {}
|
||||
|
||||
@ -253,7 +251,7 @@ void G1RootProcessor::process_java_roots(OopClosure* strong_roots,
|
||||
|
||||
{
|
||||
G1GCParPhaseTimesTracker x(phase_times, G1GCPhaseTimes::ThreadRoots, worker_i);
|
||||
bool is_par = _g1h->n_par_threads() > 1;
|
||||
bool is_par = n_workers() > 1;
|
||||
Threads::possibly_parallel_oops_do(is_par, strong_roots, thread_stack_clds, strong_code);
|
||||
}
|
||||
}
|
||||
@ -330,5 +328,13 @@ void G1RootProcessor::scan_remembered_sets(G1ParPushHeapRSClosure* scan_rs,
|
||||
}
|
||||
|
||||
void G1RootProcessor::set_num_workers(uint active_workers) {
|
||||
assert(active_workers == _srs.n_threads(),
|
||||
err_msg("Mismatch between number of worker threads. active_workers: %u and n_workers(): %u",
|
||||
active_workers,
|
||||
_srs.n_threads()));
|
||||
_process_strong_tasks->set_n_threads(active_workers);
|
||||
}
|
||||
|
||||
uint G1RootProcessor::n_workers() const {
|
||||
return _srs.n_threads();
|
||||
}
|
||||
|
@ -85,7 +85,7 @@ class G1RootProcessor : public StackObj {
|
||||
uint worker_i);
|
||||
|
||||
public:
|
||||
G1RootProcessor(G1CollectedHeap* g1h);
|
||||
G1RootProcessor(G1CollectedHeap* g1h, uint n_workers);
|
||||
|
||||
// Apply closures to the strongly and weakly reachable roots in the system
|
||||
// in a single pass.
|
||||
@ -114,8 +114,11 @@ public:
|
||||
OopClosure* scan_non_heap_weak_roots,
|
||||
uint worker_i);
|
||||
|
||||
// Inform the root processor about the number of worker threads
|
||||
// Inform SubTaskDone about the number of worker threads.
|
||||
void set_num_workers(uint active_workers);
|
||||
|
||||
// Number of worker threads used by the root processor.
|
||||
uint n_workers() const;
|
||||
};
|
||||
|
||||
#endif // SHARE_VM_GC_G1_G1ROOTPROCESSOR_HPP
|
||||
|
@ -38,6 +38,7 @@
|
||||
#include "gc/shared/referencePolicy.hpp"
|
||||
#include "gc/shared/space.inline.hpp"
|
||||
#include "gc/shared/spaceDecorator.hpp"
|
||||
#include "gc/shared/strongRootsScope.hpp"
|
||||
#include "memory/iterator.hpp"
|
||||
#include "oops/instanceRefKlass.hpp"
|
||||
#include "oops/oop.inline.hpp"
|
||||
@ -625,15 +626,20 @@ void DefNewGeneration::collect(bool full,
|
||||
assert(gch->no_allocs_since_save_marks(0),
|
||||
"save marks have not been newly set.");
|
||||
|
||||
gch->gen_process_roots(_level,
|
||||
true, // Process younger gens, if any,
|
||||
// as strong roots.
|
||||
true, // activate StrongRootsScope
|
||||
GenCollectedHeap::SO_ScavengeCodeCache,
|
||||
GenCollectedHeap::StrongAndWeakRoots,
|
||||
&fsc_with_no_gc_barrier,
|
||||
&fsc_with_gc_barrier,
|
||||
&cld_scan_closure);
|
||||
{
|
||||
// SerialGC runs with n_workers == 0.
|
||||
StrongRootsScope srs(0);
|
||||
|
||||
gch->gen_process_roots(&srs,
|
||||
_level,
|
||||
true, // Process younger gens, if any,
|
||||
// as strong roots.
|
||||
GenCollectedHeap::SO_ScavengeCodeCache,
|
||||
GenCollectedHeap::StrongAndWeakRoots,
|
||||
&fsc_with_no_gc_barrier,
|
||||
&fsc_with_gc_barrier,
|
||||
&cld_scan_closure);
|
||||
}
|
||||
|
||||
// "evacuate followers".
|
||||
evacuate_followers.do_void();
|
||||
|
@ -40,6 +40,7 @@
|
||||
#include "gc/shared/modRefBarrierSet.hpp"
|
||||
#include "gc/shared/referencePolicy.hpp"
|
||||
#include "gc/shared/space.hpp"
|
||||
#include "gc/shared/strongRootsScope.hpp"
|
||||
#include "oops/instanceRefKlass.hpp"
|
||||
#include "oops/oop.inline.hpp"
|
||||
#include "prims/jvmtiExport.hpp"
|
||||
@ -200,14 +201,18 @@ void GenMarkSweep::mark_sweep_phase1(int level,
|
||||
// Need new claim bits before marking starts.
|
||||
ClassLoaderDataGraph::clear_claimed_marks();
|
||||
|
||||
gch->gen_process_roots(level,
|
||||
false, // Younger gens are not roots.
|
||||
true, // activate StrongRootsScope
|
||||
GenCollectedHeap::SO_None,
|
||||
GenCollectedHeap::StrongRootsOnly,
|
||||
&follow_root_closure,
|
||||
&follow_root_closure,
|
||||
&follow_cld_closure);
|
||||
{
|
||||
StrongRootsScope srs(1);
|
||||
|
||||
gch->gen_process_roots(&srs,
|
||||
level,
|
||||
false, // Younger gens are not roots.
|
||||
GenCollectedHeap::SO_None,
|
||||
GenCollectedHeap::StrongRootsOnly,
|
||||
&follow_root_closure,
|
||||
&follow_root_closure,
|
||||
&follow_cld_closure);
|
||||
}
|
||||
|
||||
// Process reference objects found during marking
|
||||
{
|
||||
@ -284,14 +289,18 @@ void GenMarkSweep::mark_sweep_phase3(int level) {
|
||||
assert(level == 1, "We don't use mark-sweep on young generations.");
|
||||
adjust_pointer_closure.set_orig_generation(gch->old_gen());
|
||||
|
||||
gch->gen_process_roots(level,
|
||||
false, // Younger gens are not roots.
|
||||
true, // activate StrongRootsScope
|
||||
GenCollectedHeap::SO_AllCodeCache,
|
||||
GenCollectedHeap::StrongAndWeakRoots,
|
||||
&adjust_pointer_closure,
|
||||
&adjust_pointer_closure,
|
||||
&adjust_cld_closure);
|
||||
{
|
||||
StrongRootsScope srs(1);
|
||||
|
||||
gch->gen_process_roots(&srs,
|
||||
level,
|
||||
false, // Younger gens are not roots.
|
||||
GenCollectedHeap::SO_AllCodeCache,
|
||||
GenCollectedHeap::StrongAndWeakRoots,
|
||||
&adjust_pointer_closure,
|
||||
&adjust_pointer_closure,
|
||||
&adjust_cld_closure);
|
||||
}
|
||||
|
||||
gch->gen_process_weak_roots(&adjust_pointer_closure);
|
||||
|
||||
|
@ -582,15 +582,13 @@ public:
|
||||
static AssertNonScavengableClosure assert_is_non_scavengable_closure;
|
||||
#endif
|
||||
|
||||
void GenCollectedHeap::process_roots(bool activate_scope,
|
||||
void GenCollectedHeap::process_roots(StrongRootsScope* scope,
|
||||
ScanningOption so,
|
||||
OopClosure* strong_roots,
|
||||
OopClosure* weak_roots,
|
||||
CLDClosure* strong_cld_closure,
|
||||
CLDClosure* weak_cld_closure,
|
||||
CodeBlobClosure* code_roots) {
|
||||
StrongRootsScope srs(activate_scope);
|
||||
|
||||
// General roots.
|
||||
assert(Threads::thread_claim_parity() != 0, "must have called prologue code");
|
||||
assert(code_roots != NULL, "code root closure should always be set");
|
||||
@ -609,7 +607,7 @@ void GenCollectedHeap::process_roots(bool activate_scope,
|
||||
// Only process code roots from thread stacks if we aren't visiting the entire CodeCache anyway
|
||||
CodeBlobClosure* roots_from_code_p = (so & SO_AllCodeCache) ? NULL : code_roots;
|
||||
|
||||
bool is_par = n_par_threads() > 1;
|
||||
bool is_par = scope->n_threads() > 1;
|
||||
Threads::possibly_parallel_oops_do(is_par, strong_roots, roots_from_clds_p, roots_from_code_p);
|
||||
|
||||
if (!_process_strong_tasks->is_task_claimed(GCH_PS_Universe_oops_do)) {
|
||||
@ -669,9 +667,9 @@ void GenCollectedHeap::process_roots(bool activate_scope,
|
||||
|
||||
}
|
||||
|
||||
void GenCollectedHeap::gen_process_roots(int level,
|
||||
void GenCollectedHeap::gen_process_roots(StrongRootsScope* scope,
|
||||
int level,
|
||||
bool younger_gens_as_roots,
|
||||
bool activate_scope,
|
||||
ScanningOption so,
|
||||
bool only_strong_roots,
|
||||
OopsInGenClosure* not_older_gens,
|
||||
@ -689,7 +687,7 @@ void GenCollectedHeap::gen_process_roots(int level,
|
||||
OopsInGenClosure* weak_roots = only_strong_roots ? NULL : not_older_gens;
|
||||
CLDClosure* weak_cld_closure = only_strong_roots ? NULL : cld_closure;
|
||||
|
||||
process_roots(activate_scope, so,
|
||||
process_roots(scope, so,
|
||||
not_older_gens, weak_roots,
|
||||
cld_closure, weak_cld_closure,
|
||||
&mark_code_closure);
|
||||
|
@ -30,8 +30,9 @@
|
||||
#include "gc/shared/collectorPolicy.hpp"
|
||||
#include "gc/shared/generation.hpp"
|
||||
|
||||
class SubTasksDone;
|
||||
class FlexibleWorkGang;
|
||||
class StrongRootsScope;
|
||||
class SubTasksDone;
|
||||
|
||||
// A "GenCollectedHeap" is a CollectedHeap that uses generational
|
||||
// collection. It has two generations, young and old.
|
||||
@ -385,7 +386,7 @@ public:
|
||||
};
|
||||
|
||||
private:
|
||||
void process_roots(bool activate_scope,
|
||||
void process_roots(StrongRootsScope* scope,
|
||||
ScanningOption so,
|
||||
OopClosure* strong_roots,
|
||||
OopClosure* weak_roots,
|
||||
@ -393,24 +394,13 @@ public:
|
||||
CLDClosure* weak_cld_closure,
|
||||
CodeBlobClosure* code_roots);
|
||||
|
||||
void gen_process_roots(int level,
|
||||
bool younger_gens_as_roots,
|
||||
bool activate_scope,
|
||||
ScanningOption so,
|
||||
OopsInGenClosure* not_older_gens,
|
||||
OopsInGenClosure* weak_roots,
|
||||
OopsInGenClosure* older_gens,
|
||||
CLDClosure* cld_closure,
|
||||
CLDClosure* weak_cld_closure,
|
||||
CodeBlobClosure* code_closure);
|
||||
|
||||
public:
|
||||
static const bool StrongAndWeakRoots = false;
|
||||
static const bool StrongRootsOnly = true;
|
||||
|
||||
void gen_process_roots(int level,
|
||||
void gen_process_roots(StrongRootsScope* scope,
|
||||
int level,
|
||||
bool younger_gens_as_roots,
|
||||
bool activate_scope,
|
||||
ScanningOption so,
|
||||
bool only_strong_roots,
|
||||
OopsInGenClosure* not_older_gens,
|
||||
|
@ -28,24 +28,18 @@
|
||||
#include "gc/shared/strongRootsScope.hpp"
|
||||
#include "runtime/thread.hpp"
|
||||
|
||||
MarkScope::MarkScope(bool activate) : _active(activate) {
|
||||
if (_active) {
|
||||
nmethod::oops_do_marking_prologue();
|
||||
}
|
||||
MarkScope::MarkScope() {
|
||||
nmethod::oops_do_marking_prologue();
|
||||
}
|
||||
|
||||
MarkScope::~MarkScope() {
|
||||
if (_active) {
|
||||
nmethod::oops_do_marking_epilogue();
|
||||
}
|
||||
nmethod::oops_do_marking_epilogue();
|
||||
}
|
||||
|
||||
StrongRootsScope::StrongRootsScope(bool activate) : MarkScope(activate) {
|
||||
if (_active) {
|
||||
Threads::change_thread_claim_parity();
|
||||
// Zero the claimed high water mark in the StringTable
|
||||
StringTable::clear_parallel_claimed_index();
|
||||
}
|
||||
StrongRootsScope::StrongRootsScope(uint n_threads) : _n_threads(n_threads) {
|
||||
Threads::change_thread_claim_parity();
|
||||
// Zero the claimed high water mark in the StringTable
|
||||
StringTable::clear_parallel_claimed_index();
|
||||
}
|
||||
|
||||
StrongRootsScope::~StrongRootsScope() {
|
||||
|
@ -29,18 +29,21 @@
|
||||
|
||||
class MarkScope : public StackObj {
|
||||
protected:
|
||||
bool _active;
|
||||
public:
|
||||
MarkScope(bool activate = true);
|
||||
MarkScope();
|
||||
~MarkScope();
|
||||
};
|
||||
|
||||
// Sets up and tears down the required state for parallel root processing.
|
||||
|
||||
class StrongRootsScope : public MarkScope {
|
||||
// Number of threads participating in the roots processing.
|
||||
const uint _n_threads;
|
||||
|
||||
public:
|
||||
StrongRootsScope(bool activate = true);
|
||||
StrongRootsScope(uint n_threads);
|
||||
~StrongRootsScope();
|
||||
|
||||
uint n_threads() const { return _n_threads; }
|
||||
};
|
||||
|
||||
#endif // SHARE_VM_GC_SHARED_STRONGROOTSSCOPE_HPP
|
||||
|
Loading…
Reference in New Issue
Block a user