# HG changeset patch # User ysr # Date 1272907491 25200 # Node ID 3bfae429e2cf03ae49b1af778f20f2f42ed7fd49 # Parent f03d0a26bf837bec53dc4abf103cda0fa70eff2b 6948537: CMS: BOT walkers observe out-of-thin-air zeros on sun4v sparc/CMT Summary: On sun4v/CMT avoid use of memset() in BOT updates so as to prevent concurrent BOT readers from seeing the phantom zeros arising from memset()'s use of BIS. Reviewed-by: jmasa, johnc, minqi, poonam, tonyp diff -r f03d0a26bf83 -r 3bfae429e2cf src/cpu/sparc/vm/vm_version_sparc.cpp --- a/src/cpu/sparc/vm/vm_version_sparc.cpp Thu Apr 22 13:23:15 2010 -0700 +++ b/src/cpu/sparc/vm/vm_version_sparc.cpp Mon May 03 10:24:51 2010 -0700 @@ -104,6 +104,12 @@ if (FLAG_IS_DEFAULT(OptoLoopAlignment)) { FLAG_SET_DEFAULT(OptoLoopAlignment, 4); } + // When using CMS, we cannot use memset() in BOT updates because + // the sun4v/CMT version in libc_psr uses BIS which exposes + // "phantom zeros" to concurrent readers. See 6948537. + if (FLAG_IS_DEFAULT(UseMemSetInBOT) && UseConcMarkSweepGC) { + FLAG_SET_DEFAULT(UseMemSetInBOT, false); + } } // Use hardware population count instruction if available. diff -r f03d0a26bf83 -r 3bfae429e2cf src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp --- a/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp Thu Apr 22 13:23:15 2010 -0700 +++ b/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp Mon May 03 10:24:51 2010 -0700 @@ -789,6 +789,14 @@ _gc_counters = new CollectorCounters("CMS", 1); _completed_initialization = true; _inter_sweep_timer.start(); // start of time +#ifdef SPARC + // Issue a stern warning, but allow use for experimentation and debugging. + if (VM_Version::is_sun4v() && UseMemSetInBOT) { + assert(!FLAG_IS_DEFAULT(UseMemSetInBOT), "Error"); + warning("Experimental flag -XX:+UseMemSetInBOT is known to cause instability" + " on sun4v; please understand that you are using at your own risk!"); + } +#endif } const char* ConcurrentMarkSweepGeneration::name() const { diff -r f03d0a26bf83 -r 3bfae429e2cf src/share/vm/memory/blockOffsetTable.hpp --- a/src/share/vm/memory/blockOffsetTable.hpp Thu Apr 22 13:23:15 2010 -0700 +++ b/src/share/vm/memory/blockOffsetTable.hpp Mon May 03 10:24:51 2010 -0700 @@ -140,14 +140,38 @@ "right address out of range"); assert(left < right, "Heap addresses out of order"); size_t num_cards = pointer_delta(right, left) >> LogN_words; - memset(&_offset_array[index_for(left)], offset, num_cards); + + // Below, we may use an explicit loop instead of memset() + // because on certain platforms memset() can give concurrent + // readers "out-of-thin-air," phantom zeros; see 6948537. + if (UseMemSetInBOT) { + memset(&_offset_array[index_for(left)], offset, num_cards); + } else { + size_t i = index_for(left); + const size_t end = i + num_cards; + for (; i < end; i++) { + _offset_array[i] = offset; + } + } } void set_offset_array(size_t left, size_t right, u_char offset) { assert(right < _vs.committed_size(), "right address out of range"); assert(left <= right, "indexes out of order"); size_t num_cards = right - left + 1; - memset(&_offset_array[left], offset, num_cards); + + // Below, we may use an explicit loop instead of memset + // because on certain platforms memset() can give concurrent + // readers "out-of-thin-air," phantom zeros; see 6948537. + if (UseMemSetInBOT) { + memset(&_offset_array[left], offset, num_cards); + } else { + size_t i = left; + const size_t end = i + num_cards; + for (; i < end; i++) { + _offset_array[i] = offset; + } + } } void check_offset_array(size_t index, HeapWord* high, HeapWord* low) const { diff -r f03d0a26bf83 -r 3bfae429e2cf src/share/vm/runtime/globals.hpp --- a/src/share/vm/runtime/globals.hpp Thu Apr 22 13:23:15 2010 -0700 +++ b/src/share/vm/runtime/globals.hpp Mon May 03 10:24:51 2010 -0700 @@ -327,6 +327,10 @@ product(bool, UseMembar, false, \ "(Unstable) Issues membars on thread state transitions") \ \ + /* Temporary: See 6948537 */ \ + experimental(bool, UseMemSetInBOT, true, \ + "(Unstable) uses memset in BOT updates in GC code") \ + \ diagnostic(bool, UnlockDiagnosticVMOptions, trueInDebug, \ "Enable normal processing of flags relating to field diagnostics")\ \