• 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/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