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/objects-visiting.h"
9
10 #include "src/heap/array-buffer-tracker.h"
11 #include "src/heap/embedder-tracing.h"
12 #include "src/heap/mark-compact.h"
13 #include "src/macro-assembler.h"
14 #include "src/objects-body-descriptors-inl.h"
15 #include "src/objects-inl.h"
16
17 namespace v8 {
18 namespace internal {
19
20 template <typename ResultType, typename ConcreteVisitor>
21 template <typename T>
Cast(HeapObject * object)22 T* HeapVisitor<ResultType, ConcreteVisitor>::Cast(HeapObject* object) {
23 return T::cast(object);
24 }
25
26 template <typename ResultType, typename ConcreteVisitor>
Visit(HeapObject * object)27 ResultType HeapVisitor<ResultType, ConcreteVisitor>::Visit(HeapObject* object) {
28 return Visit(object->map(), object);
29 }
30
31 template <typename ResultType, typename ConcreteVisitor>
Visit(Map * map,HeapObject * object)32 ResultType HeapVisitor<ResultType, ConcreteVisitor>::Visit(Map* map,
33 HeapObject* object) {
34 ConcreteVisitor* visitor = static_cast<ConcreteVisitor*>(this);
35 switch (map->visitor_id()) {
36 #define CASE(type) \
37 case kVisit##type: \
38 return visitor->Visit##type(map, \
39 ConcreteVisitor::template Cast<type>(object));
40 TYPED_VISITOR_ID_LIST(CASE)
41 #undef CASE
42 case kVisitShortcutCandidate:
43 return visitor->VisitShortcutCandidate(
44 map, ConcreteVisitor::template Cast<ConsString>(object));
45 case kVisitNativeContext:
46 return visitor->VisitNativeContext(
47 map, ConcreteVisitor::template Cast<Context>(object));
48 case kVisitDataObject:
49 return visitor->VisitDataObject(map, object);
50 case kVisitJSObjectFast:
51 return visitor->VisitJSObjectFast(
52 map, ConcreteVisitor::template Cast<JSObject>(object));
53 case kVisitJSApiObject:
54 return visitor->VisitJSApiObject(
55 map, ConcreteVisitor::template Cast<JSObject>(object));
56 case kVisitStruct:
57 return visitor->VisitStruct(map, object);
58 case kVisitFreeSpace:
59 return visitor->VisitFreeSpace(map, FreeSpace::cast(object));
60 case kVisitWeakArray:
61 return visitor->VisitWeakArray(map, object);
62 case kVisitorIdCount:
63 UNREACHABLE();
64 }
65 UNREACHABLE();
66 // Make the compiler happy.
67 return ResultType();
68 }
69
70 template <typename ResultType, typename ConcreteVisitor>
VisitMapPointer(HeapObject * host,HeapObject ** map)71 void HeapVisitor<ResultType, ConcreteVisitor>::VisitMapPointer(
72 HeapObject* host, HeapObject** map) {
73 static_cast<ConcreteVisitor*>(this)->VisitPointer(
74 host, reinterpret_cast<Object**>(map));
75 }
76
77 #define VISIT(type) \
78 template <typename ResultType, typename ConcreteVisitor> \
79 ResultType HeapVisitor<ResultType, ConcreteVisitor>::Visit##type( \
80 Map* map, type* object) { \
81 ConcreteVisitor* visitor = static_cast<ConcreteVisitor*>(this); \
82 if (!visitor->ShouldVisit(object)) return ResultType(); \
83 if (!visitor->AllowDefaultJSObjectVisit()) { \
84 DCHECK_WITH_MSG(!map->IsJSObjectMap(), \
85 "Implement custom visitor for new JSObject subclass in " \
86 "concurrent marker"); \
87 } \
88 int size = type::BodyDescriptor::SizeOf(map, object); \
89 if (visitor->ShouldVisitMapPointer()) \
90 visitor->VisitMapPointer(object, object->map_slot()); \
91 type::BodyDescriptor::IterateBody(map, object, size, visitor); \
92 return static_cast<ResultType>(size); \
93 }
TYPED_VISITOR_ID_LIST(VISIT)94 TYPED_VISITOR_ID_LIST(VISIT)
95 #undef VISIT
96
97 template <typename ResultType, typename ConcreteVisitor>
98 ResultType HeapVisitor<ResultType, ConcreteVisitor>::VisitShortcutCandidate(
99 Map* map, ConsString* object) {
100 return static_cast<ConcreteVisitor*>(this)->VisitConsString(map, object);
101 }
102
103 template <typename ResultType, typename ConcreteVisitor>
VisitNativeContext(Map * map,Context * object)104 ResultType HeapVisitor<ResultType, ConcreteVisitor>::VisitNativeContext(
105 Map* map, Context* object) {
106 ConcreteVisitor* visitor = static_cast<ConcreteVisitor*>(this);
107 if (!visitor->ShouldVisit(object)) return ResultType();
108 int size = Context::BodyDescriptor::SizeOf(map, object);
109 if (visitor->ShouldVisitMapPointer())
110 visitor->VisitMapPointer(object, object->map_slot());
111 Context::BodyDescriptor::IterateBody(map, object, size, visitor);
112 return static_cast<ResultType>(size);
113 }
114
115 template <typename ResultType, typename ConcreteVisitor>
VisitDataObject(Map * map,HeapObject * object)116 ResultType HeapVisitor<ResultType, ConcreteVisitor>::VisitDataObject(
117 Map* map, HeapObject* object) {
118 ConcreteVisitor* visitor = static_cast<ConcreteVisitor*>(this);
119 if (!visitor->ShouldVisit(object)) return ResultType();
120 int size = map->instance_size();
121 if (visitor->ShouldVisitMapPointer())
122 visitor->VisitMapPointer(object, object->map_slot());
123 return static_cast<ResultType>(size);
124 }
125
126 template <typename ResultType, typename ConcreteVisitor>
VisitJSObjectFast(Map * map,JSObject * object)127 ResultType HeapVisitor<ResultType, ConcreteVisitor>::VisitJSObjectFast(
128 Map* map, JSObject* object) {
129 ConcreteVisitor* visitor = static_cast<ConcreteVisitor*>(this);
130 if (!visitor->ShouldVisit(object)) return ResultType();
131 int size = JSObject::FastBodyDescriptor::SizeOf(map, object);
132 if (visitor->ShouldVisitMapPointer())
133 visitor->VisitMapPointer(object, object->map_slot());
134 JSObject::FastBodyDescriptor::IterateBody(map, object, size, visitor);
135 return static_cast<ResultType>(size);
136 }
137
138 template <typename ResultType, typename ConcreteVisitor>
VisitJSApiObject(Map * map,JSObject * object)139 ResultType HeapVisitor<ResultType, ConcreteVisitor>::VisitJSApiObject(
140 Map* map, JSObject* object) {
141 ConcreteVisitor* visitor = static_cast<ConcreteVisitor*>(this);
142 if (!visitor->ShouldVisit(object)) return ResultType();
143 int size = JSObject::BodyDescriptor::SizeOf(map, object);
144 if (visitor->ShouldVisitMapPointer())
145 visitor->VisitMapPointer(object, object->map_slot());
146 JSObject::BodyDescriptor::IterateBody(map, object, size, visitor);
147 return static_cast<ResultType>(size);
148 }
149
150 template <typename ResultType, typename ConcreteVisitor>
VisitStruct(Map * map,HeapObject * object)151 ResultType HeapVisitor<ResultType, ConcreteVisitor>::VisitStruct(
152 Map* map, HeapObject* object) {
153 ConcreteVisitor* visitor = static_cast<ConcreteVisitor*>(this);
154 if (!visitor->ShouldVisit(object)) return ResultType();
155 int size = map->instance_size();
156 if (visitor->ShouldVisitMapPointer())
157 visitor->VisitMapPointer(object, object->map_slot());
158 StructBodyDescriptor::IterateBody(map, object, size, visitor);
159 return static_cast<ResultType>(size);
160 }
161
162 template <typename ResultType, typename ConcreteVisitor>
VisitFreeSpace(Map * map,FreeSpace * object)163 ResultType HeapVisitor<ResultType, ConcreteVisitor>::VisitFreeSpace(
164 Map* map, FreeSpace* object) {
165 ConcreteVisitor* visitor = static_cast<ConcreteVisitor*>(this);
166 if (!visitor->ShouldVisit(object)) return ResultType();
167 if (visitor->ShouldVisitMapPointer())
168 visitor->VisitMapPointer(object, object->map_slot());
169 return static_cast<ResultType>(FreeSpace::cast(object)->size());
170 }
171
172 template <typename ConcreteVisitor>
VisitJSFunction(Map * map,JSFunction * object)173 int NewSpaceVisitor<ConcreteVisitor>::VisitJSFunction(Map* map,
174 JSFunction* object) {
175 ConcreteVisitor* visitor = static_cast<ConcreteVisitor*>(this);
176 int size = JSFunction::BodyDescriptorWeak::SizeOf(map, object);
177 JSFunction::BodyDescriptorWeak::IterateBody(map, object, size, visitor);
178 return size;
179 }
180
181 template <typename ConcreteVisitor>
VisitNativeContext(Map * map,Context * object)182 int NewSpaceVisitor<ConcreteVisitor>::VisitNativeContext(Map* map,
183 Context* object) {
184 ConcreteVisitor* visitor = static_cast<ConcreteVisitor*>(this);
185 int size = Context::BodyDescriptor::SizeOf(map, object);
186 Context::BodyDescriptor::IterateBody(map, object, size, visitor);
187 return size;
188 }
189
190 template <typename ConcreteVisitor>
VisitJSApiObject(Map * map,JSObject * object)191 int NewSpaceVisitor<ConcreteVisitor>::VisitJSApiObject(Map* map,
192 JSObject* object) {
193 ConcreteVisitor* visitor = static_cast<ConcreteVisitor*>(this);
194 return visitor->VisitJSObject(map, object);
195 }
196
197 template <typename ResultType, typename ConcreteVisitor>
VisitWeakArray(Map * map,HeapObject * object)198 ResultType HeapVisitor<ResultType, ConcreteVisitor>::VisitWeakArray(
199 Map* map, HeapObject* object) {
200 ConcreteVisitor* visitor = static_cast<ConcreteVisitor*>(this);
201 if (!visitor->ShouldVisit(object)) return ResultType();
202 int size = WeakArrayBodyDescriptor::SizeOf(map, object);
203 if (visitor->ShouldVisitMapPointer())
204 visitor->VisitMapPointer(object, object->map_slot());
205 WeakArrayBodyDescriptor::IterateBody(map, object, size, visitor);
206 return size;
207 }
208
209 } // namespace internal
210 } // namespace v8
211
212 #endif // V8_HEAP_OBJECTS_VISITING_INL_H_
213