src/share/vm/gc_implementation/g1/concurrentMark.cpp

Print this page
rev 2585 : [mq]: g1-reference-processing

*** 848,859 **** // For each region note start of marking. NoteStartOfMarkHRClosure startcl; g1h->heap_region_iterate(&startcl); ! // Start weak-reference discovery. ! ReferenceProcessor* rp = g1h->ref_processor(); rp->verify_no_references_recorded(); rp->enable_discovery(); // enable ("weak") refs discovery rp->setup_policy(false); // snapshot the soft ref policy to be used in this cycle SATBMarkQueueSet& satb_mq_set = JavaThread::satb_mark_queue_set(); --- 848,860 ---- // For each region note start of marking. NoteStartOfMarkHRClosure startcl; g1h->heap_region_iterate(&startcl); ! // Start Concurrent Marking weak-reference discovery. ! ReferenceProcessor* rp = g1h->ref_processor_cm(); ! assert(!rp->discovery_enabled(), "Precondition"); rp->verify_no_references_recorded(); rp->enable_discovery(); // enable ("weak") refs discovery rp->setup_policy(false); // snapshot the soft ref policy to be used in this cycle SATBMarkQueueSet& satb_mq_set = JavaThread::satb_mark_queue_set();
*** 1207,1216 **** --- 1208,1218 ---- void ConcurrentMark::checkpointRootsFinal(bool clear_all_soft_refs) { // world is stopped at this checkpoint assert(SafepointSynchronize::is_at_safepoint(), "world should be stopped"); + G1CollectedHeap* g1h = G1CollectedHeap::heap(); // If a full collection has happened, we shouldn't do this. if (has_aborted()) { g1h->set_marking_complete(); // So bitmap clearing isn't confused
*** 1908,1917 **** --- 1910,1923 ---- } size_t cleaned_up_bytes = start_used_bytes - g1h->used(); g1p->decrease_known_garbage_bytes(cleaned_up_bytes); + // Clean up will have freed any regions completely full of garbage. + // Update the soft reference policy with the new heap occupancy. + Universe::update_heap_info_at_gc(); + // We need to make this be a "collection" so any collection pause that // races with it goes around and waits for completeCleanup to finish. g1h->increment_total_collections(); if (VerifyDuringGC) {
*** 2143,2163 **** true /* do_termination */); } while (_task->has_aborted() && !_cm->has_overflown()); } }; ! // Implementation of AbstractRefProcTaskExecutor for G1 ! class G1RefProcTaskExecutor: public AbstractRefProcTaskExecutor { private: G1CollectedHeap* _g1h; ConcurrentMark* _cm; CMBitMap* _bitmap; WorkGang* _workers; int _active_workers; public: ! G1RefProcTaskExecutor(G1CollectedHeap* g1h, ConcurrentMark* cm, CMBitMap* bitmap, WorkGang* workers, int n_workers) : _g1h(g1h), _cm(cm), _bitmap(bitmap), --- 2149,2171 ---- true /* do_termination */); } while (_task->has_aborted() && !_cm->has_overflown()); } }; ! // Implementation of AbstractRefProcTaskExecutor for parallel ! // reference processing at the end of G1 concurrent marking ! ! class G1CMRefProcTaskExecutor: public AbstractRefProcTaskExecutor { private: G1CollectedHeap* _g1h; ConcurrentMark* _cm; CMBitMap* _bitmap; WorkGang* _workers; int _active_workers; public: ! G1CMRefProcTaskExecutor(G1CollectedHeap* g1h, ConcurrentMark* cm, CMBitMap* bitmap, WorkGang* workers, int n_workers) : _g1h(g1h), _cm(cm), _bitmap(bitmap),
*** 2167,2185 **** // Executes the given task using concurrent marking worker threads. virtual void execute(ProcessTask& task); virtual void execute(EnqueueTask& task); }; ! class G1RefProcTaskProxy: public AbstractGangTask { typedef AbstractRefProcTaskExecutor::ProcessTask ProcessTask; ProcessTask& _proc_task; G1CollectedHeap* _g1h; ConcurrentMark* _cm; CMBitMap* _bitmap; public: ! G1RefProcTaskProxy(ProcessTask& proc_task, G1CollectedHeap* g1h, ConcurrentMark* cm, CMBitMap* bitmap) : AbstractGangTask("Process reference objects in parallel"), _proc_task(proc_task), _g1h(g1h), _cm(cm), _bitmap(bitmap) --- 2175,2193 ---- // Executes the given task using concurrent marking worker threads. virtual void execute(ProcessTask& task); virtual void execute(EnqueueTask& task); }; ! class G1CMRefProcTaskProxy: public AbstractGangTask { typedef AbstractRefProcTaskExecutor::ProcessTask ProcessTask; ProcessTask& _proc_task; G1CollectedHeap* _g1h; ConcurrentMark* _cm; CMBitMap* _bitmap; public: ! G1CMRefProcTaskProxy(ProcessTask& proc_task, G1CollectedHeap* g1h, ConcurrentMark* cm, CMBitMap* bitmap) : AbstractGangTask("Process reference objects in parallel"), _proc_task(proc_task), _g1h(g1h), _cm(cm), _bitmap(bitmap)
*** 2193,2245 **** _proc_task.work(i, g1_is_alive, g1_par_keep_alive, g1_par_drain); } }; ! void G1RefProcTaskExecutor::execute(ProcessTask& proc_task) { assert(_workers != NULL, "Need parallel worker threads."); ! G1RefProcTaskProxy proc_task_proxy(proc_task, _g1h, _cm, _bitmap); // We need to reset the phase for each task execution so that // the termination protocol of CMTask::do_marking_step works. _cm->set_phase(_active_workers, false /* concurrent */); _g1h->set_par_threads(_active_workers); _workers->run_task(&proc_task_proxy); _g1h->set_par_threads(0); } ! class G1RefEnqueueTaskProxy: public AbstractGangTask { typedef AbstractRefProcTaskExecutor::EnqueueTask EnqueueTask; EnqueueTask& _enq_task; public: ! G1RefEnqueueTaskProxy(EnqueueTask& enq_task) : AbstractGangTask("Enqueue reference objects in parallel"), _enq_task(enq_task) { } virtual void work(int i) { _enq_task.work(i); } }; ! void G1RefProcTaskExecutor::execute(EnqueueTask& enq_task) { assert(_workers != NULL, "Need parallel worker threads."); ! G1RefEnqueueTaskProxy enq_task_proxy(enq_task); _g1h->set_par_threads(_active_workers); _workers->run_task(&enq_task_proxy); _g1h->set_par_threads(0); } void ConcurrentMark::weakRefsWork(bool clear_all_soft_refs) { ResourceMark rm; HandleMark hm; G1CollectedHeap* g1h = G1CollectedHeap::heap(); ! ReferenceProcessor* rp = g1h->ref_processor(); // See the comment in G1CollectedHeap::ref_processing_init() // about how reference processing currently works in G1. // Process weak references. --- 2201,2253 ---- _proc_task.work(i, g1_is_alive, g1_par_keep_alive, g1_par_drain); } }; ! void G1CMRefProcTaskExecutor::execute(ProcessTask& proc_task) { assert(_workers != NULL, "Need parallel worker threads."); ! G1CMRefProcTaskProxy proc_task_proxy(proc_task, _g1h, _cm, _bitmap); // We need to reset the phase for each task execution so that // the termination protocol of CMTask::do_marking_step works. _cm->set_phase(_active_workers, false /* concurrent */); _g1h->set_par_threads(_active_workers); _workers->run_task(&proc_task_proxy); _g1h->set_par_threads(0); } ! class G1CMRefEnqueueTaskProxy: public AbstractGangTask { typedef AbstractRefProcTaskExecutor::EnqueueTask EnqueueTask; EnqueueTask& _enq_task; public: ! G1CMRefEnqueueTaskProxy(EnqueueTask& enq_task) : AbstractGangTask("Enqueue reference objects in parallel"), _enq_task(enq_task) { } virtual void work(int i) { _enq_task.work(i); } }; ! void G1CMRefProcTaskExecutor::execute(EnqueueTask& enq_task) { assert(_workers != NULL, "Need parallel worker threads."); ! G1CMRefEnqueueTaskProxy enq_task_proxy(enq_task); _g1h->set_par_threads(_active_workers); _workers->run_task(&enq_task_proxy); _g1h->set_par_threads(0); } void ConcurrentMark::weakRefsWork(bool clear_all_soft_refs) { ResourceMark rm; HandleMark hm; G1CollectedHeap* g1h = G1CollectedHeap::heap(); ! ReferenceProcessor* rp = g1h->ref_processor_cm(); // See the comment in G1CollectedHeap::ref_processing_init() // about how reference processing currently works in G1. // Process weak references.
*** 2253,2263 **** // We use the work gang from the G1CollectedHeap and we utilize all // the worker threads. int active_workers = g1h->workers() ? g1h->workers()->total_workers() : 1; active_workers = MAX2(MIN2(active_workers, (int)_max_task_num), 1); ! G1RefProcTaskExecutor par_task_executor(g1h, this, nextMarkBitMap(), g1h->workers(), active_workers); if (rp->processing_is_mt()) { // Set the degree of MT here. If the discovery is done MT, there --- 2261,2271 ---- // We use the work gang from the G1CollectedHeap and we utilize all // the worker threads. int active_workers = g1h->workers() ? g1h->workers()->total_workers() : 1; active_workers = MAX2(MIN2(active_workers, (int)_max_task_num), 1); ! G1CMRefProcTaskExecutor par_task_executor(g1h, this, nextMarkBitMap(), g1h->workers(), active_workers); if (rp->processing_is_mt()) { // Set the degree of MT here. If the discovery is done MT, there
*** 2297,2307 **** } else { rp->enqueue_discovered_references(); } rp->verify_no_references_recorded(); ! assert(!rp->discovery_enabled(), "should have been disabled"); // Now clean up stale oops in StringTable StringTable::unlink(&g1_is_alive); // Clean up unreferenced symbols in symbol table. SymbolTable::unlink(); --- 2305,2315 ---- } else { rp->enqueue_discovered_references(); } rp->verify_no_references_recorded(); ! assert(!rp->discovery_enabled(), "Post condition"); // Now clean up stale oops in StringTable StringTable::unlink(&g1_is_alive); // Clean up unreferenced symbols in symbol table. SymbolTable::unlink();
*** 3400,3410 **** CMTask* task) : _g1h(g1h), _cm(cm), _task(task) { assert(_ref_processor == NULL, "should be initialized to NULL"); if (G1UseConcMarkReferenceProcessing) { ! _ref_processor = g1h->ref_processor(); assert(_ref_processor != NULL, "should not be NULL"); } } void CMTask::setup_for_region(HeapRegion* hr) { --- 3408,3418 ---- CMTask* task) : _g1h(g1h), _cm(cm), _task(task) { assert(_ref_processor == NULL, "should be initialized to NULL"); if (G1UseConcMarkReferenceProcessing) { ! _ref_processor = g1h->ref_processor_cm(); assert(_ref_processor != NULL, "should not be NULL"); } } void CMTask::setup_for_region(HeapRegion* hr) {