hotspot/src/share/vm/memory/referenceProcessor.cpp
changeset 6759 67b1a69ef5aa
parent 5547 f4b087cbb361
child 7397 5b173b4ca846
equal deleted inserted replaced
6451:516540f1f076 6759:67b1a69ef5aa
     1 /*
     1 /*
     2  * Copyright (c) 2001, 2009, Oracle and/or its affiliates. All rights reserved.
     2  * Copyright (c) 2001, 2010, Oracle and/or its affiliates. All rights reserved.
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     4  *
     4  *
     5  * This code is free software; you can redistribute it and/or modify it
     5  * This code is free software; you can redistribute it and/or modify it
     6  * under the terms of the GNU General Public License version 2 only, as
     6  * under the terms of the GNU General Public License version 2 only, as
     7  * published by the Free Software Foundation.
     7  * published by the Free Software Foundation.
   135 {
   135 {
   136   _span = span;
   136   _span = span;
   137   _discovery_is_atomic = atomic_discovery;
   137   _discovery_is_atomic = atomic_discovery;
   138   _discovery_is_mt     = mt_discovery;
   138   _discovery_is_mt     = mt_discovery;
   139   _num_q               = mt_degree;
   139   _num_q               = mt_degree;
   140   _discoveredSoftRefs  = NEW_C_HEAP_ARRAY(DiscoveredList, _num_q * subclasses_of_ref);
   140   _max_num_q           = mt_degree;
       
   141   _discoveredSoftRefs  = NEW_C_HEAP_ARRAY(DiscoveredList, _max_num_q * subclasses_of_ref);
   141   if (_discoveredSoftRefs == NULL) {
   142   if (_discoveredSoftRefs == NULL) {
   142     vm_exit_during_initialization("Could not allocated RefProc Array");
   143     vm_exit_during_initialization("Could not allocated RefProc Array");
   143   }
   144   }
   144   _discoveredWeakRefs    = &_discoveredSoftRefs[_num_q];
   145   _discoveredWeakRefs    = &_discoveredSoftRefs[_max_num_q];
   145   _discoveredFinalRefs   = &_discoveredWeakRefs[_num_q];
   146   _discoveredFinalRefs   = &_discoveredWeakRefs[_max_num_q];
   146   _discoveredPhantomRefs = &_discoveredFinalRefs[_num_q];
   147   _discoveredPhantomRefs = &_discoveredFinalRefs[_max_num_q];
   147   assert(sentinel_ref() != NULL, "_sentinelRef is NULL");
   148   assert(sentinel_ref() != NULL, "_sentinelRef is NULL");
   148   // Initialized all entries to _sentinelRef
   149   // Initialized all entries to _sentinelRef
   149   for (int i = 0; i < _num_q * subclasses_of_ref; i++) {
   150   for (int i = 0; i < _max_num_q * subclasses_of_ref; i++) {
   150         _discoveredSoftRefs[i].set_head(sentinel_ref());
   151         _discoveredSoftRefs[i].set_head(sentinel_ref());
   151     _discoveredSoftRefs[i].set_length(0);
   152     _discoveredSoftRefs[i].set_length(0);
   152   }
   153   }
   153   // If we do barreirs, cache a copy of the barrier set.
   154   // If we do barreirs, cache a copy of the barrier set.
   154   if (discovered_list_needs_barrier) {
   155   if (discovered_list_needs_barrier) {
   157 }
   158 }
   158 
   159 
   159 #ifndef PRODUCT
   160 #ifndef PRODUCT
   160 void ReferenceProcessor::verify_no_references_recorded() {
   161 void ReferenceProcessor::verify_no_references_recorded() {
   161   guarantee(!_discovering_refs, "Discovering refs?");
   162   guarantee(!_discovering_refs, "Discovering refs?");
   162   for (int i = 0; i < _num_q * subclasses_of_ref; i++) {
   163   for (int i = 0; i < _max_num_q * subclasses_of_ref; i++) {
   163     guarantee(_discoveredSoftRefs[i].empty(),
   164     guarantee(_discoveredSoftRefs[i].empty(),
   164               "Found non-empty discovered list");
   165               "Found non-empty discovered list");
   165   }
   166   }
   166 }
   167 }
   167 #endif
   168 #endif
   168 
   169 
   169 void ReferenceProcessor::weak_oops_do(OopClosure* f) {
   170 void ReferenceProcessor::weak_oops_do(OopClosure* f) {
   170   for (int i = 0; i < _num_q * subclasses_of_ref; i++) {
   171   // Should this instead be
       
   172   // for (int i = 0; i < subclasses_of_ref; i++_ {
       
   173   //   for (int j = 0; j < _num_q; j++) {
       
   174   //     int index = i * _max_num_q + j;
       
   175   for (int i = 0; i < _max_num_q * subclasses_of_ref; i++) {
   171     if (UseCompressedOops) {
   176     if (UseCompressedOops) {
   172       f->do_oop((narrowOop*)_discoveredSoftRefs[i].adr_head());
   177       f->do_oop((narrowOop*)_discoveredSoftRefs[i].adr_head());
   173     } else {
   178     } else {
   174       f->do_oop((oop*)_discoveredSoftRefs[i].adr_head());
   179       f->do_oop((oop*)_discoveredSoftRefs[i].adr_head());
   175     }
   180     }
   393 
   398 
   394   virtual void work(unsigned int work_id) {
   399   virtual void work(unsigned int work_id) {
   395     assert(work_id < (unsigned int)_ref_processor.num_q(), "Index out-of-bounds");
   400     assert(work_id < (unsigned int)_ref_processor.num_q(), "Index out-of-bounds");
   396     // Simplest first cut: static partitioning.
   401     // Simplest first cut: static partitioning.
   397     int index = work_id;
   402     int index = work_id;
   398     for (int j = 0; j < subclasses_of_ref; j++, index += _n_queues) {
   403     // The increment on "index" must correspond to the maximum number of queues
       
   404     // (n_queues) with which that ReferenceProcessor was created.  That
       
   405     // is because of the "clever" way the discovered references lists were
       
   406     // allocated and are indexed into.  That number is ParallelGCThreads
       
   407     // currently.  Assert that.
       
   408     assert(_n_queues == (int) ParallelGCThreads, "Different number not expected");
       
   409     for (int j = 0;
       
   410          j < subclasses_of_ref;
       
   411          j++, index += _n_queues) {
   399       _ref_processor.enqueue_discovered_reflist(
   412       _ref_processor.enqueue_discovered_reflist(
   400         _refs_lists[index], _pending_list_addr);
   413         _refs_lists[index], _pending_list_addr);
   401       _refs_lists[index].set_head(_sentinel_ref);
   414       _refs_lists[index].set_head(_sentinel_ref);
   402       _refs_lists[index].set_length(0);
   415       _refs_lists[index].set_length(0);
   403     }
   416     }
   408 void ReferenceProcessor::enqueue_discovered_reflists(HeapWord* pending_list_addr,
   421 void ReferenceProcessor::enqueue_discovered_reflists(HeapWord* pending_list_addr,
   409   AbstractRefProcTaskExecutor* task_executor) {
   422   AbstractRefProcTaskExecutor* task_executor) {
   410   if (_processing_is_mt && task_executor != NULL) {
   423   if (_processing_is_mt && task_executor != NULL) {
   411     // Parallel code
   424     // Parallel code
   412     RefProcEnqueueTask tsk(*this, _discoveredSoftRefs,
   425     RefProcEnqueueTask tsk(*this, _discoveredSoftRefs,
   413                            pending_list_addr, sentinel_ref(), _num_q);
   426                            pending_list_addr, sentinel_ref(), _max_num_q);
   414     task_executor->execute(tsk);
   427     task_executor->execute(tsk);
   415   } else {
   428   } else {
   416     // Serial code: call the parent class's implementation
   429     // Serial code: call the parent class's implementation
   417     for (int i = 0; i < _num_q * subclasses_of_ref; i++) {
   430     for (int i = 0; i < _max_num_q * subclasses_of_ref; i++) {
   418       enqueue_discovered_reflist(_discoveredSoftRefs[i], pending_list_addr);
   431       enqueue_discovered_reflist(_discoveredSoftRefs[i], pending_list_addr);
   419       _discoveredSoftRefs[i].set_head(sentinel_ref());
   432       _discoveredSoftRefs[i].set_head(sentinel_ref());
   420       _discoveredSoftRefs[i].set_length(0);
   433       _discoveredSoftRefs[i].set_length(0);
   421     }
   434     }
   422   }
   435   }
   612   }
   625   }
   613   // Close the reachable set
   626   // Close the reachable set
   614   complete_gc->do_void();
   627   complete_gc->do_void();
   615   NOT_PRODUCT(
   628   NOT_PRODUCT(
   616     if (PrintGCDetails && TraceReferenceGC) {
   629     if (PrintGCDetails && TraceReferenceGC) {
   617       gclog_or_tty->print(" Dropped %d dead Refs out of %d "
   630       gclog_or_tty->print_cr(" Dropped %d dead Refs out of %d "
   618         "discovered Refs by policy ", iter.removed(), iter.processed());
   631         "discovered Refs by policy  list " INTPTR_FORMAT,
       
   632         iter.removed(), iter.processed(), (address)refs_list.head());
   619     }
   633     }
   620   )
   634   )
   621 }
   635 }
   622 
   636 
   623 // Traverse the list and remove any Refs that are not active, or
   637 // Traverse the list and remove any Refs that are not active, or
   649       iter.next();
   663       iter.next();
   650     }
   664     }
   651   }
   665   }
   652   NOT_PRODUCT(
   666   NOT_PRODUCT(
   653     if (PrintGCDetails && TraceReferenceGC) {
   667     if (PrintGCDetails && TraceReferenceGC) {
   654       gclog_or_tty->print(" Dropped %d active Refs out of %d "
   668       gclog_or_tty->print_cr(" Dropped %d active Refs out of %d "
   655         "Refs in discovered list ", iter.removed(), iter.processed());
   669         "Refs in discovered list " INTPTR_FORMAT,
       
   670         iter.removed(), iter.processed(), (address)refs_list.head());
   656     }
   671     }
   657   )
   672   )
   658 }
   673 }
   659 
   674 
   660 void
   675 void
   687   }
   702   }
   688   // Now close the newly reachable set
   703   // Now close the newly reachable set
   689   complete_gc->do_void();
   704   complete_gc->do_void();
   690   NOT_PRODUCT(
   705   NOT_PRODUCT(
   691     if (PrintGCDetails && TraceReferenceGC) {
   706     if (PrintGCDetails && TraceReferenceGC) {
   692       gclog_or_tty->print(" Dropped %d active Refs out of %d "
   707       gclog_or_tty->print_cr(" Dropped %d active Refs out of %d "
   693         "Refs in discovered list ", iter.removed(), iter.processed());
   708         "Refs in discovered list " INTPTR_FORMAT,
       
   709         iter.removed(), iter.processed(), (address)refs_list.head());
   694     }
   710     }
   695   )
   711   )
   696 }
   712 }
   697 
   713 
   698 // Traverse the list and process the referents, by either
   714 // Traverse the list and process the referents, by either
   702 ReferenceProcessor::process_phase3(DiscoveredList&    refs_list,
   718 ReferenceProcessor::process_phase3(DiscoveredList&    refs_list,
   703                                    bool               clear_referent,
   719                                    bool               clear_referent,
   704                                    BoolObjectClosure* is_alive,
   720                                    BoolObjectClosure* is_alive,
   705                                    OopClosure*        keep_alive,
   721                                    OopClosure*        keep_alive,
   706                                    VoidClosure*       complete_gc) {
   722                                    VoidClosure*       complete_gc) {
       
   723   ResourceMark rm;
   707   DiscoveredListIterator iter(refs_list, keep_alive, is_alive);
   724   DiscoveredListIterator iter(refs_list, keep_alive, is_alive);
   708   while (iter.has_next()) {
   725   while (iter.has_next()) {
   709     iter.update_discovered();
   726     iter.update_discovered();
   710     iter.load_ptrs(DEBUG_ONLY(false /* allow_null_referent */));
   727     iter.load_ptrs(DEBUG_ONLY(false /* allow_null_referent */));
   711     if (clear_referent) {
   728     if (clear_referent) {
   741   refs_list.set_length(0);
   758   refs_list.set_length(0);
   742 }
   759 }
   743 
   760 
   744 void ReferenceProcessor::abandon_partial_discovery() {
   761 void ReferenceProcessor::abandon_partial_discovery() {
   745   // loop over the lists
   762   // loop over the lists
   746   for (int i = 0; i < _num_q * subclasses_of_ref; i++) {
   763   for (int i = 0; i < _max_num_q * subclasses_of_ref; i++) {
   747     if (TraceReferenceGC && PrintGCDetails && ((i % _num_q) == 0)) {
   764     if (TraceReferenceGC && PrintGCDetails && ((i % _max_num_q) == 0)) {
   748       gclog_or_tty->print_cr(
   765       gclog_or_tty->print_cr(
   749         "\nAbandoning %s discovered list",
   766         "\nAbandoning %s discovered list",
   750         list_name(i));
   767         list_name(i));
   751     }
   768     }
   752     abandon_partial_discovered_list(_discoveredSoftRefs[i]);
   769     abandon_partial_discovered_list(_discoveredSoftRefs[i]);
   764   { }
   781   { }
   765   virtual void work(unsigned int i, BoolObjectClosure& is_alive,
   782   virtual void work(unsigned int i, BoolObjectClosure& is_alive,
   766                     OopClosure& keep_alive,
   783                     OopClosure& keep_alive,
   767                     VoidClosure& complete_gc)
   784                     VoidClosure& complete_gc)
   768   {
   785   {
   769     _ref_processor.process_phase1(_refs_lists[i], _policy,
   786     Thread* thr = Thread::current();
       
   787     int refs_list_index = ((WorkerThread*)thr)->id();
       
   788     _ref_processor.process_phase1(_refs_lists[refs_list_index], _policy,
   770                                   &is_alive, &keep_alive, &complete_gc);
   789                                   &is_alive, &keep_alive, &complete_gc);
   771   }
   790   }
   772 private:
   791 private:
   773   ReferencePolicy* _policy;
   792   ReferencePolicy* _policy;
   774 };
   793 };
   800   { }
   819   { }
   801   virtual void work(unsigned int i, BoolObjectClosure& is_alive,
   820   virtual void work(unsigned int i, BoolObjectClosure& is_alive,
   802                     OopClosure& keep_alive,
   821                     OopClosure& keep_alive,
   803                     VoidClosure& complete_gc)
   822                     VoidClosure& complete_gc)
   804   {
   823   {
       
   824     // Don't use "refs_list_index" calculated in this way because
       
   825     // balance_queues() has moved the Ref's into the first n queues.
       
   826     // Thread* thr = Thread::current();
       
   827     // int refs_list_index = ((WorkerThread*)thr)->id();
       
   828     // _ref_processor.process_phase3(_refs_lists[refs_list_index], _clear_referent,
   805     _ref_processor.process_phase3(_refs_lists[i], _clear_referent,
   829     _ref_processor.process_phase3(_refs_lists[i], _clear_referent,
   806                                   &is_alive, &keep_alive, &complete_gc);
   830                                   &is_alive, &keep_alive, &complete_gc);
   807   }
   831   }
   808 private:
   832 private:
   809   bool _clear_referent;
   833   bool _clear_referent;
   810 };
   834 };
   811 
   835 
   812 // Balances reference queues.
   836 // Balances reference queues.
       
   837 // Move entries from all queues[0, 1, ..., _max_num_q-1] to
       
   838 // queues[0, 1, ..., _num_q-1] because only the first _num_q
       
   839 // corresponding to the active workers will be processed.
   813 void ReferenceProcessor::balance_queues(DiscoveredList ref_lists[])
   840 void ReferenceProcessor::balance_queues(DiscoveredList ref_lists[])
   814 {
   841 {
   815   // calculate total length
   842   // calculate total length
   816   size_t total_refs = 0;
   843   size_t total_refs = 0;
   817   for (int i = 0; i < _num_q; ++i) {
   844   if (TraceReferenceGC && PrintGCDetails) {
       
   845     gclog_or_tty->print_cr("\nBalance ref_lists ");
       
   846   }
       
   847 
       
   848   for (int i = 0; i < _max_num_q; ++i) {
   818     total_refs += ref_lists[i].length();
   849     total_refs += ref_lists[i].length();
       
   850     if (TraceReferenceGC && PrintGCDetails) {
       
   851       gclog_or_tty->print("%d ", ref_lists[i].length());
       
   852     }
       
   853   }
       
   854   if (TraceReferenceGC && PrintGCDetails) {
       
   855     gclog_or_tty->print_cr(" = %d", total_refs);
   819   }
   856   }
   820   size_t avg_refs = total_refs / _num_q + 1;
   857   size_t avg_refs = total_refs / _num_q + 1;
   821   int to_idx = 0;
   858   int to_idx = 0;
   822   for (int from_idx = 0; from_idx < _num_q; from_idx++) {
   859   for (int from_idx = 0; from_idx < _max_num_q; from_idx++) {
   823     while (ref_lists[from_idx].length() > avg_refs) {
   860     bool move_all = false;
       
   861     if (from_idx >= _num_q) {
       
   862       move_all = ref_lists[from_idx].length() > 0;
       
   863     }
       
   864     while ((ref_lists[from_idx].length() > avg_refs) ||
       
   865            move_all) {
   824       assert(to_idx < _num_q, "Sanity Check!");
   866       assert(to_idx < _num_q, "Sanity Check!");
   825       if (ref_lists[to_idx].length() < avg_refs) {
   867       if (ref_lists[to_idx].length() < avg_refs) {
   826         // move superfluous refs
   868         // move superfluous refs
   827         size_t refs_to_move =
   869         size_t refs_to_move;
   828           MIN2(ref_lists[from_idx].length() - avg_refs,
   870         // Move all the Ref's if the from queue will not be processed.
   829                avg_refs - ref_lists[to_idx].length());
   871         if (move_all) {
       
   872           refs_to_move = MIN2(ref_lists[from_idx].length(),
       
   873                               avg_refs - ref_lists[to_idx].length());
       
   874         } else {
       
   875           refs_to_move = MIN2(ref_lists[from_idx].length() - avg_refs,
       
   876                               avg_refs - ref_lists[to_idx].length());
       
   877         }
   830         oop move_head = ref_lists[from_idx].head();
   878         oop move_head = ref_lists[from_idx].head();
   831         oop move_tail = move_head;
   879         oop move_tail = move_head;
   832         oop new_head  = move_head;
   880         oop new_head  = move_head;
   833         // find an element to split the list on
   881         // find an element to split the list on
   834         for (size_t j = 0; j < refs_to_move; ++j) {
   882         for (size_t j = 0; j < refs_to_move; ++j) {
   838         java_lang_ref_Reference::set_discovered(move_tail, ref_lists[to_idx].head());
   886         java_lang_ref_Reference::set_discovered(move_tail, ref_lists[to_idx].head());
   839         ref_lists[to_idx].set_head(move_head);
   887         ref_lists[to_idx].set_head(move_head);
   840         ref_lists[to_idx].inc_length(refs_to_move);
   888         ref_lists[to_idx].inc_length(refs_to_move);
   841         ref_lists[from_idx].set_head(new_head);
   889         ref_lists[from_idx].set_head(new_head);
   842         ref_lists[from_idx].dec_length(refs_to_move);
   890         ref_lists[from_idx].dec_length(refs_to_move);
       
   891         if (ref_lists[from_idx].length() == 0) {
       
   892           break;
       
   893         }
   843       } else {
   894       } else {
   844         ++to_idx;
   895         to_idx = (to_idx + 1) % _num_q;
   845       }
   896       }
   846     }
   897     }
   847   }
   898   }
       
   899 #ifdef ASSERT
       
   900   size_t balanced_total_refs = 0;
       
   901   for (int i = 0; i < _max_num_q; ++i) {
       
   902     balanced_total_refs += ref_lists[i].length();
       
   903     if (TraceReferenceGC && PrintGCDetails) {
       
   904       gclog_or_tty->print("%d ", ref_lists[i].length());
       
   905     }
       
   906   }
       
   907   if (TraceReferenceGC && PrintGCDetails) {
       
   908     gclog_or_tty->print_cr(" = %d", balanced_total_refs);
       
   909     gclog_or_tty->flush();
       
   910   }
       
   911   assert(total_refs == balanced_total_refs, "Balancing was incomplete");
       
   912 #endif
       
   913 }
       
   914 
       
   915 void ReferenceProcessor::balance_all_queues() {
       
   916   balance_queues(_discoveredSoftRefs);
       
   917   balance_queues(_discoveredWeakRefs);
       
   918   balance_queues(_discoveredFinalRefs);
       
   919   balance_queues(_discoveredPhantomRefs);
   848 }
   920 }
   849 
   921 
   850 void
   922 void
   851 ReferenceProcessor::process_discovered_reflist(
   923 ReferenceProcessor::process_discovered_reflist(
   852   DiscoveredList               refs_lists[],
   924   DiscoveredList               refs_lists[],
   855   BoolObjectClosure*           is_alive,
   927   BoolObjectClosure*           is_alive,
   856   OopClosure*                  keep_alive,
   928   OopClosure*                  keep_alive,
   857   VoidClosure*                 complete_gc,
   929   VoidClosure*                 complete_gc,
   858   AbstractRefProcTaskExecutor* task_executor)
   930   AbstractRefProcTaskExecutor* task_executor)
   859 {
   931 {
   860   bool mt = task_executor != NULL && _processing_is_mt;
   932   bool mt_processing = task_executor != NULL && _processing_is_mt;
   861   if (mt && ParallelRefProcBalancingEnabled) {
   933   // If discovery used MT and a dynamic number of GC threads, then
       
   934   // the queues must be balanced for correctness if fewer than the
       
   935   // maximum number of queues were used.  The number of queue used
       
   936   // during discovery may be different than the number to be used
       
   937   // for processing so don't depend of _num_q < _max_num_q as part
       
   938   // of the test.
       
   939   bool must_balance = _discovery_is_mt;
       
   940 
       
   941   if ((mt_processing && ParallelRefProcBalancingEnabled) ||
       
   942       must_balance) {
   862     balance_queues(refs_lists);
   943     balance_queues(refs_lists);
   863   }
   944   }
   864   if (PrintReferenceGC && PrintGCDetails) {
   945   if (PrintReferenceGC && PrintGCDetails) {
   865     size_t total = 0;
   946     size_t total = 0;
   866     for (int i = 0; i < _num_q; ++i) {
   947     for (int i = 0; i < _num_q; ++i) {
   873   // . Traverse the list and remove any SoftReferences whose
   954   // . Traverse the list and remove any SoftReferences whose
   874   //   referents are not alive, but that should be kept alive for
   955   //   referents are not alive, but that should be kept alive for
   875   //   policy reasons. Keep alive the transitive closure of all
   956   //   policy reasons. Keep alive the transitive closure of all
   876   //   such referents.
   957   //   such referents.
   877   if (policy != NULL) {
   958   if (policy != NULL) {
   878     if (mt) {
   959     if (mt_processing) {
   879       RefProcPhase1Task phase1(*this, refs_lists, policy, true /*marks_oops_alive*/);
   960       RefProcPhase1Task phase1(*this, refs_lists, policy, true /*marks_oops_alive*/);
   880       task_executor->execute(phase1);
   961       task_executor->execute(phase1);
   881     } else {
   962     } else {
   882       for (int i = 0; i < _num_q; i++) {
   963       for (int i = 0; i < _num_q; i++) {
   883         process_phase1(refs_lists[i], policy,
   964         process_phase1(refs_lists[i], policy,
   889            "Policy must be specified for soft references.");
   970            "Policy must be specified for soft references.");
   890   }
   971   }
   891 
   972 
   892   // Phase 2:
   973   // Phase 2:
   893   // . Traverse the list and remove any refs whose referents are alive.
   974   // . Traverse the list and remove any refs whose referents are alive.
   894   if (mt) {
   975   if (mt_processing) {
   895     RefProcPhase2Task phase2(*this, refs_lists, !discovery_is_atomic() /*marks_oops_alive*/);
   976     RefProcPhase2Task phase2(*this, refs_lists, !discovery_is_atomic() /*marks_oops_alive*/);
   896     task_executor->execute(phase2);
   977     task_executor->execute(phase2);
   897   } else {
   978   } else {
   898     for (int i = 0; i < _num_q; i++) {
   979     for (int i = 0; i < _num_q; i++) {
   899       process_phase2(refs_lists[i], is_alive, keep_alive, complete_gc);
   980       process_phase2(refs_lists[i], is_alive, keep_alive, complete_gc);
   900     }
   981     }
   901   }
   982   }
   902 
   983 
   903   // Phase 3:
   984   // Phase 3:
   904   // . Traverse the list and process referents as appropriate.
   985   // . Traverse the list and process referents as appropriate.
   905   if (mt) {
   986   if (mt_processing) {
   906     RefProcPhase3Task phase3(*this, refs_lists, clear_referent, true /*marks_oops_alive*/);
   987     RefProcPhase3Task phase3(*this, refs_lists, clear_referent, true /*marks_oops_alive*/);
   907     task_executor->execute(phase3);
   988     task_executor->execute(phase3);
   908   } else {
   989   } else {
   909     for (int i = 0; i < _num_q; i++) {
   990     for (int i = 0; i < _num_q; i++) {
   910       process_phase3(refs_lists[i], clear_referent,
   991       process_phase3(refs_lists[i], clear_referent,
   913   }
   994   }
   914 }
   995 }
   915 
   996 
   916 void ReferenceProcessor::clean_up_discovered_references() {
   997 void ReferenceProcessor::clean_up_discovered_references() {
   917   // loop over the lists
   998   // loop over the lists
   918   for (int i = 0; i < _num_q * subclasses_of_ref; i++) {
   999   // Should this instead be
       
  1000   // for (int i = 0; i < subclasses_of_ref; i++_ {
       
  1001   //   for (int j = 0; j < _num_q; j++) {
       
  1002   //     int index = i * _max_num_q + j;
       
  1003   for (int i = 0; i < _max_num_q * subclasses_of_ref; i++) {
   919     if (TraceReferenceGC && PrintGCDetails && ((i % _num_q) == 0)) {
  1004     if (TraceReferenceGC && PrintGCDetails && ((i % _num_q) == 0)) {
   920       gclog_or_tty->print_cr(
  1005       gclog_or_tty->print_cr(
   921         "\nScrubbing %s discovered list of Null referents",
  1006         "\nScrubbing %s discovered list of Null referents",
   922         list_name(i));
  1007         list_name(i));
   923     }
  1008     }
   974     // fashion to each of the lists.
  1059     // fashion to each of the lists.
   975     if (_processing_is_mt) {
  1060     if (_processing_is_mt) {
   976       id = next_id();
  1061       id = next_id();
   977     }
  1062     }
   978   }
  1063   }
   979   assert(0 <= id && id < _num_q, "Id is out-of-bounds (call Freud?)");
  1064   assert(0 <= id && id < _max_num_q, "Id is out-of-bounds (call Freud?)");
   980 
  1065 
   981   // Get the discovered queue to which we will add
  1066   // Get the discovered queue to which we will add
   982   DiscoveredList* list = NULL;
  1067   DiscoveredList* list = NULL;
   983   switch (rt) {
  1068   switch (rt) {
   984     case REF_OTHER:
  1069     case REF_OTHER:
   998       break;
  1083       break;
   999     case REF_NONE:
  1084     case REF_NONE:
  1000       // we should not reach here if we are an instanceRefKlass
  1085       // we should not reach here if we are an instanceRefKlass
  1001     default:
  1086     default:
  1002       ShouldNotReachHere();
  1087       ShouldNotReachHere();
       
  1088   }
       
  1089   if (TraceReferenceGC && PrintGCDetails) {
       
  1090     gclog_or_tty->print_cr("Thread %d gets list " INTPTR_FORMAT,
       
  1091       id, list);
  1003   }
  1092   }
  1004   return list;
  1093   return list;
  1005 }
  1094 }
  1006 
  1095 
  1007 inline void
  1096 inline void
  1241 #endif
  1330 #endif
  1242   // Soft references
  1331   // Soft references
  1243   {
  1332   {
  1244     TraceTime tt("Preclean SoftReferences", PrintGCDetails && PrintReferenceGC,
  1333     TraceTime tt("Preclean SoftReferences", PrintGCDetails && PrintReferenceGC,
  1245               false, gclog_or_tty);
  1334               false, gclog_or_tty);
  1246     for (int i = 0; i < _num_q; i++) {
  1335     for (int i = 0; i < _max_num_q; i++) {
  1247       if (yield->should_return()) {
  1336       if (yield->should_return()) {
  1248         return;
  1337         return;
  1249       }
  1338       }
  1250       preclean_discovered_reflist(_discoveredSoftRefs[i], is_alive,
  1339       preclean_discovered_reflist(_discoveredSoftRefs[i], is_alive,
  1251                                   keep_alive, complete_gc, yield);
  1340                                   keep_alive, complete_gc, yield);
  1338   // Close the reachable set
  1427   // Close the reachable set
  1339   complete_gc->do_void();
  1428   complete_gc->do_void();
  1340 
  1429 
  1341   NOT_PRODUCT(
  1430   NOT_PRODUCT(
  1342     if (PrintGCDetails && PrintReferenceGC) {
  1431     if (PrintGCDetails && PrintReferenceGC) {
  1343       gclog_or_tty->print(" Dropped %d Refs out of %d "
  1432       gclog_or_tty->print_cr(" Dropped %d Refs out of %d "
  1344         "Refs in discovered list ", iter.removed(), iter.processed());
  1433         "Refs in discovered list " INTPTR_FORMAT,
       
  1434         iter.removed(), iter.processed(), (address)refs_list.head());
  1345     }
  1435     }
  1346   )
  1436   )
  1347 }
  1437 }
  1348 
  1438 
  1349 const char* ReferenceProcessor::list_name(int i) {
  1439 const char* ReferenceProcessor::list_name(int i) {
  1350    assert(i >= 0 && i <= _num_q * subclasses_of_ref, "Out of bounds index");
  1440    assert(i >= 0 && i <= _max_num_q * subclasses_of_ref, "Out of bounds index");
  1351    int j = i / _num_q;
  1441    int j = i / _max_num_q;
  1352    switch (j) {
  1442    switch (j) {
  1353      case 0: return "SoftRef";
  1443      case 0: return "SoftRef";
  1354      case 1: return "WeakRef";
  1444      case 1: return "WeakRef";
  1355      case 2: return "FinalRef";
  1445      case 2: return "FinalRef";
  1356      case 3: return "PhantomRef";
  1446      case 3: return "PhantomRef";
  1370 }
  1460 }
  1371 
  1461 
  1372 #ifndef PRODUCT
  1462 #ifndef PRODUCT
  1373 void ReferenceProcessor::clear_discovered_references() {
  1463 void ReferenceProcessor::clear_discovered_references() {
  1374   guarantee(!_discovering_refs, "Discovering refs?");
  1464   guarantee(!_discovering_refs, "Discovering refs?");
  1375   for (int i = 0; i < _num_q * subclasses_of_ref; i++) {
  1465   for (int i = 0; i < _max_num_q * subclasses_of_ref; i++) {
  1376     oop obj = _discoveredSoftRefs[i].head();
  1466     oop obj = _discoveredSoftRefs[i].head();
  1377     while (obj != sentinel_ref()) {
  1467     while (obj != sentinel_ref()) {
  1378       oop next = java_lang_ref_Reference::discovered(obj);
  1468       oop next = java_lang_ref_Reference::discovered(obj);
  1379       java_lang_ref_Reference::set_discovered(obj, (oop) NULL);
  1469       java_lang_ref_Reference::set_discovered(obj, (oop) NULL);
  1380       obj = next;
  1470       obj = next;