hotspot/src/share/vm/gc/shared/referenceProcessor.cpp
changeset 40892 330a02d935ad
parent 37494 bf6caf8e99cb
child 43455 96560cffef4d
equal deleted inserted replaced
40891:8010999ff6d0 40892:330a02d935ad
   287                                           VoidClosure*       complete_gc) {
   287                                           VoidClosure*       complete_gc) {
   288   JNIHandles::weak_oops_do(is_alive, keep_alive);
   288   JNIHandles::weak_oops_do(is_alive, keep_alive);
   289   complete_gc->do_void();
   289   complete_gc->do_void();
   290 }
   290 }
   291 
   291 
   292 
   292 void ReferenceProcessor::enqueue_discovered_references(AbstractRefProcTaskExecutor* task_executor) {
   293 template <class T>
       
   294 bool enqueue_discovered_ref_helper(ReferenceProcessor* ref,
       
   295                                    AbstractRefProcTaskExecutor* task_executor) {
       
   296 
       
   297   // Remember old value of pending references list
       
   298   T* pending_list_addr = (T*)java_lang_ref_Reference::pending_list_addr();
       
   299   T old_pending_list_value = *pending_list_addr;
       
   300 
       
   301   // Enqueue references that are not made active again, and
   293   // Enqueue references that are not made active again, and
   302   // clear the decks for the next collection (cycle).
   294   // clear the decks for the next collection (cycle).
   303   ref->enqueue_discovered_reflists((HeapWord*)pending_list_addr, task_executor);
   295   enqueue_discovered_reflists(task_executor);
   304   // Do the post-barrier on pending_list_addr missed in
       
   305   // enqueue_discovered_reflist.
       
   306   oopDesc::bs()->write_ref_field(pending_list_addr, oopDesc::load_decode_heap_oop(pending_list_addr));
       
   307 
   296 
   308   // Stop treating discovered references specially.
   297   // Stop treating discovered references specially.
   309   ref->disable_discovery();
   298   disable_discovery();
   310 
   299 }
   311   // Return true if new pending references were added
   300 
   312   return old_pending_list_value != *pending_list_addr;
   301 void ReferenceProcessor::enqueue_discovered_reflist(DiscoveredList& refs_list) {
   313 }
       
   314 
       
   315 bool ReferenceProcessor::enqueue_discovered_references(AbstractRefProcTaskExecutor* task_executor) {
       
   316   if (UseCompressedOops) {
       
   317     return enqueue_discovered_ref_helper<narrowOop>(this, task_executor);
       
   318   } else {
       
   319     return enqueue_discovered_ref_helper<oop>(this, task_executor);
       
   320   }
       
   321 }
       
   322 
       
   323 void ReferenceProcessor::enqueue_discovered_reflist(DiscoveredList& refs_list,
       
   324                                                     HeapWord* pending_list_addr) {
       
   325   // Given a list of refs linked through the "discovered" field
   302   // Given a list of refs linked through the "discovered" field
   326   // (java.lang.ref.Reference.discovered), self-loop their "next" field
   303   // (java.lang.ref.Reference.discovered), self-loop their "next" field
   327   // thus distinguishing them from active References, then
   304   // thus distinguishing them from active References, then
   328   // prepend them to the pending list.
   305   // prepend them to the pending list.
   329   //
   306   //
   352     java_lang_ref_Reference::set_next_raw(obj, obj);
   329     java_lang_ref_Reference::set_next_raw(obj, obj);
   353     if (next_d != obj) {
   330     if (next_d != obj) {
   354       oopDesc::bs()->write_ref_field(java_lang_ref_Reference::discovered_addr(obj), next_d);
   331       oopDesc::bs()->write_ref_field(java_lang_ref_Reference::discovered_addr(obj), next_d);
   355     } else {
   332     } else {
   356       // This is the last object.
   333       // This is the last object.
   357       // Swap refs_list into pending_list_addr and
   334       // Swap refs_list into pending list and set obj's
   358       // set obj's discovered to what we read from pending_list_addr.
   335       // discovered to what we read from the pending list.
   359       oop old = oopDesc::atomic_exchange_oop(refs_list.head(), pending_list_addr);
   336       oop old = Universe::swap_reference_pending_list(refs_list.head());
   360       // Need post-barrier on pending_list_addr. See enqueue_discovered_ref_helper() above.
       
   361       java_lang_ref_Reference::set_discovered_raw(obj, old); // old may be NULL
   337       java_lang_ref_Reference::set_discovered_raw(obj, old); // old may be NULL
   362       oopDesc::bs()->write_ref_field(java_lang_ref_Reference::discovered_addr(obj), old);
   338       oopDesc::bs()->write_ref_field(java_lang_ref_Reference::discovered_addr(obj), old);
   363     }
   339     }
   364   }
   340   }
   365 }
   341 }
   367 // Parallel enqueue task
   343 // Parallel enqueue task
   368 class RefProcEnqueueTask: public AbstractRefProcTaskExecutor::EnqueueTask {
   344 class RefProcEnqueueTask: public AbstractRefProcTaskExecutor::EnqueueTask {
   369 public:
   345 public:
   370   RefProcEnqueueTask(ReferenceProcessor& ref_processor,
   346   RefProcEnqueueTask(ReferenceProcessor& ref_processor,
   371                      DiscoveredList      discovered_refs[],
   347                      DiscoveredList      discovered_refs[],
   372                      HeapWord*           pending_list_addr,
       
   373                      int                 n_queues)
   348                      int                 n_queues)
   374     : EnqueueTask(ref_processor, discovered_refs,
   349     : EnqueueTask(ref_processor, discovered_refs, n_queues)
   375                   pending_list_addr, n_queues)
       
   376   { }
   350   { }
   377 
   351 
   378   virtual void work(unsigned int work_id) {
   352   virtual void work(unsigned int work_id) {
   379     assert(work_id < (unsigned int)_ref_processor.max_num_q(), "Index out-of-bounds");
   353     assert(work_id < (unsigned int)_ref_processor.max_num_q(), "Index out-of-bounds");
   380     // Simplest first cut: static partitioning.
   354     // Simplest first cut: static partitioning.
   385     // allocated and are indexed into.
   359     // allocated and are indexed into.
   386     assert(_n_queues == (int) _ref_processor.max_num_q(), "Different number not expected");
   360     assert(_n_queues == (int) _ref_processor.max_num_q(), "Different number not expected");
   387     for (int j = 0;
   361     for (int j = 0;
   388          j < ReferenceProcessor::number_of_subclasses_of_ref();
   362          j < ReferenceProcessor::number_of_subclasses_of_ref();
   389          j++, index += _n_queues) {
   363          j++, index += _n_queues) {
   390       _ref_processor.enqueue_discovered_reflist(
   364       _ref_processor.enqueue_discovered_reflist(_refs_lists[index]);
   391         _refs_lists[index], _pending_list_addr);
       
   392       _refs_lists[index].set_head(NULL);
   365       _refs_lists[index].set_head(NULL);
   393       _refs_lists[index].set_length(0);
   366       _refs_lists[index].set_length(0);
   394     }
   367     }
   395   }
   368   }
   396 };
   369 };
   397 
   370 
   398 // Enqueue references that are not made active again
   371 // Enqueue references that are not made active again
   399 void ReferenceProcessor::enqueue_discovered_reflists(HeapWord* pending_list_addr,
   372 void ReferenceProcessor::enqueue_discovered_reflists(AbstractRefProcTaskExecutor* task_executor) {
   400   AbstractRefProcTaskExecutor* task_executor) {
       
   401   if (_processing_is_mt && task_executor != NULL) {
   373   if (_processing_is_mt && task_executor != NULL) {
   402     // Parallel code
   374     // Parallel code
   403     RefProcEnqueueTask tsk(*this, _discovered_refs,
   375     RefProcEnqueueTask tsk(*this, _discovered_refs, _max_num_q);
   404                            pending_list_addr, _max_num_q);
       
   405     task_executor->execute(tsk);
   376     task_executor->execute(tsk);
   406   } else {
   377   } else {
   407     // Serial code: call the parent class's implementation
   378     // Serial code: call the parent class's implementation
   408     for (uint i = 0; i < _max_num_q * number_of_subclasses_of_ref(); i++) {
   379     for (uint i = 0; i < _max_num_q * number_of_subclasses_of_ref(); i++) {
   409       enqueue_discovered_reflist(_discovered_refs[i], pending_list_addr);
   380       enqueue_discovered_reflist(_discovered_refs[i]);
   410       _discovered_refs[i].set_head(NULL);
   381       _discovered_refs[i].set_head(NULL);
   411       _discovered_refs[i].set_length(0);
   382       _discovered_refs[i].set_length(0);
   412     }
   383     }
   413   }
   384   }
   414 }
   385 }