src/share/vm/memory/referenceProcessor.cpp

changeset 887
00b023ae2d78
parent 791
1ee8caae33af
child 888
c96030fff130
     1.1 --- a/src/share/vm/memory/referenceProcessor.cpp	Wed Nov 19 14:20:51 2008 -0800
     1.2 +++ b/src/share/vm/memory/referenceProcessor.cpp	Thu Nov 20 12:27:41 2008 -0800
     1.3 @@ -47,7 +47,9 @@
     1.4    }
     1.5    bool   empty() const          { return head() == ReferenceProcessor::sentinel_ref(); }
     1.6    size_t length()               { return _len; }
     1.7 -  void   set_length(size_t len) { _len = len; }
     1.8 +  void   set_length(size_t len) { _len = len;  }
     1.9 +  void   inc_length(size_t inc) { _len += inc; assert(_len > 0, "Error"); }
    1.10 +  void   dec_length(size_t dec) { _len -= dec; }
    1.11  private:
    1.12    // Set value depending on UseCompressedOops. This could be a template class
    1.13    // but then we have to fix all the instantiations and declarations that use this class.
    1.14 @@ -436,13 +438,13 @@
    1.15    // The "allow_null_referent" argument tells us to allow for the possibility
    1.16    // of a NULL referent in the discovered Reference object. This typically
    1.17    // happens in the case of concurrent collectors that may have done the
    1.18 -  // discovery concurrently or interleaved with mutator execution.
    1.19 +  // discovery concurrently, or interleaved, with mutator execution.
    1.20    inline void load_ptrs(DEBUG_ONLY(bool allow_null_referent));
    1.21  
    1.22    // Move to the next discovered reference.
    1.23    inline void next();
    1.24  
    1.25 -  // Remove the current reference from the list and move to the next.
    1.26 +  // Remove the current reference from the list
    1.27    inline void remove();
    1.28  
    1.29    // Make the Reference object active again.
    1.30 @@ -476,7 +478,6 @@
    1.31    inline size_t removed() const   { return _removed; }
    1.32    )
    1.33  
    1.34 -private:
    1.35    inline void move_to_next();
    1.36  
    1.37  private:
    1.38 @@ -553,7 +554,7 @@
    1.39      oopDesc::store_heap_oop((oop*)_prev_next, _next);
    1.40    }
    1.41    NOT_PRODUCT(_removed++);
    1.42 -  move_to_next();
    1.43 +  _refs_list.dec_length(1);
    1.44  }
    1.45  
    1.46  inline void DiscoveredListIterator::move_to_next() {
    1.47 @@ -591,12 +592,13 @@
    1.48          gclog_or_tty->print_cr("Dropping reference (" INTPTR_FORMAT ": %s"  ") by policy",
    1.49                                 iter.obj(), iter.obj()->blueprint()->internal_name());
    1.50        }
    1.51 +      // Remove Reference object from list
    1.52 +      iter.remove();
    1.53        // Make the Reference object active again
    1.54        iter.make_active();
    1.55        // keep the referent around
    1.56        iter.make_referent_alive();
    1.57 -      // Remove Reference object from list
    1.58 -      iter.remove();
    1.59 +      iter.move_to_next();
    1.60      } else {
    1.61        iter.next();
    1.62      }
    1.63 @@ -629,12 +631,13 @@
    1.64                                 iter.obj(), iter.obj()->blueprint()->internal_name());
    1.65        }
    1.66        // The referent is reachable after all.
    1.67 +      // Remove Reference object from list.
    1.68 +      iter.remove();
    1.69        // Update the referent pointer as necessary: Note that this
    1.70        // should not entail any recursive marking because the
    1.71        // referent must already have been traversed.
    1.72        iter.make_referent_alive();
    1.73 -      // Remove Reference object from list
    1.74 -      iter.remove();
    1.75 +      iter.move_to_next();
    1.76      } else {
    1.77        iter.next();
    1.78      }
    1.79 @@ -670,6 +673,7 @@
    1.80        } else {
    1.81          keep_alive->do_oop((oop*)next_addr);
    1.82        }
    1.83 +      iter.move_to_next();
    1.84      } else {
    1.85        iter.next();
    1.86      }
    1.87 @@ -832,9 +836,9 @@
    1.88          }
    1.89          java_lang_ref_Reference::set_discovered(move_tail, ref_lists[to_idx].head());
    1.90          ref_lists[to_idx].set_head(move_head);
    1.91 -        ref_lists[to_idx].set_length(ref_lists[to_idx].length() + refs_to_move);
    1.92 +        ref_lists[to_idx].inc_length(refs_to_move);
    1.93          ref_lists[from_idx].set_head(new_head);
    1.94 -        ref_lists[from_idx].set_length(ref_lists[from_idx].length() - refs_to_move);
    1.95 +        ref_lists[from_idx].dec_length(refs_to_move);
    1.96        } else {
    1.97          ++to_idx;
    1.98        }
    1.99 @@ -923,7 +927,6 @@
   1.100  void ReferenceProcessor::clean_up_discovered_reflist(DiscoveredList& refs_list) {
   1.101    assert(!discovery_is_atomic(), "Else why call this method?");
   1.102    DiscoveredListIterator iter(refs_list, NULL, NULL);
   1.103 -  size_t length = refs_list.length();
   1.104    while (iter.has_next()) {
   1.105      iter.load_ptrs(DEBUG_ONLY(true /* allow_null_referent */));
   1.106      oop next = java_lang_ref_Reference::next(iter.obj());
   1.107 @@ -941,12 +944,11 @@
   1.108        )
   1.109        // Remove Reference object from list
   1.110        iter.remove();
   1.111 -      --length;
   1.112 +      iter.move_to_next();
   1.113      } else {
   1.114        iter.next();
   1.115      }
   1.116    }
   1.117 -  refs_list.set_length(length);
   1.118    NOT_PRODUCT(
   1.119      if (PrintGCDetails && TraceReferenceGC) {
   1.120        gclog_or_tty->print(
   1.121 @@ -1024,7 +1026,7 @@
   1.122      // We have separate lists for enqueueing so no synchronization
   1.123      // is necessary.
   1.124      refs_list.set_head(obj);
   1.125 -    refs_list.set_length(refs_list.length() + 1);
   1.126 +    refs_list.inc_length(1);
   1.127      if (_discovered_list_needs_barrier) {
   1.128        _bs->write_ref_field((void*)discovered_addr, current_head); guarantee(false, "Needs to be fixed: YSR");
   1.129      }
   1.130 @@ -1168,7 +1170,7 @@
   1.131        _bs->write_ref_field((oop*)discovered_addr, current_head);
   1.132      }
   1.133      list->set_head(obj);
   1.134 -    list->set_length(list->length() + 1);
   1.135 +    list->inc_length(1);
   1.136    }
   1.137  
   1.138    // In the MT discovery case, it is currently possible to see
   1.139 @@ -1209,45 +1211,48 @@
   1.140      TraceTime tt("Preclean SoftReferences", PrintGCDetails && PrintReferenceGC,
   1.141                false, gclog_or_tty);
   1.142      for (int i = 0; i < _num_q; i++) {
   1.143 +      if (yield->should_return()) {
   1.144 +        return;
   1.145 +      }
   1.146        preclean_discovered_reflist(_discoveredSoftRefs[i], is_alive,
   1.147                                    keep_alive, complete_gc, yield);
   1.148      }
   1.149    }
   1.150 -  if (yield->should_return()) {
   1.151 -    return;
   1.152 -  }
   1.153  
   1.154    // Weak references
   1.155    {
   1.156      TraceTime tt("Preclean WeakReferences", PrintGCDetails && PrintReferenceGC,
   1.157                false, gclog_or_tty);
   1.158      for (int i = 0; i < _num_q; i++) {
   1.159 +      if (yield->should_return()) {
   1.160 +        return;
   1.161 +      }
   1.162        preclean_discovered_reflist(_discoveredWeakRefs[i], is_alive,
   1.163                                    keep_alive, complete_gc, yield);
   1.164      }
   1.165    }
   1.166 -  if (yield->should_return()) {
   1.167 -    return;
   1.168 -  }
   1.169  
   1.170    // Final references
   1.171    {
   1.172      TraceTime tt("Preclean FinalReferences", PrintGCDetails && PrintReferenceGC,
   1.173                false, gclog_or_tty);
   1.174      for (int i = 0; i < _num_q; i++) {
   1.175 +      if (yield->should_return()) {
   1.176 +        return;
   1.177 +      }
   1.178        preclean_discovered_reflist(_discoveredFinalRefs[i], is_alive,
   1.179                                    keep_alive, complete_gc, yield);
   1.180      }
   1.181    }
   1.182 -  if (yield->should_return()) {
   1.183 -    return;
   1.184 -  }
   1.185  
   1.186    // Phantom references
   1.187    {
   1.188      TraceTime tt("Preclean PhantomReferences", PrintGCDetails && PrintReferenceGC,
   1.189                false, gclog_or_tty);
   1.190      for (int i = 0; i < _num_q; i++) {
   1.191 +      if (yield->should_return()) {
   1.192 +        return;
   1.193 +      }
   1.194        preclean_discovered_reflist(_discoveredPhantomRefs[i], is_alive,
   1.195                                    keep_alive, complete_gc, yield);
   1.196      }
   1.197 @@ -1256,9 +1261,12 @@
   1.198  
   1.199  // Walk the given discovered ref list, and remove all reference objects
   1.200  // whose referents are still alive, whose referents are NULL or which
   1.201 -// are not active (have a non-NULL next field). NOTE: For this to work
   1.202 -// correctly, refs discovery can not be happening concurrently with this
   1.203 -// step.
   1.204 +// are not active (have a non-NULL next field). NOTE: When we are
   1.205 +// thus precleaning the ref lists (which happens single-threaded today),
   1.206 +// we do not disable refs discovery to honour the correct semantics of
   1.207 +// java.lang.Reference. As a result, we need to be careful below
   1.208 +// that ref removal steps interleave safely with ref discovery steps
   1.209 +// (in this thread).
   1.210  void
   1.211  ReferenceProcessor::preclean_discovered_reflist(DiscoveredList&    refs_list,
   1.212                                                  BoolObjectClosure* is_alive,
   1.213 @@ -1266,7 +1274,6 @@
   1.214                                                  VoidClosure*       complete_gc,
   1.215                                                  YieldClosure*      yield) {
   1.216    DiscoveredListIterator iter(refs_list, keep_alive, is_alive);
   1.217 -  size_t length = refs_list.length();
   1.218    while (iter.has_next()) {
   1.219      iter.load_ptrs(DEBUG_ONLY(true /* allow_null_referent */));
   1.220      oop obj = iter.obj();
   1.221 @@ -1281,7 +1288,6 @@
   1.222        }
   1.223        // Remove Reference object from list
   1.224        iter.remove();
   1.225 -      --length;
   1.226        // Keep alive its cohort.
   1.227        iter.make_referent_alive();
   1.228        if (UseCompressedOops) {
   1.229 @@ -1291,12 +1297,11 @@
   1.230          oop* next_addr = (oop*)java_lang_ref_Reference::next_addr(obj);
   1.231          keep_alive->do_oop(next_addr);
   1.232        }
   1.233 +      iter.move_to_next();
   1.234      } else {
   1.235        iter.next();
   1.236      }
   1.237    }
   1.238 -  refs_list.set_length(length);
   1.239 -
   1.240    // Close the reachable set
   1.241    complete_gc->do_void();
   1.242  

mercurial