Mon, 02 Feb 2015 10:38:39 +0100
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