diff src/share/vm/gc_implementation/g1/heapRegion.inline.hpp @ 20278:2c6ef90f030a

8049421: G1 Class Unloading after completing a concurrent mark cycle Reviewed-by: tschatzl, ehelin, brutisso, coleenp, roland, iveresov Contributed-by: stefan.karlsson@oracle.com, mikael.gerdin@oracle.com
author stefank
date Mon, 07 Jul 2014 10:12:40 +0200
parents 1526a938e670
children f3aeae1f9fc5
line wrap: on
line diff
--- a/src/share/vm/gc_implementation/g1/heapRegion.inline.hpp	Tue Jul 01 09:03:55 2014 +0200
+++ b/src/share/vm/gc_implementation/g1/heapRegion.inline.hpp	Mon Jul 07 10:12:40 2014 +0200
@@ -93,18 +93,27 @@
 
 inline bool
 HeapRegion::block_is_obj(const HeapWord* p) const {
-  return p < top();
+  G1CollectedHeap* g1h = G1CollectedHeap::heap();
+  return !g1h->is_obj_dead(oop(p), this);
 }
 
 inline size_t
 HeapRegion::block_size(const HeapWord *addr) const {
-  const HeapWord* current_top = top();
-  if (addr < current_top) {
-    return oop(addr)->size();
-  } else {
-    assert(addr == current_top, "just checking");
+  // Old regions' dead objects may have dead classes
+  // We need to find the next live object in some other
+  // manner than getting the oop size
+  G1CollectedHeap* g1h = G1CollectedHeap::heap();
+  if (g1h->is_obj_dead(oop(addr), this)) {
+    HeapWord* next = g1h->concurrent_mark()->prevMarkBitMap()->
+        getNextMarkedWordAddress(addr, prev_top_at_mark_start());
+
+    assert(next > addr, "must get the next live object");
+
+    return pointer_delta(next, addr);
+  } else if (addr == top()) {
     return pointer_delta(end(), addr);
   }
+  return oop(addr)->size();
 }
 
 inline HeapWord* HeapRegion::par_allocate_no_bot_updates(size_t word_size) {