8069760: When iterating over a card, G1 often iterates over much more references than are contained in the card

Mon, 02 Feb 2015 10:38:39 +0100

author
tschatzl
date
Mon, 02 Feb 2015 10:38:39 +0100
changeset 7654
36c7518fd486
parent 7653
b6a1bf5222c5
child 7655
8e9ede9dd2cd

8069760: When iterating over a card, G1 often iterates over much more references than are contained in the card
Summary: Properly bound the iteration work for objArray-oops.
Reviewed-by: mgerdin, kbarrett

src/share/vm/gc_implementation/g1/heapRegion.cpp file | annotate | diff | comparison | revisions
     1.1 --- a/src/share/vm/gc_implementation/g1/heapRegion.cpp	Thu Jan 29 15:05:25 2015 +0100
     1.2 +++ b/src/share/vm/gc_implementation/g1/heapRegion.cpp	Mon Feb 02 10:38:39 2015 +0100
     1.3 @@ -1,5 +1,5 @@
     1.4  /*
     1.5 - * Copyright (c) 2001, 2014, Oracle and/or its affiliates. All rights reserved.
     1.6 + * Copyright (c) 2001, 2015, Oracle and/or its affiliates. All rights reserved.
     1.7   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     1.8   *
     1.9   * This code is free software; you can redistribute it and/or modify it
    1.10 @@ -468,7 +468,7 @@
    1.11    oop obj;
    1.12  
    1.13    HeapWord* next = cur;
    1.14 -  while (next <= start) {
    1.15 +  do {
    1.16      cur = next;
    1.17      obj = oop(cur);
    1.18      if (obj->klass_or_null() == NULL) {
    1.19 @@ -477,45 +477,38 @@
    1.20      }
    1.21      // Otherwise...
    1.22      next = cur + block_size(cur);
    1.23 -  }
    1.24 +  } while (next <= start);
    1.25  
    1.26    // If we finish the above loop...We have a parseable object that
    1.27    // begins on or before the start of the memory region, and ends
    1.28    // inside or spans the entire region.
    1.29 -
    1.30 -  assert(obj == oop(cur), "sanity");
    1.31    assert(cur <= start, "Loop postcondition");
    1.32    assert(obj->klass_or_null() != NULL, "Loop postcondition");
    1.33 -  assert((cur + block_size(cur)) > start, "Loop postcondition");
    1.34  
    1.35 -  if (!g1h->is_obj_dead(obj)) {
    1.36 -    obj->oop_iterate(cl, mr);
    1.37 -  }
    1.38 -
    1.39 -  while (cur < end) {
    1.40 +  do {
    1.41      obj = oop(cur);
    1.42 +    assert((cur + block_size(cur)) > (HeapWord*)obj, "Loop invariant");
    1.43      if (obj->klass_or_null() == NULL) {
    1.44        // Ran into an unparseable point.
    1.45        return cur;
    1.46 -    };
    1.47 +    }
    1.48  
    1.49 -    // Otherwise:
    1.50 -    next = cur + block_size(cur);
    1.51 +    // Advance the current pointer. "obj" still points to the object to iterate.
    1.52 +    cur = cur + block_size(cur);
    1.53  
    1.54      if (!g1h->is_obj_dead(obj)) {
    1.55 -      if (next < end || !obj->is_objArray()) {
    1.56 -        // This object either does not span the MemRegion
    1.57 -        // boundary, or if it does it's not an array.
    1.58 -        // Apply closure to whole object.
    1.59 +      // Non-objArrays are sometimes marked imprecise at the object start. We
    1.60 +      // always need to iterate over them in full.
    1.61 +      // We only iterate over object arrays in full if they are completely contained
    1.62 +      // in the memory region.
    1.63 +      if (!obj->is_objArray() || (((HeapWord*)obj) >= start && cur <= end)) {
    1.64          obj->oop_iterate(cl);
    1.65        } else {
    1.66 -        // This obj is an array that spans the boundary.
    1.67 -        // Stop at the boundary.
    1.68          obj->oop_iterate(cl, mr);
    1.69        }
    1.70      }
    1.71 -    cur = next;
    1.72 -  }
    1.73 +  } while (cur < end);
    1.74 +
    1.75    return NULL;
    1.76  }
    1.77  

mercurial