diff -r f4a6f0eba875 -r 7b88983393b7 hotspot/src/share/vm/oops/oop.inline.hpp --- a/hotspot/src/share/vm/oops/oop.inline.hpp Thu Dec 05 15:13:12 2013 -0800 +++ b/hotspot/src/share/vm/oops/oop.inline.hpp Mon Dec 02 10:26:14 2013 +0100 @@ -490,9 +490,9 @@ return size_given_klass(klass()); } -inline void update_barrier_set(void* p, oop v) { +inline void update_barrier_set(void* p, oop v, bool release = false) { assert(oopDesc::bs() != NULL, "Uninitialized bs in oop!"); - oopDesc::bs()->write_ref_field(p, v); + oopDesc::bs()->write_ref_field(p, v, release); } template inline void update_barrier_set_pre(T* p, oop v) { @@ -505,7 +505,10 @@ } else { update_barrier_set_pre(p, v); oopDesc::encode_store_heap_oop(p, v); - update_barrier_set((void*)p, v); // cast away type + // always_do_update_barrier == false => + // Either we are at a safepoint (in GC) or CMS is not used. In both + // cases it's unnecessary to mark the card as dirty with release sematics. + update_barrier_set((void*)p, v, false /* release */); // cast away type } } @@ -513,7 +516,12 @@ update_barrier_set_pre((T*)p, v); // cast away volatile // Used by release_obj_field_put, so use release_store_ptr. oopDesc::release_encode_store_heap_oop(p, v); - update_barrier_set((void*)p, v); // cast away type + // When using CMS we must mark the card corresponding to p as dirty + // with release sematics to prevent that CMS sees the dirty card but + // not the new value v at p due to reordering of the two + // stores. Note that CMS has a concurrent precleaning phase, where + // it reads the card table while the Java threads are running. + update_barrier_set((void*)p, v, true /* release */); // cast away type } // Should replace *addr = oop assignments where addr type depends on UseCompressedOops