From 4be998e634275b15fd40d7fd97772d20ec6ce445 Mon Sep 17 00:00:00 2001 From: simonis Date: Fri, 2 Dec 2016 11:07:27 +0100 Subject: [PATCH] 8170409: CMS: Crash in CardTableModRefBSForCTRS::process_chunk_boundaries Reviewed-by: simonis, tschatzl, mgerdin, dlong Contributed-by: gunter.haug@sap.com --- .../gc_implementation/parNew/parCardTableModRefBS.cpp | 11 ++++++++--- src/share/vm/memory/cardTableModRefBS.hpp | 2 +- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/src/share/vm/gc_implementation/parNew/parCardTableModRefBS.cpp b/src/share/vm/gc_implementation/parNew/parCardTableModRefBS.cpp index 9209f0d1a..34642187d 100644 --- a/src/share/vm/gc_implementation/parNew/parCardTableModRefBS.cpp +++ b/src/share/vm/gc_implementation/parNew/parCardTableModRefBS.cpp @@ -452,9 +452,13 @@ get_LNC_array_for_space(Space* sp, // 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 @@ get_LNC_array_for_space(Space* sp, _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 --git a/src/share/vm/memory/cardTableModRefBS.hpp b/src/share/vm/memory/cardTableModRefBS.hpp index c824e6185..ae15ba7ed 100644 --- a/src/share/vm/memory/cardTableModRefBS.hpp +++ b/src/share/vm/memory/cardTableModRefBS.hpp @@ -217,7 +217,7 @@ class CardTableModRefBS: public ModRefBarrierSet { 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 -- GitLab