Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(559)

Side by Side Diff: src/heap/objects-visiting.h

Issue 443933002: Move objects-visiting into heap. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 6 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/heap/mark-compact.cc ('k') | src/heap/objects-visiting.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #ifndef V8_OBJECTS_VISITING_H_ 5 #ifndef V8_OBJECTS_VISITING_H_
6 #define V8_OBJECTS_VISITING_H_ 6 #define V8_OBJECTS_VISITING_H_
7 7
8 #include "src/allocation.h" 8 #include "src/allocation.h"
9 9
10 // This file provides base classes and auxiliary methods for defining 10 // This file provides base classes and auxiliary methods for defining
11 // static object visitors used during GC. 11 // static object visitors used during GC.
12 // Visiting HeapObject body with a normal ObjectVisitor requires performing 12 // Visiting HeapObject body with a normal ObjectVisitor requires performing
13 // two switches on object's instance type to determine object size and layout 13 // two switches on object's instance type to determine object size and layout
14 // and one or more virtual method calls on visitor itself. 14 // and one or more virtual method calls on visitor itself.
15 // Static visitor is different: it provides a dispatch table which contains 15 // Static visitor is different: it provides a dispatch table which contains
16 // pointers to specialized visit functions. Each map has the visitor_id 16 // pointers to specialized visit functions. Each map has the visitor_id
17 // field which contains an index of specialized visitor to use. 17 // field which contains an index of specialized visitor to use.
18 18
19 namespace v8 { 19 namespace v8 {
20 namespace internal { 20 namespace internal {
21 21
22 22
23 // Base class for all static visitors. 23 // Base class for all static visitors.
24 class StaticVisitorBase : public AllStatic { 24 class StaticVisitorBase : public AllStatic {
25 public: 25 public:
26 #define VISITOR_ID_LIST(V) \ 26 #define VISITOR_ID_LIST(V) \
27 V(SeqOneByteString) \ 27 V(SeqOneByteString) \
28 V(SeqTwoByteString) \ 28 V(SeqTwoByteString) \
29 V(ShortcutCandidate) \ 29 V(ShortcutCandidate) \
30 V(ByteArray) \ 30 V(ByteArray) \
31 V(FreeSpace) \ 31 V(FreeSpace) \
32 V(FixedArray) \ 32 V(FixedArray) \
33 V(FixedDoubleArray) \ 33 V(FixedDoubleArray) \
34 V(FixedTypedArray) \ 34 V(FixedTypedArray) \
35 V(FixedFloat64Array) \ 35 V(FixedFloat64Array) \
36 V(ConstantPoolArray) \ 36 V(ConstantPoolArray) \
37 V(NativeContext) \ 37 V(NativeContext) \
38 V(AllocationSite) \ 38 V(AllocationSite) \
39 V(DataObject2) \ 39 V(DataObject2) \
40 V(DataObject3) \ 40 V(DataObject3) \
41 V(DataObject4) \ 41 V(DataObject4) \
42 V(DataObject5) \ 42 V(DataObject5) \
43 V(DataObject6) \ 43 V(DataObject6) \
44 V(DataObject7) \ 44 V(DataObject7) \
45 V(DataObject8) \ 45 V(DataObject8) \
46 V(DataObject9) \ 46 V(DataObject9) \
47 V(DataObjectGeneric) \ 47 V(DataObjectGeneric) \
48 V(JSObject2) \ 48 V(JSObject2) \
49 V(JSObject3) \ 49 V(JSObject3) \
50 V(JSObject4) \ 50 V(JSObject4) \
51 V(JSObject5) \ 51 V(JSObject5) \
52 V(JSObject6) \ 52 V(JSObject6) \
53 V(JSObject7) \ 53 V(JSObject7) \
54 V(JSObject8) \ 54 V(JSObject8) \
55 V(JSObject9) \ 55 V(JSObject9) \
56 V(JSObjectGeneric) \ 56 V(JSObjectGeneric) \
57 V(Struct2) \ 57 V(Struct2) \
58 V(Struct3) \ 58 V(Struct3) \
59 V(Struct4) \ 59 V(Struct4) \
60 V(Struct5) \ 60 V(Struct5) \
61 V(Struct6) \ 61 V(Struct6) \
62 V(Struct7) \ 62 V(Struct7) \
63 V(Struct8) \ 63 V(Struct8) \
64 V(Struct9) \ 64 V(Struct9) \
65 V(StructGeneric) \ 65 V(StructGeneric) \
66 V(ConsString) \ 66 V(ConsString) \
67 V(SlicedString) \ 67 V(SlicedString) \
68 V(Symbol) \ 68 V(Symbol) \
69 V(Oddball) \ 69 V(Oddball) \
70 V(Code) \ 70 V(Code) \
71 V(Map) \ 71 V(Map) \
72 V(Cell) \ 72 V(Cell) \
73 V(PropertyCell) \ 73 V(PropertyCell) \
74 V(SharedFunctionInfo) \ 74 V(SharedFunctionInfo) \
75 V(JSFunction) \ 75 V(JSFunction) \
76 V(JSWeakCollection) \ 76 V(JSWeakCollection) \
77 V(JSArrayBuffer) \ 77 V(JSArrayBuffer) \
78 V(JSTypedArray) \ 78 V(JSTypedArray) \
79 V(JSDataView) \ 79 V(JSDataView) \
80 V(JSRegExp) 80 V(JSRegExp)
81 81
82 // For data objects, JS objects and structs along with generic visitor which 82 // For data objects, JS objects and structs along with generic visitor which
83 // can visit object of any size we provide visitors specialized by 83 // can visit object of any size we provide visitors specialized by
84 // object size in words. 84 // object size in words.
85 // Ids of specialized visitors are declared in a linear order (without 85 // Ids of specialized visitors are declared in a linear order (without
86 // holes) starting from the id of visitor specialized for 2 words objects 86 // holes) starting from the id of visitor specialized for 2 words objects
87 // (base visitor id) and ending with the id of generic visitor. 87 // (base visitor id) and ending with the id of generic visitor.
88 // Method GetVisitorIdForSize depends on this ordering to calculate visitor 88 // Method GetVisitorIdForSize depends on this ordering to calculate visitor
89 // id of specialized visitor from given instance size, base visitor id and 89 // id of specialized visitor from given instance size, base visitor id and
90 // generic visitor's id. 90 // generic visitor's id.
91 enum VisitorId { 91 enum VisitorId {
92 #define VISITOR_ID_ENUM_DECL(id) kVisit##id, 92 #define VISITOR_ID_ENUM_DECL(id) kVisit##id,
93 VISITOR_ID_LIST(VISITOR_ID_ENUM_DECL) 93 VISITOR_ID_LIST(VISITOR_ID_ENUM_DECL)
94 #undef VISITOR_ID_ENUM_DECL 94 #undef VISITOR_ID_ENUM_DECL
95 kVisitorIdCount, 95 kVisitorIdCount,
96 kVisitDataObject = kVisitDataObject2, 96 kVisitDataObject = kVisitDataObject2,
97 kVisitJSObject = kVisitJSObject2, 97 kVisitJSObject = kVisitJSObject2,
98 kVisitStruct = kVisitStruct2, 98 kVisitStruct = kVisitStruct2,
99 kMinObjectSizeInWords = 2 99 kMinObjectSizeInWords = 2
100 }; 100 };
101 101
102 // Visitor ID should fit in one byte. 102 // Visitor ID should fit in one byte.
103 STATIC_ASSERT(kVisitorIdCount <= 256); 103 STATIC_ASSERT(kVisitorIdCount <= 256);
104 104
105 // Determine which specialized visitor should be used for given instance type 105 // Determine which specialized visitor should be used for given instance type
106 // and instance type. 106 // and instance type.
107 static VisitorId GetVisitorId(int instance_type, int instance_size); 107 static VisitorId GetVisitorId(int instance_type, int instance_size);
108 108
109 static VisitorId GetVisitorId(Map* map) { 109 static VisitorId GetVisitorId(Map* map) {
110 return GetVisitorId(map->instance_type(), map->instance_size()); 110 return GetVisitorId(map->instance_type(), map->instance_size());
111 } 111 }
112 112
113 // For visitors that allow specialization by size calculate VisitorId based 113 // For visitors that allow specialization by size calculate VisitorId based
114 // on size, base visitor id and generic visitor id. 114 // on size, base visitor id and generic visitor id.
115 static VisitorId GetVisitorIdForSize(VisitorId base, 115 static VisitorId GetVisitorIdForSize(VisitorId base, VisitorId generic,
116 VisitorId generic,
117 int object_size) { 116 int object_size) {
118 DCHECK((base == kVisitDataObject) || 117 DCHECK((base == kVisitDataObject) || (base == kVisitStruct) ||
119 (base == kVisitStruct) ||
120 (base == kVisitJSObject)); 118 (base == kVisitJSObject));
121 DCHECK(IsAligned(object_size, kPointerSize)); 119 DCHECK(IsAligned(object_size, kPointerSize));
122 DCHECK(kMinObjectSizeInWords * kPointerSize <= object_size); 120 DCHECK(kMinObjectSizeInWords * kPointerSize <= object_size);
123 DCHECK(object_size <= Page::kMaxRegularHeapObjectSize); 121 DCHECK(object_size <= Page::kMaxRegularHeapObjectSize);
124 122
125 const VisitorId specialization = static_cast<VisitorId>( 123 const VisitorId specialization = static_cast<VisitorId>(
126 base + (object_size >> kPointerSizeLog2) - kMinObjectSizeInWords); 124 base + (object_size >> kPointerSizeLog2) - kMinObjectSizeInWords);
127 125
128 return Min(specialization, generic); 126 return Min(specialization, generic);
129 } 127 }
130 }; 128 };
131 129
132 130
133 template<typename Callback> 131 template <typename Callback>
134 class VisitorDispatchTable { 132 class VisitorDispatchTable {
135 public: 133 public:
136 void CopyFrom(VisitorDispatchTable* other) { 134 void CopyFrom(VisitorDispatchTable* other) {
137 // We are not using memcpy to guarantee that during update 135 // We are not using memcpy to guarantee that during update
138 // every element of callbacks_ array will remain correct 136 // every element of callbacks_ array will remain correct
139 // pointer (memcpy might be implemented as a byte copying loop). 137 // pointer (memcpy might be implemented as a byte copying loop).
140 for (int i = 0; i < StaticVisitorBase::kVisitorIdCount; i++) { 138 for (int i = 0; i < StaticVisitorBase::kVisitorIdCount; i++) {
141 base::NoBarrier_Store(&callbacks_[i], other->callbacks_[i]); 139 base::NoBarrier_Store(&callbacks_[i], other->callbacks_[i]);
142 } 140 }
143 } 141 }
144 142
145 inline Callback GetVisitorById(StaticVisitorBase::VisitorId id) { 143 inline Callback GetVisitorById(StaticVisitorBase::VisitorId id) {
146 return reinterpret_cast<Callback>(callbacks_[id]); 144 return reinterpret_cast<Callback>(callbacks_[id]);
147 } 145 }
148 146
149 inline Callback GetVisitor(Map* map) { 147 inline Callback GetVisitor(Map* map) {
150 return reinterpret_cast<Callback>(callbacks_[map->visitor_id()]); 148 return reinterpret_cast<Callback>(callbacks_[map->visitor_id()]);
151 } 149 }
152 150
153 void Register(StaticVisitorBase::VisitorId id, Callback callback) { 151 void Register(StaticVisitorBase::VisitorId id, Callback callback) {
154 DCHECK(id < StaticVisitorBase::kVisitorIdCount); // id is unsigned. 152 DCHECK(id < StaticVisitorBase::kVisitorIdCount); // id is unsigned.
155 callbacks_[id] = reinterpret_cast<base::AtomicWord>(callback); 153 callbacks_[id] = reinterpret_cast<base::AtomicWord>(callback);
156 } 154 }
157 155
158 template<typename Visitor, 156 template <typename Visitor, StaticVisitorBase::VisitorId base,
159 StaticVisitorBase::VisitorId base, 157 StaticVisitorBase::VisitorId generic, int object_size_in_words>
160 StaticVisitorBase::VisitorId generic,
161 int object_size_in_words>
162 void RegisterSpecialization() { 158 void RegisterSpecialization() {
163 static const int size = object_size_in_words * kPointerSize; 159 static const int size = object_size_in_words * kPointerSize;
164 Register(StaticVisitorBase::GetVisitorIdForSize(base, generic, size), 160 Register(StaticVisitorBase::GetVisitorIdForSize(base, generic, size),
165 &Visitor::template VisitSpecialized<size>); 161 &Visitor::template VisitSpecialized<size>);
166 } 162 }
167 163
168 164
169 template<typename Visitor, 165 template <typename Visitor, StaticVisitorBase::VisitorId base,
170 StaticVisitorBase::VisitorId base, 166 StaticVisitorBase::VisitorId generic>
171 StaticVisitorBase::VisitorId generic>
172 void RegisterSpecializations() { 167 void RegisterSpecializations() {
173 STATIC_ASSERT( 168 STATIC_ASSERT((generic - base + StaticVisitorBase::kMinObjectSizeInWords) ==
174 (generic - base + StaticVisitorBase::kMinObjectSizeInWords) == 10); 169 10);
175 RegisterSpecialization<Visitor, base, generic, 2>(); 170 RegisterSpecialization<Visitor, base, generic, 2>();
176 RegisterSpecialization<Visitor, base, generic, 3>(); 171 RegisterSpecialization<Visitor, base, generic, 3>();
177 RegisterSpecialization<Visitor, base, generic, 4>(); 172 RegisterSpecialization<Visitor, base, generic, 4>();
178 RegisterSpecialization<Visitor, base, generic, 5>(); 173 RegisterSpecialization<Visitor, base, generic, 5>();
179 RegisterSpecialization<Visitor, base, generic, 6>(); 174 RegisterSpecialization<Visitor, base, generic, 6>();
180 RegisterSpecialization<Visitor, base, generic, 7>(); 175 RegisterSpecialization<Visitor, base, generic, 7>();
181 RegisterSpecialization<Visitor, base, generic, 8>(); 176 RegisterSpecialization<Visitor, base, generic, 8>();
182 RegisterSpecialization<Visitor, base, generic, 9>(); 177 RegisterSpecialization<Visitor, base, generic, 9>();
183 Register(generic, &Visitor::Visit); 178 Register(generic, &Visitor::Visit);
184 } 179 }
185 180
186 private: 181 private:
187 base::AtomicWord callbacks_[StaticVisitorBase::kVisitorIdCount]; 182 base::AtomicWord callbacks_[StaticVisitorBase::kVisitorIdCount];
188 }; 183 };
189 184
190 185
191 template<typename StaticVisitor> 186 template <typename StaticVisitor>
192 class BodyVisitorBase : public AllStatic { 187 class BodyVisitorBase : public AllStatic {
193 public: 188 public:
194 INLINE(static void IteratePointers(Heap* heap, 189 INLINE(static void IteratePointers(Heap* heap, HeapObject* object,
195 HeapObject* object, 190 int start_offset, int end_offset)) {
196 int start_offset, 191 Object** start_slot =
197 int end_offset)) { 192 reinterpret_cast<Object**>(object->address() + start_offset);
198 Object** start_slot = reinterpret_cast<Object**>(object->address() + 193 Object** end_slot =
199 start_offset); 194 reinterpret_cast<Object**>(object->address() + end_offset);
200 Object** end_slot = reinterpret_cast<Object**>(object->address() +
201 end_offset);
202 StaticVisitor::VisitPointers(heap, start_slot, end_slot); 195 StaticVisitor::VisitPointers(heap, start_slot, end_slot);
203 } 196 }
204 }; 197 };
205 198
206 199
207 template<typename StaticVisitor, typename BodyDescriptor, typename ReturnType> 200 template <typename StaticVisitor, typename BodyDescriptor, typename ReturnType>
208 class FlexibleBodyVisitor : public BodyVisitorBase<StaticVisitor> { 201 class FlexibleBodyVisitor : public BodyVisitorBase<StaticVisitor> {
209 public: 202 public:
210 INLINE(static ReturnType Visit(Map* map, HeapObject* object)) { 203 INLINE(static ReturnType Visit(Map* map, HeapObject* object)) {
211 int object_size = BodyDescriptor::SizeOf(map, object); 204 int object_size = BodyDescriptor::SizeOf(map, object);
212 BodyVisitorBase<StaticVisitor>::IteratePointers( 205 BodyVisitorBase<StaticVisitor>::IteratePointers(
213 map->GetHeap(), 206 map->GetHeap(), object, BodyDescriptor::kStartOffset, object_size);
214 object,
215 BodyDescriptor::kStartOffset,
216 object_size);
217 return static_cast<ReturnType>(object_size); 207 return static_cast<ReturnType>(object_size);
218 } 208 }
219 209
220 template<int object_size> 210 template <int object_size>
221 static inline ReturnType VisitSpecialized(Map* map, HeapObject* object) { 211 static inline ReturnType VisitSpecialized(Map* map, HeapObject* object) {
222 DCHECK(BodyDescriptor::SizeOf(map, object) == object_size); 212 DCHECK(BodyDescriptor::SizeOf(map, object) == object_size);
223 BodyVisitorBase<StaticVisitor>::IteratePointers( 213 BodyVisitorBase<StaticVisitor>::IteratePointers(
224 map->GetHeap(), 214 map->GetHeap(), object, BodyDescriptor::kStartOffset, object_size);
225 object,
226 BodyDescriptor::kStartOffset,
227 object_size);
228 return static_cast<ReturnType>(object_size); 215 return static_cast<ReturnType>(object_size);
229 } 216 }
230 }; 217 };
231 218
232 219
233 template<typename StaticVisitor, typename BodyDescriptor, typename ReturnType> 220 template <typename StaticVisitor, typename BodyDescriptor, typename ReturnType>
234 class FixedBodyVisitor : public BodyVisitorBase<StaticVisitor> { 221 class FixedBodyVisitor : public BodyVisitorBase<StaticVisitor> {
235 public: 222 public:
236 INLINE(static ReturnType Visit(Map* map, HeapObject* object)) { 223 INLINE(static ReturnType Visit(Map* map, HeapObject* object)) {
237 BodyVisitorBase<StaticVisitor>::IteratePointers( 224 BodyVisitorBase<StaticVisitor>::IteratePointers(
238 map->GetHeap(), 225 map->GetHeap(), object, BodyDescriptor::kStartOffset,
239 object,
240 BodyDescriptor::kStartOffset,
241 BodyDescriptor::kEndOffset); 226 BodyDescriptor::kEndOffset);
242 return static_cast<ReturnType>(BodyDescriptor::kSize); 227 return static_cast<ReturnType>(BodyDescriptor::kSize);
243 } 228 }
244 }; 229 };
245 230
246 231
247 // Base class for visitors used for a linear new space iteration. 232 // Base class for visitors used for a linear new space iteration.
248 // IterateBody returns size of visited object. 233 // IterateBody returns size of visited object.
249 // Certain types of objects (i.e. Code objects) are not handled 234 // Certain types of objects (i.e. Code objects) are not handled
250 // by dispatch table of this visitor because they cannot appear 235 // by dispatch table of this visitor because they cannot appear
251 // in the new space. 236 // in the new space.
252 // 237 //
253 // This class is intended to be used in the following way: 238 // This class is intended to be used in the following way:
254 // 239 //
255 // class SomeVisitor : public StaticNewSpaceVisitor<SomeVisitor> { 240 // class SomeVisitor : public StaticNewSpaceVisitor<SomeVisitor> {
256 // ... 241 // ...
257 // } 242 // }
258 // 243 //
259 // This is an example of Curiously recurring template pattern 244 // This is an example of Curiously recurring template pattern
260 // (see http://en.wikipedia.org/wiki/Curiously_recurring_template_pattern). 245 // (see http://en.wikipedia.org/wiki/Curiously_recurring_template_pattern).
261 // We use CRTP to guarantee aggressive compile time optimizations (i.e. 246 // We use CRTP to guarantee aggressive compile time optimizations (i.e.
262 // inlining and specialization of StaticVisitor::VisitPointers methods). 247 // inlining and specialization of StaticVisitor::VisitPointers methods).
263 template<typename StaticVisitor> 248 template <typename StaticVisitor>
264 class StaticNewSpaceVisitor : public StaticVisitorBase { 249 class StaticNewSpaceVisitor : public StaticVisitorBase {
265 public: 250 public:
266 static void Initialize(); 251 static void Initialize();
267 252
268 INLINE(static int IterateBody(Map* map, HeapObject* obj)) { 253 INLINE(static int IterateBody(Map* map, HeapObject* obj)) {
269 return table_.GetVisitor(map)(map, obj); 254 return table_.GetVisitor(map)(map, obj);
270 } 255 }
271 256
272 INLINE(static void VisitPointers(Heap* heap, Object** start, Object** end)) { 257 INLINE(static void VisitPointers(Heap* heap, Object** start, Object** end)) {
273 for (Object** p = start; p < end; p++) StaticVisitor::VisitPointer(heap, p); 258 for (Object** p = start; p < end; p++) StaticVisitor::VisitPointer(heap, p);
274 } 259 }
275 260
276 private: 261 private:
277 INLINE(static int VisitJSFunction(Map* map, HeapObject* object)) { 262 INLINE(static int VisitJSFunction(Map* map, HeapObject* object)) {
278 Heap* heap = map->GetHeap(); 263 Heap* heap = map->GetHeap();
279 VisitPointers(heap, 264 VisitPointers(heap,
280 HeapObject::RawField(object, JSFunction::kPropertiesOffset), 265 HeapObject::RawField(object, JSFunction::kPropertiesOffset),
281 HeapObject::RawField(object, JSFunction::kCodeEntryOffset)); 266 HeapObject::RawField(object, JSFunction::kCodeEntryOffset));
282 267
283 // Don't visit code entry. We are using this visitor only during scavenges. 268 // Don't visit code entry. We are using this visitor only during scavenges.
284 269
285 VisitPointers( 270 VisitPointers(
286 heap, 271 heap, HeapObject::RawField(object,
287 HeapObject::RawField(object, 272 JSFunction::kCodeEntryOffset + kPointerSize),
288 JSFunction::kCodeEntryOffset + kPointerSize), 273 HeapObject::RawField(object, JSFunction::kNonWeakFieldsEndOffset));
289 HeapObject::RawField(object,
290 JSFunction::kNonWeakFieldsEndOffset));
291 return JSFunction::kSize; 274 return JSFunction::kSize;
292 } 275 }
293 276
294 INLINE(static int VisitByteArray(Map* map, HeapObject* object)) { 277 INLINE(static int VisitByteArray(Map* map, HeapObject* object)) {
295 return reinterpret_cast<ByteArray*>(object)->ByteArraySize(); 278 return reinterpret_cast<ByteArray*>(object)->ByteArraySize();
296 } 279 }
297 280
298 INLINE(static int VisitFixedDoubleArray(Map* map, HeapObject* object)) { 281 INLINE(static int VisitFixedDoubleArray(Map* map, HeapObject* object)) {
299 int length = reinterpret_cast<FixedDoubleArray*>(object)->length(); 282 int length = reinterpret_cast<FixedDoubleArray*>(object)->length();
300 return FixedDoubleArray::SizeFor(length); 283 return FixedDoubleArray::SizeFor(length);
301 } 284 }
302 285
303 INLINE(static int VisitFixedTypedArray(Map* map, HeapObject* object)) { 286 INLINE(static int VisitFixedTypedArray(Map* map, HeapObject* object)) {
304 return reinterpret_cast<FixedTypedArrayBase*>(object)->size(); 287 return reinterpret_cast<FixedTypedArrayBase*>(object)->size();
305 } 288 }
306 289
307 INLINE(static int VisitJSObject(Map* map, HeapObject* object)) { 290 INLINE(static int VisitJSObject(Map* map, HeapObject* object)) {
308 return JSObjectVisitor::Visit(map, object); 291 return JSObjectVisitor::Visit(map, object);
309 } 292 }
310 293
311 INLINE(static int VisitSeqOneByteString(Map* map, HeapObject* object)) { 294 INLINE(static int VisitSeqOneByteString(Map* map, HeapObject* object)) {
312 return SeqOneByteString::cast(object)-> 295 return SeqOneByteString::cast(object)
313 SeqOneByteStringSize(map->instance_type()); 296 ->SeqOneByteStringSize(map->instance_type());
314 } 297 }
315 298
316 INLINE(static int VisitSeqTwoByteString(Map* map, HeapObject* object)) { 299 INLINE(static int VisitSeqTwoByteString(Map* map, HeapObject* object)) {
317 return SeqTwoByteString::cast(object)-> 300 return SeqTwoByteString::cast(object)
318 SeqTwoByteStringSize(map->instance_type()); 301 ->SeqTwoByteStringSize(map->instance_type());
319 } 302 }
320 303
321 INLINE(static int VisitFreeSpace(Map* map, HeapObject* object)) { 304 INLINE(static int VisitFreeSpace(Map* map, HeapObject* object)) {
322 return FreeSpace::cast(object)->Size(); 305 return FreeSpace::cast(object)->Size();
323 } 306 }
324 307
325 INLINE(static int VisitJSArrayBuffer(Map* map, HeapObject* object)); 308 INLINE(static int VisitJSArrayBuffer(Map* map, HeapObject* object));
326 INLINE(static int VisitJSTypedArray(Map* map, HeapObject* object)); 309 INLINE(static int VisitJSTypedArray(Map* map, HeapObject* object));
327 INLINE(static int VisitJSDataView(Map* map, HeapObject* object)); 310 INLINE(static int VisitJSDataView(Map* map, HeapObject* object));
328 311
329 class DataObjectVisitor { 312 class DataObjectVisitor {
330 public: 313 public:
331 template<int object_size> 314 template <int object_size>
332 static inline int VisitSpecialized(Map* map, HeapObject* object) { 315 static inline int VisitSpecialized(Map* map, HeapObject* object) {
333 return object_size; 316 return object_size;
334 } 317 }
335 318
336 INLINE(static int Visit(Map* map, HeapObject* object)) { 319 INLINE(static int Visit(Map* map, HeapObject* object)) {
337 return map->instance_size(); 320 return map->instance_size();
338 } 321 }
339 }; 322 };
340 323
341 typedef FlexibleBodyVisitor<StaticVisitor, 324 typedef FlexibleBodyVisitor<StaticVisitor, StructBodyDescriptor, int>
342 StructBodyDescriptor, 325 StructVisitor;
343 int> StructVisitor;
344 326
345 typedef FlexibleBodyVisitor<StaticVisitor, 327 typedef FlexibleBodyVisitor<StaticVisitor, JSObject::BodyDescriptor, int>
346 JSObject::BodyDescriptor, 328 JSObjectVisitor;
347 int> JSObjectVisitor;
348 329
349 typedef int (*Callback)(Map* map, HeapObject* object); 330 typedef int (*Callback)(Map* map, HeapObject* object);
350 331
351 static VisitorDispatchTable<Callback> table_; 332 static VisitorDispatchTable<Callback> table_;
352 }; 333 };
353 334
354 335
355 template<typename StaticVisitor> 336 template <typename StaticVisitor>
356 VisitorDispatchTable<typename StaticNewSpaceVisitor<StaticVisitor>::Callback> 337 VisitorDispatchTable<typename StaticNewSpaceVisitor<StaticVisitor>::Callback>
357 StaticNewSpaceVisitor<StaticVisitor>::table_; 338 StaticNewSpaceVisitor<StaticVisitor>::table_;
358 339
359 340
360 // Base class for visitors used to transitively mark the entire heap. 341 // Base class for visitors used to transitively mark the entire heap.
361 // IterateBody returns nothing. 342 // IterateBody returns nothing.
362 // Certain types of objects might not be handled by this base class and 343 // Certain types of objects might not be handled by this base class and
363 // no visitor function is registered by the generic initialization. A 344 // no visitor function is registered by the generic initialization. A
364 // specialized visitor function needs to be provided by the inheriting 345 // specialized visitor function needs to be provided by the inheriting
365 // class itself for those cases. 346 // class itself for those cases.
366 // 347 //
367 // This class is intended to be used in the following way: 348 // This class is intended to be used in the following way:
368 // 349 //
369 // class SomeVisitor : public StaticMarkingVisitor<SomeVisitor> { 350 // class SomeVisitor : public StaticMarkingVisitor<SomeVisitor> {
370 // ... 351 // ...
371 // } 352 // }
372 // 353 //
373 // This is an example of Curiously recurring template pattern. 354 // This is an example of Curiously recurring template pattern.
374 template<typename StaticVisitor> 355 template <typename StaticVisitor>
375 class StaticMarkingVisitor : public StaticVisitorBase { 356 class StaticMarkingVisitor : public StaticVisitorBase {
376 public: 357 public:
377 static void Initialize(); 358 static void Initialize();
378 359
379 INLINE(static void IterateBody(Map* map, HeapObject* obj)) { 360 INLINE(static void IterateBody(Map* map, HeapObject* obj)) {
380 table_.GetVisitor(map)(map, obj); 361 table_.GetVisitor(map)(map, obj);
381 } 362 }
382 363
383 INLINE(static void VisitPropertyCell(Map* map, HeapObject* object)); 364 INLINE(static void VisitPropertyCell(Map* map, HeapObject* object));
384 INLINE(static void VisitCodeEntry(Heap* heap, Address entry_address)); 365 INLINE(static void VisitCodeEntry(Heap* heap, Address entry_address));
385 INLINE(static void VisitEmbeddedPointer(Heap* heap, RelocInfo* rinfo)); 366 INLINE(static void VisitEmbeddedPointer(Heap* heap, RelocInfo* rinfo));
386 INLINE(static void VisitCell(Heap* heap, RelocInfo* rinfo)); 367 INLINE(static void VisitCell(Heap* heap, RelocInfo* rinfo));
387 INLINE(static void VisitDebugTarget(Heap* heap, RelocInfo* rinfo)); 368 INLINE(static void VisitDebugTarget(Heap* heap, RelocInfo* rinfo));
388 INLINE(static void VisitCodeTarget(Heap* heap, RelocInfo* rinfo)); 369 INLINE(static void VisitCodeTarget(Heap* heap, RelocInfo* rinfo));
389 INLINE(static void VisitCodeAgeSequence(Heap* heap, RelocInfo* rinfo)); 370 INLINE(static void VisitCodeAgeSequence(Heap* heap, RelocInfo* rinfo));
390 INLINE(static void VisitExternalReference(RelocInfo* rinfo)) { } 371 INLINE(static void VisitExternalReference(RelocInfo* rinfo)) {}
391 INLINE(static void VisitRuntimeEntry(RelocInfo* rinfo)) { } 372 INLINE(static void VisitRuntimeEntry(RelocInfo* rinfo)) {}
392 // Skip the weak next code link in a code object. 373 // Skip the weak next code link in a code object.
393 INLINE(static void VisitNextCodeLink(Heap* heap, Object** slot)) { } 374 INLINE(static void VisitNextCodeLink(Heap* heap, Object** slot)) {}
394 375
395 // TODO(mstarzinger): This should be made protected once refactoring is done. 376 // TODO(mstarzinger): This should be made protected once refactoring is done.
396 // Mark non-optimize code for functions inlined into the given optimized 377 // Mark non-optimize code for functions inlined into the given optimized
397 // code. This will prevent it from being flushed. 378 // code. This will prevent it from being flushed.
398 static void MarkInlinedFunctionsCode(Heap* heap, Code* code); 379 static void MarkInlinedFunctionsCode(Heap* heap, Code* code);
399 380
400 protected: 381 protected:
401 INLINE(static void VisitMap(Map* map, HeapObject* object)); 382 INLINE(static void VisitMap(Map* map, HeapObject* object));
402 INLINE(static void VisitCode(Map* map, HeapObject* object)); 383 INLINE(static void VisitCode(Map* map, HeapObject* object));
403 INLINE(static void VisitSharedFunctionInfo(Map* map, HeapObject* object)); 384 INLINE(static void VisitSharedFunctionInfo(Map* map, HeapObject* object));
(...skipping 18 matching lines...) Expand all
422 403
423 // Helpers used by code flushing support that visit pointer fields and treat 404 // Helpers used by code flushing support that visit pointer fields and treat
424 // references to code objects either strongly or weakly. 405 // references to code objects either strongly or weakly.
425 static void VisitSharedFunctionInfoStrongCode(Heap* heap, HeapObject* object); 406 static void VisitSharedFunctionInfoStrongCode(Heap* heap, HeapObject* object);
426 static void VisitSharedFunctionInfoWeakCode(Heap* heap, HeapObject* object); 407 static void VisitSharedFunctionInfoWeakCode(Heap* heap, HeapObject* object);
427 static void VisitJSFunctionStrongCode(Heap* heap, HeapObject* object); 408 static void VisitJSFunctionStrongCode(Heap* heap, HeapObject* object);
428 static void VisitJSFunctionWeakCode(Heap* heap, HeapObject* object); 409 static void VisitJSFunctionWeakCode(Heap* heap, HeapObject* object);
429 410
430 class DataObjectVisitor { 411 class DataObjectVisitor {
431 public: 412 public:
432 template<int size> 413 template <int size>
433 static inline void VisitSpecialized(Map* map, HeapObject* object) { 414 static inline void VisitSpecialized(Map* map, HeapObject* object) {}
434 }
435 415
436 INLINE(static void Visit(Map* map, HeapObject* object)) { 416 INLINE(static void Visit(Map* map, HeapObject* object)) {}
437 }
438 }; 417 };
439 418
440 typedef FlexibleBodyVisitor<StaticVisitor, 419 typedef FlexibleBodyVisitor<StaticVisitor, FixedArray::BodyDescriptor, void>
441 FixedArray::BodyDescriptor, 420 FixedArrayVisitor;
442 void> FixedArrayVisitor;
443 421
444 typedef FlexibleBodyVisitor<StaticVisitor, 422 typedef FlexibleBodyVisitor<StaticVisitor, JSObject::BodyDescriptor, void>
445 JSObject::BodyDescriptor, 423 JSObjectVisitor;
446 void> JSObjectVisitor;
447 424
448 typedef FlexibleBodyVisitor<StaticVisitor, 425 typedef FlexibleBodyVisitor<StaticVisitor, StructBodyDescriptor, void>
449 StructBodyDescriptor, 426 StructObjectVisitor;
450 void> StructObjectVisitor;
451 427
452 typedef void (*Callback)(Map* map, HeapObject* object); 428 typedef void (*Callback)(Map* map, HeapObject* object);
453 429
454 static VisitorDispatchTable<Callback> table_; 430 static VisitorDispatchTable<Callback> table_;
455 }; 431 };
456 432
457 433
458 template<typename StaticVisitor> 434 template <typename StaticVisitor>
459 VisitorDispatchTable<typename StaticMarkingVisitor<StaticVisitor>::Callback> 435 VisitorDispatchTable<typename StaticMarkingVisitor<StaticVisitor>::Callback>
460 StaticMarkingVisitor<StaticVisitor>::table_; 436 StaticMarkingVisitor<StaticVisitor>::table_;
461 437
462 438
463 class WeakObjectRetainer; 439 class WeakObjectRetainer;
464 440
465 441
466 // A weak list is single linked list where each element has a weak pointer to 442 // A weak list is single linked list where each element has a weak pointer to
467 // the next element. Given the head of the list, this function removes dead 443 // the next element. Given the head of the list, this function removes dead
468 // elements from the list and if requested records slots for next-element 444 // elements from the list and if requested records slots for next-element
469 // pointers. The template parameter T is a WeakListVisitor that defines how to 445 // pointers. The template parameter T is a WeakListVisitor that defines how to
470 // access the next-element pointers. 446 // access the next-element pointers.
471 template <class T> 447 template <class T>
472 Object* VisitWeakList(Heap* heap, Object* list, WeakObjectRetainer* retainer); 448 Object* VisitWeakList(Heap* heap, Object* list, WeakObjectRetainer* retainer);
473 449 }
474 } } // namespace v8::internal 450 } // namespace v8::internal
475 451
476 #endif // V8_OBJECTS_VISITING_H_ 452 #endif // V8_OBJECTS_VISITING_H_
OLDNEW
« no previous file with comments | « src/heap/mark-compact.cc ('k') | src/heap/objects-visiting.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698