diff --git a/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp b/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp index cd2ccd10945042971b31891375e2f98491c16155..e2e27c0f353ffb285f7eaee464b15980f3f2ecf4 100644 --- a/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp +++ b/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp @@ -1961,6 +1961,7 @@ void CMSCollector::do_compaction_work(bool clear_all_soft_refs) { ref_processor()->set_enqueuing_is_done(false); ref_processor()->enable_discovery(); + ref_processor()->snap_policy(clear_all_soft_refs); // If an asynchronous collection finishes, the _modUnionTable is // all clear. If we are assuming the collection from an asynchronous // collection, clear the _modUnionTable. @@ -2384,6 +2385,9 @@ void CMSCollector::collect_in_foreground(bool clear_all_soft_refs) { Universe::verify(true); } + // Snapshot the soft reference policy to be used in this collection cycle. + ref_processor()->snap_policy(clear_all_soft_refs); + bool init_mark_was_synchronous = false; // until proven otherwise while (_collectorState != Idling) { if (TraceCMSState) { @@ -4591,11 +4595,11 @@ size_t CMSCollector::preclean_mod_union_table( if (!dirtyRegion.is_empty()) { assert(numDirtyCards > 0, "consistency check"); HeapWord* stop_point = NULL; + stopTimer(); + CMSTokenSyncWithLocks ts(true, gen->freelistLock(), + bitMapLock()); + startTimer(); { - stopTimer(); - CMSTokenSyncWithLocks ts(true, gen->freelistLock(), - bitMapLock()); - startTimer(); verify_work_stacks_empty(); verify_overflow_empty(); sample_eden(); @@ -4612,10 +4616,6 @@ size_t CMSCollector::preclean_mod_union_table( assert((CMSPermGenPrecleaningEnabled && (gen == _permGen)) || (_collectorState == AbortablePreclean && should_abort_preclean()), "Unparsable objects should only be in perm gen."); - - stopTimer(); - CMSTokenSyncWithLocks ts(true, bitMapLock()); - startTimer(); _modUnionTable.mark_range(MemRegion(stop_point, dirtyRegion.end())); if (should_abort_preclean()) { break; // out of preclean loop @@ -5678,23 +5678,14 @@ void CMSCollector::refProcessingWork(bool asynch, bool clear_all_soft_refs) { ResourceMark rm; HandleMark hm; - ReferencePolicy* soft_ref_policy; - assert(!ref_processor()->enqueuing_is_done(), "Enqueuing should not be complete"); + ReferenceProcessor* rp = ref_processor(); + assert(rp->span().equals(_span), "Spans should be equal"); + assert(!rp->enqueuing_is_done(), "Enqueuing should not be complete"); // Process weak references. - if (clear_all_soft_refs) { - soft_ref_policy = new AlwaysClearPolicy(); - } else { -#ifdef COMPILER2 - soft_ref_policy = new LRUMaxHeapPolicy(); -#else - soft_ref_policy = new LRUCurrentHeapPolicy(); -#endif // COMPILER2 - } + rp->snap_policy(clear_all_soft_refs); verify_work_stacks_empty(); - ReferenceProcessor* rp = ref_processor(); - assert(rp->span().equals(_span), "Spans should be equal"); CMSKeepAliveClosure cmsKeepAliveClosure(this, _span, &_markBitMap, &_markStack, false /* !preclean */); CMSDrainMarkingStackClosure cmsDrainMarkingStackClosure(this, @@ -5704,14 +5695,12 @@ void CMSCollector::refProcessingWork(bool asynch, bool clear_all_soft_refs) { TraceTime t("weak refs processing", PrintGCDetails, false, gclog_or_tty); if (rp->processing_is_mt()) { CMSRefProcTaskExecutor task_executor(*this); - rp->process_discovered_references(soft_ref_policy, - &_is_alive_closure, + rp->process_discovered_references(&_is_alive_closure, &cmsKeepAliveClosure, &cmsDrainMarkingStackClosure, &task_executor); } else { - rp->process_discovered_references(soft_ref_policy, - &_is_alive_closure, + rp->process_discovered_references(&_is_alive_closure, &cmsKeepAliveClosure, &cmsDrainMarkingStackClosure, NULL); @@ -6166,8 +6155,8 @@ void CMSCollector::verify_ok_to_terminate() const { #endif size_t CMSCollector::block_size_using_printezis_bits(HeapWord* addr) const { - assert(_markBitMap.isMarked(addr) && _markBitMap.isMarked(addr + 1), - "missing Printezis mark?"); + assert(_markBitMap.isMarked(addr) && _markBitMap.isMarked(addr + 1), + "missing Printezis mark?"); HeapWord* nextOneAddr = _markBitMap.getNextMarkedWordAddress(addr + 2); size_t size = pointer_delta(nextOneAddr + 1, addr); assert(size == CompactibleFreeListSpace::adjustObjectSize(size), diff --git a/src/share/vm/gc_implementation/g1/concurrentMark.cpp b/src/share/vm/gc_implementation/g1/concurrentMark.cpp index 036e0e7fcf3b8f56e336456231fedd249216c65f..65f64e2ad1614a16e85daca8cb86e02f7af8ef98 100644 --- a/src/share/vm/gc_implementation/g1/concurrentMark.cpp +++ b/src/share/vm/gc_implementation/g1/concurrentMark.cpp @@ -811,6 +811,7 @@ void ConcurrentMark::checkpointRootsInitialPost() { ReferenceProcessor* rp = g1h->ref_processor(); rp->verify_no_references_recorded(); rp->enable_discovery(); // enable ("weak") refs discovery + rp->snap_policy(false); // snapshot the soft ref policy to be used in this cycle SATBMarkQueueSet& satb_mq_set = JavaThread::satb_mark_queue_set(); satb_mq_set.set_process_completed_threshold(G1SATBProcessCompletedThreshold); @@ -1829,32 +1830,21 @@ class G1CMDrainMarkingStackClosure: public VoidClosure { void ConcurrentMark::weakRefsWork(bool clear_all_soft_refs) { ResourceMark rm; HandleMark hm; - ReferencePolicy* soft_ref_policy; + G1CollectedHeap* g1h = G1CollectedHeap::heap(); + ReferenceProcessor* rp = g1h->ref_processor(); // Process weak references. - if (clear_all_soft_refs) { - soft_ref_policy = new AlwaysClearPolicy(); - } else { -#ifdef COMPILER2 - soft_ref_policy = new LRUMaxHeapPolicy(); -#else - soft_ref_policy = new LRUCurrentHeapPolicy(); -#endif - } + rp->snap_policy(clear_all_soft_refs); assert(_markStack.isEmpty(), "mark stack should be empty"); - G1CollectedHeap* g1 = G1CollectedHeap::heap(); - G1CMIsAliveClosure g1IsAliveClosure(g1); - - G1CMKeepAliveClosure g1KeepAliveClosure(g1, this, nextMarkBitMap()); + G1CMIsAliveClosure g1IsAliveClosure (g1h); + G1CMKeepAliveClosure g1KeepAliveClosure(g1h, this, nextMarkBitMap()); G1CMDrainMarkingStackClosure g1DrainMarkingStackClosure(nextMarkBitMap(), &_markStack, &g1KeepAliveClosure); // XXXYYY Also: copy the parallel ref processing code from CMS. - ReferenceProcessor* rp = g1->ref_processor(); - rp->process_discovered_references(soft_ref_policy, - &g1IsAliveClosure, + rp->process_discovered_references(&g1IsAliveClosure, &g1KeepAliveClosure, &g1DrainMarkingStackClosure, NULL); diff --git a/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp b/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp index 370745f36e1b7d143284fbead953b4d11f9b2417..5aaa483b91c19ed2b41288fb9a7bc568b1638de6 100644 --- a/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp +++ b/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp @@ -891,6 +891,7 @@ void G1CollectedHeap::do_collection(bool full, bool clear_all_soft_refs, ReferenceProcessorIsAliveMutator rp_is_alive_null(ref_processor(), NULL); ref_processor()->enable_discovery(); + ref_processor()->snap_policy(clear_all_soft_refs); // Do collection work { @@ -2463,7 +2464,7 @@ G1CollectedHeap::do_collection_pause_at_safepoint(HeapRegion* popular_region) { COMPILER2_PRESENT(DerivedPointerTable::clear()); - // We want to turn off ref discovere, if necessary, and turn it back on + // We want to turn off ref discovery, if necessary, and turn it back on // on again later if we do. bool was_enabled = ref_processor()->discovery_enabled(); if (was_enabled) ref_processor()->disable_discovery(); diff --git a/src/share/vm/gc_implementation/g1/g1MarkSweep.cpp b/src/share/vm/gc_implementation/g1/g1MarkSweep.cpp index 3c5eccb4a7bf5459a9d825371e3cf9a8ccf4cc2d..4aa08a2319eeb9a4cdce091b389fc5b11ca3e03e 100644 --- a/src/share/vm/gc_implementation/g1/g1MarkSweep.cpp +++ b/src/share/vm/gc_implementation/g1/g1MarkSweep.cpp @@ -33,8 +33,9 @@ void G1MarkSweep::invoke_at_safepoint(ReferenceProcessor* rp, // hook up weak ref data so it can be used during Mark-Sweep assert(GenMarkSweep::ref_processor() == NULL, "no stomping"); - GenMarkSweep::_ref_processor = rp; assert(rp != NULL, "should be non-NULL"); + GenMarkSweep::_ref_processor = rp; + rp->snap_policy(clear_all_softrefs); // When collecting the permanent generation methodOops may be moving, // so we either have to flush all bcp data or convert it into bci. @@ -121,23 +122,12 @@ void G1MarkSweep::mark_sweep_phase1(bool& marked_for_unloading, &GenMarkSweep::follow_root_closure); // Process reference objects found during marking - ReferencePolicy *soft_ref_policy; - if (clear_all_softrefs) { - soft_ref_policy = new AlwaysClearPolicy(); - } else { -#ifdef COMPILER2 - soft_ref_policy = new LRUMaxHeapPolicy(); -#else - soft_ref_policy = new LRUCurrentHeapPolicy(); -#endif - } - assert(soft_ref_policy != NULL,"No soft reference policy"); - GenMarkSweep::ref_processor()->process_discovered_references( - soft_ref_policy, - &GenMarkSweep::is_alive, - &GenMarkSweep::keep_alive, - &GenMarkSweep::follow_stack_closure, - NULL); + ReferenceProcessor* rp = GenMarkSweep::ref_processor(); + rp->snap_policy(clear_all_softrefs); + rp->process_discovered_references(&GenMarkSweep::is_alive, + &GenMarkSweep::keep_alive, + &GenMarkSweep::follow_stack_closure, + NULL); // Follow system dictionary roots and unload classes bool purged_class = SystemDictionary::do_unloading(&GenMarkSweep::is_alive); diff --git a/src/share/vm/gc_implementation/parNew/parNewGeneration.cpp b/src/share/vm/gc_implementation/parNew/parNewGeneration.cpp index 7803f08b56a722a3114ac9db2210e97b1b7ebf7f..aca77d20634b33b1364d8967817dbf0bac06f59a 100644 --- a/src/share/vm/gc_implementation/parNew/parNewGeneration.cpp +++ b/src/share/vm/gc_implementation/parNew/parNewGeneration.cpp @@ -759,17 +759,12 @@ void ParNewGeneration::collect(bool full, thread_state_set.steals(), thread_state_set.pops()+thread_state_set.steals()); } - assert(thread_state_set.pushes() == thread_state_set.pops() + thread_state_set.steals(), + assert(thread_state_set.pushes() == thread_state_set.pops() + + thread_state_set.steals(), "Or else the queues are leaky."); - // For now, process discovered weak refs sequentially. -#ifdef COMPILER2 - ReferencePolicy *soft_ref_policy = new LRUMaxHeapPolicy(); -#else - ReferencePolicy *soft_ref_policy = new LRUCurrentHeapPolicy(); -#endif // COMPILER2 - // Process (weak) reference objects found during scavenge. + ReferenceProcessor* rp = ref_processor(); IsAliveClosure is_alive(this); ScanWeakRefClosure scan_weak_ref(this); KeepAliveClosure keep_alive(&scan_weak_ref); @@ -778,18 +773,17 @@ void ParNewGeneration::collect(bool full, set_promo_failure_scan_stack_closure(&scan_without_gc_barrier); EvacuateFollowersClosureGeneral evacuate_followers(gch, _level, &scan_without_gc_barrier, &scan_with_gc_barrier); - if (ref_processor()->processing_is_mt()) { + rp->snap_policy(clear_all_soft_refs); + if (rp->processing_is_mt()) { ParNewRefProcTaskExecutor task_executor(*this, thread_state_set); - ref_processor()->process_discovered_references( - soft_ref_policy, &is_alive, &keep_alive, &evacuate_followers, - &task_executor); + rp->process_discovered_references(&is_alive, &keep_alive, + &evacuate_followers, &task_executor); } else { thread_state_set.flush(); gch->set_par_threads(0); // 0 ==> non-parallel. gch->save_marks(); - ref_processor()->process_discovered_references( - soft_ref_policy, &is_alive, &keep_alive, &evacuate_followers, - NULL); + rp->process_discovered_references(&is_alive, &keep_alive, + &evacuate_followers, NULL); } if (!promotion_failed()) { // Swap the survivor spaces. @@ -851,14 +845,14 @@ void ParNewGeneration::collect(bool full, SpecializationStats::print(); - ref_processor()->set_enqueuing_is_done(true); - if (ref_processor()->processing_is_mt()) { + rp->set_enqueuing_is_done(true); + if (rp->processing_is_mt()) { ParNewRefProcTaskExecutor task_executor(*this, thread_state_set); - ref_processor()->enqueue_discovered_references(&task_executor); + rp->enqueue_discovered_references(&task_executor); } else { - ref_processor()->enqueue_discovered_references(NULL); + rp->enqueue_discovered_references(NULL); } - ref_processor()->verify_no_references_recorded(); + rp->verify_no_references_recorded(); } static int sum; diff --git a/src/share/vm/gc_implementation/parallelScavenge/psMarkSweep.cpp b/src/share/vm/gc_implementation/parallelScavenge/psMarkSweep.cpp index 97d9e31b7e336883329a862ba2880c60b13bf5fb..5134f47e7a543d5d5e9fbf8c0e06f501143b656a 100644 --- a/src/share/vm/gc_implementation/parallelScavenge/psMarkSweep.cpp +++ b/src/share/vm/gc_implementation/parallelScavenge/psMarkSweep.cpp @@ -172,6 +172,7 @@ void PSMarkSweep::invoke_no_policy(bool clear_all_softrefs) { COMPILER2_PRESENT(DerivedPointerTable::clear()); ref_processor()->enable_discovery(); + ref_processor()->snap_policy(clear_all_softrefs); mark_sweep_phase1(clear_all_softrefs); @@ -517,20 +518,9 @@ void PSMarkSweep::mark_sweep_phase1(bool clear_all_softrefs) { // Process reference objects found during marking { - ReferencePolicy *soft_ref_policy; - if (clear_all_softrefs) { - soft_ref_policy = new AlwaysClearPolicy(); - } else { -#ifdef COMPILER2 - soft_ref_policy = new LRUMaxHeapPolicy(); -#else - soft_ref_policy = new LRUCurrentHeapPolicy(); -#endif // COMPILER2 - } - assert(soft_ref_policy != NULL,"No soft reference policy"); + ref_processor()->snap_policy(clear_all_softrefs); ref_processor()->process_discovered_references( - soft_ref_policy, is_alive_closure(), mark_and_push_closure(), - follow_stack_closure(), NULL); + is_alive_closure(), mark_and_push_closure(), follow_stack_closure(), NULL); } // Follow system dictionary roots and unload classes diff --git a/src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.cpp b/src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.cpp index a84a955f0d37c4c8458960d4424db542c3e147f3..9ca6b6c804c3865d66bb7e17d0f1d9f44f9cefe0 100644 --- a/src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.cpp +++ b/src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.cpp @@ -1578,6 +1578,7 @@ void PSParallelCompact::invoke_no_policy(bool maximum_heap_compaction) { COMPILER2_PRESENT(DerivedPointerTable::clear()); ref_processor()->enable_discovery(); + ref_processor()->snap_policy(maximum_heap_compaction); bool marked_for_unloading = false; @@ -1894,26 +1895,14 @@ void PSParallelCompact::marking_phase(ParCompactionManager* cm, // Process reference objects found during marking { TraceTime tm_r("reference processing", print_phases(), true, gclog_or_tty); - ReferencePolicy *soft_ref_policy; - if (maximum_heap_compaction) { - soft_ref_policy = new AlwaysClearPolicy(); - } else { -#ifdef COMPILER2 - soft_ref_policy = new LRUMaxHeapPolicy(); -#else - soft_ref_policy = new LRUCurrentHeapPolicy(); -#endif // COMPILER2 - } - assert(soft_ref_policy != NULL, "No soft reference policy"); if (ref_processor()->processing_is_mt()) { RefProcTaskExecutor task_executor; ref_processor()->process_discovered_references( - soft_ref_policy, is_alive_closure(), &mark_and_push_closure, - &follow_stack_closure, &task_executor); + is_alive_closure(), &mark_and_push_closure, &follow_stack_closure, + &task_executor); } else { ref_processor()->process_discovered_references( - soft_ref_policy, is_alive_closure(), &mark_and_push_closure, - &follow_stack_closure, NULL); + is_alive_closure(), &mark_and_push_closure, &follow_stack_closure, NULL); } } diff --git a/src/share/vm/gc_implementation/parallelScavenge/psScavenge.cpp b/src/share/vm/gc_implementation/parallelScavenge/psScavenge.cpp index 090b15f64baa48fd9dd956d108cb65c51fea27ae..4aa7d5afe388909c1edada0a2a45faf3b57ef323 100644 --- a/src/share/vm/gc_implementation/parallelScavenge/psScavenge.cpp +++ b/src/share/vm/gc_implementation/parallelScavenge/psScavenge.cpp @@ -330,6 +330,7 @@ bool PSScavenge::invoke_no_policy() { COMPILER2_PRESENT(DerivedPointerTable::clear()); reference_processor()->enable_discovery(); + reference_processor()->snap_policy(false); // We track how much was promoted to the next generation for // the AdaptiveSizePolicy. @@ -394,24 +395,16 @@ bool PSScavenge::invoke_no_policy() { // Process reference objects discovered during scavenge { -#ifdef COMPILER2 - ReferencePolicy *soft_ref_policy = new LRUMaxHeapPolicy(); -#else - ReferencePolicy *soft_ref_policy = new LRUCurrentHeapPolicy(); -#endif // COMPILER2 - + reference_processor()->snap_policy(false); // not always_clear PSKeepAliveClosure keep_alive(promotion_manager); PSEvacuateFollowersClosure evac_followers(promotion_manager); - assert(soft_ref_policy != NULL,"No soft reference policy"); if (reference_processor()->processing_is_mt()) { PSRefProcTaskExecutor task_executor; reference_processor()->process_discovered_references( - soft_ref_policy, &_is_alive_closure, &keep_alive, &evac_followers, - &task_executor); + &_is_alive_closure, &keep_alive, &evac_followers, &task_executor); } else { reference_processor()->process_discovered_references( - soft_ref_policy, &_is_alive_closure, &keep_alive, &evac_followers, - NULL); + &_is_alive_closure, &keep_alive, &evac_followers, NULL); } } diff --git a/src/share/vm/includeDB_core b/src/share/vm/includeDB_core index 3b4dd2e38fe487ac6b096f082d5c36e3ae553377..ed59dfeed1d2b635fe6a8524be8778310409c7dd 100644 --- a/src/share/vm/includeDB_core +++ b/src/share/vm/includeDB_core @@ -3434,6 +3434,7 @@ referenceProcessor.cpp referenceProcessor.hpp referenceProcessor.cpp systemDictionary.hpp referenceProcessor.hpp instanceRefKlass.hpp +referenceProcessor.hpp referencePolicy.hpp reflection.cpp arguments.hpp reflection.cpp handles.inline.hpp diff --git a/src/share/vm/memory/defNewGeneration.cpp b/src/share/vm/memory/defNewGeneration.cpp index 63278cee70378998aac98a0312b3af0f8481ea8b..e953e7545b54b570b12e11a6447d189ff8e08dcc 100644 --- a/src/share/vm/memory/defNewGeneration.cpp +++ b/src/share/vm/memory/defNewGeneration.cpp @@ -540,14 +540,6 @@ void DefNewGeneration::collect(bool full, assert(gch->no_allocs_since_save_marks(0), "save marks have not been newly set."); - // Weak refs. - // FIXME: Are these storage leaks, or are they resource objects? -#ifdef COMPILER2 - ReferencePolicy *soft_ref_policy = new LRUMaxHeapPolicy(); -#else - ReferencePolicy *soft_ref_policy = new LRUCurrentHeapPolicy(); -#endif // COMPILER2 - // Not very pretty. CollectorPolicy* cp = gch->collector_policy(); @@ -574,8 +566,10 @@ void DefNewGeneration::collect(bool full, evacuate_followers.do_void(); FastKeepAliveClosure keep_alive(this, &scan_weak_ref); - ref_processor()->process_discovered_references( - soft_ref_policy, &is_alive, &keep_alive, &evacuate_followers, NULL); + ReferenceProcessor* rp = ref_processor(); + rp->snap_policy(clear_all_soft_refs); + rp->process_discovered_references(&is_alive, &keep_alive, &evacuate_followers, + NULL); if (!promotion_failed()) { // Swap the survivor spaces. eden()->clear(SpaceDecorator::Mangle); diff --git a/src/share/vm/memory/genCollectedHeap.cpp b/src/share/vm/memory/genCollectedHeap.cpp index 0cfa60bd2b99d55d5e6b939814c73140dcd58d96..f411d4d7bfa94ca7920200e2e0aca5e0ca0df98f 100644 --- a/src/share/vm/memory/genCollectedHeap.cpp +++ b/src/share/vm/memory/genCollectedHeap.cpp @@ -525,8 +525,9 @@ void GenCollectedHeap::do_collection(bool full, if (rp->discovery_is_atomic()) { rp->verify_no_references_recorded(); rp->enable_discovery(); + rp->snap_policy(clear_all_soft_refs); } else { - // collect() will enable discovery as appropriate + // collect() below will enable discovery as appropriate } _gens[i]->collect(full, clear_all_soft_refs, size, is_tlab); if (!rp->enqueuing_is_done()) { diff --git a/src/share/vm/memory/genMarkSweep.cpp b/src/share/vm/memory/genMarkSweep.cpp index 50562ab2e994d05a21b0fbb0d8781e4d2cc2a2af..f0c41d75c00117db445dc09c00a20ca84290f904 100644 --- a/src/share/vm/memory/genMarkSweep.cpp +++ b/src/share/vm/memory/genMarkSweep.cpp @@ -31,8 +31,9 @@ void GenMarkSweep::invoke_at_safepoint(int level, ReferenceProcessor* rp, // hook up weak ref data so it can be used during Mark-Sweep assert(ref_processor() == NULL, "no stomping"); - _ref_processor = rp; assert(rp != NULL, "should be non-NULL"); + _ref_processor = rp; + rp->snap_policy(clear_all_softrefs); TraceTime t1("Full GC", PrintGC && !PrintGCDetails, true, gclog_or_tty); @@ -245,20 +246,9 @@ void GenMarkSweep::mark_sweep_phase1(int level, // Process reference objects found during marking { - ReferencePolicy *soft_ref_policy; - if (clear_all_softrefs) { - soft_ref_policy = new AlwaysClearPolicy(); - } else { -#ifdef COMPILER2 - soft_ref_policy = new LRUMaxHeapPolicy(); -#else - soft_ref_policy = new LRUCurrentHeapPolicy(); -#endif // COMPILER2 - } - assert(soft_ref_policy != NULL,"No soft reference policy"); + ref_processor()->snap_policy(clear_all_softrefs); ref_processor()->process_discovered_references( - soft_ref_policy, &is_alive, &keep_alive, - &follow_stack_closure, NULL); + &is_alive, &keep_alive, &follow_stack_closure, NULL); } // Follow system dictionary roots and unload classes diff --git a/src/share/vm/memory/referencePolicy.cpp b/src/share/vm/memory/referencePolicy.cpp index 08fa2a15767b77f7beb5f1d7130a626f016ef054..0d23d1ddf369e7142a53663ed7807fba29f2f4c0 100644 --- a/src/share/vm/memory/referencePolicy.cpp +++ b/src/share/vm/memory/referencePolicy.cpp @@ -26,6 +26,11 @@ # include "incls/_referencePolicy.cpp.incl" LRUCurrentHeapPolicy::LRUCurrentHeapPolicy() { + snap(); +} + +// Capture state (of-the-VM) information needed to evaluate the policy +void LRUCurrentHeapPolicy::snap() { _max_interval = (Universe::get_heap_free_at_last_gc() / M) * SoftRefLRUPolicyMSPerMB; assert(_max_interval >= 0,"Sanity check"); } @@ -47,6 +52,11 @@ bool LRUCurrentHeapPolicy::should_clear_reference(oop p) { /////////////////////// MaxHeap ////////////////////// LRUMaxHeapPolicy::LRUMaxHeapPolicy() { + snap(); +} + +// Capture state (of-the-VM) information needed to evaluate the policy +void LRUMaxHeapPolicy::snap() { size_t max_heap = MaxHeapSize; max_heap -= Universe::get_heap_used_at_last_gc(); max_heap /= M; diff --git a/src/share/vm/memory/referencePolicy.hpp b/src/share/vm/memory/referencePolicy.hpp index 5645d060d5f4be77bfa998bfb528c5c52201453f..538ab183a0c5a05e40145f6d91c2393ddb80f031 100644 --- a/src/share/vm/memory/referencePolicy.hpp +++ b/src/share/vm/memory/referencePolicy.hpp @@ -26,9 +26,11 @@ // should be cleared. -class ReferencePolicy : public ResourceObj { +class ReferencePolicy : public CHeapObj { public: virtual bool should_clear_reference(oop p) { ShouldNotReachHere(); return true; } + // Capture state (of-the-VM) information needed to evaluate the policy + virtual void snap() { /* do nothing */ } }; class NeverClearPolicy : public ReferencePolicy { @@ -48,6 +50,8 @@ class LRUCurrentHeapPolicy : public ReferencePolicy { public: LRUCurrentHeapPolicy(); + // Capture state (of-the-VM) information needed to evaluate the policy + void snap(); bool should_clear_reference(oop p); }; @@ -58,5 +62,7 @@ class LRUMaxHeapPolicy : public ReferencePolicy { public: LRUMaxHeapPolicy(); + // Capture state (of-the-VM) information needed to evaluate the policy + void snap(); bool should_clear_reference(oop p); }; diff --git a/src/share/vm/memory/referenceProcessor.cpp b/src/share/vm/memory/referenceProcessor.cpp index 98da052b35b8807c61c7c4455b38237823b8cda3..648fbbd47367d0c79fa5eb71e0f39fcf5fa86df4 100644 --- a/src/share/vm/memory/referenceProcessor.cpp +++ b/src/share/vm/memory/referenceProcessor.cpp @@ -25,6 +25,11 @@ # include "incls/_precompiled.incl" # include "incls/_referenceProcessor.cpp.incl" +ReferencePolicy* ReferenceProcessor::_always_clear_soft_ref_policy = NULL; +ReferencePolicy* ReferenceProcessor::_default_soft_ref_policy = NULL; +oop ReferenceProcessor::_sentinelRef = NULL; +const int subclasses_of_ref = REF_PHANTOM - REF_OTHER; + // List of discovered references. class DiscoveredList { public: @@ -58,10 +63,6 @@ private: size_t _len; }; -oop ReferenceProcessor::_sentinelRef = NULL; - -const int subclasses_of_ref = REF_PHANTOM - REF_OTHER; - void referenceProcessor_init() { ReferenceProcessor::init_statics(); } @@ -82,6 +83,12 @@ void ReferenceProcessor::init_statics() { } assert(_sentinelRef != NULL && _sentinelRef->is_oop(), "Just constructed it!"); + _always_clear_soft_ref_policy = new AlwaysClearPolicy(); + _default_soft_ref_policy = new COMPILER2_PRESENT(LRUMaxHeapPolicy()) + NOT_COMPILER2(LRUCurrentHeapPolicy()); + if (_always_clear_soft_ref_policy == NULL || _default_soft_ref_policy == NULL) { + vm_exit_during_initialization("Could not allocate reference policy object"); + } guarantee(RefDiscoveryPolicy == ReferenceBasedDiscovery || RefDiscoveryPolicy == ReferentBasedDiscovery, "Unrecongnized RefDiscoveryPolicy"); @@ -108,6 +115,7 @@ ReferenceProcessor::create_ref_processor(MemRegion span, vm_exit_during_initialization("Could not allocate ReferenceProcessor object"); } rp->set_is_alive_non_header(is_alive_non_header); + rp->snap_policy(false /* default soft ref policy */); return rp; } @@ -194,7 +202,6 @@ void ReferenceProcessor::update_soft_ref_master_clock() { } void ReferenceProcessor::process_discovered_references( - ReferencePolicy* policy, BoolObjectClosure* is_alive, OopClosure* keep_alive, VoidClosure* complete_gc, @@ -209,7 +216,7 @@ void ReferenceProcessor::process_discovered_references( // Soft references { TraceTime tt("SoftReference", trace_time, false, gclog_or_tty); - process_discovered_reflist(_discoveredSoftRefs, policy, true, + process_discovered_reflist(_discoveredSoftRefs, _current_soft_ref_policy, true, is_alive, keep_alive, complete_gc, task_executor); } @@ -1092,15 +1099,28 @@ bool ReferenceProcessor::discover_reference(oop obj, ReferenceType rt) { // reachable. if (is_alive_non_header() != NULL) { oop referent = java_lang_ref_Reference::referent(obj); - // We'd like to assert the following: - // assert(referent != NULL, "Refs with null referents already filtered"); - // However, since this code may be executed concurrently with - // mutators, which can clear() the referent, it is not - // guaranteed that the referent is non-NULL. + // In the case of non-concurrent discovery, the last + // disjunct below should hold. It may not hold in the + // case of concurrent discovery because mutators may + // concurrently clear() a Reference. + assert(UseConcMarkSweepGC || UseG1GC || referent != NULL, + "Refs with null referents already filtered"); if (is_alive_non_header()->do_object_b(referent)) { return false; // referent is reachable } } + if (rt == REF_SOFT) { + // For soft refs we can decide now if these are not + // current candidates for clearing, in which case we + // can mark through them now, rather than delaying that + // to the reference-processing phase. Since all current + // time-stamp policies advance the soft-ref clock only + // at a major collection cycle, this is always currently + // accurate. + if (!_current_soft_ref_policy->should_clear_reference(obj)) { + return false; + } + } HeapWord* const discovered_addr = java_lang_ref_Reference::discovered_addr(obj); const oop discovered = java_lang_ref_Reference::discovered(obj); diff --git a/src/share/vm/memory/referenceProcessor.hpp b/src/share/vm/memory/referenceProcessor.hpp index c07c4e34388d997e00798a17753d2c0e9a625a23..d4ebec200fa55cac3c7a5bf61333109e96cdbefa 100644 --- a/src/share/vm/memory/referenceProcessor.hpp +++ b/src/share/vm/memory/referenceProcessor.hpp @@ -23,7 +23,7 @@ */ // ReferenceProcessor class encapsulates the per-"collector" processing -// of "weak" references for GC. The interface is useful for supporting +// of java.lang.Reference objects for GC. The interface is useful for supporting // a generational abstraction, in particular when there are multiple // generations that are being independently collected -- possibly // concurrently and/or incrementally. Note, however, that the @@ -75,6 +75,14 @@ class ReferenceProcessor : public CHeapObj { // all collectors but the CMS collector). BoolObjectClosure* _is_alive_non_header; + // Soft ref clearing policies + // . the default policy + static ReferencePolicy* _default_soft_ref_policy; + // . the "clear all" policy + static ReferencePolicy* _always_clear_soft_ref_policy; + // . the current policy below is either one of the above + ReferencePolicy* _current_soft_ref_policy; + // The discovered ref lists themselves // The MT'ness degree of the queues below @@ -90,6 +98,12 @@ class ReferenceProcessor : public CHeapObj { DiscoveredList* discovered_soft_refs() { return _discoveredSoftRefs; } static oop sentinel_ref() { return _sentinelRef; } static oop* adr_sentinel_ref() { return &_sentinelRef; } + ReferencePolicy* snap_policy(bool always_clear) { + _current_soft_ref_policy = always_clear ? + _always_clear_soft_ref_policy : _default_soft_ref_policy; + _current_soft_ref_policy->snap(); // snapshot the policy threshold + return _current_soft_ref_policy; + } public: // Process references with a certain reachability level. @@ -297,8 +311,7 @@ class ReferenceProcessor : public CHeapObj { bool discover_reference(oop obj, ReferenceType rt); // Process references found during GC (called by the garbage collector) - void process_discovered_references(ReferencePolicy* policy, - BoolObjectClosure* is_alive, + void process_discovered_references(BoolObjectClosure* is_alive, OopClosure* keep_alive, VoidClosure* complete_gc, AbstractRefProcTaskExecutor* task_executor); diff --git a/src/share/vm/memory/universe.cpp b/src/share/vm/memory/universe.cpp index 651e96680412e90974c30ae11f3dbba511caffdb..ffe583ecc16028d5e2c75580214997352184e9f5 100644 --- a/src/share/vm/memory/universe.cpp +++ b/src/share/vm/memory/universe.cpp @@ -96,7 +96,7 @@ bool Universe::_bootstrapping = false; bool Universe::_fully_initialized = false; size_t Universe::_heap_capacity_at_last_gc; -size_t Universe::_heap_used_at_last_gc; +size_t Universe::_heap_used_at_last_gc = 0; CollectedHeap* Universe::_collectedHeap = NULL; address Universe::_heap_base = NULL; diff --git a/src/share/vm/utilities/macros.hpp b/src/share/vm/utilities/macros.hpp index 770ac0b38764a3379e43b22a52bb954b999f0425..20b2871c58336f21d7c478351a0b5e15126356f8 100644 --- a/src/share/vm/utilities/macros.hpp +++ b/src/share/vm/utilities/macros.hpp @@ -65,8 +65,10 @@ // COMPILER2 variant #ifdef COMPILER2 #define COMPILER2_PRESENT(code) code +#define NOT_COMPILER2(code) #else // COMPILER2 #define COMPILER2_PRESENT(code) +#define NOT_COMPILER2(code) code #endif // COMPILER2