Projects
Mega:24.03:SP1:Everything
openjdk-1.8.0
_service:tar_scm:G1-Full-GC-parallel-mark.patch
Sign Up
Log In
Username
Password
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File _service:tar_scm:G1-Full-GC-parallel-mark.patch of Package openjdk-1.8.0
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
Locations
Projects
Search
Status Monitor
Help
Open Build Service
OBS Manuals
API Documentation
OBS Portal
Reporting a Bug
Contact
Mailing List
Forums
Chat (IRC)
Twitter
Open Build Service (OBS)
is an
openSUSE project
.
浙ICP备2022010568号-2