代码拉取完成,页面将自动刷新
同步操作将从 src-openEuler/openjdk-1.8.0 强制同步,此操作会覆盖自 Fork 仓库以来所做的任何修改,且无法恢复!!!
确定后同步将在后台操作,完成时将刷新页面,请耐心等待。
From 2821582ff1191393781ccf93d46d9c31230c8a4a Mon Sep 17 00:00:00 2001
From: mashoubing <mashoubing1@huawei.com>
Date: Mon, 11 Oct 2021 12:11:25 +0800
Subject: [PATCH 3/4] G1: Full GC parallel mark
---
.../concurrentMarkSweepGeneration.cpp | 2 +-
.../g1/g1BlockOffsetTable.inline.hpp | 2 +-
.../gc_implementation/g1/g1CollectedHeap.cpp | 2 +-
.../vm/gc_implementation/g1/g1MarkSweep.cpp | 233 +++++++++++++-----
.../vm/gc_implementation/g1/g1MarkSweep.hpp | 9 +-
.../gc_implementation/g1/g1RootProcessor.cpp | 23 +-
.../gc_implementation/g1/g1RootProcessor.hpp | 9 +-
.../vm/gc_implementation/g1/g1StringDedup.cpp | 10 +-
.../vm/gc_implementation/g1/g1StringDedup.hpp | 4 +-
.../parallelScavenge/parallelScavengeHeap.cpp | 2 +-
.../parallelScavenge/psMarkSweep.cpp | 5 +
.../parallelScavenge/psMarkSweep.hpp | 33 +--
.../parallelScavenge/psScavenge.cpp | 2 +-
.../vm/gc_implementation/shared/markSweep.cpp | 44 ++--
.../vm/gc_implementation/shared/markSweep.hpp | 89 ++++---
.../shared/markSweep.inline.hpp | 41 ++-
hotspot/src/share/vm/memory/genMarkSweep.cpp | 6 +
hotspot/src/share/vm/memory/genMarkSweep.hpp | 18 +-
hotspot/src/share/vm/memory/generation.cpp | 2 +-
.../vm/oops/instanceClassLoaderKlass.cpp | 6 +-
.../vm/oops/instanceClassLoaderKlass.hpp | 2 +-
hotspot/src/share/vm/oops/instanceKlass.cpp | 6 +-
hotspot/src/share/vm/oops/instanceKlass.hpp | 2 +-
.../src/share/vm/oops/instanceMirrorKlass.cpp | 10 +-
.../src/share/vm/oops/instanceMirrorKlass.hpp | 2 +-
.../src/share/vm/oops/instanceRefKlass.cpp | 18 +-
.../src/share/vm/oops/instanceRefKlass.hpp | 2 +-
hotspot/src/share/vm/oops/klass.hpp | 3 +-
hotspot/src/share/vm/oops/markOop.hpp | 2 +-
hotspot/src/share/vm/oops/objArrayKlass.cpp | 8 +-
hotspot/src/share/vm/oops/objArrayKlass.hpp | 6 +-
.../share/vm/oops/objArrayKlass.inline.hpp | 12 +-
hotspot/src/share/vm/oops/oop.hpp | 4 +-
hotspot/src/share/vm/oops/oop.inline.hpp | 4 +-
hotspot/src/share/vm/oops/typeArrayKlass.cpp | 2 +-
hotspot/src/share/vm/oops/typeArrayKlass.hpp | 2 +-
36 files changed, 401 insertions(+), 226 deletions(-)
diff --git a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp
index 3c3deab28..d31f9a54a 100644
--- a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp
+++ b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp
@@ -2079,7 +2079,7 @@ void CMSCollector::do_compaction_work(bool clear_all_soft_refs) {
_intra_sweep_estimate.padded_average());
}
- GenMarkSweep::invoke_at_safepoint(_cmsGen->level(),
+ GenMarkSweep::the_gen_mark()->invoke_at_safepoint(_cmsGen->level(),
ref_processor(), clear_all_soft_refs);
#ifdef ASSERT
CompactibleFreeListSpace* cms_space = _cmsGen->cmsSpace();
diff --git a/hotspot/src/share/vm/gc_implementation/g1/g1BlockOffsetTable.inline.hpp b/hotspot/src/share/vm/gc_implementation/g1/g1BlockOffsetTable.inline.hpp
index 912acdbe0..9a8cb877d 100644
--- a/hotspot/src/share/vm/gc_implementation/g1/g1BlockOffsetTable.inline.hpp
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1BlockOffsetTable.inline.hpp
@@ -51,7 +51,7 @@ G1BlockOffsetTable::block_start_const(const void* addr) const {
assert((index) < (_reserved.word_size() >> LogN_words), \
err_msg("%s - index: "SIZE_FORMAT", _vs.committed_size: "SIZE_FORMAT, \
msg, (index), (_reserved.word_size() >> LogN_words))); \
- assert(!G1Uncommit && G1CollectedHeap::heap()->is_in_exact(address_for_index_raw(index)) || G1Uncommit, \
+ assert((!G1Uncommit && G1CollectedHeap::heap()->is_in_exact(address_for_index_raw(index))) || G1Uncommit, \
err_msg("Index "SIZE_FORMAT" corresponding to "PTR_FORMAT \
" (%u) is not in committed area.", \
(index), \
diff --git a/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp b/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp
index 060531901..1f1042caa 100644
--- a/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp
@@ -1371,7 +1371,7 @@ bool G1CollectedHeap::do_collection(bool explicit_gc,
// how reference processing currently works in G1.
// Temporarily make discovery by the STW ref processor single threaded (non-MT).
- ReferenceProcessorMTDiscoveryMutator stw_rp_disc_ser(ref_processor_stw(), false);
+ ReferenceProcessorMTDiscoveryMutator stw_rp_disc_ser(ref_processor_stw(), G1ParallelFullGC);
// Temporarily clear the STW ref processor's _is_alive_non_header field.
ReferenceProcessorIsAliveMutator stw_rp_is_alive_null(ref_processor_stw(), NULL);
diff --git a/hotspot/src/share/vm/gc_implementation/g1/g1MarkSweep.cpp b/hotspot/src/share/vm/gc_implementation/g1/g1MarkSweep.cpp
index 2a14b967a..9ab422405 100644
--- a/hotspot/src/share/vm/gc_implementation/g1/g1MarkSweep.cpp
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1MarkSweep.cpp
@@ -216,13 +216,17 @@ size_t G1RePrepareClosure::apply(oop obj) {
bool G1MarkSweep::_parallel_prepare_compact = false;
bool G1MarkSweep::_parallel_adjust = false;
+bool G1MarkSweep::_parallel_mark = false;
+uint G1MarkSweep::_active_workers = 0;
void G1MarkSweep::invoke_at_safepoint(ReferenceProcessor* rp,
bool clear_all_softrefs) {
assert(SafepointSynchronize::is_at_safepoint(), "must be at a safepoint");
- uint active_workers = G1CollectedHeap::heap()->workers()->active_workers();
+
+ _active_workers = G1CollectedHeap::heap()->workers()->active_workers();
if (G1ParallelFullGC) {
+ _parallel_mark = true;
_parallel_prepare_compact = true;
_parallel_adjust = true;
}
@@ -238,6 +242,19 @@ void G1MarkSweep::invoke_at_safepoint(ReferenceProcessor* rp,
assert(rp != NULL, "should be non-NULL");
assert(rp == G1CollectedHeap::heap()->ref_processor_stw(), "Precondition");
+ GenMarkSweep* marks = new GenMarkSweep[_active_workers];
+
+ if (!_parallel_mark) {
+ allocate_stacks();
+ } else {
+ for (uint i = 0; i < _active_workers; i++) {
+ marks[i]._preserved_count_max = 0;
+ marks[i]._preserved_marks = NULL;
+ marks[i]._preserved_count = 0;
+ marks[i].set_worker_id(i);
+ }
+ }
+
GenMarkSweep::_ref_processor = rp;
rp->setup_policy(clear_all_softrefs);
@@ -248,30 +265,42 @@ void G1MarkSweep::invoke_at_safepoint(ReferenceProcessor* rp,
bool marked_for_unloading = false;
- allocate_stacks();
-
// We should save the marks of the currently locked biased monitors.
// The marking doesn't preserve the marks of biased objects.
BiasedLocking::preserve_marks();
{
- G1FullGCCompactionPoints cps(active_workers);
+ G1FullGCCompactionPoints cps(_active_workers);
- mark_sweep_phase1(marked_for_unloading, clear_all_softrefs);
+ mark_sweep_phase1(marked_for_unloading, clear_all_softrefs, marks);
mark_sweep_phase2(&cps);
// Don't add any more derived pointers during phase3
COMPILER2_PRESENT(DerivedPointerTable::set_active(false));
- mark_sweep_phase3();
+ mark_sweep_phase3(marks);
mark_sweep_phase4(&cps);
}
- GenMarkSweep::restore_marks();
+ if (!_parallel_mark) {
+ GenMarkSweep::the_gen_mark()->restore_marks();
+ } else {
+ for (uint i = 0; i < _active_workers; i++) {
+ marks[i].restore_marks();
+ }
+ }
+
BiasedLocking::restore_marks();
- GenMarkSweep::deallocate_stacks();
+
+ if (!_parallel_mark) {
+ GenMarkSweep::the_gen_mark()->deallocate_stacks();
+ } else {
+ for (uint i = 0; i < _active_workers; i++) {
+ marks[i].deallocate_stacks();
+ }
+ }
// "free at last gc" is calculated from these.
// CHF: cheating for now!!!
@@ -281,20 +310,62 @@ void G1MarkSweep::invoke_at_safepoint(ReferenceProcessor* rp,
Threads::gc_epilogue();
CodeCache::gc_epilogue();
JvmtiExport::gc_epilogue();
-
// refs processing: clean slate
GenMarkSweep::_ref_processor = NULL;
}
+void G1MarkSweep::run_task(AbstractGangTask* task) {
+ G1CollectedHeap::heap()->workers()->run_task(task);
+}
void G1MarkSweep::allocate_stacks() {
- GenMarkSweep::_preserved_count_max = 0;
- GenMarkSweep::_preserved_marks = NULL;
- GenMarkSweep::_preserved_count = 0;
+ GenMarkSweep::the_gen_mark()->_preserved_count_max = 0;
+ GenMarkSweep::the_gen_mark()->_preserved_marks = NULL;
+ GenMarkSweep::the_gen_mark()->_preserved_count = 0;
}
+class G1FullGCMarkTask : public AbstractGangTask {
+protected:
+ G1RootProcessor _root_processor;
+ GenMarkSweep* _marks;
+
+public:
+ G1FullGCMarkTask(GenMarkSweep* marks, uint active_workers) :
+ AbstractGangTask("G1 mark task"),
+ _root_processor(G1CollectedHeap::heap()),
+ _marks(marks) {
+ _root_processor.set_num_workers(active_workers);
+ }
+ virtual ~G1FullGCMarkTask() { }
+
+ void work(uint worker_id) {
+ Ticks start = Ticks::now();
+
+ ResourceMark rm;
+
+ MarkingCodeBlobClosure follow_code_closure(&_marks[worker_id].follow_root_closure,
+ !CodeBlobToOopClosure::FixRelocations);
+ {
+
+ if (ClassUnloading) {
+ _root_processor.process_strong_roots(&_marks[worker_id].follow_root_closure,
+ &_marks[worker_id].follow_cld_closure,
+ &follow_code_closure,
+ worker_id);
+ } else {
+ _root_processor.process_all_roots_no_string_table(&_marks[worker_id].follow_root_closure,
+ &_marks[worker_id].follow_cld_closure,
+ &follow_code_closure);
+ }
+ _marks[worker_id].follow_stack();
+ }
+ }
+};
+
+
void G1MarkSweep::mark_sweep_phase1(bool& marked_for_unloading,
- bool clear_all_softrefs) {
+ bool clear_all_softrefs,
+ GenMarkSweep* marks) {
// Recursively traverse all live objects and mark them
GCTraceTime tm("phase 1", G1Log::fine() && Verbose, true, gc_timer(), gc_tracer()->gc_id());
GenMarkSweep::trace(" 1");
@@ -304,52 +375,87 @@ void G1MarkSweep::mark_sweep_phase1(bool& marked_for_unloading,
// Need cleared claim bits for the roots processing
ClassLoaderDataGraph::clear_claimed_marks();
- MarkingCodeBlobClosure follow_code_closure(&GenMarkSweep::follow_root_closure, !CodeBlobToOopClosure::FixRelocations);
- {
- G1RootProcessor root_processor(g1h);
- if (ClassUnloading) {
- root_processor.process_strong_roots(&GenMarkSweep::follow_root_closure,
- &GenMarkSweep::follow_cld_closure,
- &follow_code_closure);
- } else {
- root_processor.process_all_roots_no_string_table(
- &GenMarkSweep::follow_root_closure,
- &GenMarkSweep::follow_cld_closure,
- &follow_code_closure);
+ if (!_parallel_mark) {
+
+ MarkingCodeBlobClosure follow_code_closure(&GenMarkSweep::the_gen_mark()->follow_root_closure,
+ !CodeBlobToOopClosure::FixRelocations);
+ {
+ G1RootProcessor root_processor(g1h);
+ if (ClassUnloading) {
+ root_processor.process_strong_roots(&GenMarkSweep::the_gen_mark()->follow_root_closure,
+ &GenMarkSweep::the_gen_mark()->follow_cld_closure,
+ &follow_code_closure);
+ } else {
+ root_processor.process_all_roots_no_string_table(&GenMarkSweep::the_gen_mark()->follow_root_closure,
+ &GenMarkSweep::the_gen_mark()->follow_cld_closure,
+ &follow_code_closure);
+ }
}
- }
- // Process reference objects found during marking
- ReferenceProcessor* rp = GenMarkSweep::ref_processor();
- assert(rp == g1h->ref_processor_stw(), "Sanity");
+ // Process reference objects found during marking
+ ReferenceProcessor* rp = GenMarkSweep::ref_processor();
+ assert(rp == g1h->ref_processor_stw(), "Sanity");
+
+ rp->setup_policy(clear_all_softrefs);
+ const ReferenceProcessorStats& stats =
+ rp->process_discovered_references(&GenMarkSweep::the_gen_mark()->is_alive,
+ &GenMarkSweep::the_gen_mark()->keep_alive,
+ &GenMarkSweep::the_gen_mark()->follow_stack_closure,
+ NULL,
+ gc_timer(),
+ gc_tracer()->gc_id());
+ gc_tracer()->report_gc_reference_stats(stats);
- rp->setup_policy(clear_all_softrefs);
- const ReferenceProcessorStats& stats =
- rp->process_discovered_references(&GenMarkSweep::is_alive,
- &GenMarkSweep::keep_alive,
- &GenMarkSweep::follow_stack_closure,
- NULL,
- gc_timer(),
- gc_tracer()->gc_id());
- gc_tracer()->report_gc_reference_stats(stats);
+ // This is the point where the entire marking should have completed.
+ assert(GenMarkSweep::the_gen_mark()->_marking_stack.is_empty(), "Marking should have completed");
- // This is the point where the entire marking should have completed.
- assert(GenMarkSweep::_marking_stack.is_empty(), "Marking should have completed");
+ if (ClassUnloading) {
+ // Unload classes and purge the SystemDictionary.
+ bool purged_class = SystemDictionary::do_unloading(&GenMarkSweep::the_gen_mark()->is_alive);
+ // Unload nmethods.
+ CodeCache::do_unloading(&GenMarkSweep::the_gen_mark()->is_alive, purged_class);
+ // Prune dead klasses from subklass/sibling/implementor lists.
+ Klass::clean_weak_klass_links(&GenMarkSweep::the_gen_mark()->is_alive);
+ }
+ // Delete entries for dead interned string and clean up unreferenced symbols in symbol table.
+ G1CollectedHeap::heap()->unlink_string_and_symbol_table(&GenMarkSweep::the_gen_mark()->is_alive);
+ } else {
+ G1FullGCMarkTask task(marks, _active_workers);
+ FlexibleWorkGang* flexible = G1CollectedHeap::heap()->workers();
+ SharedHeap::heap()->set_par_threads(_active_workers);
+ flexible->run_task(&task);
+ SharedHeap::heap()->set_par_threads(0);
+
+ // Process reference objects found during marking
+ ReferenceProcessor* rp = MarkSweep::ref_processor();
+ assert(rp == g1h->ref_processor_stw(), "Sanity");
- if (ClassUnloading) {
+ rp->setup_policy(clear_all_softrefs);
- // Unload classes and purge the SystemDictionary.
- bool purged_class = SystemDictionary::do_unloading(&GenMarkSweep::is_alive);
+ const ReferenceProcessorStats& stats =
+ rp->process_discovered_references(&marks[0].is_alive,
+ &marks[0].keep_alive,
+ &marks[0].follow_stack_closure,
+ NULL,
+ gc_timer(),
+ gc_tracer()->gc_id());
+ gc_tracer()->report_gc_reference_stats(stats);
+
+ if (ClassUnloading) {
- // Unload nmethods.
- CodeCache::do_unloading(&GenMarkSweep::is_alive, purged_class);
+ // Unload classes and purge the SystemDictionary.
+ bool purged_class = SystemDictionary::do_unloading(&marks[0].is_alive);
- // Prune dead klasses from subklass/sibling/implementor lists.
- Klass::clean_weak_klass_links(&GenMarkSweep::is_alive);
+ // Unload nmethods.
+ CodeCache::do_unloading(&marks[0].is_alive, purged_class);
+
+ // Prune dead klasses from subklass/sibling/implementor lists.
+ Klass::clean_weak_klass_links(&marks[0].is_alive);
+ }
+ // Delete entries for dead interned string and clean up unreferenced symbols in symbol table.
+ G1CollectedHeap::heap()->unlink_string_and_symbol_table(&marks[0].is_alive);
}
- // Delete entries for dead interned string and clean up unreferenced symbols in symbol table.
- G1CollectedHeap::heap()->unlink_string_and_symbol_table(&GenMarkSweep::is_alive);
if (VerifyDuringGC) {
HandleMark hm; // handle scope
@@ -374,7 +480,7 @@ void G1MarkSweep::mark_sweep_phase1(bool& marked_for_unloading,
}
}
- gc_tracer()->report_object_count_after_gc(&GenMarkSweep::is_alive);
+ gc_tracer()->report_object_count_after_gc(&GenMarkSweep::the_gen_mark()->is_alive);
}
@@ -603,7 +709,7 @@ public:
}
};
-void G1MarkSweep::mark_sweep_phase3() {
+void G1MarkSweep::mark_sweep_phase3(GenMarkSweep* marks) {
G1CollectedHeap* g1h = G1CollectedHeap::heap();
// Adjust the pointers to reflect the new locations
@@ -613,33 +719,40 @@ void G1MarkSweep::mark_sweep_phase3() {
// Need cleared claim bits for the roots processing
ClassLoaderDataGraph::clear_claimed_marks();
- CodeBlobToOopClosure adjust_code_closure(&GenMarkSweep::adjust_pointer_closure,
+ CodeBlobToOopClosure adjust_code_closure(&GenMarkSweep::the_gen_mark()->adjust_pointer_closure,
CodeBlobToOopClosure::FixRelocations);
{
G1RootProcessor root_processor(g1h);
- root_processor.process_all_roots(&GenMarkSweep::adjust_pointer_closure,
- &GenMarkSweep::adjust_cld_closure,
+ root_processor.process_all_roots(&GenMarkSweep::the_gen_mark()->adjust_pointer_closure,
+ &GenMarkSweep::the_gen_mark()->adjust_cld_closure,
&adjust_code_closure);
}
assert(GenMarkSweep::ref_processor() == g1h->ref_processor_stw(), "Sanity");
- g1h->ref_processor_stw()->weak_oops_do(&GenMarkSweep::adjust_pointer_closure);
+ g1h->ref_processor_stw()->weak_oops_do(&GenMarkSweep::the_gen_mark()->adjust_pointer_closure);
// Now adjust pointers in remaining weak roots. (All of which should
// have been cleared if they pointed to non-surviving objects.)
- JNIHandles::weak_oops_do(&GenMarkSweep::adjust_pointer_closure);
- JFR_ONLY(Jfr::weak_oops_do(&GenMarkSweep::adjust_pointer_closure));
+ JNIHandles::weak_oops_do(&GenMarkSweep::the_gen_mark()->adjust_pointer_closure);
+ JFR_ONLY(Jfr::weak_oops_do(&GenMarkSweep::the_gen_mark()->adjust_pointer_closure));
if (G1StringDedup::is_enabled()) {
- G1StringDedup::oops_do(&GenMarkSweep::adjust_pointer_closure);
+ G1StringDedup::oops_do(&GenMarkSweep::the_gen_mark()->adjust_pointer_closure);
}
- GenMarkSweep::adjust_marks();
-
if (!_parallel_adjust) {
+ GenMarkSweep::the_gen_mark()->adjust_marks();
G1AdjustPointersClosure blk;
g1h->heap_region_iterate(&blk);
} else {
+ if (!_parallel_mark) {
+ GenMarkSweep::the_gen_mark()->adjust_marks();
+ } else {
+ for (uint i = 0; i < _active_workers; i++) {
+ marks[i].adjust_marks();
+ }
+ }
+
G1FullGCAdjustTask task;
FlexibleWorkGang* flexible = G1CollectedHeap::heap()->workers();
flexible->run_task(&task);
diff --git a/hotspot/src/share/vm/gc_implementation/g1/g1MarkSweep.hpp b/hotspot/src/share/vm/gc_implementation/g1/g1MarkSweep.hpp
index 82aa6b63e..0787cfe86 100644
--- a/hotspot/src/share/vm/gc_implementation/g1/g1MarkSweep.hpp
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1MarkSweep.hpp
@@ -75,16 +75,19 @@ class G1MarkSweep : AllStatic {
private:
static bool _parallel_prepare_compact;
static bool _parallel_adjust;
+ static bool _parallel_mark;
+ static uint _active_workers;
private:
-
+ static void run_task(AbstractGangTask* task);
// Mark live objects
static void mark_sweep_phase1(bool& marked_for_deopt,
- bool clear_all_softrefs);
+ bool clear_all_softrefs,
+ GenMarkSweep* marks);
// Calculate new addresses
static void mark_sweep_phase2(G1FullGCCompactionPoints* cps);
// Update pointers
- static void mark_sweep_phase3();
+ static void mark_sweep_phase3(GenMarkSweep* marks);
// Move objects to new positions
static void mark_sweep_phase4(G1FullGCCompactionPoints* cps);
diff --git a/hotspot/src/share/vm/gc_implementation/g1/g1RootProcessor.cpp b/hotspot/src/share/vm/gc_implementation/g1/g1RootProcessor.cpp
index 5b27a017a..6b0f8e8bd 100644
--- a/hotspot/src/share/vm/gc_implementation/g1/g1RootProcessor.cpp
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1RootProcessor.cpp
@@ -213,10 +213,11 @@ void G1RootProcessor::evacuate_roots(OopClosure* scan_non_heap_roots,
void G1RootProcessor::process_strong_roots(OopClosure* oops,
CLDClosure* clds,
- CodeBlobClosure* blobs) {
+ CodeBlobClosure* blobs,
+ uint worker_id) {
- process_java_roots(oops, clds, clds, NULL, blobs, NULL, 0);
- process_vm_roots(oops, NULL, NULL, 0);
+ process_java_roots(oops, clds, clds, NULL, blobs, NULL, worker_id);
+ process_vm_roots(oops, NULL, NULL, worker_id);
_process_strong_tasks.all_tasks_completed();
}
@@ -224,23 +225,25 @@ void G1RootProcessor::process_strong_roots(OopClosure* oops,
void G1RootProcessor::process_all_roots(OopClosure* oops,
CLDClosure* clds,
CodeBlobClosure* blobs,
- bool process_string_table) {
+ bool process_string_table,
+ uint worker_id) {
- process_java_roots(oops, NULL, clds, clds, NULL, NULL, 0);
- process_vm_roots(oops, oops, NULL, 0);
+ process_java_roots(oops, NULL, clds, clds, NULL, NULL, worker_id);
+ process_vm_roots(oops, oops, NULL, worker_id);
if (process_string_table) {
- process_string_table_roots(oops, NULL, 0);
+ process_string_table_roots(oops, NULL, worker_id);
}
- process_code_cache_roots(blobs, NULL, 0);
+ process_code_cache_roots(blobs, NULL, worker_id);
_process_strong_tasks.all_tasks_completed();
}
void G1RootProcessor::process_all_roots(OopClosure* oops,
CLDClosure* clds,
- CodeBlobClosure* blobs) {
- process_all_roots(oops, clds, blobs, true);
+ CodeBlobClosure* blobs,
+ uint worker_id) {
+ process_all_roots(oops, clds, blobs, true, worker_id);
}
void G1RootProcessor::process_all_roots_no_string_table(OopClosure* oops,
diff --git a/hotspot/src/share/vm/gc_implementation/g1/g1RootProcessor.hpp b/hotspot/src/share/vm/gc_implementation/g1/g1RootProcessor.hpp
index ad4e75ba3..8395ee2e4 100644
--- a/hotspot/src/share/vm/gc_implementation/g1/g1RootProcessor.hpp
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1RootProcessor.hpp
@@ -75,7 +75,8 @@ class G1RootProcessor : public StackObj {
void process_all_roots(OopClosure* oops,
CLDClosure* clds,
CodeBlobClosure* blobs,
- bool process_string_table);
+ bool process_string_table,
+ uint worker_id = 0);
void process_java_roots(OopClosure* scan_non_heap_roots,
CLDClosure* thread_stack_clds,
@@ -114,12 +115,14 @@ public:
// Apply oops, clds and blobs to all strongly reachable roots in the system
void process_strong_roots(OopClosure* oops,
CLDClosure* clds,
- CodeBlobClosure* blobs);
+ CodeBlobClosure* blobs,
+ uint worker_id = 0);
// Apply oops, clds and blobs to strongly and weakly reachable roots in the system
void process_all_roots(OopClosure* oops,
CLDClosure* clds,
- CodeBlobClosure* blobs);
+ CodeBlobClosure* blobs,
+ uint worker_id = 0);
// Apply scan_rs to all locations in the union of the remembered sets for all
// regions in the collection set
diff --git a/hotspot/src/share/vm/gc_implementation/g1/g1StringDedup.cpp b/hotspot/src/share/vm/gc_implementation/g1/g1StringDedup.cpp
index bb960ee3a..804d1e141 100644
--- a/hotspot/src/share/vm/gc_implementation/g1/g1StringDedup.cpp
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1StringDedup.cpp
@@ -49,10 +49,10 @@ void G1StringDedup::stop() {
G1StringDedupThread::stop();
}
-bool G1StringDedup::is_candidate_from_mark(oop obj) {
+bool G1StringDedup::is_candidate_from_mark(oop obj, uint age) {
if (java_lang_String::is_instance(obj)) {
bool from_young = G1CollectedHeap::heap()->heap_region_containing_raw(obj)->is_young();
- if (from_young && obj->age() < StringDeduplicationAgeThreshold) {
+ if (from_young && age < StringDeduplicationAgeThreshold) {
// Candidate found. String is being evacuated from young to old but has not
// reached the deduplication age threshold, i.e. has not previously been a
// candidate during its life in the young generation.
@@ -64,10 +64,10 @@ bool G1StringDedup::is_candidate_from_mark(oop obj) {
return false;
}
-void G1StringDedup::enqueue_from_mark(oop java_string) {
+void G1StringDedup::enqueue_from_mark(oop java_string, uint age, uint worker_id) {
assert(is_enabled(), "String deduplication not enabled");
- if (is_candidate_from_mark(java_string)) {
- G1StringDedupQueue::push(0 /* worker_id */, java_string);
+ if (is_candidate_from_mark(java_string, age)) {
+ G1StringDedupQueue::push(worker_id /* worker_id */, java_string);
}
}
diff --git a/hotspot/src/share/vm/gc_implementation/g1/g1StringDedup.hpp b/hotspot/src/share/vm/gc_implementation/g1/g1StringDedup.hpp
index 3792a667a..d14284b9a 100644
--- a/hotspot/src/share/vm/gc_implementation/g1/g1StringDedup.hpp
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1StringDedup.hpp
@@ -102,7 +102,7 @@ private:
// Candidate selection policies, returns true if the given object is
// candidate for string deduplication.
- static bool is_candidate_from_mark(oop obj);
+ static bool is_candidate_from_mark(oop obj, uint age);
static bool is_candidate_from_evacuation(bool from_young, bool to_young, oop obj);
public:
@@ -124,7 +124,7 @@ public:
// Enqueues a deduplication candidate for later processing by the deduplication
// thread. Before enqueuing, these functions apply the appropriate candidate
// selection policy to filters out non-candidates.
- static void enqueue_from_mark(oop java_string);
+ static void enqueue_from_mark(oop java_string, uint age, uint worker_id);
static void enqueue_from_evacuation(bool from_young, bool to_young,
unsigned int queue, oop java_string);
diff --git a/hotspot/src/share/vm/gc_implementation/parallelScavenge/parallelScavengeHeap.cpp b/hotspot/src/share/vm/gc_implementation/parallelScavenge/parallelScavengeHeap.cpp
index a8a87cc1b..74c15844b 100644
--- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/parallelScavengeHeap.cpp
+++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/parallelScavengeHeap.cpp
@@ -430,7 +430,7 @@ void ParallelScavengeHeap::do_full_collection(bool clear_all_soft_refs) {
bool maximum_compaction = clear_all_soft_refs;
PSParallelCompact::invoke(maximum_compaction);
} else {
- PSMarkSweep::invoke(clear_all_soft_refs);
+ PSMarkSweep::the_ps_mark()->invoke(clear_all_soft_refs);
}
}
diff --git a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psMarkSweep.cpp b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psMarkSweep.cpp
index 2542ba1ca..4f8890f04 100644
--- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psMarkSweep.cpp
+++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psMarkSweep.cpp
@@ -59,10 +59,15 @@
PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC
+MarkSweep* PSMarkSweep::_the_ps_mark = NULL;
elapsedTimer PSMarkSweep::_accumulated_time;
jlong PSMarkSweep::_time_of_last_gc = 0;
CollectorCounters* PSMarkSweep::_counters = NULL;
+void PSMarkSweep::ps_marksweep_init() {
+ PSMarkSweep::_the_ps_mark = new (ResourceObj::C_HEAP, mtGC) PSMarkSweep();
+}
+
void PSMarkSweep::initialize() {
MemRegion mr = Universe::heap()->reserved_region();
_ref_processor = new ReferenceProcessor(mr); // a vanilla ref proc
diff --git a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psMarkSweep.hpp b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psMarkSweep.hpp
index 46073f9e2..01666ea4d 100644
--- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psMarkSweep.hpp
+++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psMarkSweep.hpp
@@ -34,34 +34,36 @@ class PSYoungGen;
class PSOldGen;
class PSMarkSweep : public MarkSweep {
+ friend void marksweep_init();
private:
static elapsedTimer _accumulated_time;
static jlong _time_of_last_gc; // ms
static CollectorCounters* _counters;
+ static MarkSweep* _the_ps_mark;
// Closure accessors
- static OopClosure* mark_and_push_closure() { return &MarkSweep::mark_and_push_closure; }
- static VoidClosure* follow_stack_closure() { return (VoidClosure*)&MarkSweep::follow_stack_closure; }
- static CLDClosure* follow_cld_closure() { return &MarkSweep::follow_cld_closure; }
- static OopClosure* adjust_pointer_closure() { return (OopClosure*)&MarkSweep::adjust_pointer_closure; }
- static CLDClosure* adjust_cld_closure() { return &MarkSweep::adjust_cld_closure; }
- static BoolObjectClosure* is_alive_closure() { return (BoolObjectClosure*)&MarkSweep::is_alive; }
+ OopClosure* mark_and_push_closure() { return &(MarkSweep::mark_and_push_closure); }
+ VoidClosure* follow_stack_closure() { return (VoidClosure*)&(MarkSweep::follow_stack_closure); }
+ CLDClosure* follow_cld_closure() { return &(MarkSweep::follow_cld_closure); }
+ OopClosure* adjust_pointer_closure() { return (OopClosure*)&(MarkSweep::adjust_pointer_closure); }
+ CLDClosure* adjust_cld_closure() { return &(MarkSweep::adjust_cld_closure); }
+ BoolObjectClosure* is_alive_closure() { return (BoolObjectClosure*)&(MarkSweep::is_alive); }
debug_only(public:) // Used for PSParallelCompact debugging
// Mark live objects
- static void mark_sweep_phase1(bool clear_all_softrefs);
+ void mark_sweep_phase1(bool clear_all_softrefs);
// Calculate new addresses
- static void mark_sweep_phase2();
+ void mark_sweep_phase2();
debug_only(private:) // End used for PSParallelCompact debugging
// Update pointers
- static void mark_sweep_phase3();
+ void mark_sweep_phase3();
// Move objects to new positions
- static void mark_sweep_phase4();
+ void mark_sweep_phase4();
debug_only(public:) // Used for PSParallelCompact debugging
// Temporary data structures for traversal and storing/restoring marks
- static void allocate_stacks();
- static void deallocate_stacks();
+ void allocate_stacks();
+ void deallocate_stacks();
static void set_ref_processor(ReferenceProcessor* rp) { // delete this method
_ref_processor = rp;
}
@@ -75,10 +77,13 @@ class PSMarkSweep : public MarkSweep {
// Reset time since last full gc
static void reset_millis_since_last_gc();
+ static void ps_marksweep_init();
public:
- static void invoke(bool clear_all_softrefs);
- static bool invoke_no_policy(bool clear_all_softrefs);
+ static inline PSMarkSweep* the_ps_mark() { return (PSMarkSweep*)_the_ps_mark; }
+
+ void invoke(bool clear_all_softrefs);
+ bool invoke_no_policy(bool clear_all_softrefs);
static void initialize();
diff --git a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psScavenge.cpp b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psScavenge.cpp
index 12e282eeb..670cd3e64 100644
--- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psScavenge.cpp
+++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psScavenge.cpp
@@ -248,7 +248,7 @@ bool PSScavenge::invoke() {
if (UseParallelOldGC) {
full_gc_done = PSParallelCompact::invoke_no_policy(clear_all_softrefs);
} else {
- full_gc_done = PSMarkSweep::invoke_no_policy(clear_all_softrefs);
+ full_gc_done = PSMarkSweep::the_ps_mark()->invoke_no_policy(clear_all_softrefs);
}
}
diff --git a/hotspot/src/share/vm/gc_implementation/shared/markSweep.cpp b/hotspot/src/share/vm/gc_implementation/shared/markSweep.cpp
index e2629b652..596207934 100644
--- a/hotspot/src/share/vm/gc_implementation/shared/markSweep.cpp
+++ b/hotspot/src/share/vm/gc_implementation/shared/markSweep.cpp
@@ -24,10 +24,12 @@
#include "precompiled.hpp"
#include "compiler/compileBroker.hpp"
+#include "gc_implementation/parallelScavenge/psMarkSweep.hpp"
#include "gc_implementation/shared/gcTimer.hpp"
#include "gc_implementation/shared/gcTrace.hpp"
#include "gc_implementation/shared/markSweep.inline.hpp"
#include "gc_interface/collectedHeap.inline.hpp"
+#include "memory/genMarkSweep.hpp"
#include "oops/methodData.hpp"
#include "oops/objArrayKlass.inline.hpp"
#include "oops/oop.inline.hpp"
@@ -36,53 +38,41 @@ PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC
uint MarkSweep::_total_invocations = 0;
-Stack<oop, mtGC> MarkSweep::_marking_stack;
-Stack<ObjArrayTask, mtGC> MarkSweep::_objarray_stack;
-
-Stack<oop, mtGC> MarkSweep::_preserved_oop_stack;
-Stack<markOop, mtGC> MarkSweep::_preserved_mark_stack;
-size_t MarkSweep::_preserved_count = 0;
-size_t MarkSweep::_preserved_count_max = 0;
-PreservedMark* MarkSweep::_preserved_marks = NULL;
ReferenceProcessor* MarkSweep::_ref_processor = NULL;
STWGCTimer* MarkSweep::_gc_timer = NULL;
SerialOldTracer* MarkSweep::_gc_tracer = NULL;
-MarkSweep::FollowRootClosure MarkSweep::follow_root_closure;
-
-void MarkSweep::FollowRootClosure::do_oop(oop* p) { follow_root(p); }
-void MarkSweep::FollowRootClosure::do_oop(narrowOop* p) { follow_root(p); }
-
-MarkSweep::MarkAndPushClosure MarkSweep::mark_and_push_closure;
-CLDToOopClosure MarkSweep::follow_cld_closure(&mark_and_push_closure);
-CLDToOopClosure MarkSweep::adjust_cld_closure(&adjust_pointer_closure);
+void MarkSweep::FollowRootClosure::do_oop(oop* p) { _mark->follow_root(p); }
+void MarkSweep::FollowRootClosure::do_oop(narrowOop* p) { _mark->follow_root(p); }
-void MarkSweep::MarkAndPushClosure::do_oop(oop* p) { mark_and_push(p); }
-void MarkSweep::MarkAndPushClosure::do_oop(narrowOop* p) { mark_and_push(p); }
+void MarkSweep::MarkAndPushClosure::do_oop(oop* p) { _mark->mark_and_push(p); }
+void MarkSweep::MarkAndPushClosure::do_oop(narrowOop* p) { _mark->mark_and_push(p); }
void MarkSweep::follow_class_loader(ClassLoaderData* cld) {
MarkSweep::follow_cld_closure.do_cld(cld);
}
+MarkSweep* MarkSweep::the_mark() {
+ return GenMarkSweep::the_gen_mark();
+}
+
void MarkSweep::follow_stack() {
do {
while (!_marking_stack.is_empty()) {
oop obj = _marking_stack.pop();
assert (obj->is_gc_marked(), "p must be marked");
- obj->follow_contents();
+ obj->follow_contents(this);
}
// Process ObjArrays one at a time to avoid marking stack bloat.
if (!_objarray_stack.is_empty()) {
ObjArrayTask task = _objarray_stack.pop();
ObjArrayKlass* k = (ObjArrayKlass*)task.obj()->klass();
- k->oop_follow_contents(task.obj(), task.index());
+ k->oop_follow_contents(task.obj(), task.index(), this);
}
} while (!_marking_stack.is_empty() || !_objarray_stack.is_empty());
}
-MarkSweep::FollowStackClosure MarkSweep::follow_stack_closure;
-
-void MarkSweep::FollowStackClosure::do_void() { follow_stack(); }
+void MarkSweep::FollowStackClosure::do_void() { _mark->follow_stack(); }
// We preserve the mark which should be replaced at the end and the location
// that it will go. Note that the object that this markOop belongs to isn't
@@ -100,8 +90,6 @@ void MarkSweep::preserve_mark(oop obj, markOop mark) {
}
}
-MarkSweep::AdjustPointerClosure MarkSweep::adjust_pointer_closure;
-
void MarkSweep::AdjustPointerClosure::do_oop(oop* p) { adjust_pointer(p); }
void MarkSweep::AdjustPointerClosure::do_oop(narrowOop* p) { adjust_pointer(p); }
@@ -143,18 +131,16 @@ void MarkSweep::restore_marks() {
}
}
-MarkSweep::IsAliveClosure MarkSweep::is_alive;
-
bool MarkSweep::IsAliveClosure::do_object_b(oop p) { return p->is_gc_marked(); }
-MarkSweep::KeepAliveClosure MarkSweep::keep_alive;
-
void MarkSweep::KeepAliveClosure::do_oop(oop* p) { MarkSweep::KeepAliveClosure::do_oop_work(p); }
void MarkSweep::KeepAliveClosure::do_oop(narrowOop* p) { MarkSweep::KeepAliveClosure::do_oop_work(p); }
void marksweep_init() {
MarkSweep::_gc_timer = new (ResourceObj::C_HEAP, mtGC) STWGCTimer();
MarkSweep::_gc_tracer = new (ResourceObj::C_HEAP, mtGC) SerialOldTracer();
+ PSMarkSweep::ps_marksweep_init();
+ GenMarkSweep::gen_marksweep_init();
}
#ifndef PRODUCT
diff --git a/hotspot/src/share/vm/gc_implementation/shared/markSweep.hpp b/hotspot/src/share/vm/gc_implementation/shared/markSweep.hpp
index 462643e2f..813a5aef7 100644
--- a/hotspot/src/share/vm/gc_implementation/shared/markSweep.hpp
+++ b/hotspot/src/share/vm/gc_implementation/shared/markSweep.hpp
@@ -49,43 +49,55 @@ class STWGCTimer;
// declared at end
class PreservedMark;
-class MarkSweep : AllStatic {
+class MarkSweep : public ResourceObj {
//
// Inline closure decls
//
class FollowRootClosure: public OopsInGenClosure {
+ MarkSweep* _mark;
public:
+ FollowRootClosure(MarkSweep* mark) : _mark(mark) { }
virtual void do_oop(oop* p);
virtual void do_oop(narrowOop* p);
};
class MarkAndPushClosure: public OopClosure {
+ MarkSweep* _mark;
public:
+ MarkAndPushClosure(MarkSweep* mark) : _mark(mark) { }
virtual void do_oop(oop* p);
virtual void do_oop(narrowOop* p);
};
class FollowStackClosure: public VoidClosure {
+ MarkSweep* _mark;
public:
+ FollowStackClosure(MarkSweep* mark) : _mark(mark) { }
virtual void do_void();
};
class AdjustPointerClosure: public OopsInGenClosure {
+ MarkSweep* _mark;
public:
+ AdjustPointerClosure(MarkSweep* mark) : _mark(mark) { }
virtual void do_oop(oop* p);
virtual void do_oop(narrowOop* p);
};
// Used for java/lang/ref handling
class IsAliveClosure: public BoolObjectClosure {
+ MarkSweep* _mark;
public:
+ IsAliveClosure(MarkSweep* mark) : _mark(mark) { }
virtual bool do_object_b(oop p);
};
class KeepAliveClosure: public OopClosure {
+ MarkSweep* _mark;
protected:
template <class T> void do_oop_work(T* p);
public:
+ KeepAliveClosure(MarkSweep* mark) : _mark(mark) { }
virtual void do_oop(oop* p);
virtual void do_oop(narrowOop* p);
};
@@ -106,37 +118,49 @@ class MarkSweep : AllStatic {
static uint _total_invocations;
// Traversal stacks used during phase1
- static Stack<oop, mtGC> _marking_stack;
- static Stack<ObjArrayTask, mtGC> _objarray_stack;
+ Stack<oop, mtGC> _marking_stack;
+ Stack<ObjArrayTask, mtGC> _objarray_stack;
// Space for storing/restoring mark word
- static Stack<markOop, mtGC> _preserved_mark_stack;
- static Stack<oop, mtGC> _preserved_oop_stack;
- static size_t _preserved_count;
- static size_t _preserved_count_max;
- static PreservedMark* _preserved_marks;
+ Stack<markOop, mtGC> _preserved_mark_stack;
+ Stack<oop, mtGC> _preserved_oop_stack;
+ size_t _preserved_count;
+ size_t _preserved_count_max;
+ PreservedMark* _preserved_marks;
+ uint _worker_id;
// Reference processing (used in ...follow_contents)
static ReferenceProcessor* _ref_processor;
static STWGCTimer* _gc_timer;
static SerialOldTracer* _gc_tracer;
- // Non public closures
- static KeepAliveClosure keep_alive;
-
// Debugging
static void trace(const char* msg) PRODUCT_RETURN;
+ bool par_mark(oop obj);
public:
+ static MarkSweep* the_mark();
+ KeepAliveClosure keep_alive;
// Public closures
- static IsAliveClosure is_alive;
- static FollowRootClosure follow_root_closure;
- static MarkAndPushClosure mark_and_push_closure;
- static FollowStackClosure follow_stack_closure;
- static CLDToOopClosure follow_cld_closure;
- static AdjustPointerClosure adjust_pointer_closure;
- static CLDToOopClosure adjust_cld_closure;
+ IsAliveClosure is_alive;
+ FollowRootClosure follow_root_closure;
+ MarkAndPushClosure mark_and_push_closure;
+ FollowStackClosure follow_stack_closure;
+ CLDToOopClosure follow_cld_closure;
+ AdjustPointerClosure adjust_pointer_closure;
+ CLDToOopClosure adjust_cld_closure;
+
+ MarkSweep() :
+ is_alive(this),
+ follow_root_closure(this),
+ mark_and_push_closure(this),
+ follow_stack_closure(this),
+ follow_cld_closure(&mark_and_push_closure),
+ adjust_pointer_closure(this),
+ adjust_cld_closure(&adjust_pointer_closure),
+ keep_alive(this)
+ { }
// Accessors
static uint total_invocations() { return _total_invocations; }
@@ -147,26 +171,23 @@ class MarkSweep : AllStatic {
static STWGCTimer* gc_timer() { return _gc_timer; }
static SerialOldTracer* gc_tracer() { return _gc_tracer; }
+ void set_worker_id(uint worker_id) { _worker_id = worker_id; }
// Call backs for marking
- static void mark_object(oop obj);
+ bool mark_object(oop obj);
// Mark pointer and follow contents. Empty marking stack afterwards.
- template <class T> static inline void follow_root(T* p);
+ template <class T> inline void follow_root(T* p);
// Check mark and maybe push on marking stack
- template <class T> static void mark_and_push(T* p);
-
- static inline void push_objarray(oop obj, size_t index);
-
- static void follow_stack(); // Empty marking stack.
-
- static void follow_klass(Klass* klass);
-
- static void follow_class_loader(ClassLoaderData* cld);
-
- static void preserve_mark(oop p, markOop mark);
- // Save the mark word so it can be restored later
- static void adjust_marks(); // Adjust the pointers in the preserved marks table
- static void restore_marks(); // Restore the marks that we saved in preserve_mark
+ template <class T> void mark_and_push(T* p);
+
+ inline void push_objarray(oop obj, size_t index);
+ void follow_stack(); // Empty marking st
+ void follow_klass(Klass* klass);
+ void follow_class_loader(ClassLoaderData* cld);
+ void preserve_mark(oop p, markOop mark);
+ // Save the mark word so it can be restored later
+ void adjust_marks(); // Adjust the pointers in the preserved marks table
+ void restore_marks(); // Restore the marks that we saved in preserve_mark
template <class T> static inline void adjust_pointer(T* p);
};
diff --git a/hotspot/src/share/vm/gc_implementation/shared/markSweep.inline.hpp b/hotspot/src/share/vm/gc_implementation/shared/markSweep.inline.hpp
index c08e7a637..f9ede2487 100644
--- a/hotspot/src/share/vm/gc_implementation/shared/markSweep.inline.hpp
+++ b/hotspot/src/share/vm/gc_implementation/shared/markSweep.inline.hpp
@@ -34,22 +34,43 @@
#include "gc_implementation/parallelScavenge/psParallelCompact.hpp"
#endif // INCLUDE_ALL_GCS
-inline void MarkSweep::mark_object(oop obj) {
+inline bool MarkSweep::par_mark(oop obj) {
+ markOop origin = obj->mark();
+ markOop target = markOopDesc::prototype()->set_marked();
+ void* res = Atomic::cmpxchg_ptr(target, obj->mark_addr(), origin);
+ if (res == origin) {
+ return true;
+ } else {
+ return false;
+ }
+}
+
+inline bool MarkSweep::mark_object(oop obj) {
+ markOop mark = obj->mark();
#if INCLUDE_ALL_GCS
if (G1StringDedup::is_enabled()) {
// We must enqueue the object before it is marked
// as we otherwise can't read the object's age.
- G1StringDedup::enqueue_from_mark(obj);
+ uint age = 0;
+ if (mark->has_displaced_mark_helper()) {
+ age = mark->displaced_mark_helper()->age();
+ } else {
+ age = mark->age();
+ }
+
+ G1StringDedup::enqueue_from_mark(obj, age, _worker_id);
}
#endif
// some marks may contain information we need to preserve so we store them away
// and overwrite the mark. We'll restore it at the end of markSweep.
- markOop mark = obj->mark();
- obj->set_mark(markOopDesc::prototype()->set_marked());
+ if (mark->is_marked() || !par_mark(obj)) {
+ return false;
+ }
if (mark->must_be_preserved(obj)) {
preserve_mark(obj, mark);
}
+ return true;
}
inline void MarkSweep::follow_klass(Klass* klass) {
@@ -64,8 +85,9 @@ template <class T> inline void MarkSweep::follow_root(T* p) {
if (!oopDesc::is_null(heap_oop)) {
oop obj = oopDesc::decode_heap_oop_not_null(heap_oop);
if (!obj->mark()->is_marked()) {
- mark_object(obj);
- obj->follow_contents();
+ if (mark_object(obj)) {
+ obj->follow_contents(this);
+ }
}
}
follow_stack();
@@ -77,8 +99,9 @@ template <class T> inline void MarkSweep::mark_and_push(T* p) {
if (!oopDesc::is_null(heap_oop)) {
oop obj = oopDesc::decode_heap_oop_not_null(heap_oop);
if (!obj->mark()->is_marked()) {
- mark_object(obj);
- _marking_stack.push(obj);
+ if (mark_object(obj)) {
+ _marking_stack.push(obj);
+ }
}
}
}
@@ -108,7 +131,7 @@ template <class T> inline void MarkSweep::adjust_pointer(T* p) {
}
template <class T> inline void MarkSweep::KeepAliveClosure::do_oop_work(T* p) {
- mark_and_push(p);
+ _mark->mark_and_push(p);
}
#endif // SHARE_VM_GC_IMPLEMENTATION_SHARED_MARKSWEEP_INLINE_HPP
diff --git a/hotspot/src/share/vm/memory/genMarkSweep.cpp b/hotspot/src/share/vm/memory/genMarkSweep.cpp
index c5dc4947c..132703d5a 100644
--- a/hotspot/src/share/vm/memory/genMarkSweep.cpp
+++ b/hotspot/src/share/vm/memory/genMarkSweep.cpp
@@ -52,6 +52,12 @@
#include "utilities/copy.hpp"
#include "utilities/events.hpp"
+GenMarkSweep* GenMarkSweep::_the_gen_mark = NULL;
+
+void GenMarkSweep::gen_marksweep_init() {
+ GenMarkSweep::_the_gen_mark = new (ResourceObj::C_HEAP, mtGC) GenMarkSweep();
+}
+
void GenMarkSweep::invoke_at_safepoint(int level, ReferenceProcessor* rp, bool clear_all_softrefs) {
guarantee(level == 1, "We always collect both old and young.");
assert(SafepointSynchronize::is_at_safepoint(), "must be at a safepoint");
diff --git a/hotspot/src/share/vm/memory/genMarkSweep.hpp b/hotspot/src/share/vm/memory/genMarkSweep.hpp
index b6147ab5b..76d4ae1a2 100644
--- a/hotspot/src/share/vm/memory/genMarkSweep.hpp
+++ b/hotspot/src/share/vm/memory/genMarkSweep.hpp
@@ -30,24 +30,28 @@
class GenMarkSweep : public MarkSweep {
friend class VM_MarkSweep;
friend class G1MarkSweep;
+ friend void marksweep_init();
+ static GenMarkSweep* _the_gen_mark;
+ static void gen_marksweep_init();
public:
- static void invoke_at_safepoint(int level, ReferenceProcessor* rp,
+ static inline GenMarkSweep* the_gen_mark() { return _the_gen_mark; }
+ void invoke_at_safepoint(int level, ReferenceProcessor* rp,
bool clear_all_softrefs);
private:
// Mark live objects
- static void mark_sweep_phase1(int level, bool clear_all_softrefs);
+ void mark_sweep_phase1(int level, bool clear_all_softrefs);
// Calculate new addresses
- static void mark_sweep_phase2();
+ void mark_sweep_phase2();
// Update pointers
- static void mark_sweep_phase3(int level);
+ void mark_sweep_phase3(int level);
// Move objects to new positions
- static void mark_sweep_phase4();
+ void mark_sweep_phase4();
// Temporary data structures for traversal and storing/restoring marks
- static void allocate_stacks();
- static void deallocate_stacks();
+ void allocate_stacks();
+ void deallocate_stacks();
};
#endif // SHARE_VM_MEMORY_GENMARKSWEEP_HPP
diff --git a/hotspot/src/share/vm/memory/generation.cpp b/hotspot/src/share/vm/memory/generation.cpp
index 9d6c926e1..4e9848bb9 100644
--- a/hotspot/src/share/vm/memory/generation.cpp
+++ b/hotspot/src/share/vm/memory/generation.cpp
@@ -648,7 +648,7 @@ void OneContigSpaceCardGeneration::collect(bool full,
SerialOldTracer* gc_tracer = GenMarkSweep::gc_tracer();
gc_tracer->report_gc_start(gch->gc_cause(), gc_timer->gc_start());
- GenMarkSweep::invoke_at_safepoint(_level, ref_processor(), clear_all_soft_refs);
+ GenMarkSweep::the_gen_mark()->invoke_at_safepoint(_level, ref_processor(), clear_all_soft_refs);
gc_timer->register_gc_end();
diff --git a/hotspot/src/share/vm/oops/instanceClassLoaderKlass.cpp b/hotspot/src/share/vm/oops/instanceClassLoaderKlass.cpp
index 131ecbfb0..bb35ffd38 100644
--- a/hotspot/src/share/vm/oops/instanceClassLoaderKlass.cpp
+++ b/hotspot/src/share/vm/oops/instanceClassLoaderKlass.cpp
@@ -114,14 +114,14 @@ ALL_OOP_OOP_ITERATE_CLOSURES_2(InstanceClassLoaderKlass_OOP_OOP_ITERATE_BACKWARD
ALL_OOP_OOP_ITERATE_CLOSURES_1(InstanceClassLoaderKlass_OOP_OOP_ITERATE_DEFN_m)
ALL_OOP_OOP_ITERATE_CLOSURES_2(InstanceClassLoaderKlass_OOP_OOP_ITERATE_DEFN_m)
-void InstanceClassLoaderKlass::oop_follow_contents(oop obj) {
- InstanceKlass::oop_follow_contents(obj);
+void InstanceClassLoaderKlass::oop_follow_contents(oop obj, MarkSweep* mark) {
+ InstanceKlass::oop_follow_contents(obj, mark);
ClassLoaderData * const loader_data = java_lang_ClassLoader::loader_data(obj);
// We must NULL check here, since the class loader
// can be found before the loader data has been set up.
if(loader_data != NULL) {
- MarkSweep::follow_class_loader(loader_data);
+ mark->follow_class_loader(loader_data);
}
}
diff --git a/hotspot/src/share/vm/oops/instanceClassLoaderKlass.hpp b/hotspot/src/share/vm/oops/instanceClassLoaderKlass.hpp
index 309ebf96c..47abfed45 100644
--- a/hotspot/src/share/vm/oops/instanceClassLoaderKlass.hpp
+++ b/hotspot/src/share/vm/oops/instanceClassLoaderKlass.hpp
@@ -71,7 +71,7 @@ public:
#endif // INCLUDE_ALL_GCS
// Garbage collection
- void oop_follow_contents(oop obj);
+ void oop_follow_contents(oop obj, MarkSweep* mark);
// Parallel Scavenge and Parallel Old
PARALLEL_GC_DECLS
diff --git a/hotspot/src/share/vm/oops/instanceKlass.cpp b/hotspot/src/share/vm/oops/instanceKlass.cpp
index c1707bf8b..895fbbf07 100644
--- a/hotspot/src/share/vm/oops/instanceKlass.cpp
+++ b/hotspot/src/share/vm/oops/instanceKlass.cpp
@@ -2280,12 +2280,12 @@ template <class T> void assert_nothing(T *p) {}
} \
}
-void InstanceKlass::oop_follow_contents(oop obj) {
+void InstanceKlass::oop_follow_contents(oop obj, MarkSweep* mark) {
assert(obj != NULL, "can't follow the content of NULL object");
- MarkSweep::follow_klass(obj->klass());
+ mark->follow_klass(obj->klass());
InstanceKlass_OOP_MAP_ITERATE( \
obj, \
- MarkSweep::mark_and_push(p), \
+ mark->mark_and_push(p), \
assert_is_in_closed_subset)
}
diff --git a/hotspot/src/share/vm/oops/instanceKlass.hpp b/hotspot/src/share/vm/oops/instanceKlass.hpp
index 3d6f85911..39d2c580c 100644
--- a/hotspot/src/share/vm/oops/instanceKlass.hpp
+++ b/hotspot/src/share/vm/oops/instanceKlass.hpp
@@ -1013,7 +1013,7 @@ class InstanceKlass: public Klass {
#endif // INCLUDE_JVMTI
// Garbage collection
- void oop_follow_contents(oop obj);
+ void oop_follow_contents(oop obj, MarkSweep* mark);
int oop_adjust_pointers(oop obj);
void clean_weak_instanceklass_links(BoolObjectClosure* is_alive);
diff --git a/hotspot/src/share/vm/oops/instanceMirrorKlass.cpp b/hotspot/src/share/vm/oops/instanceMirrorKlass.cpp
index 82c804108..fdf2e42af 100644
--- a/hotspot/src/share/vm/oops/instanceMirrorKlass.cpp
+++ b/hotspot/src/share/vm/oops/instanceMirrorKlass.cpp
@@ -150,8 +150,8 @@ template <class T> void assert_nothing(T *p) {}
}
-void InstanceMirrorKlass::oop_follow_contents(oop obj) {
- InstanceKlass::oop_follow_contents(obj);
+void InstanceMirrorKlass::oop_follow_contents(oop obj, MarkSweep* mark) {
+ InstanceKlass::oop_follow_contents(obj, mark);
// Follow the klass field in the mirror.
Klass* klass = java_lang_Class::as_Klass(obj);
@@ -164,9 +164,9 @@ void InstanceMirrorKlass::oop_follow_contents(oop obj) {
// the call to follow_class_loader is made when the class loader itself
// is handled.
if (klass->oop_is_instance() && InstanceKlass::cast(klass)->is_anonymous()) {
- MarkSweep::follow_class_loader(klass->class_loader_data());
+ mark->follow_class_loader(klass->class_loader_data());
} else {
- MarkSweep::follow_klass(klass);
+ mark->follow_klass(klass);
}
} else {
// If klass is NULL then this a mirror for a primitive type.
@@ -177,7 +177,7 @@ void InstanceMirrorKlass::oop_follow_contents(oop obj) {
InstanceMirrorKlass_OOP_ITERATE( \
start_of_static_fields(obj), java_lang_Class::static_oop_field_count(obj), \
- MarkSweep::mark_and_push(p), \
+ mark->mark_and_push(p), \
assert_is_in_closed_subset)
}
diff --git a/hotspot/src/share/vm/oops/instanceMirrorKlass.hpp b/hotspot/src/share/vm/oops/instanceMirrorKlass.hpp
index b861639ee..759f7d074 100644
--- a/hotspot/src/share/vm/oops/instanceMirrorKlass.hpp
+++ b/hotspot/src/share/vm/oops/instanceMirrorKlass.hpp
@@ -89,7 +89,7 @@ class InstanceMirrorKlass: public InstanceKlass {
// Garbage collection
int oop_adjust_pointers(oop obj);
- void oop_follow_contents(oop obj);
+ void oop_follow_contents(oop obj, MarkSweep* mark);
// Parallel Scavenge and Parallel Old
PARALLEL_GC_DECLS
diff --git a/hotspot/src/share/vm/oops/instanceRefKlass.cpp b/hotspot/src/share/vm/oops/instanceRefKlass.cpp
index a14989314..2c3fe7496 100644
--- a/hotspot/src/share/vm/oops/instanceRefKlass.cpp
+++ b/hotspot/src/share/vm/oops/instanceRefKlass.cpp
@@ -48,7 +48,7 @@
PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC
template <class T>
-void specialized_oop_follow_contents(InstanceRefKlass* ref, oop obj) {
+void specialized_oop_follow_contents(InstanceRefKlass* ref, oop obj, MarkSweep* mark) {
T* referent_addr = (T*)java_lang_ref_Reference::referent_addr(obj);
T heap_oop = oopDesc::load_heap_oop(referent_addr);
debug_only(
@@ -61,7 +61,7 @@ void specialized_oop_follow_contents(InstanceRefKlass* ref, oop obj) {
if (!referent->is_gc_marked() &&
MarkSweep::ref_processor()->discover_reference(obj, ref->reference_type())) {
// reference was discovered, referent will be traversed later
- ref->InstanceKlass::oop_follow_contents(obj);
+ ref->InstanceKlass::oop_follow_contents(obj, mark);
debug_only(
if(TraceReferenceGC && PrintGCDetails) {
gclog_or_tty->print_cr(" Non NULL enqueued " INTPTR_FORMAT, (void *)obj);
@@ -75,7 +75,7 @@ void specialized_oop_follow_contents(InstanceRefKlass* ref, oop obj) {
gclog_or_tty->print_cr(" Non NULL normal " INTPTR_FORMAT, (void *)obj);
}
)
- MarkSweep::mark_and_push(referent_addr);
+ mark->mark_and_push(referent_addr);
}
}
T* next_addr = (T*)java_lang_ref_Reference::next_addr(obj);
@@ -91,7 +91,7 @@ void specialized_oop_follow_contents(InstanceRefKlass* ref, oop obj) {
INTPTR_FORMAT, discovered_addr);
}
)
- MarkSweep::mark_and_push(discovered_addr);
+ mark->mark_and_push(discovered_addr);
}
} else {
#ifdef ASSERT
@@ -111,15 +111,15 @@ void specialized_oop_follow_contents(InstanceRefKlass* ref, oop obj) {
gclog_or_tty->print_cr(" Process next as normal " INTPTR_FORMAT, next_addr);
}
)
- MarkSweep::mark_and_push(next_addr);
- ref->InstanceKlass::oop_follow_contents(obj);
+ mark->mark_and_push(next_addr);
+ ref->InstanceKlass::oop_follow_contents(obj, mark);
}
-void InstanceRefKlass::oop_follow_contents(oop obj) {
+void InstanceRefKlass::oop_follow_contents(oop obj, MarkSweep* mark) {
if (UseCompressedOops) {
- specialized_oop_follow_contents<narrowOop>(this, obj);
+ specialized_oop_follow_contents<narrowOop>(this, obj, mark);
} else {
- specialized_oop_follow_contents<oop>(this, obj);
+ specialized_oop_follow_contents<oop>(this, obj, mark);
}
}
diff --git a/hotspot/src/share/vm/oops/instanceRefKlass.hpp b/hotspot/src/share/vm/oops/instanceRefKlass.hpp
index 3140977b4..4a15c4c75 100644
--- a/hotspot/src/share/vm/oops/instanceRefKlass.hpp
+++ b/hotspot/src/share/vm/oops/instanceRefKlass.hpp
@@ -65,7 +65,7 @@ class InstanceRefKlass: public InstanceKlass {
// Garbage collection
int oop_adjust_pointers(oop obj);
- void oop_follow_contents(oop obj);
+ void oop_follow_contents(oop obj, MarkSweep* mark);
// Parallel Scavenge and Parallel Old
PARALLEL_GC_DECLS
diff --git a/hotspot/src/share/vm/oops/klass.hpp b/hotspot/src/share/vm/oops/klass.hpp
index b7588abd0..f70587eab 100644
--- a/hotspot/src/share/vm/oops/klass.hpp
+++ b/hotspot/src/share/vm/oops/klass.hpp
@@ -93,6 +93,7 @@ class klassVtable;
class ParCompactionManager;
class KlassSizeStats;
class fieldDescriptor;
+class MarkSweep;
class Klass : public Metadata {
friend class VMStructs;
@@ -538,7 +539,7 @@ protected:
virtual const char* signature_name() const;
// garbage collection support
- virtual void oop_follow_contents(oop obj) = 0;
+ virtual void oop_follow_contents(oop obj, MarkSweep* mark) = 0;
virtual int oop_adjust_pointers(oop obj) = 0;
// Parallel Scavenge and Parallel Old
diff --git a/hotspot/src/share/vm/oops/markOop.hpp b/hotspot/src/share/vm/oops/markOop.hpp
index 649217c88..a80c99be4 100644
--- a/hotspot/src/share/vm/oops/markOop.hpp
+++ b/hotspot/src/share/vm/oops/markOop.hpp
@@ -102,8 +102,8 @@ class ObjectMonitor;
class JavaThread;
class markOopDesc: public oopDesc {
- private:
// Conversion
+ public:
uintptr_t value() const { return (uintptr_t) this; }
public:
diff --git a/hotspot/src/share/vm/oops/objArrayKlass.cpp b/hotspot/src/share/vm/oops/objArrayKlass.cpp
index 8049209bf..19abfbd5a 100644
--- a/hotspot/src/share/vm/oops/objArrayKlass.cpp
+++ b/hotspot/src/share/vm/oops/objArrayKlass.cpp
@@ -454,13 +454,13 @@ void ObjArrayKlass::initialize(TRAPS) {
a, p, low, high, do_oop) \
}
-void ObjArrayKlass::oop_follow_contents(oop obj) {
+void ObjArrayKlass::oop_follow_contents(oop obj, MarkSweep* mark) {
assert (obj->is_array(), "obj must be array");
- MarkSweep::follow_klass(obj->klass());
+ mark->follow_klass(obj->klass());
if (UseCompressedOops) {
- objarray_follow_contents<narrowOop>(obj, 0);
+ objarray_follow_contents<narrowOop>(obj, 0, mark);
} else {
- objarray_follow_contents<oop>(obj, 0);
+ objarray_follow_contents<oop>(obj, 0, mark);
}
}
diff --git a/hotspot/src/share/vm/oops/objArrayKlass.hpp b/hotspot/src/share/vm/oops/objArrayKlass.hpp
index cfe31e86e..ab3cbc61c 100644
--- a/hotspot/src/share/vm/oops/objArrayKlass.hpp
+++ b/hotspot/src/share/vm/oops/objArrayKlass.hpp
@@ -104,9 +104,9 @@ class ObjArrayKlass : public ArrayKlass {
void initialize(TRAPS);
// Garbage collection
- void oop_follow_contents(oop obj);
- inline void oop_follow_contents(oop obj, int index);
- template <class T> inline void objarray_follow_contents(oop obj, int index);
+ void oop_follow_contents(oop obj, MarkSweep* mark);
+ inline void oop_follow_contents(oop obj, int index, MarkSweep* mark);
+ template <class T> inline void objarray_follow_contents(oop obj, int index, MarkSweep* mark);
int oop_adjust_pointers(oop obj);
diff --git a/hotspot/src/share/vm/oops/objArrayKlass.inline.hpp b/hotspot/src/share/vm/oops/objArrayKlass.inline.hpp
index e082df55a..96637bad7 100644
--- a/hotspot/src/share/vm/oops/objArrayKlass.inline.hpp
+++ b/hotspot/src/share/vm/oops/objArrayKlass.inline.hpp
@@ -33,16 +33,16 @@
#include "gc_implementation/parallelScavenge/psParallelCompact.hpp"
#endif // INCLUDE_ALL_GCS
-void ObjArrayKlass::oop_follow_contents(oop obj, int index) {
+void ObjArrayKlass::oop_follow_contents(oop obj, int index, MarkSweep* mark) {
if (UseCompressedOops) {
- objarray_follow_contents<narrowOop>(obj, index);
+ objarray_follow_contents<narrowOop>(obj, index, mark);
} else {
- objarray_follow_contents<oop>(obj, index);
+ objarray_follow_contents<oop>(obj, index, mark);
}
}
template <class T>
-void ObjArrayKlass::objarray_follow_contents(oop obj, int index) {
+void ObjArrayKlass::objarray_follow_contents(oop obj, int index, MarkSweep* mark) {
objArrayOop a = objArrayOop(obj);
const size_t len = size_t(a->length());
const size_t beg_index = size_t(index);
@@ -56,11 +56,11 @@ void ObjArrayKlass::objarray_follow_contents(oop obj, int index) {
// Push the non-NULL elements of the next stride on the marking stack.
for (T* e = beg; e < end; e++) {
- MarkSweep::mark_and_push<T>(e);
+ mark->mark_and_push<T>(e);
}
if (end_index < len) {
- MarkSweep::push_objarray(a, end_index); // Push the continuation.
+ mark->push_objarray(a, end_index); // Push the continuation.
}
}
diff --git a/hotspot/src/share/vm/oops/oop.hpp b/hotspot/src/share/vm/oops/oop.hpp
index a5c1d69bf..f452e7473 100644
--- a/hotspot/src/share/vm/oops/oop.hpp
+++ b/hotspot/src/share/vm/oops/oop.hpp
@@ -56,6 +56,8 @@ class CMSIsAliveClosure;
class PSPromotionManager;
class ParCompactionManager;
+class MarkSweep;
+
class oopDesc {
friend class VMStructs;
private:
@@ -298,7 +300,7 @@ class oopDesc {
bool is_gc_marked() const;
// Apply "MarkSweep::mark_and_push" to (the address of) every non-NULL
// reference field in "this".
- void follow_contents(void);
+ void follow_contents(MarkSweep* mark);
#if INCLUDE_ALL_GCS
// Parallel Scavenge
diff --git a/hotspot/src/share/vm/oops/oop.inline.hpp b/hotspot/src/share/vm/oops/oop.inline.hpp
index ed37d0558..6407f830f 100644
--- a/hotspot/src/share/vm/oops/oop.inline.hpp
+++ b/hotspot/src/share/vm/oops/oop.inline.hpp
@@ -655,9 +655,9 @@ inline bool oopDesc::is_unlocked_oop() const {
}
#endif // PRODUCT
-inline void oopDesc::follow_contents(void) {
+inline void oopDesc::follow_contents(MarkSweep* mark) {
assert (is_gc_marked(), "should be marked");
- klass()->oop_follow_contents(this);
+ klass()->oop_follow_contents(this, mark);
}
// Used by scavengers
diff --git a/hotspot/src/share/vm/oops/typeArrayKlass.cpp b/hotspot/src/share/vm/oops/typeArrayKlass.cpp
index d69267d42..f17524e4b 100644
--- a/hotspot/src/share/vm/oops/typeArrayKlass.cpp
+++ b/hotspot/src/share/vm/oops/typeArrayKlass.cpp
@@ -204,7 +204,7 @@ int TypeArrayKlass::oop_size(oop obj) const {
return t->object_size();
}
-void TypeArrayKlass::oop_follow_contents(oop obj) {
+void TypeArrayKlass::oop_follow_contents(oop obj, MarkSweep* mark) {
assert(obj->is_typeArray(),"must be a type array");
// Performance tweak: We skip iterating over the klass pointer since we
// know that Universe::TypeArrayKlass never moves.
diff --git a/hotspot/src/share/vm/oops/typeArrayKlass.hpp b/hotspot/src/share/vm/oops/typeArrayKlass.hpp
index cf363fc76..c5cdd7000 100644
--- a/hotspot/src/share/vm/oops/typeArrayKlass.hpp
+++ b/hotspot/src/share/vm/oops/typeArrayKlass.hpp
@@ -77,7 +77,7 @@ class TypeArrayKlass : public ArrayKlass {
int oop_oop_iterate_m(oop obj, ExtendedOopClosure* blk, MemRegion mr);
// Garbage collection
- void oop_follow_contents(oop obj);
+ void oop_follow_contents(oop obj, MarkSweep* mark);
int oop_adjust_pointers(oop obj);
// Parallel Scavenge and Parallel Old
--
2.22.0
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。