Commit c06cb88b authored by Ulan Degenbaev's avatar Ulan Degenbaev Committed by Commit Bot

[heap, serializer] Fix data race in serialization of DescriptorArray

This patch ensures that the serializer does not read the field of
the DescriptorArray that can be changed concurrently by GC.

Bug: v8:8803
Change-Id: I849fd2278abd228a46351ab18efb8bfd201ceafc
Reviewed-on: https://chromium-review.googlesource.com/c/1458239
Commit-Queue: Ulan Degenbaev <ulan@chromium.org>
Reviewed-by: 's avatarJakob Gruber <jgruber@chromium.org>
Cr-Commit-Position: refs/heads/master@{#59465}
parent b9af6ad8
......@@ -312,11 +312,13 @@ HeapObject Deserializer::PostProcessNewObject(HeapObject obj, int space) {
bytecode_array->set_interrupt_budget(
interpreter::Interpreter::InterruptBudget());
bytecode_array->set_osr_loop_nesting_level(0);
} else if (obj->IsDescriptorArray()) {
// Reset the marking state of the descriptor array.
}
#ifdef DEBUG
if (obj->IsDescriptorArray()) {
DescriptorArray descriptor_array = DescriptorArray::cast(obj);
descriptor_array->set_raw_number_of_marked_descriptors(0);
DCHECK_EQ(0, descriptor_array->raw_number_of_marked_descriptors());
}
#endif
// Check alignment.
DCHECK_EQ(0, Heap::GetFillToAlign(obj->address(),
......
......@@ -790,6 +790,31 @@ void Serializer::ObjectSerializer::VisitCodeTarget(Code host,
bytes_processed_so_far_ += rinfo->target_address_size();
}
namespace {
// Similar to OutputRawData, but substitutes the given field with the given
// value instead of reading it from the object.
void OutputRawWithCustomField(SnapshotByteSink* sink, Address object_start,
int written_so_far, int bytes_to_write,
int field_offset, int field_size,
const byte* field_value) {
int offset = field_offset - written_so_far;
if (0 <= offset && offset < bytes_to_write) {
DCHECK_GE(bytes_to_write, offset + field_size);
sink->PutRaw(reinterpret_cast<byte*>(object_start + written_so_far), offset,
"Bytes");
sink->PutRaw(field_value, field_size, "Bytes");
written_so_far += offset + field_size;
bytes_to_write -= offset + field_size;
sink->PutRaw(reinterpret_cast<byte*>(object_start + written_so_far),
bytes_to_write, "Bytes");
} else {
sink->PutRaw(reinterpret_cast<byte*>(object_start + written_so_far),
bytes_to_write, "Bytes");
}
}
} // anonymous namespace
void Serializer::ObjectSerializer::OutputRawData(Address up_to) {
Address object_start = object_->address();
int base = bytes_processed_so_far_;
......@@ -814,21 +839,21 @@ void Serializer::ObjectSerializer::OutputRawData(Address up_to) {
reinterpret_cast<void*>(object_start + base), bytes_to_output);
#endif // MEMORY_SANITIZER
if (object_->IsBytecodeArray()) {
// The code age byte can be changed concurrently by GC.
const int bytes_to_age_byte = BytecodeArray::kBytecodeAgeOffset - base;
if (0 <= bytes_to_age_byte && bytes_to_age_byte < bytes_to_output) {
sink_->PutRaw(reinterpret_cast<byte*>(object_start + base),
bytes_to_age_byte, "Bytes");
byte bytecode_age = BytecodeArray::kNoAgeBytecodeAge;
sink_->PutRaw(&bytecode_age, 1, "Bytes");
const int bytes_written = bytes_to_age_byte + 1;
sink_->PutRaw(
reinterpret_cast<byte*>(object_start + base + bytes_written),
bytes_to_output - bytes_written, "Bytes");
} else {
sink_->PutRaw(reinterpret_cast<byte*>(object_start + base),
bytes_to_output, "Bytes");
}
// The bytecode age field can be changed by GC concurrently.
byte field_value = BytecodeArray::kNoAgeBytecodeAge;
OutputRawWithCustomField(sink_, object_start, base, bytes_to_output,
BytecodeArray::kBytecodeAgeOffset,
sizeof(field_value), &field_value);
} else if (object_->IsDescriptorArray()) {
// The number of marked descriptors field can be changed by GC
// concurrently.
byte field_value[2];
field_value[0] = 0;
field_value[1] = 0;
OutputRawWithCustomField(
sink_, object_start, base, bytes_to_output,
DescriptorArray::kRawNumberOfMarkedDescriptorsOffset,
sizeof(field_value), field_value);
} else {
sink_->PutRaw(reinterpret_cast<byte*>(object_start + base),
bytes_to_output, "Bytes");
......
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