# HG changeset patch # User simonis # Date 1480673247 -3600 # Node ID c70ebf41026a8521472cb9dd0e0d97d116c90850 # Parent f8a5d01c09292f811b4b4807066a92d0a67f6507 8170409: CMS: Crash in CardTableModRefBSForCTRS::process_chunk_boundaries Reviewed-by: simonis, tschatzl, mgerdin, dlong Contributed-by: gunter.haug@sap.com diff -r f8a5d01c0929 -r c70ebf41026a src/share/vm/gc_implementation/parNew/parCardTableModRefBS.cpp --- a/src/share/vm/gc_implementation/parNew/parCardTableModRefBS.cpp Thu Dec 08 15:12:58 2016 +0300 +++ b/src/share/vm/gc_implementation/parNew/parCardTableModRefBS.cpp Fri Dec 02 11:07:27 2016 +0100 @@ -452,9 +452,13 @@ // event lock and do the read again in case some other thread had already // succeeded and done the resize. int cur_collection = Universe::heap()->total_collections(); - if (_last_LNC_resizing_collection[i] != cur_collection) { + // Updated _last_LNC_resizing_collection[i] must not be visible before + // _lowest_non_clean and friends are visible. Therefore use acquire/release + // to guarantee this on non TSO architecures. + if (OrderAccess::load_acquire(&_last_LNC_resizing_collection[i]) != cur_collection) { MutexLocker x(ParGCRareEvent_lock); - if (_last_LNC_resizing_collection[i] != cur_collection) { + // This load_acquire is here for clarity only. The MutexLocker already fences. + if (OrderAccess::load_acquire(&_last_LNC_resizing_collection[i]) != cur_collection) { if (_lowest_non_clean[i] == NULL || n_chunks != _lowest_non_clean_chunk_size[i]) { @@ -474,7 +478,8 @@ _lowest_non_clean[i][j] = NULL; } } - _last_LNC_resizing_collection[i] = cur_collection; + // Make sure this gets visible only after _lowest_non_clean* was initialized + OrderAccess::release_store(&_last_LNC_resizing_collection[i], cur_collection); } } // In any case, now do the initialization. diff -r f8a5d01c0929 -r c70ebf41026a src/share/vm/memory/cardTableModRefBS.hpp --- a/src/share/vm/memory/cardTableModRefBS.hpp Thu Dec 08 15:12:58 2016 +0300 +++ b/src/share/vm/memory/cardTableModRefBS.hpp Fri Dec 02 11:07:27 2016 +0100 @@ -217,7 +217,7 @@ CardArr* _lowest_non_clean; size_t* _lowest_non_clean_chunk_size; uintptr_t* _lowest_non_clean_base_chunk_index; - int* _last_LNC_resizing_collection; + volatile int* _last_LNC_resizing_collection; // Initializes "lowest_non_clean" to point to the array for the region // covering "sp", and "lowest_non_clean_base_chunk_index" to the chunk