1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #ifndef V8_HEAP_OBJECTS_VISITING_INL_H_
6 #define V8_HEAP_OBJECTS_VISITING_INL_H_
7
8 #include "src/heap/embedder-tracing.h"
9 #include "src/heap/mark-compact.h"
10 #include "src/heap/objects-visiting.h"
11 #include "src/objects/arguments.h"
12 #include "src/objects/free-space-inl.h"
13 #include "src/objects/js-weak-refs-inl.h"
14 #include "src/objects/module-inl.h"
15 #include "src/objects/objects-body-descriptors-inl.h"
16 #include "src/objects/objects-inl.h"
17 #include "src/objects/oddball.h"
18 #include "src/objects/ordered-hash-table.h"
19 #include "src/objects/synthetic-module-inl.h"
20 #include "src/objects/torque-defined-classes.h"
21 #include "src/wasm/wasm-objects.h"
22
23 namespace v8 {
24 namespace internal {
25
26 template <typename ResultType, typename ConcreteVisitor>
27 template <typename T>
Cast(HeapObject object)28 T HeapVisitor<ResultType, ConcreteVisitor>::Cast(HeapObject object) {
29 return T::cast(object);
30 }
31
32 template <typename ResultType, typename ConcreteVisitor>
Visit(HeapObject object)33 ResultType HeapVisitor<ResultType, ConcreteVisitor>::Visit(HeapObject object) {
34 return Visit(object.map(), object);
35 }
36
37 template <typename ResultType, typename ConcreteVisitor>
Visit(Map map,HeapObject object)38 ResultType HeapVisitor<ResultType, ConcreteVisitor>::Visit(Map map,
39 HeapObject object) {
40 ConcreteVisitor* visitor = static_cast<ConcreteVisitor*>(this);
41 switch (map.visitor_id()) {
42 #define CASE(TypeName) \
43 case kVisit##TypeName: \
44 return visitor->Visit##TypeName( \
45 map, ConcreteVisitor::template Cast<TypeName>(object));
46 TYPED_VISITOR_ID_LIST(CASE)
47 TORQUE_VISITOR_ID_LIST(CASE)
48 #undef CASE
49 case kVisitShortcutCandidate:
50 return visitor->VisitShortcutCandidate(
51 map, ConcreteVisitor::template Cast<ConsString>(object));
52 case kVisitDataObject:
53 return visitor->VisitDataObject(map, object);
54 case kVisitJSObjectFast:
55 return visitor->VisitJSObjectFast(
56 map, ConcreteVisitor::template Cast<JSObject>(object));
57 case kVisitJSApiObject:
58 return visitor->VisitJSApiObject(
59 map, ConcreteVisitor::template Cast<JSObject>(object));
60 case kVisitStruct:
61 return visitor->VisitStruct(map, object);
62 case kVisitFreeSpace:
63 return visitor->VisitFreeSpace(map, FreeSpace::cast(object));
64 case kDataOnlyVisitorIdCount:
65 case kVisitorIdCount:
66 UNREACHABLE();
67 }
68 UNREACHABLE();
69 // Make the compiler happy.
70 return ResultType();
71 }
72
73 template <typename ResultType, typename ConcreteVisitor>
VisitMapPointer(HeapObject host)74 void HeapVisitor<ResultType, ConcreteVisitor>::VisitMapPointer(
75 HeapObject host) {
76 DCHECK(!host.map_word().IsForwardingAddress());
77 static_cast<ConcreteVisitor*>(this)->VisitPointer(host, host.map_slot());
78 }
79
80 #define VISIT(TypeName) \
81 template <typename ResultType, typename ConcreteVisitor> \
82 ResultType HeapVisitor<ResultType, ConcreteVisitor>::Visit##TypeName( \
83 Map map, TypeName object) { \
84 ConcreteVisitor* visitor = static_cast<ConcreteVisitor*>(this); \
85 if (!visitor->ShouldVisit(object)) return ResultType(); \
86 if (!visitor->AllowDefaultJSObjectVisit()) { \
87 DCHECK_WITH_MSG(!map.IsJSObjectMap(), \
88 "Implement custom visitor for new JSObject subclass in " \
89 "concurrent marker"); \
90 } \
91 int size = TypeName::BodyDescriptor::SizeOf(map, object); \
92 if (visitor->ShouldVisitMapPointer()) { \
93 visitor->VisitMapPointer(object); \
94 } \
95 TypeName::BodyDescriptor::IterateBody(map, object, size, visitor); \
96 return static_cast<ResultType>(size); \
97 }
98 TYPED_VISITOR_ID_LIST(VISIT)
TORQUE_VISITOR_ID_LIST(VISIT)99 TORQUE_VISITOR_ID_LIST(VISIT)
100 #undef VISIT
101
102 template <typename ResultType, typename ConcreteVisitor>
103 ResultType HeapVisitor<ResultType, ConcreteVisitor>::VisitShortcutCandidate(
104 Map map, ConsString object) {
105 return static_cast<ConcreteVisitor*>(this)->VisitConsString(map, object);
106 }
107
108 template <typename ResultType, typename ConcreteVisitor>
VisitDataObject(Map map,HeapObject object)109 ResultType HeapVisitor<ResultType, ConcreteVisitor>::VisitDataObject(
110 Map map, HeapObject object) {
111 ConcreteVisitor* visitor = static_cast<ConcreteVisitor*>(this);
112 if (!visitor->ShouldVisit(object)) return ResultType();
113 int size = map.instance_size();
114 if (visitor->ShouldVisitMapPointer()) {
115 visitor->VisitMapPointer(object);
116 }
117 return static_cast<ResultType>(size);
118 }
119
120 template <typename ResultType, typename ConcreteVisitor>
VisitJSObjectFast(Map map,JSObject object)121 ResultType HeapVisitor<ResultType, ConcreteVisitor>::VisitJSObjectFast(
122 Map map, JSObject object) {
123 ConcreteVisitor* visitor = static_cast<ConcreteVisitor*>(this);
124 if (!visitor->ShouldVisit(object)) return ResultType();
125 int size = JSObject::FastBodyDescriptor::SizeOf(map, object);
126 if (visitor->ShouldVisitMapPointer()) {
127 visitor->VisitMapPointer(object);
128 }
129 JSObject::FastBodyDescriptor::IterateBody(map, object, size, visitor);
130 return static_cast<ResultType>(size);
131 }
132
133 template <typename ResultType, typename ConcreteVisitor>
VisitJSApiObject(Map map,JSObject object)134 ResultType HeapVisitor<ResultType, ConcreteVisitor>::VisitJSApiObject(
135 Map map, JSObject object) {
136 ConcreteVisitor* visitor = static_cast<ConcreteVisitor*>(this);
137 if (!visitor->ShouldVisit(object)) return ResultType();
138 int size = JSObject::BodyDescriptor::SizeOf(map, object);
139 if (visitor->ShouldVisitMapPointer()) {
140 visitor->VisitMapPointer(object);
141 }
142 JSObject::BodyDescriptor::IterateBody(map, object, size, visitor);
143 return static_cast<ResultType>(size);
144 }
145
146 template <typename ResultType, typename ConcreteVisitor>
VisitStruct(Map map,HeapObject object)147 ResultType HeapVisitor<ResultType, ConcreteVisitor>::VisitStruct(
148 Map map, HeapObject object) {
149 ConcreteVisitor* visitor = static_cast<ConcreteVisitor*>(this);
150 if (!visitor->ShouldVisit(object)) return ResultType();
151 int size = map.instance_size();
152 if (visitor->ShouldVisitMapPointer()) {
153 visitor->VisitMapPointer(object);
154 }
155 StructBodyDescriptor::IterateBody(map, object, size, visitor);
156 return static_cast<ResultType>(size);
157 }
158
159 template <typename ResultType, typename ConcreteVisitor>
VisitFreeSpace(Map map,FreeSpace object)160 ResultType HeapVisitor<ResultType, ConcreteVisitor>::VisitFreeSpace(
161 Map map, FreeSpace object) {
162 ConcreteVisitor* visitor = static_cast<ConcreteVisitor*>(this);
163 if (!visitor->ShouldVisit(object)) return ResultType();
164 if (visitor->ShouldVisitMapPointer()) {
165 visitor->VisitMapPointer(object);
166 }
167 return static_cast<ResultType>(object.size());
168 }
169
170 template <typename ConcreteVisitor>
VisitNativeContext(Map map,NativeContext object)171 int NewSpaceVisitor<ConcreteVisitor>::VisitNativeContext(Map map,
172 NativeContext object) {
173 ConcreteVisitor* visitor = static_cast<ConcreteVisitor*>(this);
174 int size = NativeContext::BodyDescriptor::SizeOf(map, object);
175 NativeContext::BodyDescriptor::IterateBody(map, object, size, visitor);
176 return size;
177 }
178
179 template <typename ConcreteVisitor>
VisitJSApiObject(Map map,JSObject object)180 int NewSpaceVisitor<ConcreteVisitor>::VisitJSApiObject(Map map,
181 JSObject object) {
182 ConcreteVisitor* visitor = static_cast<ConcreteVisitor*>(this);
183 return visitor->VisitJSObject(map, object);
184 }
185
186 template <typename ConcreteVisitor>
VisitSharedFunctionInfo(Map map,SharedFunctionInfo object)187 int NewSpaceVisitor<ConcreteVisitor>::VisitSharedFunctionInfo(
188 Map map, SharedFunctionInfo object) {
189 UNREACHABLE();
190 return 0;
191 }
192
193 template <typename ConcreteVisitor>
VisitWeakCell(Map map,WeakCell weak_cell)194 int NewSpaceVisitor<ConcreteVisitor>::VisitWeakCell(Map map,
195 WeakCell weak_cell) {
196 UNREACHABLE();
197 return 0;
198 }
199
200 } // namespace internal
201 } // namespace v8
202
203 #endif // V8_HEAP_OBJECTS_VISITING_INL_H_
204