# HG changeset patch # User aph # Date 1560524924 -3600 # Fri Jun 14 16:08:44 2019 +0100 # Node ID 2130faf9ac6df5c8655e53dcffe7cc4bebd0e1e6 # Parent ce601e800f56af59edfda40e19a92a8d3121a1cd 8225716: G1 GC: Undefined behaviour in G1BlockOffsetTablePart::block_at_or_preceding Reviewed-by: kbarrett, tschatzl diff --git a/src/hotspot/share/gc/g1/g1BlockOffsetTable.cpp b/src/hotspot/share/gc/g1/g1BlockOffsetTable.cpp --- a/src/hotspot/share/gc/g1/g1BlockOffsetTable.cpp +++ b/src/hotspot/share/gc/g1/g1BlockOffsetTable.cpp @@ -406,7 +406,7 @@ size_t bottom_index = _bot->index_for_raw(_space->bottom()); assert(_bot->address_for_index_raw(bottom_index) == _space->bottom(), "Precondition of call"); - _bot->set_offset_array_raw(bottom_index, 0); + _bot->set_offset_array(bottom_index, 0); } HeapWord* G1BlockOffsetTablePart::initialize_threshold() { diff --git a/src/hotspot/share/gc/g1/g1BlockOffsetTable.hpp b/src/hotspot/share/gc/g1/g1BlockOffsetTable.hpp --- a/src/hotspot/share/gc/g1/g1BlockOffsetTable.hpp +++ b/src/hotspot/share/gc/g1/g1BlockOffsetTable.hpp @@ -52,7 +52,7 @@ // Array for keeping offsets for retrieving object start fast given an // address. - u_char* _offset_array; // byte array keeping backwards offsets + volatile u_char* _offset_array; // byte array keeping backwards offsets void check_offset(size_t offset, const char* msg) const { assert(offset <= BOTConstants::N_words, @@ -64,10 +64,6 @@ // For performance these have to devolve to array accesses in product builds. inline u_char offset_array(size_t index) const; - void set_offset_array_raw(size_t index, u_char offset) { - _offset_array[index] = offset; - } - inline void set_offset_array(size_t index, u_char offset); inline void set_offset_array(size_t index, HeapWord* high, HeapWord* low); diff --git a/src/hotspot/share/gc/g1/g1BlockOffsetTable.inline.hpp b/src/hotspot/share/gc/g1/g1BlockOffsetTable.inline.hpp --- a/src/hotspot/share/gc/g1/g1BlockOffsetTable.inline.hpp +++ b/src/hotspot/share/gc/g1/g1BlockOffsetTable.inline.hpp @@ -29,6 +29,7 @@ #include "gc/g1/heapRegion.hpp" #include "gc/shared/memset_with_concurrent_readers.hpp" #include "gc/shared/space.hpp" +#include "runtime/atomic.hpp" inline HeapWord* G1BlockOffsetTablePart::block_start(const void* addr) { if (addr >= _space->bottom() && addr < _space->end()) { @@ -51,12 +52,12 @@ u_char G1BlockOffsetTable::offset_array(size_t index) const { check_index(index, "index out of range"); - return _offset_array[index]; + return Atomic::load(&_offset_array[index]); } void G1BlockOffsetTable::set_offset_array(size_t index, u_char offset) { check_index(index, "index out of range"); - set_offset_array_raw(index, offset); + Atomic::store(offset, &_offset_array[index]); } void G1BlockOffsetTable::set_offset_array(size_t index, HeapWord* high, HeapWord* low) { @@ -71,7 +72,8 @@ check_index(right, "right index out of range"); assert(left <= right, "indexes out of order"); size_t num_cards = right - left + 1; - memset_with_concurrent_readers(&_offset_array[left], offset, num_cards); + memset_with_concurrent_readers + (const_cast (&_offset_array[left]), offset, num_cards); } // Variant of index_for that does not check the index for validity.