Commit 4f43be96 authored by Ulan Degenbaev's avatar Ulan Degenbaev Committed by Commit Bot

[heap] Fix a data race in Scavenger.

Scavenger::PromoteObject and Scavenger::SemiSpaceCopyObject load and
dereference the map of the object to compute the alignment.

This is unsafe because the object can be already migrated by another
thread and the map word can contain the forwarding address.

This patch removes the map load and uses the provided map argument to
compute the alignment.

Bug: chromium:811278,chromium:807178
Change-Id: I7343344dc65ae26eefb2602c55dee87bb511bc72
Reviewed-on: https://chromium-review.googlesource.com/939172
Commit-Queue: Ulan Degenbaev <ulan@chromium.org>
Reviewed-by: 's avatarYang Guo <yangguo@chromium.org>
Reviewed-by: 's avatarMichael Lippautz <mlippautz@chromium.org>
Cr-Commit-Position: refs/heads/master@{#51592}
parent 10d8aab1
......@@ -1406,7 +1406,8 @@ class EvacuateVisitorBase : public HeapObjectVisitor {
#ifdef VERIFY_HEAP
if (AbortCompactionForTesting(object)) return false;
#endif // VERIFY_HEAP
AllocationAlignment alignment = object->RequiredAlignment();
AllocationAlignment alignment =
HeapObject::RequiredAlignment(object->map());
AllocationResult allocation =
local_allocator_->Allocate(target_space, size, alignment);
if (allocation.To(target_object)) {
......@@ -1511,7 +1512,8 @@ class EvacuateNewSpaceVisitor final : public EvacuateVisitorBase {
inline AllocationSpace AllocateTargetObject(HeapObject* old_object, int size,
HeapObject** target_object) {
AllocationAlignment alignment = old_object->RequiredAlignment();
AllocationAlignment alignment =
HeapObject::RequiredAlignment(old_object->map());
AllocationSpace space_allocated_in = NEW_SPACE;
AllocationResult allocation =
local_allocator_->Allocate(NEW_SPACE, size, alignment);
......
......@@ -71,7 +71,7 @@ bool Scavenger::MigrateObject(Map* map, HeapObject* source, HeapObject* target,
bool Scavenger::SemiSpaceCopyObject(Map* map, HeapObject** slot,
HeapObject* object, int object_size) {
DCHECK(heap()->AllowedToBeMigrated(object, NEW_SPACE));
AllocationAlignment alignment = object->RequiredAlignment();
AllocationAlignment alignment = HeapObject::RequiredAlignment(map);
AllocationResult allocation =
allocator_.Allocate(NEW_SPACE, object_size, alignment);
......@@ -97,7 +97,7 @@ bool Scavenger::SemiSpaceCopyObject(Map* map, HeapObject** slot,
bool Scavenger::PromoteObject(Map* map, HeapObject** slot, HeapObject* object,
int object_size) {
AllocationAlignment alignment = object->RequiredAlignment();
AllocationAlignment alignment = HeapObject::RequiredAlignment(map);
AllocationResult allocation =
allocator_.Allocate(OLD_SPACE, object_size, alignment);
......
......@@ -1735,13 +1735,14 @@ WriteBarrierMode HeapObject::GetWriteBarrierMode(
return UPDATE_WRITE_BARRIER;
}
AllocationAlignment HeapObject::RequiredAlignment() const {
AllocationAlignment HeapObject::RequiredAlignment(Map* map) {
#ifdef V8_HOST_ARCH_32_BIT
if ((IsFixedFloat64Array() || IsFixedDoubleArray()) &&
FixedArrayBase::cast(this)->length() != 0) {
int instance_type = map->instance_type();
if (instance_type == FIXED_FLOAT64_ARRAY_TYPE ||
instance_type == FIXED_DOUBLE_ARRAY_TYPE) {
return kDoubleAligned;
}
if (IsHeapNumber()) return kDoubleUnaligned;
if (instance_type == HEAP_NUMBER_TYPE) return kDoubleUnaligned;
#endif // V8_HOST_ARCH_32_BIT
return kWordAligned;
}
......
......@@ -1816,7 +1816,7 @@ class HeapObject: public Object {
static void VerifyHeapPointer(Object* p);
#endif
inline AllocationAlignment RequiredAlignment() const;
static inline AllocationAlignment RequiredAlignment(Map* map);
// Whether the object needs rehashing. That is the case if the object's
// content depends on FLAG_hash_seed. When the object is deserialized into
......
......@@ -251,7 +251,8 @@ HeapObject* Deserializer<AllocatorT>::PostProcessNewObject(HeapObject* obj,
bytecode_array->set_osr_loop_nesting_level(0);
}
// Check alignment.
DCHECK_EQ(0, Heap::GetFillToAlign(obj->address(), obj->RequiredAlignment()));
DCHECK_EQ(0, Heap::GetFillToAlign(obj->address(),
HeapObject::RequiredAlignment(obj->map())));
return obj;
}
......
......@@ -284,7 +284,7 @@ void Serializer<AllocatorT>::PutAttachedReference(SerializerReference reference,
template <class AllocatorT>
int Serializer<AllocatorT>::PutAlignmentPrefix(HeapObject* object) {
AllocationAlignment alignment = object->RequiredAlignment();
AllocationAlignment alignment = HeapObject::RequiredAlignment(object->map());
if (alignment != kWordAligned) {
DCHECK(1 <= alignment && alignment <= 3);
byte prefix = (kAlignmentPrefix - 1) + alignment;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment