[serializer] Add write barrier for forward ref writes

Forward reference resolution writes didn't have a write barrier,
which means the slot wouldn't be recorded if there was an active
slot recording marker running.

Now use the same SlotAccessor interface as the other deserializer
writes, to make sure that the correct write barrier is called.

As a drive-by, clean up SlotAccessorForHeapObject into two static
constructors, to differentiate between access by slot index and
offset.

Fixed: v8:11065
Bug: v8:10460
Change-Id: I5b3a3d94057763324d6e1727d96b65c73ba5d7b4
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2504263
Commit-Queue: Leszek Swirski <leszeks@chromium.org>
Commit-Queue: Jakob Gruber <jgruber@chromium.org>
Auto-Submit: Leszek Swirski <leszeks@chromium.org>
Reviewed-by: Jakob Gruber <jgruber@chromium.org>
Cr-Commit-Position: refs/heads/master@{#70839}
This commit is contained in:
Leszek Swirski 2020-10-28 11:47:07 +01:00 committed by Commit Bot
parent 83980b82ff
commit 1301daebd9

View File

@ -47,8 +47,14 @@ namespace internal {
// HeapObject, which is updated if the HeapObject moves.
class SlotAccessorForHeapObject {
public:
SlotAccessorForHeapObject(Handle<HeapObject> object, int index)
: object_(object), offset_(index * kTaggedSize) {}
static SlotAccessorForHeapObject ForSlotIndex(Handle<HeapObject> object,
int index) {
return SlotAccessorForHeapObject(object, index * kTaggedSize);
}
static SlotAccessorForHeapObject ForSlotOffset(Handle<HeapObject> object,
int offset) {
return SlotAccessorForHeapObject(object, offset);
}
MaybeObjectSlot slot() const { return object_->RawMaybeWeakField(offset_); }
Handle<HeapObject> object() const { return object_; }
@ -94,6 +100,9 @@ class SlotAccessorForHeapObject {
}
private:
SlotAccessorForHeapObject(Handle<HeapObject> object, int offset)
: object_(object), offset_(offset) {}
const Handle<HeapObject> object_;
const int offset_;
};
@ -754,7 +763,7 @@ void Deserializer::ReadData(Handle<HeapObject> object, int start_slot_index,
while (current < end_slot_index) {
byte data = source_.Get();
current += ReadSingleBytecodeData(
data, SlotAccessorForHeapObject(object, current));
data, SlotAccessorForHeapObject::ForSlotIndex(object, current));
}
CHECK_EQ(current, end_slot_index);
}
@ -897,9 +906,9 @@ int Deserializer::ReadSingleBytecodeData(byte data,
Handle<HeapObject> obj = slot_accessor.object();
int index = source_.GetInt();
auto& forward_ref = unresolved_forward_refs_[index];
TaggedField<MaybeObject>::store(
*forward_ref.object, forward_ref.offset,
HeapObjectReference::From(*obj, forward_ref.ref_type));
SlotAccessorForHeapObject::ForSlotOffset(forward_ref.object,
forward_ref.offset)
.Write(*obj, forward_ref.ref_type);
num_unresolved_forward_refs_--;
if (num_unresolved_forward_refs_ == 0) {
// If there's no more pending fields, clear the entire pending field