Commit 7e78e45b authored by Ulan Degenbaev's avatar Ulan Degenbaev Committed by Commit Bot

[heap] Use snapshotting protocol for all JSObject subclasses.

Bug: chromium:825828
Change-Id: I1f27c08fa8febe521412fddb6ae964969671764b
Reviewed-on: https://chromium-review.googlesource.com/980933Reviewed-by: 's avatarMichael Lippautz <mlippautz@chromium.org>
Commit-Queue: Ulan Degenbaev <ulan@chromium.org>
Cr-Commit-Position: refs/heads/master@{#52230}
parent 33ebf6a9
......@@ -91,6 +91,8 @@ class ConcurrentMarkingVisitor final
return marking_state_.GreyToBlack(object);
}
bool AllowDefaultJSObjectVisit() { return false; }
void ProcessStrongHeapObject(HeapObject* host, Object** slot,
HeapObject* heap_object) {
MarkObject(heap_object);
......@@ -163,18 +165,19 @@ class ConcurrentMarkingVisitor final
// ===========================================================================
int VisitJSObject(Map* map, JSObject* object) {
int size = JSObject::BodyDescriptor::SizeOf(map, object);
int used_size = map->UsedInstanceSize();
DCHECK_LE(used_size, size);
DCHECK_GE(used_size, JSObject::kHeaderSize);
const SlotSnapshot& snapshot = MakeSlotSnapshot(map, object, used_size);
if (!ShouldVisit(object)) return 0;
VisitPointersInSnapshot(object, snapshot);
return size;
return VisitJSObjectSubclass(map, object);
}
int VisitJSObjectFast(Map* map, JSObject* object) {
return VisitJSObject(map, object);
return VisitJSObjectSubclass(map, object);
}
int VisitJSArrayBuffer(Map* map, JSArrayBuffer* object) {
return VisitJSObjectSubclass(map, object);
}
int VisitWasmInstanceObject(Map* map, WasmInstanceObject* object) {
return VisitJSObjectSubclass(map, object);
}
int VisitJSApiObject(Map* map, JSObject* object) {
......@@ -185,6 +188,17 @@ class ConcurrentMarkingVisitor final
return 0;
}
int VisitJSFunction(Map* map, JSFunction* object) {
int size = JSFunction::BodyDescriptorWeak::SizeOf(map, object);
int used_size = map->UsedInstanceSize();
DCHECK_LE(used_size, size);
DCHECK_GE(used_size, JSObject::kHeaderSize);
const SlotSnapshot& snapshot = MakeSlotSnapshotWeak(map, object, used_size);
if (!ShouldVisit(object)) return 0;
VisitPointersInSnapshot(object, snapshot);
return size;
}
// ===========================================================================
// Strings with pointers =====================================================
// ===========================================================================
......@@ -287,14 +301,6 @@ class ConcurrentMarkingVisitor final
return size;
}
int VisitJSFunction(Map* map, JSFunction* object) {
if (!ShouldVisit(object)) return 0;
int size = JSFunction::BodyDescriptorWeak::SizeOf(map, object);
VisitMapPointer(object, object->map_slot());
JSFunction::BodyDescriptorWeak::IterateBody(map, object, size, this);
return size;
}
int VisitMap(Map* meta_map, Map* map) {
if (marking_state_.IsGrey(map)) {
// Maps have ad-hoc weakness for descriptor arrays. They also clear the
......@@ -398,16 +404,35 @@ class ConcurrentMarkingVisitor final
SlotSnapshot* slot_snapshot_;
};
template <typename T>
int VisitJSObjectSubclass(Map* map, T* object) {
int size = T::BodyDescriptor::SizeOf(map, object);
int used_size = map->UsedInstanceSize();
DCHECK_LE(used_size, size);
DCHECK_GE(used_size, T::kHeaderSize);
const SlotSnapshot& snapshot = MakeSlotSnapshot(map, object, used_size);
if (!ShouldVisit(object)) return 0;
VisitPointersInSnapshot(object, snapshot);
return size;
}
template <typename T>
const SlotSnapshot& MakeSlotSnapshot(Map* map, T* object, int size) {
// TODO(ulan): Iterate only the existing fields and skip slack at the end
// of the object.
SlotSnapshottingVisitor visitor(&slot_snapshot_);
visitor.VisitPointer(object,
reinterpret_cast<Object**>(object->map_slot()));
T::BodyDescriptor::IterateBody(map, object, size, &visitor);
return slot_snapshot_;
}
template <typename T>
const SlotSnapshot& MakeSlotSnapshotWeak(Map* map, T* object, int size) {
SlotSnapshottingVisitor visitor(&slot_snapshot_);
visitor.VisitPointer(object,
reinterpret_cast<Object**>(object->map_slot()));
T::BodyDescriptorWeak::IterateBody(map, object, size, &visitor);
return slot_snapshot_;
}
ConcurrentMarking::MarkingWorklist::View shared_;
ConcurrentMarking::MarkingWorklist::View bailout_;
WeakObjects* weak_objects_;
......
......@@ -71,17 +71,22 @@ void HeapVisitor<ResultType, ConcreteVisitor>::VisitMapPointer(
host, reinterpret_cast<Object**>(map));
}
#define VISIT(type) \
template <typename ResultType, typename ConcreteVisitor> \
ResultType HeapVisitor<ResultType, ConcreteVisitor>::Visit##type( \
Map* map, type* object) { \
ConcreteVisitor* visitor = static_cast<ConcreteVisitor*>(this); \
if (!visitor->ShouldVisit(object)) return ResultType(); \
int size = type::BodyDescriptor::SizeOf(map, object); \
if (visitor->ShouldVisitMapPointer()) \
visitor->VisitMapPointer(object, object->map_slot()); \
type::BodyDescriptor::IterateBody(map, object, size, visitor); \
return static_cast<ResultType>(size); \
#define VISIT(type) \
template <typename ResultType, typename ConcreteVisitor> \
ResultType HeapVisitor<ResultType, ConcreteVisitor>::Visit##type( \
Map* map, type* object) { \
ConcreteVisitor* visitor = static_cast<ConcreteVisitor*>(this); \
if (!visitor->ShouldVisit(object)) return ResultType(); \
if (!visitor->AllowDefaultJSObjectVisit()) { \
DCHECK_WITH_MSG(!map->IsJSObjectMap(), \
"Implement custom visitor for new JSObject subclass in " \
"concurrent marker"); \
} \
int size = type::BodyDescriptor::SizeOf(map, object); \
if (visitor->ShouldVisitMapPointer()) \
visitor->VisitMapPointer(object, object->map_slot()); \
type::BodyDescriptor::IterateBody(map, object, size, visitor); \
return static_cast<ResultType>(size); \
}
TYPED_VISITOR_ID_LIST(VISIT)
#undef VISIT
......
......@@ -84,6 +84,9 @@ class HeapVisitor : public ObjectVisitor {
V8_INLINE bool ShouldVisitMapPointer() { return true; }
// A callback for visiting the map pointer in the object header.
V8_INLINE void VisitMapPointer(HeapObject* host, HeapObject** map);
// If this predicate returns false, then the heap visitor will fail
// in default Visit implemention for subclasses of JSObject.
V8_INLINE bool AllowDefaultJSObjectVisit() { return true; }
#define VISIT(type) V8_INLINE ResultType Visit##type(Map* map, type* object);
TYPED_VISITOR_ID_LIST(VISIT)
......
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