8080110: Remove usage of CollectedHeap::n_par_threads() from root processing

Reviewed-by: jmasa, kbarrett
This commit is contained in:
Stefan Karlsson 2015-05-21 09:23:00 +02:00
parent e13e75547c
commit c13872f88d
14 changed files with 176 additions and 142 deletions

View File

@ -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(),
&notOlder,
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(),
&notOlder,
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(),
&notOlder,
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(),
&notOlder,
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(&notOlder, 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(),
&notOlder,
@ -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,

View File

@ -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());

View File

@ -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; }

View File

@ -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() ||

View File

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

View File

@ -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);

View File

@ -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();
}

View File

@ -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

View File

@ -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();

View File

@ -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);

View File

@ -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);

View File

@ -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,

View File

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

View File

@ -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