OLD | NEW |
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 |
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
98 kVisitJSObject = kVisitJSObject2, | 98 kVisitJSObject = kVisitJSObject2, |
99 kVisitStruct = kVisitStruct2, | 99 kVisitStruct = kVisitStruct2, |
100 kMinObjectSizeInWords = 2 | 100 kMinObjectSizeInWords = 2 |
101 }; | 101 }; |
102 | 102 |
103 // Visitor ID should fit in one byte. | 103 // Visitor ID should fit in one byte. |
104 STATIC_ASSERT(kVisitorIdCount <= 256); | 104 STATIC_ASSERT(kVisitorIdCount <= 256); |
105 | 105 |
106 // Determine which specialized visitor should be used for given instance type | 106 // Determine which specialized visitor should be used for given instance type |
107 // and instance type. | 107 // and instance type. |
108 static VisitorId GetVisitorId(int instance_type, int instance_size); | 108 static VisitorId GetVisitorId(int instance_type, int instance_size, |
| 109 bool has_unboxed_fields); |
109 | 110 |
110 static VisitorId GetVisitorId(Map* map) { | 111 static VisitorId GetVisitorId(Map* map) { |
111 return GetVisitorId(map->instance_type(), map->instance_size()); | 112 return GetVisitorId(map->instance_type(), map->instance_size(), |
| 113 FLAG_unbox_double_fields && |
| 114 !map->layout_descriptor()->IsFastPointerLayout()); |
112 } | 115 } |
113 | 116 |
114 // For visitors that allow specialization by size calculate VisitorId based | 117 // For visitors that allow specialization by size calculate VisitorId based |
115 // on size, base visitor id and generic visitor id. | 118 // on size, base visitor id and generic visitor id. |
116 static VisitorId GetVisitorIdForSize(VisitorId base, VisitorId generic, | 119 static VisitorId GetVisitorIdForSize(VisitorId base, VisitorId generic, |
117 int object_size) { | 120 int object_size, |
| 121 bool has_unboxed_fields) { |
118 DCHECK((base == kVisitDataObject) || (base == kVisitStruct) || | 122 DCHECK((base == kVisitDataObject) || (base == kVisitStruct) || |
119 (base == kVisitJSObject)); | 123 (base == kVisitJSObject)); |
120 DCHECK(IsAligned(object_size, kPointerSize)); | 124 DCHECK(IsAligned(object_size, kPointerSize)); |
121 DCHECK(kMinObjectSizeInWords * kPointerSize <= object_size); | 125 DCHECK(kMinObjectSizeInWords * kPointerSize <= object_size); |
122 DCHECK(object_size <= Page::kMaxRegularHeapObjectSize); | 126 DCHECK(object_size <= Page::kMaxRegularHeapObjectSize); |
| 127 DCHECK(!has_unboxed_fields || (base == kVisitJSObject)); |
| 128 |
| 129 if (has_unboxed_fields) return generic; |
123 | 130 |
124 const VisitorId specialization = static_cast<VisitorId>( | 131 const VisitorId specialization = static_cast<VisitorId>( |
125 base + (object_size >> kPointerSizeLog2) - kMinObjectSizeInWords); | 132 base + (object_size >> kPointerSizeLog2) - kMinObjectSizeInWords); |
126 | 133 |
127 return Min(specialization, generic); | 134 return Min(specialization, generic); |
128 } | 135 } |
129 }; | 136 }; |
130 | 137 |
131 | 138 |
132 template <typename Callback> | 139 template <typename Callback> |
(...skipping 18 matching lines...) Expand all Loading... |
151 | 158 |
152 void Register(StaticVisitorBase::VisitorId id, Callback callback) { | 159 void Register(StaticVisitorBase::VisitorId id, Callback callback) { |
153 DCHECK(id < StaticVisitorBase::kVisitorIdCount); // id is unsigned. | 160 DCHECK(id < StaticVisitorBase::kVisitorIdCount); // id is unsigned. |
154 callbacks_[id] = reinterpret_cast<base::AtomicWord>(callback); | 161 callbacks_[id] = reinterpret_cast<base::AtomicWord>(callback); |
155 } | 162 } |
156 | 163 |
157 template <typename Visitor, StaticVisitorBase::VisitorId base, | 164 template <typename Visitor, StaticVisitorBase::VisitorId base, |
158 StaticVisitorBase::VisitorId generic, int object_size_in_words> | 165 StaticVisitorBase::VisitorId generic, int object_size_in_words> |
159 void RegisterSpecialization() { | 166 void RegisterSpecialization() { |
160 static const int size = object_size_in_words * kPointerSize; | 167 static const int size = object_size_in_words * kPointerSize; |
161 Register(StaticVisitorBase::GetVisitorIdForSize(base, generic, size), | 168 Register(StaticVisitorBase::GetVisitorIdForSize(base, generic, size, false), |
162 &Visitor::template VisitSpecialized<size>); | 169 &Visitor::template VisitSpecialized<size>); |
163 } | 170 } |
164 | 171 |
165 | 172 |
166 template <typename Visitor, StaticVisitorBase::VisitorId base, | 173 template <typename Visitor, StaticVisitorBase::VisitorId base, |
167 StaticVisitorBase::VisitorId generic> | 174 StaticVisitorBase::VisitorId generic> |
168 void RegisterSpecializations() { | 175 void RegisterSpecializations() { |
169 STATIC_ASSERT((generic - base + StaticVisitorBase::kMinObjectSizeInWords) == | 176 STATIC_ASSERT((generic - base + StaticVisitorBase::kMinObjectSizeInWords) == |
170 10); | 177 10); |
171 RegisterSpecialization<Visitor, base, generic, 2>(); | 178 RegisterSpecialization<Visitor, base, generic, 2>(); |
(...skipping 10 matching lines...) Expand all Loading... |
182 private: | 189 private: |
183 base::AtomicWord callbacks_[StaticVisitorBase::kVisitorIdCount]; | 190 base::AtomicWord callbacks_[StaticVisitorBase::kVisitorIdCount]; |
184 }; | 191 }; |
185 | 192 |
186 | 193 |
187 template <typename StaticVisitor> | 194 template <typename StaticVisitor> |
188 class BodyVisitorBase : public AllStatic { | 195 class BodyVisitorBase : public AllStatic { |
189 public: | 196 public: |
190 INLINE(static void IteratePointers(Heap* heap, HeapObject* object, | 197 INLINE(static void IteratePointers(Heap* heap, HeapObject* object, |
191 int start_offset, int end_offset)) { | 198 int start_offset, int end_offset)) { |
192 Object** start_slot = | 199 DCHECK(!FLAG_unbox_double_fields || |
193 reinterpret_cast<Object**>(object->address() + start_offset); | 200 object->map()->layout_descriptor()->IsFastPointerLayout()); |
194 Object** end_slot = | 201 IterateRawPointers(heap, object, start_offset, end_offset); |
195 reinterpret_cast<Object**>(object->address() + end_offset); | 202 } |
196 StaticVisitor::VisitPointers(heap, start_slot, end_slot); | 203 |
| 204 INLINE(static void IterateBody(Heap* heap, HeapObject* object, |
| 205 int start_offset, int end_offset)) { |
| 206 if (!FLAG_unbox_double_fields || |
| 207 object->map()->layout_descriptor()->IsFastPointerLayout()) { |
| 208 IterateRawPointers(heap, object, start_offset, end_offset); |
| 209 } else { |
| 210 IterateBodyUsingLayoutDescriptor(heap, object, start_offset, end_offset); |
| 211 } |
| 212 } |
| 213 |
| 214 private: |
| 215 INLINE(static void IterateRawPointers(Heap* heap, HeapObject* object, |
| 216 int start_offset, int end_offset)) { |
| 217 StaticVisitor::VisitPointers(heap, |
| 218 HeapObject::RawField(object, start_offset), |
| 219 HeapObject::RawField(object, end_offset)); |
| 220 } |
| 221 |
| 222 static void IterateBodyUsingLayoutDescriptor(Heap* heap, HeapObject* object, |
| 223 int start_offset, |
| 224 int end_offset) { |
| 225 DCHECK(FLAG_unbox_double_fields); |
| 226 DCHECK(IsAligned(start_offset, kPointerSize) && |
| 227 IsAligned(end_offset, kPointerSize)); |
| 228 |
| 229 InobjectPropertiesHelper helper(object->map()); |
| 230 DCHECK(!helper.all_fields_tagged()); |
| 231 |
| 232 for (int offset = start_offset; offset < end_offset; |
| 233 offset += kPointerSize) { |
| 234 // Visit tagged fields only. |
| 235 if (helper.IsTagged(offset)) { |
| 236 IterateRawPointers(heap, object, offset, offset + kPointerSize); |
| 237 } |
| 238 } |
197 } | 239 } |
198 }; | 240 }; |
199 | 241 |
200 | 242 |
201 template <typename StaticVisitor, typename BodyDescriptor, typename ReturnType> | 243 template <typename StaticVisitor, typename BodyDescriptor, typename ReturnType> |
202 class FlexibleBodyVisitor : public BodyVisitorBase<StaticVisitor> { | 244 class FlexibleBodyVisitor : public BodyVisitorBase<StaticVisitor> { |
203 public: | 245 public: |
204 INLINE(static ReturnType Visit(Map* map, HeapObject* object)) { | 246 INLINE(static ReturnType Visit(Map* map, HeapObject* object)) { |
205 int object_size = BodyDescriptor::SizeOf(map, object); | 247 int object_size = BodyDescriptor::SizeOf(map, object); |
206 BodyVisitorBase<StaticVisitor>::IteratePointers( | 248 BodyVisitorBase<StaticVisitor>::IterateBody( |
207 map->GetHeap(), object, BodyDescriptor::kStartOffset, object_size); | 249 map->GetHeap(), object, BodyDescriptor::kStartOffset, object_size); |
208 return static_cast<ReturnType>(object_size); | 250 return static_cast<ReturnType>(object_size); |
209 } | 251 } |
210 | 252 |
211 template <int object_size> | 253 template <int object_size> |
212 static inline ReturnType VisitSpecialized(Map* map, HeapObject* object) { | 254 static inline ReturnType VisitSpecialized(Map* map, HeapObject* object) { |
213 DCHECK(BodyDescriptor::SizeOf(map, object) == object_size); | 255 DCHECK(BodyDescriptor::SizeOf(map, object) == object_size); |
214 BodyVisitorBase<StaticVisitor>::IteratePointers( | 256 BodyVisitorBase<StaticVisitor>::IteratePointers( |
215 map->GetHeap(), object, BodyDescriptor::kStartOffset, object_size); | 257 map->GetHeap(), object, BodyDescriptor::kStartOffset, object_size); |
216 return static_cast<ReturnType>(object_size); | 258 return static_cast<ReturnType>(object_size); |
217 } | 259 } |
218 }; | 260 }; |
219 | 261 |
220 | 262 |
221 template <typename StaticVisitor, typename BodyDescriptor, typename ReturnType> | 263 template <typename StaticVisitor, typename BodyDescriptor, typename ReturnType> |
222 class FixedBodyVisitor : public BodyVisitorBase<StaticVisitor> { | 264 class FixedBodyVisitor : public BodyVisitorBase<StaticVisitor> { |
223 public: | 265 public: |
224 INLINE(static ReturnType Visit(Map* map, HeapObject* object)) { | 266 INLINE(static ReturnType Visit(Map* map, HeapObject* object)) { |
225 BodyVisitorBase<StaticVisitor>::IteratePointers( | 267 BodyVisitorBase<StaticVisitor>::IterateBody(map->GetHeap(), object, |
226 map->GetHeap(), object, BodyDescriptor::kStartOffset, | 268 BodyDescriptor::kStartOffset, |
227 BodyDescriptor::kEndOffset); | 269 BodyDescriptor::kEndOffset); |
228 return static_cast<ReturnType>(BodyDescriptor::kSize); | 270 return static_cast<ReturnType>(BodyDescriptor::kSize); |
229 } | 271 } |
230 }; | 272 }; |
231 | 273 |
232 | 274 |
233 // Base class for visitors used for a linear new space iteration. | 275 // Base class for visitors used for a linear new space iteration. |
234 // IterateBody returns size of visited object. | 276 // IterateBody returns size of visited object. |
235 // Certain types of objects (i.e. Code objects) are not handled | 277 // Certain types of objects (i.e. Code objects) are not handled |
236 // by dispatch table of this visitor because they cannot appear | 278 // by dispatch table of this visitor because they cannot appear |
237 // in the new space. | 279 // in the new space. |
(...skipping 207 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
445 // the next element. Given the head of the list, this function removes dead | 487 // the next element. Given the head of the list, this function removes dead |
446 // elements from the list and if requested records slots for next-element | 488 // elements from the list and if requested records slots for next-element |
447 // pointers. The template parameter T is a WeakListVisitor that defines how to | 489 // pointers. The template parameter T is a WeakListVisitor that defines how to |
448 // access the next-element pointers. | 490 // access the next-element pointers. |
449 template <class T> | 491 template <class T> |
450 Object* VisitWeakList(Heap* heap, Object* list, WeakObjectRetainer* retainer); | 492 Object* VisitWeakList(Heap* heap, Object* list, WeakObjectRetainer* retainer); |
451 } | 493 } |
452 } // namespace v8::internal | 494 } // namespace v8::internal |
453 | 495 |
454 #endif // V8_OBJECTS_VISITING_H_ | 496 #endif // V8_OBJECTS_VISITING_H_ |
OLD | NEW |