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