# HG changeset patch # User rkennke # Date 1532689385 -7200 # Fri Jul 27 13:03:05 2018 +0200 # Node ID 32c263aa1efad1cfd48b0a79e992d76af49259af # Parent 979e349059eb9f7d0c0cffceb30bc4b3433302cf 8154343: Make SATB related code available to other GCs diff --git a/src/hotspot/share/gc/g1/dirtyCardQueue.hpp b/src/hotspot/share/gc/g1/dirtyCardQueue.hpp --- a/src/hotspot/share/gc/g1/dirtyCardQueue.hpp +++ b/src/hotspot/share/gc/g1/dirtyCardQueue.hpp @@ -25,7 +25,7 @@ #ifndef SHARE_VM_GC_G1_DIRTYCARDQUEUE_HPP #define SHARE_VM_GC_G1_DIRTYCARDQUEUE_HPP -#include "gc/g1/ptrQueue.hpp" +#include "gc/shared/ptrQueue.hpp" #include "memory/allocation.hpp" class FreeIdSet; diff --git a/src/hotspot/share/gc/g1/g1BarrierSet.cpp b/src/hotspot/share/gc/g1/g1BarrierSet.cpp --- a/src/hotspot/share/gc/g1/g1BarrierSet.cpp +++ b/src/hotspot/share/gc/g1/g1BarrierSet.cpp @@ -29,7 +29,7 @@ #include "gc/g1/g1CollectedHeap.inline.hpp" #include "gc/g1/g1ThreadLocalData.hpp" #include "gc/g1/heapRegion.hpp" -#include "gc/g1/satbMarkQueue.hpp" +#include "gc/shared/satbMarkQueue.hpp" #include "logging/log.hpp" #include "oops/access.inline.hpp" #include "oops/compressedOops.inline.hpp" diff --git a/src/hotspot/share/gc/g1/g1BarrierSet.hpp b/src/hotspot/share/gc/g1/g1BarrierSet.hpp --- a/src/hotspot/share/gc/g1/g1BarrierSet.hpp +++ b/src/hotspot/share/gc/g1/g1BarrierSet.hpp @@ -26,7 +26,7 @@ #define SHARE_VM_GC_G1_G1BARRIERSET_HPP #include "gc/g1/dirtyCardQueue.hpp" -#include "gc/g1/satbMarkQueue.hpp" +#include "gc/shared/satbMarkQueue.hpp" #include "gc/shared/cardTableBarrierSet.hpp" class DirtyCardQueueSet; diff --git a/src/hotspot/share/gc/g1/g1CollectedHeap.cpp b/src/hotspot/share/gc/g1/g1CollectedHeap.cpp --- a/src/hotspot/share/gc/g1/g1CollectedHeap.cpp +++ b/src/hotspot/share/gc/g1/g1CollectedHeap.cpp @@ -4980,3 +4980,57 @@ memory_pools.append(_old_pool); return memory_pools; } + +// Return true if a SATB buffer entry refers to an object that +// requires marking. +// +// The entry must point into the heap. In particular, it must not +// be a NULL pointer. NULL pointers are pre-filtered and never +// inserted into a SATB buffer. +// +// An entry that is below the NTAMS pointer for the containing heap +// region requires marking. Such an entry must point to a valid object. +// +// An entry that is at least the NTAMS pointer for the containing heap +// region might be any of the following, none of which should be marked. +// +// * A reference to an object allocated since marking started. +// According to SATB, such objects are implicitly kept live and do +// not need to be dealt with via SATB buffer processing. +// +// * A reference to a young generation object. Young objects are +// handled separately and are not marked by concurrent marking. +// +// * A stale reference to a young generation object. If a young +// generation object reference is recorded and not filtered out +// before being moved by a young collection, the reference becomes +// stale. +// +// * A stale reference to an eagerly reclaimed humongous object. If a +// humongous object is recorded and then reclaimed, the reference +// becomes stale. +// +// The stale reference cases are implicitly handled by the NTAMS +// comparison. Because of the possibility of stale references, buffer +// processing must be somewhat circumspect and not assume entries +// in an unfiltered buffer refer to valid objects. +bool G1CollectedHeap::retain_satb_entry(const void* entry) const { + // Includes rejection of NULL pointers. + assert(is_in_reserved(entry), + "Non-heap pointer in SATB buffer: " PTR_FORMAT, p2i(entry)); + + HeapRegion* region = heap_region_containing(entry); + assert(region != NULL, "No region for " PTR_FORMAT, p2i(entry)); + if (entry >= region->next_top_at_mark_start()) { + return false; + } + + assert(oopDesc::is_oop(oop(entry), true /* ignore mark word */), + "Invalid oop in SATB buffer: " PTR_FORMAT, p2i(entry)); + + return !is_marked_next((oop)entry); +} + +SATBMarkQueue* G1CollectedHeap::satb_mark_queue(JavaThread* t) const { + return &G1ThreadLocalData::satb_mark_queue(t); +} diff --git a/src/hotspot/share/gc/g1/g1CollectedHeap.hpp b/src/hotspot/share/gc/g1/g1CollectedHeap.hpp --- a/src/hotspot/share/gc/g1/g1CollectedHeap.hpp +++ b/src/hotspot/share/gc/g1/g1CollectedHeap.hpp @@ -1300,6 +1300,9 @@ inline bool is_obj_dead_full(const oop obj, const HeapRegion* hr) const; inline bool is_obj_dead_full(const oop obj) const; + virtual bool retain_satb_entry(const void* entry) const; + virtual SATBMarkQueue* satb_mark_queue(JavaThread* t) const; + G1ConcurrentMark* concurrent_mark() const { return _cm; } // Refinement diff --git a/src/hotspot/share/gc/g1/g1ThreadLocalData.hpp b/src/hotspot/share/gc/g1/g1ThreadLocalData.hpp --- a/src/hotspot/share/gc/g1/g1ThreadLocalData.hpp +++ b/src/hotspot/share/gc/g1/g1ThreadLocalData.hpp @@ -26,7 +26,7 @@ #include "gc/g1/dirtyCardQueue.hpp" #include "gc/g1/g1BarrierSet.hpp" -#include "gc/g1/satbMarkQueue.hpp" +#include "gc/shared/satbMarkQueue.hpp" #include "runtime/thread.hpp" #include "utilities/debug.hpp" #include "utilities/sizes.hpp" diff --git a/src/hotspot/share/gc/shared/collectedHeap.hpp b/src/hotspot/share/gc/shared/collectedHeap.hpp --- a/src/hotspot/share/gc/shared/collectedHeap.hpp +++ b/src/hotspot/share/gc/shared/collectedHeap.hpp @@ -50,6 +50,7 @@ class GCMemoryManager; class MemoryPool; class MetaspaceSummary; +class SATBMarkQueue; class SoftRefPolicy; class Thread; class ThreadClosure; @@ -577,6 +578,16 @@ virtual bool is_oop(oop object) const; + virtual bool retain_satb_entry(const void* entry) const { + Unimplemented(); + return true; + } + + virtual SATBMarkQueue* satb_mark_queue(JavaThread* t) const { + Unimplemented(); + return NULL; + } + // Non product verification and debugging. #ifndef PRODUCT // Support for PromotionFailureALot. Return true if it's time to cause a diff --git a/src/hotspot/share/gc/g1/ptrQueue.cpp b/src/hotspot/share/gc/shared/ptrQueue.cpp rename from src/hotspot/share/gc/g1/ptrQueue.cpp rename to src/hotspot/share/gc/shared/ptrQueue.cpp --- a/src/hotspot/share/gc/g1/ptrQueue.cpp +++ b/src/hotspot/share/gc/shared/ptrQueue.cpp @@ -23,7 +23,7 @@ */ #include "precompiled.hpp" -#include "gc/g1/ptrQueue.hpp" +#include "gc/shared/ptrQueue.hpp" #include "memory/allocation.hpp" #include "memory/allocation.inline.hpp" #include "runtime/mutex.hpp" diff --git a/src/hotspot/share/gc/g1/ptrQueue.hpp b/src/hotspot/share/gc/shared/ptrQueue.hpp rename from src/hotspot/share/gc/g1/ptrQueue.hpp rename to src/hotspot/share/gc/shared/ptrQueue.hpp diff --git a/src/hotspot/share/gc/g1/satbMarkQueue.cpp b/src/hotspot/share/gc/shared/satbMarkQueue.cpp rename from src/hotspot/share/gc/g1/satbMarkQueue.cpp rename to src/hotspot/share/gc/shared/satbMarkQueue.cpp --- a/src/hotspot/share/gc/g1/satbMarkQueue.cpp +++ b/src/hotspot/share/gc/shared/satbMarkQueue.cpp @@ -24,10 +24,9 @@ #include "precompiled.hpp" #include "jvm.h" -#include "gc/g1/g1CollectedHeap.inline.hpp" -#include "gc/g1/g1ThreadLocalData.hpp" -#include "gc/g1/satbMarkQueue.hpp" +#include "gc/shared/satbMarkQueue.hpp" #include "gc/shared/collectedHeap.hpp" +#include "logging/log.hpp" #include "memory/allocation.inline.hpp" #include "oops/oop.inline.hpp" #include "runtime/mutexLocker.hpp" @@ -52,68 +51,12 @@ flush_impl(); } -// Return true if a SATB buffer entry refers to an object that -// requires marking. -// -// The entry must point into the G1 heap. In particular, it must not -// be a NULL pointer. NULL pointers are pre-filtered and never -// inserted into a SATB buffer. -// -// An entry that is below the NTAMS pointer for the containing heap -// region requires marking. Such an entry must point to a valid object. -// -// An entry that is at least the NTAMS pointer for the containing heap -// region might be any of the following, none of which should be marked. -// -// * A reference to an object allocated since marking started. -// According to SATB, such objects are implicitly kept live and do -// not need to be dealt with via SATB buffer processing. -// -// * A reference to a young generation object. Young objects are -// handled separately and are not marked by concurrent marking. -// -// * A stale reference to a young generation object. If a young -// generation object reference is recorded and not filtered out -// before being moved by a young collection, the reference becomes -// stale. -// -// * A stale reference to an eagerly reclaimed humongous object. If a -// humongous object is recorded and then reclaimed, the reference -// becomes stale. -// -// The stale reference cases are implicitly handled by the NTAMS -// comparison. Because of the possibility of stale references, buffer -// processing must be somewhat circumspect and not assume entries -// in an unfiltered buffer refer to valid objects. - -inline bool requires_marking(const void* entry, G1CollectedHeap* heap) { - // Includes rejection of NULL pointers. - assert(heap->is_in_reserved(entry), - "Non-heap pointer in SATB buffer: " PTR_FORMAT, p2i(entry)); - - HeapRegion* region = heap->heap_region_containing(entry); - assert(region != NULL, "No region for " PTR_FORMAT, p2i(entry)); - if (entry >= region->next_top_at_mark_start()) { - return false; - } - - assert(oopDesc::is_oop(oop(entry), true /* ignore mark word */), - "Invalid oop in SATB buffer: " PTR_FORMAT, p2i(entry)); - - return true; -} - -inline bool retain_entry(const void* entry, G1CollectedHeap* heap) { - return requires_marking(entry, heap) && !heap->is_marked_next((oop)entry); -} - // This method removes entries from a SATB buffer that will not be // useful to the concurrent marking threads. Entries are retained if // they require marking and are not already marked. Retained entries // are compacted toward the top of the buffer. - void SATBMarkQueue::filter() { - G1CollectedHeap* g1h = G1CollectedHeap::heap(); + CollectedHeap* heap = Universe::heap(); void** buf = _buf; if (buf == NULL) { @@ -128,10 +71,10 @@ for ( ; src < dst; ++src) { // Search low to high for an entry to keep. void* entry = *src; - if (retain_entry(entry, g1h)) { + if (heap->retain_satb_entry(entry)) { // Found keeper. Search high to low for an entry to discard. while (src < --dst) { - if (!retain_entry(*dst, g1h)) { + if (!heap->retain_satb_entry(*dst)) { *dst = entry; // Replace discard with keeper. break; } @@ -208,7 +151,7 @@ } void SATBMarkQueueSet::handle_zero_index_for_thread(JavaThread* t) { - G1ThreadLocalData::satb_mark_queue(t).handle_zero_index(); + Universe::heap()->satb_mark_queue(t)->handle_zero_index(); } #ifdef ASSERT @@ -216,8 +159,9 @@ log_error(gc, verify)("Expected SATB active state: %s", expected_active ? "ACTIVE" : "INACTIVE"); log_error(gc, verify)("Actual SATB active states:"); log_error(gc, verify)(" Queue set: %s", is_active() ? "ACTIVE" : "INACTIVE"); + CollectedHeap* heap = Universe::heap(); for (JavaThreadIteratorWithHandle jtiwh; JavaThread *t = jtiwh.next(); ) { - log_error(gc, verify)(" Thread \"%s\" queue: %s", t->name(), G1ThreadLocalData::satb_mark_queue(t).is_active() ? "ACTIVE" : "INACTIVE"); + log_error(gc, verify)(" Thread \"%s\" queue: %s", t->name(), heap->satb_mark_queue(t)->is_active() ? "ACTIVE" : "INACTIVE"); } log_error(gc, verify)(" Shared queue: %s", shared_satb_queue()->is_active() ? "ACTIVE" : "INACTIVE"); } @@ -230,8 +174,9 @@ } // Verify thread queue states + CollectedHeap* heap = Universe::heap(); for (JavaThreadIteratorWithHandle jtiwh; JavaThread *t = jtiwh.next(); ) { - if (G1ThreadLocalData::satb_mark_queue(t).is_active() != expected_active) { + if (heap->satb_mark_queue(t)->is_active() != expected_active) { dump_active_states(expected_active); guarantee(false, "Thread SATB queue has an unexpected active state"); } @@ -251,15 +196,17 @@ verify_active_states(expected_active); #endif // ASSERT _all_active = active; + CollectedHeap* heap = Universe::heap(); for (JavaThreadIteratorWithHandle jtiwh; JavaThread *t = jtiwh.next(); ) { - G1ThreadLocalData::satb_mark_queue(t).set_active(active); + heap->satb_mark_queue(t)->set_active(active); } shared_satb_queue()->set_active(active); } void SATBMarkQueueSet::filter_thread_buffers() { + CollectedHeap* heap = Universe::heap(); for (JavaThreadIteratorWithHandle jtiwh; JavaThread *t = jtiwh.next(); ) { - G1ThreadLocalData::satb_mark_queue(t).filter(); + heap->satb_mark_queue(t)->filter(); } shared_satb_queue()->filter(); } @@ -311,9 +258,10 @@ i += 1; } + CollectedHeap* heap = Universe::heap(); for (JavaThreadIteratorWithHandle jtiwh; JavaThread *t = jtiwh.next(); ) { jio_snprintf(buffer, SATB_PRINTER_BUFFER_SIZE, "Thread: %s", t->name()); - G1ThreadLocalData::satb_mark_queue(t).print(buffer); + heap->satb_mark_queue(t)->print(buffer); } shared_satb_queue()->print("Shared"); @@ -343,8 +291,9 @@ } assert(SafepointSynchronize::is_at_safepoint(), "Must be at safepoint."); // So we can safely manipulate these queues. + CollectedHeap* heap = Universe::heap(); for (JavaThreadIteratorWithHandle jtiwh; JavaThread *t = jtiwh.next(); ) { - G1ThreadLocalData::satb_mark_queue(t).reset(); + heap->satb_mark_queue(t)->reset(); } shared_satb_queue()->reset(); } diff --git a/src/hotspot/share/gc/g1/satbMarkQueue.hpp b/src/hotspot/share/gc/shared/satbMarkQueue.hpp rename from src/hotspot/share/gc/g1/satbMarkQueue.hpp rename to src/hotspot/share/gc/shared/satbMarkQueue.hpp --- a/src/hotspot/share/gc/g1/satbMarkQueue.hpp +++ b/src/hotspot/share/gc/shared/satbMarkQueue.hpp @@ -25,7 +25,7 @@ #ifndef SHARE_VM_GC_G1_SATBMARKQUEUE_HPP #define SHARE_VM_GC_G1_SATBMARKQUEUE_HPP -#include "gc/g1/ptrQueue.hpp" +#include "gc/shared/ptrQueue.hpp" #include "memory/allocation.hpp" class JavaThread;