< prev index next >

src/hotspot/share/gc/shared/referenceProcessor.cpp

Print this page
rev 50093 : [mq]: pp2_work

*** 301,313 **** void DiscoveredListIterator::clear_referent() { RawAccess<>::oop_store(_referent_addr, oop(NULL)); } void DiscoveredListIterator::enqueue() { - // Self-loop next, so as to make Ref not active. - java_lang_ref_Reference::set_next_raw(_current_discovered, _current_discovered); - HeapAccess<AS_NO_KEEPALIVE>::oop_store_at(_current_discovered, java_lang_ref_Reference::discovered_offset, _next_discovered); } --- 301,310 ----
*** 362,403 **** complete_gc->do_void(); log_develop_trace(gc, ref)(" Dropped " SIZE_FORMAT " dead Refs out of " SIZE_FORMAT " discovered Refs by policy, from list " INTPTR_FORMAT, iter.removed(), iter.processed(), p2i(&refs_list)); } void ReferenceProcessor::process_phase2(DiscoveredList& refs_list, BoolObjectClosure* is_alive, OopClosure* keep_alive, VoidClosure* complete_gc) { ! if (discovery_is_atomic()) { ! // complete_gc is ignored in this case for this phase ! pp2_work(refs_list, is_alive, keep_alive); ! } else { ! assert(complete_gc != NULL, "Error"); ! pp2_work_concurrent_discovery(refs_list, is_alive, ! keep_alive, complete_gc); ! } ! } ! // Traverse the list and remove any Refs that are not active, or ! // whose referents are either alive or NULL. ! void ! ReferenceProcessor::pp2_work(DiscoveredList& refs_list, ! BoolObjectClosure* is_alive, ! OopClosure* keep_alive) { ! assert(discovery_is_atomic(), "Error"); DiscoveredListIterator iter(refs_list, keep_alive, is_alive); while (iter.has_next()) { ! iter.load_ptrs(DEBUG_ONLY(false /* allow_null_referent */)); ! DEBUG_ONLY(oop next = java_lang_ref_Reference::next(iter.obj());) ! assert(next == NULL, "Should not discover inactive Reference"); ! if (iter.is_referent_alive()) { ! log_develop_trace(gc, ref)("Dropping strongly reachable reference (" INTPTR_FORMAT ": %s)", ! p2i(iter.obj()), iter.obj()->klass()->internal_name()); // The referent is reachable after all. ! // Remove Reference object from list. iter.remove(); ! // Update the referent pointer as necessary: Note that this // should not entail any recursive marking because the // referent must already have been traversed. iter.make_referent_alive(); iter.move_to_next(); } else { --- 359,396 ---- complete_gc->do_void(); log_develop_trace(gc, ref)(" Dropped " SIZE_FORMAT " dead Refs out of " SIZE_FORMAT " discovered Refs by policy, from list " INTPTR_FORMAT, iter.removed(), iter.processed(), p2i(&refs_list)); } + inline void log_dropped_ref(const DiscoveredListIterator& iter, const char* reason) { + log_develop_trace(gc, ref)("Dropping %s reference " PTR_FORMAT ": %s", + reason, p2i(iter.obj()), + iter.obj()->klass()->internal_name()); + } + + // Traverse the list and remove any Refs whose referents are alive, + // or NULL if discovery is not atomic. void ReferenceProcessor::process_phase2(DiscoveredList& refs_list, BoolObjectClosure* is_alive, OopClosure* keep_alive, VoidClosure* complete_gc) { ! // complete_gc is unused. DiscoveredListIterator iter(refs_list, keep_alive, is_alive); while (iter.has_next()) { ! iter.load_ptrs(DEBUG_ONLY(!discovery_is_atomic() /* allow_null_referent */)); ! if (iter.referent() == NULL) { ! // Reference has been cleared since discovery; only possible if ! // discovery is not atomic. Remove reference from list. ! log_dropped_ref(iter, "cleared"); ! iter.remove(); ! iter.move_to_next(); ! } else if (iter.is_referent_alive()) { // The referent is reachable after all. ! // Remove reference from list. ! log_dropped_ref(iter, "reachable"); iter.remove(); ! // Update the referent pointer as necessary. Note that this // should not entail any recursive marking because the // referent must already have been traversed. iter.make_referent_alive(); iter.move_to_next(); } else {
*** 411,459 **** iter.removed(), iter.processed(), p2i(&refs_list)); } ) } - void - ReferenceProcessor::pp2_work_concurrent_discovery(DiscoveredList& refs_list, - BoolObjectClosure* is_alive, - OopClosure* keep_alive, - VoidClosure* complete_gc) { - assert(!discovery_is_atomic(), "Error"); - DiscoveredListIterator iter(refs_list, keep_alive, is_alive); - while (iter.has_next()) { - iter.load_ptrs(DEBUG_ONLY(true /* allow_null_referent */)); - HeapWord* next_addr = java_lang_ref_Reference::next_addr_raw(iter.obj()); - oop next = java_lang_ref_Reference::next(iter.obj()); - if ((iter.referent() == NULL || iter.is_referent_alive() || - next != NULL)) { - assert(oopDesc::is_oop_or_null(next), "Expected an oop or NULL for next field at " PTR_FORMAT, p2i(next)); - // Remove Reference object from list - iter.remove(); - // Trace the cohorts - iter.make_referent_alive(); - if (UseCompressedOops) { - keep_alive->do_oop((narrowOop*)next_addr); - } else { - keep_alive->do_oop((oop*)next_addr); - } - iter.move_to_next(); - } else { - iter.next(); - } - } - // Now close the newly reachable set - complete_gc->do_void(); - NOT_PRODUCT( - if (iter.processed() > 0) { - log_develop_trace(gc, ref)(" Dropped " SIZE_FORMAT " active Refs out of " SIZE_FORMAT - " Refs in discovered list " INTPTR_FORMAT, - iter.removed(), iter.processed(), p2i(&refs_list)); - } - ) - } - void ReferenceProcessor::process_phase3(DiscoveredList& refs_list, bool clear_referent, BoolObjectClosure* is_alive, OopClosure* keep_alive, VoidClosure* complete_gc) { --- 404,413 ----
*** 463,474 **** iter.load_ptrs(DEBUG_ONLY(false /* allow_null_referent */)); if (clear_referent) { // NULL out referent pointer iter.clear_referent(); } else { ! // keep the referent around iter.make_referent_alive(); } iter.enqueue(); log_develop_trace(gc, ref)("Adding %sreference (" INTPTR_FORMAT ": %s) as pending", clear_referent ? "cleared " : "", p2i(iter.obj()), iter.obj()->klass()->internal_name()); assert(oopDesc::is_oop(iter.obj(), UseConcMarkSweepGC), "Adding a bad reference"); --- 417,432 ---- iter.load_ptrs(DEBUG_ONLY(false /* allow_null_referent */)); if (clear_referent) { // NULL out referent pointer iter.clear_referent(); } else { ! // Current reference is a FinalReference; that's the only kind we ! // don't clear the referent, instead keeping it for calling finalize. iter.make_referent_alive(); + // Self-loop next, to mark it not active. + assert(java_lang_ref_Reference::next(iter.obj()) == NULL, "enqueued FinalReference"); + java_lang_ref_Reference::set_next_raw(iter.obj(), iter.obj()); } iter.enqueue(); log_develop_trace(gc, ref)("Adding %sreference (" INTPTR_FORMAT ": %s) as pending", clear_referent ? "cleared " : "", p2i(iter.obj()), iter.obj()->klass()->internal_name()); assert(oopDesc::is_oop(iter.obj(), UseConcMarkSweepGC), "Adding a bad reference");
*** 896,908 **** bool ReferenceProcessor::discover_reference(oop obj, ReferenceType rt) { // Make sure we are discovering refs (rather than processing discovered refs). if (!_discovering_refs || !RegisterReferences) { return false; } ! // We only discover active references. ! oop next = java_lang_ref_Reference::next(obj); ! if (next != NULL) { // Ref is no longer active return false; } if (RefDiscoveryPolicy == ReferenceBasedDiscovery && !is_subject_to_discovery(obj)) { --- 854,866 ---- bool ReferenceProcessor::discover_reference(oop obj, ReferenceType rt) { // Make sure we are discovering refs (rather than processing discovered refs). if (!_discovering_refs || !RegisterReferences) { return false; } ! ! if ((rt == REF_FINAL) && (java_lang_ref_Reference::next(obj) != NULL)) { ! // Don't rediscover non-active FinalReferences. return false; } if (RefDiscoveryPolicy == ReferenceBasedDiscovery && !is_subject_to_discovery(obj)) {
*** 1087,1114 **** YieldClosure* yield) { DiscoveredListIterator iter(refs_list, keep_alive, is_alive); while (iter.has_next()) { iter.load_ptrs(DEBUG_ONLY(true /* allow_null_referent */)); oop obj = iter.obj(); ! oop next = java_lang_ref_Reference::next(obj); ! if (iter.referent() == NULL || iter.is_referent_alive() || ! next != NULL) { ! // The referent has been cleared, or is alive, or the Reference is not ! // active; we need to trace and mark its cohort. log_develop_trace(gc, ref)("Precleaning Reference (" INTPTR_FORMAT ": %s)", p2i(iter.obj()), iter.obj()->klass()->internal_name()); // Remove Reference object from list iter.remove(); // Keep alive its cohort. iter.make_referent_alive(); - if (UseCompressedOops) { - narrowOop* next_addr = (narrowOop*)java_lang_ref_Reference::next_addr_raw(obj); - keep_alive->do_oop(next_addr); - } else { - oop* next_addr = (oop*)java_lang_ref_Reference::next_addr_raw(obj); - keep_alive->do_oop(next_addr); - } iter.move_to_next(); } else { iter.next(); } } --- 1045,1063 ---- YieldClosure* yield) { DiscoveredListIterator iter(refs_list, keep_alive, is_alive); while (iter.has_next()) { iter.load_ptrs(DEBUG_ONLY(true /* allow_null_referent */)); oop obj = iter.obj(); ! if (iter.referent() == NULL || iter.is_referent_alive()) { ! // The referent has been cleared, or is alive; we need to trace ! // and mark its cohort. log_develop_trace(gc, ref)("Precleaning Reference (" INTPTR_FORMAT ": %s)", p2i(iter.obj()), iter.obj()->klass()->internal_name()); // Remove Reference object from list iter.remove(); // Keep alive its cohort. iter.make_referent_alive(); iter.move_to_next(); } else { iter.next(); } }
< prev index next >