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

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

Issue 2808533002: [heap] Reland "Remove size specializations in static object visitors. (patchset #4 id:60001 of http… (Closed)
Patch Set: Created 3 years, 8 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
« no previous file with comments | « no previous file | 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 #include "src/heap/embedder-tracing.h" 9 #include "src/heap/embedder-tracing.h"
10 #include "src/heap/heap.h" 10 #include "src/heap/heap.h"
(...skipping 23 matching lines...) Expand all
34 V(ShortcutCandidate) \ 34 V(ShortcutCandidate) \
35 V(ByteArray) \ 35 V(ByteArray) \
36 V(BytecodeArray) \ 36 V(BytecodeArray) \
37 V(FreeSpace) \ 37 V(FreeSpace) \
38 V(FixedArray) \ 38 V(FixedArray) \
39 V(FixedDoubleArray) \ 39 V(FixedDoubleArray) \
40 V(FixedTypedArray) \ 40 V(FixedTypedArray) \
41 V(FixedFloat64Array) \ 41 V(FixedFloat64Array) \
42 V(NativeContext) \ 42 V(NativeContext) \
43 V(AllocationSite) \ 43 V(AllocationSite) \
44 V(DataObject2) \ 44 V(DataObject) \
45 V(DataObject3) \ 45 V(JSObjectFast) \
46 V(DataObject4) \ 46 V(JSObject) \
47 V(DataObject5) \ 47 V(JSApiObject) \
48 V(DataObject6) \ 48 V(Struct) \
49 V(DataObject7) \
50 V(DataObject8) \
51 V(DataObject9) \
52 V(DataObjectGeneric) \
53 V(JSObject2) \
54 V(JSObject3) \
55 V(JSObject4) \
56 V(JSObject5) \
57 V(JSObject6) \
58 V(JSObject7) \
59 V(JSObject8) \
60 V(JSObject9) \
61 V(JSObjectGeneric) \
62 V(JSApiObject2) \
63 V(JSApiObject3) \
64 V(JSApiObject4) \
65 V(JSApiObject5) \
66 V(JSApiObject6) \
67 V(JSApiObject7) \
68 V(JSApiObject8) \
69 V(JSApiObject9) \
70 V(JSApiObjectGeneric) \
71 V(Struct2) \
72 V(Struct3) \
73 V(Struct4) \
74 V(Struct5) \
75 V(Struct6) \
76 V(Struct7) \
77 V(Struct8) \
78 V(Struct9) \
79 V(StructGeneric) \
80 V(ConsString) \ 49 V(ConsString) \
81 V(SlicedString) \ 50 V(SlicedString) \
82 V(ThinString) \ 51 V(ThinString) \
83 V(Symbol) \ 52 V(Symbol) \
84 V(Oddball) \ 53 V(Oddball) \
85 V(Code) \ 54 V(Code) \
86 V(Map) \ 55 V(Map) \
87 V(Cell) \ 56 V(Cell) \
88 V(PropertyCell) \ 57 V(PropertyCell) \
89 V(WeakCell) \ 58 V(WeakCell) \
(...skipping 10 matching lines...) Expand all
100 // Ids of specialized visitors are declared in a linear order (without 69 // Ids of specialized visitors are declared in a linear order (without
101 // holes) starting from the id of visitor specialized for 2 words objects 70 // holes) starting from the id of visitor specialized for 2 words objects
102 // (base visitor id) and ending with the id of generic visitor. 71 // (base visitor id) and ending with the id of generic visitor.
103 // Method GetVisitorIdForSize depends on this ordering to calculate visitor 72 // Method GetVisitorIdForSize depends on this ordering to calculate visitor
104 // id of specialized visitor from given instance size, base visitor id and 73 // id of specialized visitor from given instance size, base visitor id and
105 // generic visitor's id. 74 // generic visitor's id.
106 enum VisitorId { 75 enum VisitorId {
107 #define VISITOR_ID_ENUM_DECL(id) kVisit##id, 76 #define VISITOR_ID_ENUM_DECL(id) kVisit##id,
108 VISITOR_ID_LIST(VISITOR_ID_ENUM_DECL) 77 VISITOR_ID_LIST(VISITOR_ID_ENUM_DECL)
109 #undef VISITOR_ID_ENUM_DECL 78 #undef VISITOR_ID_ENUM_DECL
110 kVisitorIdCount, 79 kVisitorIdCount
111 kVisitDataObject = kVisitDataObject2,
112 kVisitJSObject = kVisitJSObject2,
113 kVisitJSApiObject = kVisitJSApiObject2,
114 kVisitStruct = kVisitStruct2,
115 }; 80 };
116 81
117 // Visitor ID should fit in one byte. 82 // Visitor ID should fit in one byte.
118 STATIC_ASSERT(kVisitorIdCount <= 256); 83 STATIC_ASSERT(kVisitorIdCount <= 256);
119 84
120 // Determine which specialized visitor should be used for given instance type 85 // Determine which specialized visitor should be used for given instance type
121 // and instance type. 86 // and instance type.
122 static VisitorId GetVisitorId(int instance_type, int instance_size, 87 static VisitorId GetVisitorId(int instance_type, int instance_size,
123 bool has_unboxed_fields); 88 bool has_unboxed_fields);
124 89
125 // Determine which specialized visitor should be used for given map. 90 // Determine which specialized visitor should be used for given map.
126 static VisitorId GetVisitorId(Map* map); 91 static VisitorId GetVisitorId(Map* map);
127
128 // For visitors that allow specialization by size calculate VisitorId based
129 // on size, base visitor id and generic visitor id.
130 static VisitorId GetVisitorIdForSize(VisitorId base, VisitorId generic,
131 int object_size,
132 bool has_unboxed_fields) {
133 DCHECK((base == kVisitDataObject) || (base == kVisitStruct) ||
134 (base == kVisitJSObject) || (base == kVisitJSApiObject));
135 DCHECK(IsAligned(object_size, kPointerSize));
136 DCHECK(Heap::kMinObjectSizeInWords * kPointerSize <= object_size);
137 DCHECK(object_size <= kMaxRegularHeapObjectSize);
138 DCHECK(!has_unboxed_fields || (base == kVisitJSObject) ||
139 (base == kVisitJSApiObject));
140
141 if (has_unboxed_fields) return generic;
142
143 int visitor_id = Min(
144 base + (object_size >> kPointerSizeLog2) - Heap::kMinObjectSizeInWords,
145 static_cast<int>(generic));
146
147 return static_cast<VisitorId>(visitor_id);
148 }
149 }; 92 };
150 93
151 94
152 template <typename Callback> 95 template <typename Callback>
153 class VisitorDispatchTable { 96 class VisitorDispatchTable {
154 public: 97 public:
155 void CopyFrom(VisitorDispatchTable* other) { 98 void CopyFrom(VisitorDispatchTable* other) {
156 // We are not using memcpy to guarantee that during update 99 // We are not using memcpy to guarantee that during update
157 // every element of callbacks_ array will remain correct 100 // every element of callbacks_ array will remain correct
158 // pointer (memcpy might be implemented as a byte copying loop). 101 // pointer (memcpy might be implemented as a byte copying loop).
159 for (int i = 0; i < StaticVisitorBase::kVisitorIdCount; i++) { 102 for (int i = 0; i < StaticVisitorBase::kVisitorIdCount; i++) {
160 base::NoBarrier_Store(&callbacks_[i], other->callbacks_[i]); 103 base::NoBarrier_Store(&callbacks_[i], other->callbacks_[i]);
161 } 104 }
162 } 105 }
163 106
164 inline Callback GetVisitor(Map* map); 107 inline Callback GetVisitor(Map* map);
165 108
166 inline Callback GetVisitorById(StaticVisitorBase::VisitorId id) { 109 inline Callback GetVisitorById(StaticVisitorBase::VisitorId id) {
167 return reinterpret_cast<Callback>(callbacks_[id]); 110 return reinterpret_cast<Callback>(callbacks_[id]);
168 } 111 }
169 112
170 void Register(StaticVisitorBase::VisitorId id, Callback callback) { 113 void Register(StaticVisitorBase::VisitorId id, Callback callback) {
171 DCHECK(id < StaticVisitorBase::kVisitorIdCount); // id is unsigned. 114 DCHECK(id < StaticVisitorBase::kVisitorIdCount); // id is unsigned.
172 callbacks_[id] = reinterpret_cast<base::AtomicWord>(callback); 115 callbacks_[id] = reinterpret_cast<base::AtomicWord>(callback);
173 } 116 }
174 117
175 template <typename Visitor, StaticVisitorBase::VisitorId base,
176 StaticVisitorBase::VisitorId generic, int object_size_in_words>
177 void RegisterSpecialization() {
178 static const int size = object_size_in_words * kPointerSize;
179 Register(StaticVisitorBase::GetVisitorIdForSize(base, generic, size, false),
180 &Visitor::template VisitSpecialized<size>);
181 }
182
183
184 template <typename Visitor, StaticVisitorBase::VisitorId base,
185 StaticVisitorBase::VisitorId generic>
186 void RegisterSpecializations() {
187 STATIC_ASSERT((generic - base + Heap::kMinObjectSizeInWords) == 10);
188 RegisterSpecialization<Visitor, base, generic, 2>();
189 RegisterSpecialization<Visitor, base, generic, 3>();
190 RegisterSpecialization<Visitor, base, generic, 4>();
191 RegisterSpecialization<Visitor, base, generic, 5>();
192 RegisterSpecialization<Visitor, base, generic, 6>();
193 RegisterSpecialization<Visitor, base, generic, 7>();
194 RegisterSpecialization<Visitor, base, generic, 8>();
195 RegisterSpecialization<Visitor, base, generic, 9>();
196 Register(generic, &Visitor::Visit);
197 }
198
199 private: 118 private:
200 base::AtomicWord callbacks_[StaticVisitorBase::kVisitorIdCount]; 119 base::AtomicWord callbacks_[StaticVisitorBase::kVisitorIdCount];
201 }; 120 };
202 121
203 122
204 template <typename StaticVisitor, typename BodyDescriptor, typename ReturnType> 123 template <typename StaticVisitor, typename BodyDescriptor, typename ReturnType>
205 class FlexibleBodyVisitor : public AllStatic { 124 class FlexibleBodyVisitor : public AllStatic {
206 public: 125 public:
207 INLINE(static ReturnType Visit(Map* map, HeapObject* object)) { 126 INLINE(static ReturnType Visit(Map* map, HeapObject* object)) {
208 int object_size = BodyDescriptor::SizeOf(map, object); 127 int object_size = BodyDescriptor::SizeOf(map, object);
209 BodyDescriptor::template IterateBody<StaticVisitor>(object, object_size); 128 BodyDescriptor::template IterateBody<StaticVisitor>(object, object_size);
210 return static_cast<ReturnType>(object_size); 129 return static_cast<ReturnType>(object_size);
211 } 130 }
212
213 // This specialization is only suitable for objects containing pointer fields.
214 template <int object_size>
215 static inline ReturnType VisitSpecialized(Map* map, HeapObject* object) {
216 DCHECK(BodyDescriptor::SizeOf(map, object) == object_size);
217 DCHECK(!FLAG_unbox_double_fields || map->HasFastPointerLayout());
218 StaticVisitor::VisitPointers(
219 object->GetHeap(), object,
220 HeapObject::RawField(object, BodyDescriptor::kStartOffset),
221 HeapObject::RawField(object, object_size));
222 return static_cast<ReturnType>(object_size);
223 }
224 }; 131 };
225 132
226 133
227 template <typename StaticVisitor, typename BodyDescriptor, typename ReturnType> 134 template <typename StaticVisitor, typename BodyDescriptor, typename ReturnType>
228 class FixedBodyVisitor : public AllStatic { 135 class FixedBodyVisitor : public AllStatic {
229 public: 136 public:
230 INLINE(static ReturnType Visit(Map* map, HeapObject* object)) { 137 INLINE(static ReturnType Visit(Map* map, HeapObject* object)) {
231 BodyDescriptor::template IterateBody<StaticVisitor>(object); 138 BodyDescriptor::template IterateBody<StaticVisitor>(object);
232 return static_cast<ReturnType>(BodyDescriptor::kSize); 139 return static_cast<ReturnType>(BodyDescriptor::kSize);
233 } 140 }
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
282 189
283 INLINE(static int VisitByteArray(Map* map, HeapObject* object)) { 190 INLINE(static int VisitByteArray(Map* map, HeapObject* object)) {
284 return reinterpret_cast<ByteArray*>(object)->ByteArraySize(); 191 return reinterpret_cast<ByteArray*>(object)->ByteArraySize();
285 } 192 }
286 193
287 INLINE(static int VisitFixedDoubleArray(Map* map, HeapObject* object)) { 194 INLINE(static int VisitFixedDoubleArray(Map* map, HeapObject* object)) {
288 int length = reinterpret_cast<FixedDoubleArray*>(object)->length(); 195 int length = reinterpret_cast<FixedDoubleArray*>(object)->length();
289 return FixedDoubleArray::SizeFor(length); 196 return FixedDoubleArray::SizeFor(length);
290 } 197 }
291 198
292 INLINE(static int VisitJSObject(Map* map, HeapObject* object)) {
293 return JSObjectVisitor::Visit(map, object);
294 }
295
296 INLINE(static int VisitSeqOneByteString(Map* map, HeapObject* object)) { 199 INLINE(static int VisitSeqOneByteString(Map* map, HeapObject* object)) {
297 return SeqOneByteString::cast(object) 200 return SeqOneByteString::cast(object)
298 ->SeqOneByteStringSize(map->instance_type()); 201 ->SeqOneByteStringSize(map->instance_type());
299 } 202 }
300 203
301 INLINE(static int VisitSeqTwoByteString(Map* map, HeapObject* object)) { 204 INLINE(static int VisitSeqTwoByteString(Map* map, HeapObject* object)) {
302 return SeqTwoByteString::cast(object) 205 return SeqTwoByteString::cast(object)
303 ->SeqTwoByteStringSize(map->instance_type()); 206 ->SeqTwoByteStringSize(map->instance_type());
304 } 207 }
305 208
(...skipping 12 matching lines...) Expand all
318 return map->instance_size(); 221 return map->instance_size();
319 } 222 }
320 }; 223 };
321 224
322 typedef FlexibleBodyVisitor<StaticVisitor, StructBodyDescriptor, int> 225 typedef FlexibleBodyVisitor<StaticVisitor, StructBodyDescriptor, int>
323 StructVisitor; 226 StructVisitor;
324 227
325 typedef FlexibleBodyVisitor<StaticVisitor, JSObject::BodyDescriptor, int> 228 typedef FlexibleBodyVisitor<StaticVisitor, JSObject::BodyDescriptor, int>
326 JSObjectVisitor; 229 JSObjectVisitor;
327 230
231 // Visitor for JSObjects without unboxed double fields.
232 typedef FlexibleBodyVisitor<StaticVisitor, JSObject::FastBodyDescriptor, int>
233 JSObjectFastVisitor;
234
328 typedef int (*Callback)(Map* map, HeapObject* object); 235 typedef int (*Callback)(Map* map, HeapObject* object);
329 236
330 static VisitorDispatchTable<Callback> table_; 237 static VisitorDispatchTable<Callback> table_;
331 }; 238 };
332 239
333 240
334 template <typename StaticVisitor> 241 template <typename StaticVisitor>
335 VisitorDispatchTable<typename StaticNewSpaceVisitor<StaticVisitor>::Callback> 242 VisitorDispatchTable<typename StaticNewSpaceVisitor<StaticVisitor>::Callback>
336 StaticNewSpaceVisitor<StaticVisitor>::table_; 243 StaticNewSpaceVisitor<StaticVisitor>::table_;
337 244
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
401 public: 308 public:
402 template <int size> 309 template <int size>
403 static inline void VisitSpecialized(Map* map, HeapObject* object) {} 310 static inline void VisitSpecialized(Map* map, HeapObject* object) {}
404 311
405 INLINE(static void Visit(Map* map, HeapObject* object)) {} 312 INLINE(static void Visit(Map* map, HeapObject* object)) {}
406 }; 313 };
407 314
408 typedef FlexibleBodyVisitor<StaticVisitor, FixedArray::BodyDescriptor, void> 315 typedef FlexibleBodyVisitor<StaticVisitor, FixedArray::BodyDescriptor, void>
409 FixedArrayVisitor; 316 FixedArrayVisitor;
410 317
318 typedef FlexibleBodyVisitor<StaticVisitor, JSObject::FastBodyDescriptor, void>
319 JSObjectFastVisitor;
411 typedef FlexibleBodyVisitor<StaticVisitor, JSObject::BodyDescriptor, void> 320 typedef FlexibleBodyVisitor<StaticVisitor, JSObject::BodyDescriptor, void>
412 JSObjectVisitor; 321 JSObjectVisitor;
413 322
414 class JSApiObjectVisitor : AllStatic { 323 class JSApiObjectVisitor : AllStatic {
415 public: 324 public:
416 template <int size>
417 static inline void VisitSpecialized(Map* map, HeapObject* object) {
418 TracePossibleWrapper(object);
419 JSObjectVisitor::template VisitSpecialized<size>(map, object);
420 }
421
422 INLINE(static void Visit(Map* map, HeapObject* object)) { 325 INLINE(static void Visit(Map* map, HeapObject* object)) {
423 TracePossibleWrapper(object); 326 TracePossibleWrapper(object);
424 JSObjectVisitor::Visit(map, object); 327 JSObjectVisitor::Visit(map, object);
425 } 328 }
426 329
427 private: 330 private:
428 INLINE(static void TracePossibleWrapper(HeapObject* object)) { 331 INLINE(static void TracePossibleWrapper(HeapObject* object)) {
429 if (object->GetHeap()->local_embedder_heap_tracer()->InUse()) { 332 if (object->GetHeap()->local_embedder_heap_tracer()->InUse()) {
430 DCHECK(object->IsJSObject()); 333 DCHECK(object->IsJSObject());
431 object->GetHeap()->TracePossibleWrapper(JSObject::cast(object)); 334 object->GetHeap()->TracePossibleWrapper(JSObject::cast(object));
(...skipping 22 matching lines...) Expand all
454 // the next element. Given the head of the list, this function removes dead 357 // the next element. Given the head of the list, this function removes dead
455 // elements from the list and if requested records slots for next-element 358 // elements from the list and if requested records slots for next-element
456 // pointers. The template parameter T is a WeakListVisitor that defines how to 359 // pointers. The template parameter T is a WeakListVisitor that defines how to
457 // access the next-element pointers. 360 // access the next-element pointers.
458 template <class T> 361 template <class T>
459 Object* VisitWeakList(Heap* heap, Object* list, WeakObjectRetainer* retainer); 362 Object* VisitWeakList(Heap* heap, Object* list, WeakObjectRetainer* retainer);
460 } // namespace internal 363 } // namespace internal
461 } // namespace v8 364 } // namespace v8
462 365
463 #endif // V8_OBJECTS_VISITING_H_ 366 #endif // V8_OBJECTS_VISITING_H_
OLDNEW
« no previous file with comments | « no previous file | src/heap/objects-visiting.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698