changeset 7435:b0eed0b189c3

Several smallish fixes. Most notably, don't apply evacuation closure on discovered field in refs. Added some useful asserts to check that no unmarked object gets assigned anywhere during evacuation.
author Roman Kennke <rkennke@redhat.com>
date Mon, 08 Dec 2014 17:40:13 +0100
parents d0c408606d42
children 9e06c024409c
files src/share/vm/gc_implementation/shenandoah/shenandoahHeap.cpp src/share/vm/oops/oop.cpp src/share/vm/oops/oop.hpp src/share/vm/oops/oop.inline.hpp
diffstat 4 files changed, 53 insertions(+), 13 deletions(-) [+]
line wrap: on
line diff
--- a/src/share/vm/gc_implementation/shenandoah/shenandoahHeap.cpp	Fri Dec 05 19:10:36 2014 +0100
+++ b/src/share/vm/gc_implementation/shenandoah/shenandoahHeap.cpp	Mon Dec 08 17:40:13 2014 +0100
@@ -1231,6 +1231,7 @@
 
     oop obj = oopDesc::load_heap_oop(p);
     if (obj != NULL && _heap->in_cset_fast_test((HeapWord*) obj)) {
+      assert(_heap->is_marked_current(obj), "only evacuate marked objects");
       oopDesc::store_heap_oop(p, _heap->evacuate_object(obj, _thread));
     }
   }
@@ -1238,10 +1239,6 @@
   void do_oop(narrowOop* p) {
     Unimplemented();
   }
-
-  bool apply_to_weak_ref_discovered_field() {
-    return true;
-  }
 };
 
 class ShenandoahEvacuateUpdateStrongRootsTask : public AbstractGangTask {
@@ -2289,16 +2286,17 @@
     copy_object(p, filler);    
 #endif
 
+  if (ShenandoahUpdateRefsEarly) {
+    mark_current(oop(copy));
+  }
+
+
   HeapWord* result = BrooksPointer::get(p).cas_forwardee((HeapWord*) p, copy);
 
   oop return_val;
   if (result == (HeapWord*) p) {
     return_val = oop(copy);
 
-    if (ShenandoahUpdateRefsEarly) {
-      mark_current(return_val);
-    }
-
 #ifdef ASSERT
     if (ShenandoahTraceEvacuations) {
       tty->print("Copy of %p to %p succeeded \n", (HeapWord*) p, copy);
@@ -2382,7 +2380,9 @@
 
 bool  ShenandoahIsAliveClosure:: do_object_b(oop obj) { 
 
-  obj = ShenandoahBarrierSet::resolve_oop_static(obj);
+  if (! ShenandoahUpdateRefsEarly) {
+    obj = ShenandoahBarrierSet::resolve_oop_static(obj);
+  }
   assert(obj == ShenandoahBarrierSet::resolve_oop_static(obj), "needs to be in to-space");
 
     HeapWord* addr = (HeapWord*) obj;
@@ -2408,7 +2408,7 @@
       }
     }
 
-    return addr != NULL && (!sh->is_in(addr) || !sh->is_obj_ill(obj));
+    return addr != NULL && sh->is_marked_current(obj); //(!sh->is_in(addr) || !sh->is_obj_ill(obj));
 }
 
 void ShenandoahHeap::ref_processing_init() {
--- a/src/share/vm/oops/oop.cpp	Fri Dec 05 19:10:36 2014 +0100
+++ b/src/share/vm/oops/oop.cpp	Mon Dec 08 17:40:13 2014 +0100
@@ -25,6 +25,9 @@
 #include "precompiled.hpp"
 #include "classfile/altHashing.hpp"
 #include "classfile/javaClasses.hpp"
+#ifdef ASSERT
+#include "gc_implementation/shenandoah/shenandoahHeap.hpp"
+#endif
 #include "oops/oop.inline.hpp"
 #include "runtime/handles.inline.hpp"
 #include "runtime/thread.inline.hpp"
@@ -118,6 +121,17 @@
   }
 }
 
+#ifdef ASSERT
+void oopDesc::shenandoah_check_store_value(oop v) {
+  if (UseShenandoahGC) {
+    ShenandoahHeap* sh = ShenandoahHeap::heap();
+    if (sh->is_evacuation_in_progress()) {
+      assert(v == NULL || sh->is_marked_current(v), "only store marked oops into fields or arrays");
+    }
+  }
+}
+#endif
+
 VerifyOopClosure VerifyOopClosure::verify_oop;
 
 void VerifyOopClosure::do_oop(oop* p)       { VerifyOopClosure::do_oop_work(p); }
--- a/src/share/vm/oops/oop.hpp	Fri Dec 05 19:10:36 2014 +0100
+++ b/src/share/vm/oops/oop.hpp	Mon Dec 08 17:40:13 2014 +0100
@@ -166,6 +166,10 @@
   static oop load_decode_heap_oop(narrowOop* p);
   static oop load_decode_heap_oop(oop* p);
 
+#ifdef ASSERT
+  static void shenandoah_check_store_value(oop v);
+#endif
+
   // Store an oop into the heap.
   static void store_heap_oop(narrowOop* p, narrowOop v);
   static void store_heap_oop(oop* p, oop v);
--- a/src/share/vm/oops/oop.inline.hpp	Fri Dec 05 19:10:36 2014 +0100
+++ b/src/share/vm/oops/oop.inline.hpp	Mon Dec 08 17:40:13 2014 +0100
@@ -240,20 +240,42 @@
 }
 
 // Store already encoded heap oop into the heap.
-inline void oopDesc::store_heap_oop(oop* p, oop v)                 { *p = v; }
+inline void oopDesc::store_heap_oop(oop* p, oop v)                 {
+#ifdef ASSERT
+  shenandoah_check_store_value(v);
+#endif
+ *p = v;
+}
 inline void oopDesc::store_heap_oop(narrowOop* p, narrowOop v)     { *p = v; }
 
 // Encode and store a heap oop.
 inline void oopDesc::encode_store_heap_oop_not_null(narrowOop* p, oop v) {
+#ifdef ASSERT
+  shenandoah_check_store_value(v);
+#endif
+
   *p = encode_heap_oop_not_null(v);
 }
-inline void oopDesc::encode_store_heap_oop_not_null(oop* p, oop v) { *p = v; }
+inline void oopDesc::encode_store_heap_oop_not_null(oop* p, oop v) {
+#ifdef ASSERT
+  shenandoah_check_store_value(v);
+#endif
+ *p = v;
+}
 
 // Encode and store a heap oop allowing for null.
 inline void oopDesc::encode_store_heap_oop(narrowOop* p, oop v) {
+#ifdef ASSERT
+  shenandoah_check_store_value(v);
+#endif
   *p = encode_heap_oop(v);
 }
-inline void oopDesc::encode_store_heap_oop(oop* p, oop v) { *p = v; }
+inline void oopDesc::encode_store_heap_oop(oop* p, oop v) {
+#ifdef ASSERT
+  shenandoah_check_store_value(v);
+#endif
+ *p = v;
+}
 
 // Store heap oop as is for volatile fields.
 inline void oopDesc::release_store_heap_oop(volatile oop* p, oop v) {