src/share/vm/gc_implementation/g1/g1RemSet.inline.hpp

changeset 2302
878b57474103
parent 2216
c32059ef4dc0
child 2314
f95d63e2154a
     1.1 --- a/src/share/vm/gc_implementation/g1/g1RemSet.inline.hpp	Mon Nov 15 16:25:14 2010 -0800
     1.2 +++ b/src/share/vm/gc_implementation/g1/g1RemSet.inline.hpp	Tue Nov 16 14:07:33 2010 -0800
     1.3 @@ -31,17 +31,12 @@
     1.4  }
     1.5  
     1.6  template <class T>
     1.7 -inline void G1RemSet::write_ref_nv(HeapRegion* from, T* p) {
     1.8 -  par_write_ref_nv(from, p, 0);
     1.9 -}
    1.10 -
    1.11 -inline bool G1RemSet::self_forwarded(oop obj) {
    1.12 -  bool result =  (obj->is_forwarded() && (obj->forwardee()== obj));
    1.13 -  return result;
    1.14 +inline void G1RemSet::write_ref(HeapRegion* from, T* p) {
    1.15 +  par_write_ref(from, p, 0);
    1.16  }
    1.17  
    1.18  template <class T>
    1.19 -inline void G1RemSet::par_write_ref_nv(HeapRegion* from, T* p, int tid) {
    1.20 +inline void G1RemSet::par_write_ref(HeapRegion* from, T* p, int tid) {
    1.21    oop obj = oopDesc::load_decode_heap_oop(p);
    1.22  #ifdef ASSERT
    1.23    // can't do because of races
    1.24 @@ -62,34 +57,15 @@
    1.25    assert(from == NULL || from->is_in_reserved(p), "p is not in from");
    1.26  
    1.27    HeapRegion* to = _g1->heap_region_containing(obj);
    1.28 -  // The test below could be optimized by applying a bit op to to and from.
    1.29 -  if (to != NULL && from != NULL && from != to) {
    1.30 -    // The _traversal_in_progress flag is true during the collection pause,
    1.31 -    // false during the evacuation failure handling. This should avoid a
    1.32 -    // potential loop if we were to add the card containing 'p' to the DCQS
    1.33 -    // that's used to regenerate the remembered sets for the collection set,
    1.34 -    // in the event of an evacuation failure, here. The UpdateRSImmediate
    1.35 -    // closure will eventally call this routine.
    1.36 -    if (_traversal_in_progress &&
    1.37 -        to->in_collection_set() && !self_forwarded(obj)) {
    1.38 -
    1.39 -      assert(_cset_rs_update_cl[tid] != NULL, "should have been set already");
    1.40 -      _cset_rs_update_cl[tid]->do_oop(p);
    1.41 -
    1.42 -      // Deferred updates to the CSet are either discarded (in the normal case),
    1.43 -      // or processed (if an evacuation failure occurs) at the end
    1.44 -      // of the collection.
    1.45 -      // See G1RemSet::cleanup_after_oops_into_collection_set_do().
    1.46 -    } else {
    1.47 +  if (to != NULL && from != to) {
    1.48  #if G1_REM_SET_LOGGING
    1.49 -      gclog_or_tty->print_cr("Adding " PTR_FORMAT " (" PTR_FORMAT ") to RS"
    1.50 -                             " for region [" PTR_FORMAT ", " PTR_FORMAT ")",
    1.51 -                             p, obj,
    1.52 -                             to->bottom(), to->end());
    1.53 +    gclog_or_tty->print_cr("Adding " PTR_FORMAT " (" PTR_FORMAT ") to RS"
    1.54 +                           " for region [" PTR_FORMAT ", " PTR_FORMAT ")",
    1.55 +                           p, obj,
    1.56 +                           to->bottom(), to->end());
    1.57  #endif
    1.58 -      assert(to->rem_set() != NULL, "Need per-region 'into' remsets.");
    1.59 -      to->rem_set()->add_reference(p, tid);
    1.60 -    }
    1.61 +    assert(to->rem_set() != NULL, "Need per-region 'into' remsets.");
    1.62 +    to->rem_set()->add_reference(p, tid);
    1.63    }
    1.64  }
    1.65  
    1.66 @@ -108,3 +84,64 @@
    1.67    }
    1.68  }
    1.69  
    1.70 +template <class T>
    1.71 +inline void UpdateRSOrPushRefOopClosure::do_oop_work(T* p) {
    1.72 +  oop obj = oopDesc::load_decode_heap_oop(p);
    1.73 +#ifdef ASSERT
    1.74 +  // can't do because of races
    1.75 +  // assert(obj == NULL || obj->is_oop(), "expected an oop");
    1.76 +
    1.77 +  // Do the safe subset of is_oop
    1.78 +  if (obj != NULL) {
    1.79 +#ifdef CHECK_UNHANDLED_OOPS
    1.80 +    oopDesc* o = obj.obj();
    1.81 +#else
    1.82 +    oopDesc* o = obj;
    1.83 +#endif // CHECK_UNHANDLED_OOPS
    1.84 +    assert((intptr_t)o % MinObjAlignmentInBytes == 0, "not oop aligned");
    1.85 +    assert(Universe::heap()->is_in_reserved(obj), "must be in heap");
    1.86 +  }
    1.87 +#endif // ASSERT
    1.88 +
    1.89 +  assert(_from != NULL, "from region must be non-NULL");
    1.90 +
    1.91 +  HeapRegion* to = _g1->heap_region_containing(obj);
    1.92 +  if (to != NULL && _from != to) {
    1.93 +    // The _record_refs_into_cset flag is true during the RSet
    1.94 +    // updating part of an evacuation pause. It is false at all
    1.95 +    // other times:
    1.96 +    //  * rebuilding the rembered sets after a full GC
    1.97 +    //  * during concurrent refinement.
    1.98 +    //  * updating the remembered sets of regions in the collection
    1.99 +    //    set in the event of an evacuation failure (when deferred
   1.100 +    //    updates are enabled).
   1.101 +
   1.102 +    if (_record_refs_into_cset && to->in_collection_set()) {
   1.103 +      // We are recording references that point into the collection
   1.104 +      // set and this particular reference does exactly that...
   1.105 +      // If the referenced object has already been forwarded
   1.106 +      // to itself, we are handling an evacuation failure and
   1.107 +      // we have already visited/tried to copy this object
   1.108 +      // there is no need to retry.
   1.109 +      if (!self_forwarded(obj)) {
   1.110 +        assert(_push_ref_cl != NULL, "should not be null");
   1.111 +        // Push the reference in the refs queue of the G1ParScanThreadState
   1.112 +        // instance for this worker thread.
   1.113 +        _push_ref_cl->do_oop(p);
   1.114 +      }
   1.115 +
   1.116 +      // Deferred updates to the CSet are either discarded (in the normal case),
   1.117 +      // or processed (if an evacuation failure occurs) at the end
   1.118 +      // of the collection.
   1.119 +      // See G1RemSet::cleanup_after_oops_into_collection_set_do().
   1.120 +    } else {
   1.121 +      // We either don't care about pushing references that point into the
   1.122 +      // collection set (i.e. we're not during an evacuation pause) _or_
   1.123 +      // the reference doesn't point into the collection set. Either way
   1.124 +      // we add the reference directly to the RSet of the region containing
   1.125 +      // the referenced object.
   1.126 +      _g1_rem_set->par_write_ref(_from, p, _worker_i);
   1.127 +    }
   1.128 +  }
   1.129 +}
   1.130 +

mercurial