< prev index next >
src/hotspot/share/gc/shared/satbMarkQueue.cpp
Print this page
rev 51258 : 8154343: Make SATB related code available to other GCs
*** 22,35 ****
*
*/
#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/collectedHeap.hpp"
#include "memory/allocation.inline.hpp"
#include "oops/oop.inline.hpp"
#include "runtime/mutexLocker.hpp"
#include "runtime/safepoint.hpp"
#include "runtime/thread.hpp"
--- 22,34 ----
*
*/
#include "precompiled.hpp"
#include "jvm.h"
! #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"
#include "runtime/safepoint.hpp"
#include "runtime/thread.hpp"
*** 50,121 ****
// buffer then flush_impl can deallocate the buffer.
filter();
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();
void** buf = _buf;
if (buf == NULL) {
// nothing to do
return;
--- 49,64 ----
// buffer then flush_impl can deallocate the buffer.
filter();
flush_impl();
}
// 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() {
! CollectedHeap* heap = Universe::heap();
void** buf = _buf;
if (buf == NULL) {
// nothing to do
return;
*** 126,139 ****
void** dst = &buf[capacity()];
assert(src <= dst, "invariant");
for ( ; src < dst; ++src) {
// Search low to high for an entry to keep.
void* entry = *src;
! if (retain_entry(entry, g1h)) {
// Found keeper. Search high to low for an entry to discard.
while (src < --dst) {
! if (!retain_entry(*dst, g1h)) {
*dst = entry; // Replace discard with keeper.
break;
}
}
// If discard search failed (src == dst), the outer loop will also end.
--- 69,82 ----
void** dst = &buf[capacity()];
assert(src <= dst, "invariant");
for ( ; src < dst; ++src) {
// Search low to high for an entry to keep.
void* entry = *src;
! if (heap->retain_satb_entry(entry)) {
// Found keeper. Search high to low for an entry to discard.
while (src < --dst) {
! if (!heap->retain_satb_entry(*dst)) {
*dst = entry; // Replace discard with keeper.
break;
}
}
// If discard search failed (src == dst), the outer loop will also end.
*** 206,225 ****
PtrQueueSet::initialize(cbl_mon, fl_lock, process_completed_threshold, -1);
_shared_satb_queue.set_lock(lock);
}
void SATBMarkQueueSet::handle_zero_index_for_thread(JavaThread* t) {
! G1ThreadLocalData::satb_mark_queue(t).handle_zero_index();
}
#ifdef ASSERT
void SATBMarkQueueSet::dump_active_states(bool expected_active) {
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");
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)(" Shared queue: %s", shared_satb_queue()->is_active() ? "ACTIVE" : "INACTIVE");
}
void SATBMarkQueueSet::verify_active_states(bool expected_active) {
--- 149,169 ----
PtrQueueSet::initialize(cbl_mon, fl_lock, process_completed_threshold, -1);
_shared_satb_queue.set_lock(lock);
}
void SATBMarkQueueSet::handle_zero_index_for_thread(JavaThread* t) {
! Universe::heap()->satb_mark_queue(t)->handle_zero_index();
}
#ifdef ASSERT
void SATBMarkQueueSet::dump_active_states(bool expected_active) {
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(), heap->satb_mark_queue(t)->is_active() ? "ACTIVE" : "INACTIVE");
}
log_error(gc, verify)(" Shared queue: %s", shared_satb_queue()->is_active() ? "ACTIVE" : "INACTIVE");
}
void SATBMarkQueueSet::verify_active_states(bool expected_active) {
*** 228,239 ****
dump_active_states(expected_active);
guarantee(false, "SATB queue set has an unexpected active state");
}
// Verify thread queue states
for (JavaThreadIteratorWithHandle jtiwh; JavaThread *t = jtiwh.next(); ) {
! if (G1ThreadLocalData::satb_mark_queue(t).is_active() != expected_active) {
dump_active_states(expected_active);
guarantee(false, "Thread SATB queue has an unexpected active state");
}
}
--- 172,184 ----
dump_active_states(expected_active);
guarantee(false, "SATB queue set has an unexpected active state");
}
// Verify thread queue states
+ CollectedHeap* heap = Universe::heap();
for (JavaThreadIteratorWithHandle jtiwh; JavaThread *t = jtiwh.next(); ) {
! 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");
}
}
*** 249,267 ****
assert(SafepointSynchronize::is_at_safepoint(), "Must be at safepoint.");
#ifdef ASSERT
verify_active_states(expected_active);
#endif // ASSERT
_all_active = active;
for (JavaThreadIteratorWithHandle jtiwh; JavaThread *t = jtiwh.next(); ) {
! G1ThreadLocalData::satb_mark_queue(t).set_active(active);
}
shared_satb_queue()->set_active(active);
}
void SATBMarkQueueSet::filter_thread_buffers() {
for (JavaThreadIteratorWithHandle jtiwh; JavaThread *t = jtiwh.next(); ) {
! G1ThreadLocalData::satb_mark_queue(t).filter();
}
shared_satb_queue()->filter();
}
bool SATBMarkQueueSet::apply_closure_to_completed_buffer(SATBBufferClosure* cl) {
--- 194,214 ----
assert(SafepointSynchronize::is_at_safepoint(), "Must be at safepoint.");
#ifdef ASSERT
verify_active_states(expected_active);
#endif // ASSERT
_all_active = active;
+ CollectedHeap* heap = Universe::heap();
for (JavaThreadIteratorWithHandle jtiwh; JavaThread *t = jtiwh.next(); ) {
! 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(); ) {
! heap->satb_mark_queue(t)->filter();
}
shared_satb_queue()->filter();
}
bool SATBMarkQueueSet::apply_closure_to_completed_buffer(SATBBufferClosure* cl) {
*** 309,321 ****
print_satb_buffer(buffer, buf, nd->index(), buffer_size());
nd = nd->next();
i += 1;
}
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);
}
shared_satb_queue()->print("Shared");
tty->cr();
--- 256,269 ----
print_satb_buffer(buffer, buf, nd->index(), buffer_size());
nd = nd->next();
i += 1;
}
+ CollectedHeap* heap = Universe::heap();
for (JavaThreadIteratorWithHandle jtiwh; JavaThread *t = jtiwh.next(); ) {
jio_snprintf(buffer, SATB_PRINTER_BUFFER_SIZE, "Thread: %s", t->name());
! heap->satb_mark_queue(t)->print(buffer);
}
shared_satb_queue()->print("Shared");
tty->cr();
*** 341,350 ****
buffers_to_delete = nd->next();
deallocate_buffer(nd);
}
assert(SafepointSynchronize::is_at_safepoint(), "Must be at safepoint.");
// So we can safely manipulate these queues.
for (JavaThreadIteratorWithHandle jtiwh; JavaThread *t = jtiwh.next(); ) {
! G1ThreadLocalData::satb_mark_queue(t).reset();
}
shared_satb_queue()->reset();
}
--- 289,299 ----
buffers_to_delete = nd->next();
deallocate_buffer(nd);
}
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(); ) {
! heap->satb_mark_queue(t)->reset();
}
shared_satb_queue()->reset();
}
< prev index next >