• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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/data-handler-inl.h"
13 #include "src/objects/free-space-inl.h"
14 #include "src/objects/js-weak-refs-inl.h"
15 #include "src/objects/module-inl.h"
16 #include "src/objects/objects-body-descriptors-inl.h"
17 #include "src/objects/objects-inl.h"
18 #include "src/objects/oddball.h"
19 #include "src/objects/ordered-hash-table.h"
20 #include "src/objects/synthetic-module-inl.h"
21 #include "src/objects/torque-defined-classes.h"
22 #include "src/objects/visitors.h"
23 
24 #if V8_ENABLE_WEBASSEMBLY
25 #include "src/wasm/wasm-objects.h"
26 #endif  // V8_ENABLE_WEBASSEMBLY
27 
28 namespace v8 {
29 namespace internal {
30 
31 template <typename ResultType, typename ConcreteVisitor>
HeapVisitor(PtrComprCageBase cage_base,PtrComprCageBase code_cage_base)32 HeapVisitor<ResultType, ConcreteVisitor>::HeapVisitor(
33     PtrComprCageBase cage_base, PtrComprCageBase code_cage_base)
34     : ObjectVisitorWithCageBases(cage_base, code_cage_base) {}
35 
36 template <typename ResultType, typename ConcreteVisitor>
HeapVisitor(Isolate * isolate)37 HeapVisitor<ResultType, ConcreteVisitor>::HeapVisitor(Isolate* isolate)
38     : ObjectVisitorWithCageBases(isolate) {}
39 
40 template <typename ResultType, typename ConcreteVisitor>
HeapVisitor(Heap * heap)41 HeapVisitor<ResultType, ConcreteVisitor>::HeapVisitor(Heap* heap)
42     : ObjectVisitorWithCageBases(heap) {}
43 
44 template <typename ResultType, typename ConcreteVisitor>
45 template <typename T>
Cast(HeapObject object)46 T HeapVisitor<ResultType, ConcreteVisitor>::Cast(HeapObject object) {
47   return T::cast(object);
48 }
49 
50 template <typename ResultType, typename ConcreteVisitor>
Visit(HeapObject object)51 ResultType HeapVisitor<ResultType, ConcreteVisitor>::Visit(HeapObject object) {
52   return Visit(object.map(cage_base()), object);
53 }
54 
55 template <typename ResultType, typename ConcreteVisitor>
Visit(Map map,HeapObject object)56 ResultType HeapVisitor<ResultType, ConcreteVisitor>::Visit(Map map,
57                                                            HeapObject object) {
58   ConcreteVisitor* visitor = static_cast<ConcreteVisitor*>(this);
59   switch (map.visitor_id()) {
60 #define CASE(TypeName)               \
61   case kVisit##TypeName:             \
62     return visitor->Visit##TypeName( \
63         map, ConcreteVisitor::template Cast<TypeName>(object));
64     TYPED_VISITOR_ID_LIST(CASE)
65     TORQUE_VISITOR_ID_LIST(CASE)
66 #undef CASE
67     case kVisitShortcutCandidate:
68       return visitor->VisitShortcutCandidate(
69           map, ConcreteVisitor::template Cast<ConsString>(object));
70     case kVisitDataObject:
71       return visitor->VisitDataObject(map, object);
72     case kVisitJSObjectFast:
73       return visitor->VisitJSObjectFast(
74           map, ConcreteVisitor::template Cast<JSObject>(object));
75     case kVisitJSApiObject:
76       return visitor->VisitJSApiObject(
77           map, ConcreteVisitor::template Cast<JSObject>(object));
78     case kVisitStruct:
79       return visitor->VisitStruct(map, object);
80     case kVisitFreeSpace:
81       return visitor->VisitFreeSpace(map, FreeSpace::cast(object));
82     case kDataOnlyVisitorIdCount:
83     case kVisitorIdCount:
84       UNREACHABLE();
85   }
86   UNREACHABLE();
87   // Make the compiler happy.
88   return ResultType();
89 }
90 
91 template <typename ResultType, typename ConcreteVisitor>
VisitMapPointer(HeapObject host)92 void HeapVisitor<ResultType, ConcreteVisitor>::VisitMapPointer(
93     HeapObject host) {
94   DCHECK(!host.map_word(kRelaxedLoad).IsForwardingAddress());
95   if (!static_cast<ConcreteVisitor*>(this)->ShouldVisitMapPointer()) return;
96   static_cast<ConcreteVisitor*>(this)->VisitMapPointer(host);
97 }
98 
99 #define VISIT(TypeName)                                                        \
100   template <typename ResultType, typename ConcreteVisitor>                     \
101   ResultType HeapVisitor<ResultType, ConcreteVisitor>::Visit##TypeName(        \
102       Map map, TypeName object) {                                              \
103     ConcreteVisitor* visitor = static_cast<ConcreteVisitor*>(this);            \
104     if (!visitor->ShouldVisit(object)) return ResultType();                    \
105     if (!visitor->AllowDefaultJSObjectVisit()) {                               \
106       DCHECK_WITH_MSG(!map.IsJSObjectMap(),                                    \
107                       "Implement custom visitor for new JSObject subclass in " \
108                       "concurrent marker");                                    \
109     }                                                                          \
110     int size = TypeName::BodyDescriptor::SizeOf(map, object);                  \
111     if (visitor->ShouldVisitMapPointer()) {                                    \
112       visitor->VisitMapPointer(object);                                        \
113     }                                                                          \
114     TypeName::BodyDescriptor::IterateBody(map, object, size, visitor);         \
115     return static_cast<ResultType>(size);                                      \
116   }
117 TYPED_VISITOR_ID_LIST(VISIT)
TORQUE_VISITOR_ID_LIST(VISIT)118 TORQUE_VISITOR_ID_LIST(VISIT)
119 #undef VISIT
120 
121 template <typename ResultType, typename ConcreteVisitor>
122 ResultType HeapVisitor<ResultType, ConcreteVisitor>::VisitShortcutCandidate(
123     Map map, ConsString object) {
124   return static_cast<ConcreteVisitor*>(this)->VisitConsString(map, object);
125 }
126 
127 template <typename ResultType, typename ConcreteVisitor>
VisitDataObject(Map map,HeapObject object)128 ResultType HeapVisitor<ResultType, ConcreteVisitor>::VisitDataObject(
129     Map map, HeapObject object) {
130   ConcreteVisitor* visitor = static_cast<ConcreteVisitor*>(this);
131   if (!visitor->ShouldVisit(object)) return ResultType();
132   int size = map.instance_size();
133   if (visitor->ShouldVisitMapPointer()) {
134     visitor->VisitMapPointer(object);
135   }
136 #ifdef V8_SANDBOXED_EXTERNAL_POINTERS
137   // The following types have external pointers, which must be visited.
138   // TODO(v8:10391) Consider adding custom visitor IDs for these.
139   if (object.IsExternalOneByteString()) {
140     ExternalOneByteString::BodyDescriptor::IterateBody(map, object, size,
141                                                        visitor);
142   } else if (object.IsExternalTwoByteString()) {
143     ExternalTwoByteString::BodyDescriptor::IterateBody(map, object, size,
144                                                        visitor);
145   } else if (object.IsForeign()) {
146     Foreign::BodyDescriptor::IterateBody(map, object, size, visitor);
147   }
148 #endif  // V8_SANDBOXED_EXTERNAL_POINTERS
149   return static_cast<ResultType>(size);
150 }
151 
152 template <typename ResultType, typename ConcreteVisitor>
VisitJSObjectFast(Map map,JSObject object)153 ResultType HeapVisitor<ResultType, ConcreteVisitor>::VisitJSObjectFast(
154     Map map, JSObject object) {
155   ConcreteVisitor* visitor = static_cast<ConcreteVisitor*>(this);
156   if (!visitor->ShouldVisit(object)) return ResultType();
157   int size = JSObject::FastBodyDescriptor::SizeOf(map, object);
158   if (visitor->ShouldVisitMapPointer()) {
159     visitor->VisitMapPointer(object);
160   }
161   JSObject::FastBodyDescriptor::IterateBody(map, object, size, visitor);
162   return static_cast<ResultType>(size);
163 }
164 
165 template <typename ResultType, typename ConcreteVisitor>
VisitJSApiObject(Map map,JSObject object)166 ResultType HeapVisitor<ResultType, ConcreteVisitor>::VisitJSApiObject(
167     Map map, JSObject object) {
168   ConcreteVisitor* visitor = static_cast<ConcreteVisitor*>(this);
169   if (!visitor->ShouldVisit(object)) return ResultType();
170   int size = JSObject::BodyDescriptor::SizeOf(map, object);
171   if (visitor->ShouldVisitMapPointer()) {
172     visitor->VisitMapPointer(object);
173   }
174   JSObject::BodyDescriptor::IterateBody(map, object, size, visitor);
175   return static_cast<ResultType>(size);
176 }
177 
178 template <typename ResultType, typename ConcreteVisitor>
VisitStruct(Map map,HeapObject object)179 ResultType HeapVisitor<ResultType, ConcreteVisitor>::VisitStruct(
180     Map map, HeapObject object) {
181   ConcreteVisitor* visitor = static_cast<ConcreteVisitor*>(this);
182   if (!visitor->ShouldVisit(object)) return ResultType();
183   int size = map.instance_size();
184   if (visitor->ShouldVisitMapPointer()) {
185     visitor->VisitMapPointer(object);
186   }
187   StructBodyDescriptor::IterateBody(map, object, size, visitor);
188   return static_cast<ResultType>(size);
189 }
190 
191 template <typename ResultType, typename ConcreteVisitor>
VisitFreeSpace(Map map,FreeSpace object)192 ResultType HeapVisitor<ResultType, ConcreteVisitor>::VisitFreeSpace(
193     Map map, FreeSpace object) {
194   ConcreteVisitor* visitor = static_cast<ConcreteVisitor*>(this);
195   if (!visitor->ShouldVisit(object)) return ResultType();
196   if (visitor->ShouldVisitMapPointer()) {
197     visitor->VisitMapPointer(object);
198   }
199   return static_cast<ResultType>(object.size(kRelaxedLoad));
200 }
201 
202 template <typename ConcreteVisitor>
NewSpaceVisitor(Isolate * isolate)203 NewSpaceVisitor<ConcreteVisitor>::NewSpaceVisitor(Isolate* isolate)
204     : HeapVisitor<int, ConcreteVisitor>(isolate) {}
205 
206 template <typename ConcreteVisitor>
VisitNativeContext(Map map,NativeContext object)207 int NewSpaceVisitor<ConcreteVisitor>::VisitNativeContext(Map map,
208                                                          NativeContext object) {
209   ConcreteVisitor* visitor = static_cast<ConcreteVisitor*>(this);
210   int size = NativeContext::BodyDescriptor::SizeOf(map, object);
211   NativeContext::BodyDescriptor::IterateBody(map, object, size, visitor);
212   return size;
213 }
214 
215 template <typename ConcreteVisitor>
VisitJSApiObject(Map map,JSObject object)216 int NewSpaceVisitor<ConcreteVisitor>::VisitJSApiObject(Map map,
217                                                        JSObject object) {
218   ConcreteVisitor* visitor = static_cast<ConcreteVisitor*>(this);
219   return visitor->VisitJSObject(map, object);
220 }
221 
222 template <typename ConcreteVisitor>
VisitSharedFunctionInfo(Map map,SharedFunctionInfo object)223 int NewSpaceVisitor<ConcreteVisitor>::VisitSharedFunctionInfo(
224     Map map, SharedFunctionInfo object) {
225   UNREACHABLE();
226   return 0;
227 }
228 
229 template <typename ConcreteVisitor>
VisitWeakCell(Map map,WeakCell weak_cell)230 int NewSpaceVisitor<ConcreteVisitor>::VisitWeakCell(Map map,
231                                                     WeakCell weak_cell) {
232   UNREACHABLE();
233   return 0;
234 }
235 
236 }  // namespace internal
237 }  // namespace v8
238 
239 #endif  // V8_HEAP_OBJECTS_VISITING_INL_H_
240