< prev index next >

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

Print this page
rev 49905 : imported patch 8201492-properly-implement-non-contiguous-reference-processing
rev 49908 : imported patch 8202021-cleanup-referenceprocessor
rev 49909 : imported patch 8202021-stefanj-review
rev 49910 : imported patch 8202017-reference-processor-remove-enqueue
rev 49911 : [mq]: 8202017-kim-review


 478   ResourceMark rm;
 479   DiscoveredListIterator iter(refs_list, keep_alive, is_alive);
 480   while (iter.has_next()) {
 481     iter.load_ptrs(DEBUG_ONLY(false /* allow_null_referent */));
 482     if (clear_referent) {
 483       // NULL out referent pointer
 484       iter.clear_referent();
 485     } else {
 486       // keep the referent around
 487       iter.make_referent_alive();
 488     }
 489     iter.enqueue();
 490     log_develop_trace(gc, ref)("Adding %sreference (" INTPTR_FORMAT ": %s) as pending",
 491                                clear_referent ? "cleared " : "", p2i(iter.obj()), iter.obj()->klass()->internal_name());
 492     assert(oopDesc::is_oop(iter.obj(), UseConcMarkSweepGC), "Adding a bad reference");
 493     iter.next();
 494   }
 495   iter.complete_enqeue();
 496   // Close the reachable set
 497   complete_gc->do_void();



 498 }
 499 
 500 void
 501 ReferenceProcessor::clear_discovered_references(DiscoveredList& refs_list) {
 502   oop obj = NULL;
 503   oop next = refs_list.head();
 504   while (next != obj) {
 505     obj = next;
 506     next = java_lang_ref_Reference::discovered(obj);
 507     java_lang_ref_Reference::set_discovered_raw(obj, NULL);
 508   }
 509   refs_list.set_head(NULL);
 510   refs_list.set_length(0);
 511 }
 512 
 513 void ReferenceProcessor::abandon_partial_discovery() {
 514   // loop over the lists
 515   for (uint i = 0; i < _max_num_queues * number_of_subclasses_of_ref(); i++) {
 516     if ((i % _max_num_queues) == 0) {
 517       log_develop_trace(gc, ref)("Abandoning %s discovered list", list_name(i));


 587 };
 588 
 589 class RefProcPhase3Task: public AbstractRefProcTaskExecutor::ProcessTask {
 590 public:
 591   RefProcPhase3Task(ReferenceProcessor&           ref_processor,
 592                     DiscoveredList                refs_lists[],
 593                     bool                         clear_referent,
 594                     bool                          marks_oops_alive,
 595                     ReferenceProcessorPhaseTimes* phase_times)
 596     : ProcessTask(ref_processor, refs_lists, marks_oops_alive, phase_times),
 597       _clear_referent(clear_referent)
 598   { }
 599   virtual void work(unsigned int i, BoolObjectClosure& is_alive,
 600                     OopClosure& keep_alive,
 601                     VoidClosure& complete_gc)
 602   {
 603     RefProcWorkerTimeTracker tt(ReferenceProcessorPhaseTimes::RefPhase3, _phase_times, i);
 604 
 605     _ref_processor.process_phase3(_refs_lists[i], _clear_referent,
 606                                   &is_alive, &keep_alive, &complete_gc);
 607     _refs_lists[i].set_head(NULL);
 608     _refs_lists[i].set_length(0);
 609   }
 610 private:
 611   bool _clear_referent;
 612 };
 613 
 614 #ifndef PRODUCT
 615 void ReferenceProcessor::log_reflist_counts(DiscoveredList ref_lists[], uint active_length, size_t total_refs) {
 616   if (!log_is_enabled(Trace, gc, ref)) {
 617     return;
 618   }
 619 
 620   stringStream st;
 621   for (uint i = 0; i < active_length; ++i) {
 622     st.print(SIZE_FORMAT " ", ref_lists[i].length());
 623   }
 624   log_develop_trace(gc, ref)("%s= " SIZE_FORMAT, st.as_string(), total_refs);
 625 #ifdef ASSERT
 626   for (uint i = active_length; i < _max_num_queues; i++) {
 627     assert(ref_lists[i].length() == 0, SIZE_FORMAT " unexpected References in %u",
 628            ref_lists[i].length(), i);


 770       task_executor->execute(phase2);
 771     } else {
 772       for (uint i = 0; i < _max_num_queues; i++) {
 773         process_phase2(refs_lists[i], is_alive, keep_alive, complete_gc);
 774       }
 775     }
 776   }
 777 
 778   // Phase 3:
 779   // . Traverse the list and process referents as appropriate.
 780   {
 781     RefProcParPhaseTimeTracker tt(ReferenceProcessorPhaseTimes::RefPhase3, phase_times);
 782 
 783     if (mt_processing) {
 784       RefProcPhase3Task phase3(*this, refs_lists, clear_referent, true /*marks_oops_alive*/, phase_times);
 785       task_executor->execute(phase3);
 786     } else {
 787       for (uint i = 0; i < _max_num_queues; i++) {
 788         process_phase3(refs_lists[i], clear_referent,
 789                        is_alive, keep_alive, complete_gc);
 790        refs_lists[i].set_head(NULL);
 791        refs_lists[i].set_length(0);
 792       }
 793     }
 794   }
 795 }
 796 
 797 inline DiscoveredList* ReferenceProcessor::get_discovered_list(ReferenceType rt) {
 798   uint id = 0;
 799   // Determine the queue index to use for this object.
 800   if (_discovery_is_mt) {
 801     // During a multi-threaded discovery phase,
 802     // each thread saves to its "own" list.
 803     Thread* thr = Thread::current();
 804     id = thr->as_Worker_thread()->id();
 805   } else {
 806     // single-threaded discovery, we save in round-robin
 807     // fashion to each of the lists.
 808     if (_processing_is_mt) {
 809       id = next_id();
 810     }
 811   }




 478   ResourceMark rm;
 479   DiscoveredListIterator iter(refs_list, keep_alive, is_alive);
 480   while (iter.has_next()) {
 481     iter.load_ptrs(DEBUG_ONLY(false /* allow_null_referent */));
 482     if (clear_referent) {
 483       // NULL out referent pointer
 484       iter.clear_referent();
 485     } else {
 486       // keep the referent around
 487       iter.make_referent_alive();
 488     }
 489     iter.enqueue();
 490     log_develop_trace(gc, ref)("Adding %sreference (" INTPTR_FORMAT ": %s) as pending",
 491                                clear_referent ? "cleared " : "", p2i(iter.obj()), iter.obj()->klass()->internal_name());
 492     assert(oopDesc::is_oop(iter.obj(), UseConcMarkSweepGC), "Adding a bad reference");
 493     iter.next();
 494   }
 495   iter.complete_enqeue();
 496   // Close the reachable set
 497   complete_gc->do_void();
 498   // Clear the list.
 499   refs_list.set_head(NULL);
 500   refs_list.set_length(0);
 501 }
 502 
 503 void
 504 ReferenceProcessor::clear_discovered_references(DiscoveredList& refs_list) {
 505   oop obj = NULL;
 506   oop next = refs_list.head();
 507   while (next != obj) {
 508     obj = next;
 509     next = java_lang_ref_Reference::discovered(obj);
 510     java_lang_ref_Reference::set_discovered_raw(obj, NULL);
 511   }
 512   refs_list.set_head(NULL);
 513   refs_list.set_length(0);
 514 }
 515 
 516 void ReferenceProcessor::abandon_partial_discovery() {
 517   // loop over the lists
 518   for (uint i = 0; i < _max_num_queues * number_of_subclasses_of_ref(); i++) {
 519     if ((i % _max_num_queues) == 0) {
 520       log_develop_trace(gc, ref)("Abandoning %s discovered list", list_name(i));


 590 };
 591 
 592 class RefProcPhase3Task: public AbstractRefProcTaskExecutor::ProcessTask {
 593 public:
 594   RefProcPhase3Task(ReferenceProcessor&           ref_processor,
 595                     DiscoveredList                refs_lists[],
 596                     bool                         clear_referent,
 597                     bool                          marks_oops_alive,
 598                     ReferenceProcessorPhaseTimes* phase_times)
 599     : ProcessTask(ref_processor, refs_lists, marks_oops_alive, phase_times),
 600       _clear_referent(clear_referent)
 601   { }
 602   virtual void work(unsigned int i, BoolObjectClosure& is_alive,
 603                     OopClosure& keep_alive,
 604                     VoidClosure& complete_gc)
 605   {
 606     RefProcWorkerTimeTracker tt(ReferenceProcessorPhaseTimes::RefPhase3, _phase_times, i);
 607 
 608     _ref_processor.process_phase3(_refs_lists[i], _clear_referent,
 609                                   &is_alive, &keep_alive, &complete_gc);


 610   }
 611 private:
 612   bool _clear_referent;
 613 };
 614 
 615 #ifndef PRODUCT
 616 void ReferenceProcessor::log_reflist_counts(DiscoveredList ref_lists[], uint active_length, size_t total_refs) {
 617   if (!log_is_enabled(Trace, gc, ref)) {
 618     return;
 619   }
 620 
 621   stringStream st;
 622   for (uint i = 0; i < active_length; ++i) {
 623     st.print(SIZE_FORMAT " ", ref_lists[i].length());
 624   }
 625   log_develop_trace(gc, ref)("%s= " SIZE_FORMAT, st.as_string(), total_refs);
 626 #ifdef ASSERT
 627   for (uint i = active_length; i < _max_num_queues; i++) {
 628     assert(ref_lists[i].length() == 0, SIZE_FORMAT " unexpected References in %u",
 629            ref_lists[i].length(), i);


 771       task_executor->execute(phase2);
 772     } else {
 773       for (uint i = 0; i < _max_num_queues; i++) {
 774         process_phase2(refs_lists[i], is_alive, keep_alive, complete_gc);
 775       }
 776     }
 777   }
 778 
 779   // Phase 3:
 780   // . Traverse the list and process referents as appropriate.
 781   {
 782     RefProcParPhaseTimeTracker tt(ReferenceProcessorPhaseTimes::RefPhase3, phase_times);
 783 
 784     if (mt_processing) {
 785       RefProcPhase3Task phase3(*this, refs_lists, clear_referent, true /*marks_oops_alive*/, phase_times);
 786       task_executor->execute(phase3);
 787     } else {
 788       for (uint i = 0; i < _max_num_queues; i++) {
 789         process_phase3(refs_lists[i], clear_referent,
 790                        is_alive, keep_alive, complete_gc);


 791       }
 792     }
 793   }
 794 }
 795 
 796 inline DiscoveredList* ReferenceProcessor::get_discovered_list(ReferenceType rt) {
 797   uint id = 0;
 798   // Determine the queue index to use for this object.
 799   if (_discovery_is_mt) {
 800     // During a multi-threaded discovery phase,
 801     // each thread saves to its "own" list.
 802     Thread* thr = Thread::current();
 803     id = thr->as_Worker_thread()->id();
 804   } else {
 805     // single-threaded discovery, we save in round-robin
 806     // fashion to each of the lists.
 807     if (_processing_is_mt) {
 808       id = next_id();
 809     }
 810   }


< prev index next >