< prev index next >

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

Print this page
rev 49831 : imported patch 8201492-properly-implement-non-contiguous-reference-processing
rev 49834 : [mq]: 8202021-cleanup-referenceprocessor
rev 49835 : [mq]: 8202021-stefanj-review
rev 49836 : [mq]: 8202017-reference-processor-remove-enqueue

*** 273,389 **** phase_times->set_total_time_ms((os::elapsedTime() - start_time) * 1000); return stats; } - void ReferenceProcessor::enqueue_discovered_references(AbstractRefProcTaskExecutor* task_executor, - ReferenceProcessorPhaseTimes* phase_times) { - // Enqueue references that are not made active again, and - // clear the decks for the next collection (cycle). - enqueue_discovered_reflists(task_executor, phase_times); - - // Stop treating discovered references specially. - disable_discovery(); - } - - void ReferenceProcessor::enqueue_discovered_reflist(DiscoveredList& refs_list) { - // Given a list of refs linked through the "discovered" field - // (java.lang.ref.Reference.discovered), self-loop their "next" field - // thus distinguishing them from active References, then - // prepend them to the pending list. - // - // The Java threads will see the Reference objects linked together through - // the discovered field. Instead of trying to do the write barrier updates - // in all places in the reference processor where we manipulate the discovered - // field we make sure to do the barrier here where we anyway iterate through - // all linked Reference objects. Note that it is important to not dirty any - // cards during reference processing since this will cause card table - // verification to fail for G1. - log_develop_trace(gc, ref)("ReferenceProcessor::enqueue_discovered_reflist list " INTPTR_FORMAT, p2i(&refs_list)); - - oop obj = NULL; - oop next_discovered = refs_list.head(); - // Walk down the list, self-looping the next field - // so that the References are not considered active. - while (obj != next_discovered) { - obj = next_discovered; - assert(obj->is_instance(), "should be an instance object"); - assert(InstanceKlass::cast(obj->klass())->is_reference_instance_klass(), "should be reference object"); - next_discovered = java_lang_ref_Reference::discovered(obj); - log_develop_trace(gc, ref)(" obj " INTPTR_FORMAT "/next_discovered " INTPTR_FORMAT, p2i(obj), p2i(next_discovered)); - assert(java_lang_ref_Reference::next(obj) == NULL, - "Reference not active; should not be discovered"); - // Self-loop next, so as to make Ref not active. - java_lang_ref_Reference::set_next_raw(obj, obj); - if (next_discovered != obj) { - HeapAccess<AS_NO_KEEPALIVE>::oop_store_at(obj, java_lang_ref_Reference::discovered_offset, next_discovered); - } else { - // This is the last object. - // Swap refs_list into pending list and set obj's - // discovered to what we read from the pending list. - oop old = Universe::swap_reference_pending_list(refs_list.head()); - HeapAccess<AS_NO_KEEPALIVE>::oop_store_at(obj, java_lang_ref_Reference::discovered_offset, old); - } - } - } - - // Parallel enqueue task - class RefProcEnqueueTask: public AbstractRefProcTaskExecutor::EnqueueTask { - public: - RefProcEnqueueTask(ReferenceProcessor& ref_processor, - DiscoveredList discovered_refs[], - int n_queues, - ReferenceProcessorPhaseTimes* phase_times) - : EnqueueTask(ref_processor, discovered_refs, n_queues, phase_times) - { } - - virtual void work(unsigned int work_id) { - RefProcWorkerTimeTracker tt(ReferenceProcessorPhaseTimes::RefEnqueue, _phase_times, work_id); - - assert(work_id < (unsigned int)_ref_processor.max_num_queues(), "Index out-of-bounds"); - // Simplest first cut: static partitioning. - int index = work_id; - // The increment on "index" must correspond to the maximum number of queues - // (n_queues) with which that ReferenceProcessor was created. That - // is because of the "clever" way the discovered references lists were - // allocated and are indexed into. - assert(_n_queues == (int) _ref_processor.max_num_queues(), "Different number not expected"); - for (int j = 0; - j < ReferenceProcessor::number_of_subclasses_of_ref(); - j++, index += _n_queues) { - _ref_processor.enqueue_discovered_reflist(_refs_lists[index]); - _refs_lists[index].set_head(NULL); - _refs_lists[index].set_length(0); - } - } - }; - - // Enqueue references that are not made active again - void ReferenceProcessor::enqueue_discovered_reflists(AbstractRefProcTaskExecutor* task_executor, - ReferenceProcessorPhaseTimes* phase_times) { - - ReferenceProcessorStats stats(total_count(_discoveredSoftRefs), - total_count(_discoveredWeakRefs), - total_count(_discoveredFinalRefs), - total_count(_discoveredPhantomRefs)); - - RefProcEnqueueTimeTracker tt(phase_times, stats); - - if (_processing_is_mt && task_executor != NULL) { - // Parallel code - RefProcEnqueueTask tsk(*this, _discovered_refs, _max_num_queues, phase_times); - task_executor->execute(tsk); - } else { - // Serial code: call the parent class's implementation - for (uint i = 0; i < _max_num_queues * number_of_subclasses_of_ref(); i++) { - enqueue_discovered_reflist(_discovered_refs[i]); - _discovered_refs[i].set_head(NULL); - _discovered_refs[i].set_length(0); - } - } - } - void DiscoveredListIterator::load_ptrs(DEBUG_ONLY(bool allow_null_referent)) { _discovered_addr = java_lang_ref_Reference::discovered_addr_raw(_current_discovered); oop discovered = java_lang_ref_Reference::discovered(_current_discovered); assert(_discovered_addr && oopDesc::is_oop_or_null(discovered), "Expected an oop or NULL for discovered field at " PTR_FORMAT, p2i(discovered)); --- 273,282 ----
*** 425,434 **** --- 318,346 ---- 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); + } + + void DiscoveredListIterator::complete_enqeue() { + if (_prev_discovered != NULL) { + // This is the last object. + // Swap refs_list into pending list and set obj's + // discovered to what we read from the pending list. + oop old = Universe::swap_reference_pending_list(_refs_list.head()); + HeapAccess<AS_NO_KEEPALIVE>::oop_store_at(_prev_discovered, java_lang_ref_Reference::discovered_offset, old); + } + } + // NOTE: process_phase*() are largely similar, and at a high level // merely iterate over the extant list applying a predicate to // each of its elements and possibly removing that element from the // list and applying some further closures to that element. // We should consider the possibility of replacing these
*** 572,586 **** --- 484,500 ---- 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"); iter.next(); } + iter.complete_enqeue(); // Close the reachable set complete_gc->do_void(); } void
*** 688,697 **** --- 602,613 ---- { RefProcWorkerTimeTracker tt(ReferenceProcessorPhaseTimes::RefPhase3, _phase_times, i); _ref_processor.process_phase3(_refs_lists[i], _clear_referent, &is_alive, &keep_alive, &complete_gc); + _refs_lists[i].set_head(NULL); + _refs_lists[i].set_length(0); } private: bool _clear_referent; };
*** 801,817 **** log_reflist_counts(ref_lists, _num_queues, balanced_total_refs); assert(total_refs == balanced_total_refs, "Balancing was incomplete"); #endif } - void ReferenceProcessor::balance_all_queues() { - balance_queues(_discoveredSoftRefs); - balance_queues(_discoveredWeakRefs); - balance_queues(_discoveredFinalRefs); - balance_queues(_discoveredPhantomRefs); - } - void ReferenceProcessor::process_discovered_reflist( DiscoveredList refs_lists[], ReferencePolicy* policy, bool clear_referent, BoolObjectClosure* is_alive, --- 717,726 ----
*** 876,885 **** --- 785,796 ---- task_executor->execute(phase3); } else { for (uint i = 0; i < _max_num_queues; i++) { process_phase3(refs_lists[i], clear_referent, is_alive, keep_alive, complete_gc); + refs_lists[i].set_head(NULL); + refs_lists[i].set_length(0); } } } }
< prev index next >