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

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

Issue 2800923004: Revert of [heap] Remove size specializations in static object visitors. (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(DataObject) \ 44 V(DataObject2) \
45 V(JSObjectFast) \ 45 V(DataObject3) \
46 V(JSObject) \ 46 V(DataObject4) \
47 V(JSApiObject) \ 47 V(DataObject5) \
48 V(Struct) \ 48 V(DataObject6) \
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) \
49 V(ConsString) \ 80 V(ConsString) \
50 V(SlicedString) \ 81 V(SlicedString) \
51 V(ThinString) \ 82 V(ThinString) \
52 V(Symbol) \ 83 V(Symbol) \
53 V(Oddball) \ 84 V(Oddball) \
54 V(Code) \ 85 V(Code) \
55 V(Map) \ 86 V(Map) \
56 V(Cell) \ 87 V(Cell) \
57 V(PropertyCell) \ 88 V(PropertyCell) \
58 V(WeakCell) \ 89 V(WeakCell) \
(...skipping 10 matching lines...) Expand all
69 // Ids of specialized visitors are declared in a linear order (without 100 // Ids of specialized visitors are declared in a linear order (without
70 // holes) starting from the id of visitor specialized for 2 words objects 101 // holes) starting from the id of visitor specialized for 2 words objects
71 // (base visitor id) and ending with the id of generic visitor. 102 // (base visitor id) and ending with the id of generic visitor.
72 // Method GetVisitorIdForSize depends on this ordering to calculate visitor 103 // Method GetVisitorIdForSize depends on this ordering to calculate visitor
73 // id of specialized visitor from given instance size, base visitor id and 104 // id of specialized visitor from given instance size, base visitor id and
74 // generic visitor's id. 105 // generic visitor's id.
75 enum VisitorId { 106 enum VisitorId {
76 #define VISITOR_ID_ENUM_DECL(id) kVisit##id, 107 #define VISITOR_ID_ENUM_DECL(id) kVisit##id,
77 VISITOR_ID_LIST(VISITOR_ID_ENUM_DECL) 108 VISITOR_ID_LIST(VISITOR_ID_ENUM_DECL)
78 #undef VISITOR_ID_ENUM_DECL 109 #undef VISITOR_ID_ENUM_DECL
79 kVisitorIdCount 110 kVisitorIdCount,
111 kVisitDataObject = kVisitDataObject2,
112 kVisitJSObject = kVisitJSObject2,
113 kVisitJSApiObject = kVisitJSApiObject2,
114 kVisitStruct = kVisitStruct2,
80 }; 115 };
81 116
82 // Visitor ID should fit in one byte. 117 // Visitor ID should fit in one byte.
83 STATIC_ASSERT(kVisitorIdCount <= 256); 118 STATIC_ASSERT(kVisitorIdCount <= 256);
84 119
85 // Determine which specialized visitor should be used for given instance type 120 // Determine which specialized visitor should be used for given instance type
86 // and instance type. 121 // and instance type.
87 static VisitorId GetVisitorId(int instance_type, int instance_size, 122 static VisitorId GetVisitorId(int instance_type, int instance_size,
88 bool has_unboxed_fields); 123 bool has_unboxed_fields);
89 124
90 // Determine which specialized visitor should be used for given map. 125 // Determine which specialized visitor should be used for given map.
91 static VisitorId GetVisitorId(Map* map); 126 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 }
92 }; 149 };
93 150
94 151
95 template <typename Callback> 152 template <typename Callback>
96 class VisitorDispatchTable { 153 class VisitorDispatchTable {
97 public: 154 public:
98 void CopyFrom(VisitorDispatchTable* other) { 155 void CopyFrom(VisitorDispatchTable* other) {
99 // We are not using memcpy to guarantee that during update 156 // We are not using memcpy to guarantee that during update
100 // every element of callbacks_ array will remain correct 157 // every element of callbacks_ array will remain correct
101 // pointer (memcpy might be implemented as a byte copying loop). 158 // pointer (memcpy might be implemented as a byte copying loop).
102 for (int i = 0; i < StaticVisitorBase::kVisitorIdCount; i++) { 159 for (int i = 0; i < StaticVisitorBase::kVisitorIdCount; i++) {
103 base::NoBarrier_Store(&callbacks_[i], other->callbacks_[i]); 160 base::NoBarrier_Store(&callbacks_[i], other->callbacks_[i]);
104 } 161 }
105 } 162 }
106 163
107 inline Callback GetVisitor(Map* map); 164 inline Callback GetVisitor(Map* map);
108 165
109 inline Callback GetVisitorById(StaticVisitorBase::VisitorId id) { 166 inline Callback GetVisitorById(StaticVisitorBase::VisitorId id) {
110 return reinterpret_cast<Callback>(callbacks_[id]); 167 return reinterpret_cast<Callback>(callbacks_[id]);
111 } 168 }
112 169
113 void Register(StaticVisitorBase::VisitorId id, Callback callback) { 170 void Register(StaticVisitorBase::VisitorId id, Callback callback) {
114 DCHECK(id < StaticVisitorBase::kVisitorIdCount); // id is unsigned. 171 DCHECK(id < StaticVisitorBase::kVisitorIdCount); // id is unsigned.
115 callbacks_[id] = reinterpret_cast<base::AtomicWord>(callback); 172 callbacks_[id] = reinterpret_cast<base::AtomicWord>(callback);
116 } 173 }
117 174
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
118 private: 199 private:
119 base::AtomicWord callbacks_[StaticVisitorBase::kVisitorIdCount]; 200 base::AtomicWord callbacks_[StaticVisitorBase::kVisitorIdCount];
120 }; 201 };
121 202
122 203
123 template <typename StaticVisitor, typename BodyDescriptor, typename ReturnType> 204 template <typename StaticVisitor, typename BodyDescriptor, typename ReturnType>
124 class FlexibleBodyVisitor : public AllStatic { 205 class FlexibleBodyVisitor : public AllStatic {
125 public: 206 public:
126 INLINE(static ReturnType Visit(Map* map, HeapObject* object)) { 207 INLINE(static ReturnType Visit(Map* map, HeapObject* object)) {
127 int object_size = BodyDescriptor::SizeOf(map, object); 208 int object_size = BodyDescriptor::SizeOf(map, object);
128 BodyDescriptor::template IterateBody<StaticVisitor>(object, object_size); 209 BodyDescriptor::template IterateBody<StaticVisitor>(object, object_size);
129 return static_cast<ReturnType>(object_size); 210 return static_cast<ReturnType>(object_size);
130 } 211 }
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 }
131 }; 224 };
132 225
133 226
134 template <typename StaticVisitor, typename BodyDescriptor, typename ReturnType> 227 template <typename StaticVisitor, typename BodyDescriptor, typename ReturnType>
135 class FixedBodyVisitor : public AllStatic { 228 class FixedBodyVisitor : public AllStatic {
136 public: 229 public:
137 INLINE(static ReturnType Visit(Map* map, HeapObject* object)) { 230 INLINE(static ReturnType Visit(Map* map, HeapObject* object)) {
138 BodyDescriptor::template IterateBody<StaticVisitor>(object); 231 BodyDescriptor::template IterateBody<StaticVisitor>(object);
139 return static_cast<ReturnType>(BodyDescriptor::kSize); 232 return static_cast<ReturnType>(BodyDescriptor::kSize);
140 } 233 }
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
189 282
190 INLINE(static int VisitByteArray(Map* map, HeapObject* object)) { 283 INLINE(static int VisitByteArray(Map* map, HeapObject* object)) {
191 return reinterpret_cast<ByteArray*>(object)->ByteArraySize(); 284 return reinterpret_cast<ByteArray*>(object)->ByteArraySize();
192 } 285 }
193 286
194 INLINE(static int VisitFixedDoubleArray(Map* map, HeapObject* object)) { 287 INLINE(static int VisitFixedDoubleArray(Map* map, HeapObject* object)) {
195 int length = reinterpret_cast<FixedDoubleArray*>(object)->length(); 288 int length = reinterpret_cast<FixedDoubleArray*>(object)->length();
196 return FixedDoubleArray::SizeFor(length); 289 return FixedDoubleArray::SizeFor(length);
197 } 290 }
198 291
292 INLINE(static int VisitJSObject(Map* map, HeapObject* object)) {
293 return JSObjectVisitor::Visit(map, object);
294 }
295
199 INLINE(static int VisitSeqOneByteString(Map* map, HeapObject* object)) { 296 INLINE(static int VisitSeqOneByteString(Map* map, HeapObject* object)) {
200 return SeqOneByteString::cast(object) 297 return SeqOneByteString::cast(object)
201 ->SeqOneByteStringSize(map->instance_type()); 298 ->SeqOneByteStringSize(map->instance_type());
202 } 299 }
203 300
204 INLINE(static int VisitSeqTwoByteString(Map* map, HeapObject* object)) { 301 INLINE(static int VisitSeqTwoByteString(Map* map, HeapObject* object)) {
205 return SeqTwoByteString::cast(object) 302 return SeqTwoByteString::cast(object)
206 ->SeqTwoByteStringSize(map->instance_type()); 303 ->SeqTwoByteStringSize(map->instance_type());
207 } 304 }
208 305
(...skipping 12 matching lines...) Expand all
221 return map->instance_size(); 318 return map->instance_size();
222 } 319 }
223 }; 320 };
224 321
225 typedef FlexibleBodyVisitor<StaticVisitor, StructBodyDescriptor, int> 322 typedef FlexibleBodyVisitor<StaticVisitor, StructBodyDescriptor, int>
226 StructVisitor; 323 StructVisitor;
227 324
228 typedef FlexibleBodyVisitor<StaticVisitor, JSObject::BodyDescriptor, int> 325 typedef FlexibleBodyVisitor<StaticVisitor, JSObject::BodyDescriptor, int>
229 JSObjectVisitor; 326 JSObjectVisitor;
230 327
231 // Visitor for JSObjects without unboxed double fields.
232 typedef FlexibleBodyVisitor<StaticVisitor, JSObject::FastBodyDescriptor, int>
233 JSObjectFastVisitor;
234
235 typedef int (*Callback)(Map* map, HeapObject* object); 328 typedef int (*Callback)(Map* map, HeapObject* object);
236 329
237 static VisitorDispatchTable<Callback> table_; 330 static VisitorDispatchTable<Callback> table_;
238 }; 331 };
239 332
240 333
241 template <typename StaticVisitor> 334 template <typename StaticVisitor>
242 VisitorDispatchTable<typename StaticNewSpaceVisitor<StaticVisitor>::Callback> 335 VisitorDispatchTable<typename StaticNewSpaceVisitor<StaticVisitor>::Callback>
243 StaticNewSpaceVisitor<StaticVisitor>::table_; 336 StaticNewSpaceVisitor<StaticVisitor>::table_;
244 337
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
308 public: 401 public:
309 template <int size> 402 template <int size>
310 static inline void VisitSpecialized(Map* map, HeapObject* object) {} 403 static inline void VisitSpecialized(Map* map, HeapObject* object) {}
311 404
312 INLINE(static void Visit(Map* map, HeapObject* object)) {} 405 INLINE(static void Visit(Map* map, HeapObject* object)) {}
313 }; 406 };
314 407
315 typedef FlexibleBodyVisitor<StaticVisitor, FixedArray::BodyDescriptor, void> 408 typedef FlexibleBodyVisitor<StaticVisitor, FixedArray::BodyDescriptor, void>
316 FixedArrayVisitor; 409 FixedArrayVisitor;
317 410
318 typedef FlexibleBodyVisitor<StaticVisitor, JSObject::FastBodyDescriptor, void>
319 JSObjectFastVisitor;
320 typedef FlexibleBodyVisitor<StaticVisitor, JSObject::BodyDescriptor, void> 411 typedef FlexibleBodyVisitor<StaticVisitor, JSObject::BodyDescriptor, void>
321 JSObjectVisitor; 412 JSObjectVisitor;
322 413
323 class JSApiObjectVisitor : AllStatic { 414 class JSApiObjectVisitor : AllStatic {
324 public: 415 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
325 INLINE(static void Visit(Map* map, HeapObject* object)) { 422 INLINE(static void Visit(Map* map, HeapObject* object)) {
326 TracePossibleWrapper(object); 423 TracePossibleWrapper(object);
327 JSObjectVisitor::Visit(map, object); 424 JSObjectVisitor::Visit(map, object);
328 } 425 }
329 426
330 private: 427 private:
331 INLINE(static void TracePossibleWrapper(HeapObject* object)) { 428 INLINE(static void TracePossibleWrapper(HeapObject* object)) {
332 if (object->GetHeap()->local_embedder_heap_tracer()->InUse()) { 429 if (object->GetHeap()->local_embedder_heap_tracer()->InUse()) {
333 DCHECK(object->IsJSObject()); 430 DCHECK(object->IsJSObject());
334 object->GetHeap()->TracePossibleWrapper(JSObject::cast(object)); 431 object->GetHeap()->TracePossibleWrapper(JSObject::cast(object));
(...skipping 22 matching lines...) Expand all
357 // the next element. Given the head of the list, this function removes dead 454 // the next element. Given the head of the list, this function removes dead
358 // elements from the list and if requested records slots for next-element 455 // elements from the list and if requested records slots for next-element
359 // pointers. The template parameter T is a WeakListVisitor that defines how to 456 // pointers. The template parameter T is a WeakListVisitor that defines how to
360 // access the next-element pointers. 457 // access the next-element pointers.
361 template <class T> 458 template <class T>
362 Object* VisitWeakList(Heap* heap, Object* list, WeakObjectRetainer* retainer); 459 Object* VisitWeakList(Heap* heap, Object* list, WeakObjectRetainer* retainer);
363 } // namespace internal 460 } // namespace internal
364 } // namespace v8 461 } // namespace v8
365 462
366 #endif // V8_OBJECTS_VISITING_H_ 463 #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