[objects] Add WeakCell::relaxed_target method
Loads target but with relaxed load. Concurrent marking needs to load field with relaxed load, since the main thread could change this field when unregistering. Change-Id: I809b1d4db1dd58c92bdb998601c2f709073104af Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2192661 Reviewed-by: Ulan Degenbaev <ulan@chromium.org> Commit-Queue: Dominik Inführ <dinfuehr@chromium.org> Cr-Commit-Position: refs/heads/master@{#67707}
This commit is contained in:
parent
0056effb20
commit
ace32e55ea
@ -323,26 +323,23 @@ int MarkingVisitorBase<ConcreteVisitor, MarkingState>::VisitWeakCell(
|
||||
int size = WeakCell::BodyDescriptor::SizeOf(map, weak_cell);
|
||||
this->VisitMapPointer(weak_cell);
|
||||
WeakCell::BodyDescriptor::IterateBody(map, weak_cell, size, this);
|
||||
if (weak_cell.target().IsHeapObject()) {
|
||||
HeapObject target = HeapObject::cast(weak_cell.target());
|
||||
HeapObject unregister_token =
|
||||
HeapObject::cast(weak_cell.unregister_token());
|
||||
concrete_visitor()->SynchronizePageAccess(target);
|
||||
concrete_visitor()->SynchronizePageAccess(unregister_token);
|
||||
if (concrete_visitor()->marking_state()->IsBlackOrGrey(target) &&
|
||||
concrete_visitor()->marking_state()->IsBlackOrGrey(unregister_token)) {
|
||||
// Record the slots inside the WeakCell, since the IterateBody above
|
||||
// didn't visit it.
|
||||
ObjectSlot slot = weak_cell.RawField(WeakCell::kTargetOffset);
|
||||
concrete_visitor()->RecordSlot(weak_cell, slot, target);
|
||||
slot = weak_cell.RawField(WeakCell::kUnregisterTokenOffset);
|
||||
concrete_visitor()->RecordSlot(weak_cell, slot, unregister_token);
|
||||
} else {
|
||||
// WeakCell points to a potentially dead object or a dead unregister
|
||||
// token. We have to process them when we know the liveness of the whole
|
||||
// transitive closure.
|
||||
weak_objects_->weak_cells.Push(task_id_, weak_cell);
|
||||
}
|
||||
HeapObject target = weak_cell.relaxed_target();
|
||||
HeapObject unregister_token = HeapObject::cast(weak_cell.unregister_token());
|
||||
concrete_visitor()->SynchronizePageAccess(target);
|
||||
concrete_visitor()->SynchronizePageAccess(unregister_token);
|
||||
if (concrete_visitor()->marking_state()->IsBlackOrGrey(target) &&
|
||||
concrete_visitor()->marking_state()->IsBlackOrGrey(unregister_token)) {
|
||||
// Record the slots inside the WeakCell, since the IterateBody above
|
||||
// didn't visit it.
|
||||
ObjectSlot slot = weak_cell.RawField(WeakCell::kTargetOffset);
|
||||
concrete_visitor()->RecordSlot(weak_cell, slot, target);
|
||||
slot = weak_cell.RawField(WeakCell::kUnregisterTokenOffset);
|
||||
concrete_visitor()->RecordSlot(weak_cell, slot, unregister_token);
|
||||
} else {
|
||||
// WeakCell points to a potentially dead object or a dead unregister
|
||||
// token. We have to process them when we know the liveness of the whole
|
||||
// transitive closure.
|
||||
weak_objects_->weak_cells.Push(task_id_, weak_cell);
|
||||
}
|
||||
return size;
|
||||
}
|
||||
|
@ -177,6 +177,10 @@ bool JSFinalizationRegistry::NeedsCleanup() const {
|
||||
return cleared_cells().IsWeakCell();
|
||||
}
|
||||
|
||||
HeapObject WeakCell::relaxed_target() const {
|
||||
return TaggedField<HeapObject>::Relaxed_Load(*this, kTargetOffset);
|
||||
}
|
||||
|
||||
template <typename GCNotifyUpdatedSlotCallback>
|
||||
void WeakCell::Nullify(Isolate* isolate,
|
||||
GCNotifyUpdatedSlotCallback gc_notify_updated_slot) {
|
||||
|
@ -89,6 +89,9 @@ class WeakCell : public TorqueGeneratedWeakCell<WeakCell, HeapObject> {
|
||||
|
||||
class BodyDescriptor;
|
||||
|
||||
// Provide relaxed load access to target field.
|
||||
inline HeapObject relaxed_target() const;
|
||||
|
||||
// Nullify is called during GC and it modifies the pointers in WeakCell and
|
||||
// JSFinalizationRegistry. Thus we need to tell the GC about the modified
|
||||
// slots via the gc_notify_updated_slot function. The normal write barrier is
|
||||
|
Loading…
Reference in New Issue
Block a user