| Index: src/spaces.cc
|
| diff --git a/src/spaces.cc b/src/spaces.cc
|
| index 7831ef1ecdf66ecd1f4bcbd9c92abd8a392349a1..20efbf72e080f36d8fe9e50833cce25043f7c928 100644
|
| --- a/src/spaces.cc
|
| +++ b/src/spaces.cc
|
| @@ -2017,10 +2017,13 @@ void FreeListNode::set_size(Heap* heap, int size_in_bytes) {
|
| // field and a next pointer, we give it a filler map that gives it the
|
| // correct size.
|
| if (size_in_bytes > FreeSpace::kHeaderSize) {
|
| - set_map_no_write_barrier(heap->raw_unchecked_free_space_map());
|
| // Can't use FreeSpace::cast because it fails during deserialization.
|
| + // We have to set the size first with a release store before we store
|
| + // the map because a concurrent store buffer scan on scavenge must not
|
| + // observe a map with an invalid size.
|
| FreeSpace* this_as_free_space = reinterpret_cast<FreeSpace*>(this);
|
| - this_as_free_space->set_size(size_in_bytes);
|
| + this_as_free_space->nobarrier_set_size(size_in_bytes);
|
| + synchronized_set_map_no_write_barrier(heap->raw_unchecked_free_space_map());
|
| } else if (size_in_bytes == kPointerSize) {
|
| set_map_no_write_barrier(heap->raw_unchecked_one_pointer_filler_map());
|
| } else if (size_in_bytes == 2 * kPointerSize) {
|
| @@ -2064,11 +2067,11 @@ void FreeListNode::set_next(FreeListNode* next) {
|
| // stage.
|
| if (map() == GetHeap()->raw_unchecked_free_space_map()) {
|
| ASSERT(map() == NULL || Size() >= kNextOffset + kPointerSize);
|
| - Memory::Address_at(address() + kNextOffset) =
|
| - reinterpret_cast<Address>(next);
|
| + NoBarrier_Store(reinterpret_cast<AtomicWord*>(address() + kNextOffset),
|
| + reinterpret_cast<AtomicWord>(next));
|
| } else {
|
| - Memory::Address_at(address() + kPointerSize) =
|
| - reinterpret_cast<Address>(next);
|
| + NoBarrier_Store(reinterpret_cast<AtomicWord*>(address() + kPointerSize),
|
| + reinterpret_cast<AtomicWord>(next));
|
| }
|
| }
|
|
|
|
|