# HG changeset patch # User Roman Kennke # Date 1418056813 -3600 # Node ID b0eed0b189c34e74185c207ec6bea5f9944cb147 # Parent d0c408606d420a1ff486f6b7ba632c7dd765d866 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. diff -r d0c408606d42 -r b0eed0b189c3 src/share/vm/gc_implementation/shenandoah/shenandoahHeap.cpp --- 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() { diff -r d0c408606d42 -r b0eed0b189c3 src/share/vm/oops/oop.cpp --- 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); } diff -r d0c408606d42 -r b0eed0b189c3 src/share/vm/oops/oop.hpp --- 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); diff -r d0c408606d42 -r b0eed0b189c3 src/share/vm/oops/oop.inline.hpp --- 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) {