8064473: Improved handling of age during object copy in G1

Fri, 14 Nov 2014 15:03:39 +0100

author
sfriberg
date
Fri, 14 Nov 2014 15:03:39 +0100
changeset 7645
f2e3f0e1f97d
parent 7644
2af69bed8db6
child 7646
5743a702da65

8064473: Improved handling of age during object copy in G1
Reviewed-by: brutisso, tschatzl

src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp file | annotate | diff | comparison | revisions
src/share/vm/gc_implementation/g1/g1ParScanThreadState.cpp file | annotate | diff | comparison | revisions
src/share/vm/gc_implementation/g1/g1ParScanThreadState.hpp file | annotate | diff | comparison | revisions
src/share/vm/gc_implementation/g1/g1ParScanThreadState.inline.hpp file | annotate | diff | comparison | revisions
src/share/vm/gc_implementation/shared/ageTable.hpp file | annotate | diff | comparison | revisions
     1.1 --- a/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp	Fri Oct 10 12:15:51 2014 +0200
     1.2 +++ b/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp	Fri Nov 14 15:03:39 2014 +0100
     1.3 @@ -4479,10 +4479,11 @@
     1.4  
     1.5    if (state == G1CollectedHeap::InCSet) {
     1.6      oop forwardee;
     1.7 -    if (obj->is_forwarded()) {
     1.8 -      forwardee = obj->forwardee();
     1.9 +    markOop m = obj->mark();
    1.10 +    if (m->is_marked()) {
    1.11 +      forwardee = (oop) m->decode_pointer();
    1.12      } else {
    1.13 -      forwardee = _par_scan_state->copy_to_survivor_space(obj);
    1.14 +      forwardee = _par_scan_state->copy_to_survivor_space(obj, m);
    1.15      }
    1.16      assert(forwardee != NULL, "forwardee should not be NULL");
    1.17      oopDesc::encode_store_heap_oop(p, forwardee);
     2.1 --- a/src/share/vm/gc_implementation/g1/g1ParScanThreadState.cpp	Fri Oct 10 12:15:51 2014 +0200
     2.2 +++ b/src/share/vm/gc_implementation/g1/g1ParScanThreadState.cpp	Fri Nov 14 15:03:39 2014 +0100
     2.3 @@ -150,7 +150,8 @@
     2.4    } while (!_refs->is_empty());
     2.5  }
     2.6  
     2.7 -oop G1ParScanThreadState::copy_to_survivor_space(oop const old) {
     2.8 +oop G1ParScanThreadState::copy_to_survivor_space(oop const old,
     2.9 +                                                 markOop const old_mark) {
    2.10    size_t word_sz = old->size();
    2.11    HeapRegion* from_region = _g1h->heap_region_containing_raw(old);
    2.12    // +1 to make the -1 indexes valid...
    2.13 @@ -158,9 +159,8 @@
    2.14    assert( (from_region->is_young() && young_index >  0) ||
    2.15           (!from_region->is_young() && young_index == 0), "invariant" );
    2.16    G1CollectorPolicy* g1p = _g1h->g1_policy();
    2.17 -  markOop m = old->mark();
    2.18 -  int age = m->has_displaced_mark_helper() ? m->displaced_mark_helper()->age()
    2.19 -                                           : m->age();
    2.20 +  uint age = old_mark->has_displaced_mark_helper() ? old_mark->displaced_mark_helper()->age()
    2.21 +                                                   : old_mark->age();
    2.22    GCAllocPurpose alloc_purpose = g1p->evacuation_destination(from_region, age,
    2.23                                                               word_sz);
    2.24    AllocationContext_t context = from_region->allocation_context();
    2.25 @@ -196,30 +196,22 @@
    2.26      alloc_purpose = to_region->is_young() ? GCAllocForSurvived : GCAllocForTenured;
    2.27  
    2.28      if (g1p->track_object_age(alloc_purpose)) {
    2.29 -      // We could simply do obj->incr_age(). However, this causes a
    2.30 -      // performance issue. obj->incr_age() will first check whether
    2.31 -      // the object has a displaced mark by checking its mark word;
    2.32 -      // getting the mark word from the new location of the object
    2.33 -      // stalls. So, given that we already have the mark word and we
    2.34 -      // are about to install it anyway, it's better to increase the
    2.35 -      // age on the mark word, when the object does not have a
    2.36 -      // displaced mark word. We're not expecting many objects to have
    2.37 -      // a displaced marked word, so that case is not optimized
    2.38 -      // further (it could be...) and we simply call obj->incr_age().
    2.39 -
    2.40 -      if (m->has_displaced_mark_helper()) {
    2.41 -        // in this case, we have to install the mark word first,
    2.42 +      if (age < markOopDesc::max_age) {
    2.43 +        age++;
    2.44 +      }
    2.45 +      if (old_mark->has_displaced_mark_helper()) {
    2.46 +        // In this case, we have to install the mark word first,
    2.47          // otherwise obj looks to be forwarded (the old mark word,
    2.48          // which contains the forward pointer, was copied)
    2.49 -        obj->set_mark(m);
    2.50 -        obj->incr_age();
    2.51 +        obj->set_mark(old_mark);
    2.52 +        markOop new_mark = old_mark->displaced_mark_helper()->set_age(age);
    2.53 +        old_mark->set_displaced_mark_helper(new_mark);
    2.54        } else {
    2.55 -        m = m->incr_age();
    2.56 -        obj->set_mark(m);
    2.57 +        obj->set_mark(old_mark->set_age(age));
    2.58        }
    2.59 -      age_table()->add(obj, word_sz);
    2.60 +      age_table()->add(age, word_sz);
    2.61      } else {
    2.62 -      obj->set_mark(m);
    2.63 +      obj->set_mark(old_mark);
    2.64      }
    2.65  
    2.66      if (G1StringDedup::is_enabled()) {
     3.1 --- a/src/share/vm/gc_implementation/g1/g1ParScanThreadState.hpp	Fri Oct 10 12:15:51 2014 +0200
     3.2 +++ b/src/share/vm/gc_implementation/g1/g1ParScanThreadState.hpp	Fri Nov 14 15:03:39 2014 +0100
     3.3 @@ -195,7 +195,7 @@
     3.4    inline void dispatch_reference(StarTask ref);
     3.5   public:
     3.6  
     3.7 -  oop copy_to_survivor_space(oop const obj);
     3.8 +  oop copy_to_survivor_space(oop const obj, markOop const old_mark);
     3.9  
    3.10    void trim_queue();
    3.11  
     4.1 --- a/src/share/vm/gc_implementation/g1/g1ParScanThreadState.inline.hpp	Fri Oct 10 12:15:51 2014 +0200
     4.2 +++ b/src/share/vm/gc_implementation/g1/g1ParScanThreadState.inline.hpp	Fri Nov 14 15:03:39 2014 +0100
     4.3 @@ -41,10 +41,11 @@
     4.4    G1CollectedHeap::in_cset_state_t in_cset_state = _g1h->in_cset_state(obj);
     4.5    if (in_cset_state == G1CollectedHeap::InCSet) {
     4.6      oop forwardee;
     4.7 -    if (obj->is_forwarded()) {
     4.8 -      forwardee = obj->forwardee();
     4.9 +    markOop m = obj->mark();
    4.10 +    if (m->is_marked()) {
    4.11 +      forwardee = (oop) m->decode_pointer();
    4.12      } else {
    4.13 -      forwardee = copy_to_survivor_space(obj);
    4.14 +      forwardee = copy_to_survivor_space(obj, m);
    4.15      }
    4.16      oopDesc::encode_store_heap_oop(p, forwardee);
    4.17    } else if (in_cset_state == G1CollectedHeap::IsHumongous) {
     5.1 --- a/src/share/vm/gc_implementation/shared/ageTable.hpp	Fri Oct 10 12:15:51 2014 +0200
     5.2 +++ b/src/share/vm/gc_implementation/shared/ageTable.hpp	Fri Nov 14 15:03:39 2014 +0100
     5.3 @@ -55,7 +55,10 @@
     5.4  
     5.5    // add entry
     5.6    void add(oop p, size_t oop_size) {
     5.7 -    uint age = p->age();
     5.8 +    add(p->age(), oop_size);
     5.9 +  }
    5.10 +
    5.11 +  void add(uint age, size_t oop_size) {
    5.12      assert(age > 0 && age < table_size, "invalid age of object");
    5.13      sizes[age] += oop_size;
    5.14    }

mercurial