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 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
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 bool has_non_tagged_fields); |
108 | 109 |
109 static VisitorId GetVisitorId(Map* map) { | 110 static VisitorId GetVisitorId(Map* map) { |
110 return GetVisitorId(map->instance_type(), map->instance_size()); | 111 return GetVisitorId(map->instance_type(), map->instance_size(), |
| 112 FLAG_unbox_double_fields && |
| 113 !map->layout_descriptor()->IsFastPointerLayout()); |
111 } | 114 } |
112 | 115 |
113 // For visitors that allow specialization by size calculate VisitorId based | 116 // For visitors that allow specialization by size calculate VisitorId based |
114 // on size, base visitor id and generic visitor id. | 117 // on size, base visitor id and generic visitor id. |
115 static VisitorId GetVisitorIdForSize(VisitorId base, | 118 static VisitorId GetVisitorIdForSize(VisitorId base, VisitorId generic, |
116 VisitorId generic, | 119 int object_size, |
117 int object_size) { | 120 bool has_non_tagged_fields) { |
118 ASSERT((base == kVisitDataObject) || | 121 ASSERT((base == kVisitDataObject) || |
119 (base == kVisitStruct) || | 122 (base == kVisitStruct) || |
120 (base == kVisitJSObject)); | 123 (base == kVisitJSObject)); |
121 ASSERT(IsAligned(object_size, kPointerSize)); | 124 ASSERT(IsAligned(object_size, kPointerSize)); |
122 ASSERT(kMinObjectSizeInWords * kPointerSize <= object_size); | 125 ASSERT(kMinObjectSizeInWords * kPointerSize <= object_size); |
123 ASSERT(object_size <= Page::kMaxRegularHeapObjectSize); | 126 ASSERT(object_size <= Page::kMaxRegularHeapObjectSize); |
| 127 ASSERT(!has_non_tagged_fields || (base == kVisitJSObject)); |
| 128 |
| 129 if (has_non_tagged_fields) return generic; |
124 | 130 |
125 const VisitorId specialization = static_cast<VisitorId>( | 131 const VisitorId specialization = static_cast<VisitorId>( |
126 base + (object_size >> kPointerSizeLog2) - kMinObjectSizeInWords); | 132 base + (object_size >> kPointerSizeLog2) - kMinObjectSizeInWords); |
127 | 133 |
128 return Min(specialization, generic); | 134 return Min(specialization, generic); |
129 } | 135 } |
130 }; | 136 }; |
131 | 137 |
132 | 138 |
133 template<typename Callback> | 139 template<typename Callback> |
(...skipping 20 matching lines...) Expand all Loading... |
154 ASSERT(id < StaticVisitorBase::kVisitorIdCount); // id is unsigned. | 160 ASSERT(id < StaticVisitorBase::kVisitorIdCount); // id is unsigned. |
155 callbacks_[id] = reinterpret_cast<base::AtomicWord>(callback); | 161 callbacks_[id] = reinterpret_cast<base::AtomicWord>(callback); |
156 } | 162 } |
157 | 163 |
158 template<typename Visitor, | 164 template<typename Visitor, |
159 StaticVisitorBase::VisitorId base, | 165 StaticVisitorBase::VisitorId base, |
160 StaticVisitorBase::VisitorId generic, | 166 StaticVisitorBase::VisitorId generic, |
161 int object_size_in_words> | 167 int object_size_in_words> |
162 void RegisterSpecialization() { | 168 void RegisterSpecialization() { |
163 static const int size = object_size_in_words * kPointerSize; | 169 static const int size = object_size_in_words * kPointerSize; |
164 Register(StaticVisitorBase::GetVisitorIdForSize(base, generic, size), | 170 Register(StaticVisitorBase::GetVisitorIdForSize(base, generic, size, false), |
165 &Visitor::template VisitSpecialized<size>); | 171 &Visitor::template VisitSpecialized<size>); |
166 } | 172 } |
167 | 173 |
168 | 174 |
169 template<typename Visitor, | 175 template<typename Visitor, |
170 StaticVisitorBase::VisitorId base, | 176 StaticVisitorBase::VisitorId base, |
171 StaticVisitorBase::VisitorId generic> | 177 StaticVisitorBase::VisitorId generic> |
172 void RegisterSpecializations() { | 178 void RegisterSpecializations() { |
173 STATIC_ASSERT( | 179 STATIC_ASSERT( |
174 (generic - base + StaticVisitorBase::kMinObjectSizeInWords) == 10); | 180 (generic - base + StaticVisitorBase::kMinObjectSizeInWords) == 10); |
(...skipping 13 matching lines...) Expand all Loading... |
188 }; | 194 }; |
189 | 195 |
190 | 196 |
191 template<typename StaticVisitor> | 197 template<typename StaticVisitor> |
192 class BodyVisitorBase : public AllStatic { | 198 class BodyVisitorBase : public AllStatic { |
193 public: | 199 public: |
194 INLINE(static void IteratePointers(Heap* heap, | 200 INLINE(static void IteratePointers(Heap* heap, |
195 HeapObject* object, | 201 HeapObject* object, |
196 int start_offset, | 202 int start_offset, |
197 int end_offset)) { | 203 int end_offset)) { |
198 Object** start_slot = reinterpret_cast<Object**>(object->address() + | 204 ASSERT(!FLAG_unbox_double_fields || |
199 start_offset); | 205 object->map()->layout_descriptor()->IsFastPointerLayout()); |
200 Object** end_slot = reinterpret_cast<Object**>(object->address() + | 206 IterateRawPointers(heap, object, start_offset, end_offset); |
201 end_offset); | 207 } |
202 StaticVisitor::VisitPointers(heap, start_slot, end_slot); | 208 |
| 209 INLINE(static void IterateBody(Heap* heap, HeapObject* object, |
| 210 int start_offset, int end_offset)) { |
| 211 if (!FLAG_unbox_double_fields || |
| 212 object->map()->layout_descriptor()->IsFastPointerLayout()) { |
| 213 IterateRawPointers(heap, object, start_offset, end_offset); |
| 214 } else { |
| 215 IterateBodyUsingLayoutDescriptor(heap, object, start_offset, end_offset); |
| 216 } |
| 217 } |
| 218 |
| 219 private: |
| 220 INLINE(static void IterateRawPointers(Heap* heap, HeapObject* object, |
| 221 int start_offset, int end_offset)) { |
| 222 StaticVisitor::VisitPointers(heap, |
| 223 HeapObject::RawField(object, start_offset), |
| 224 HeapObject::RawField(object, end_offset)); |
| 225 } |
| 226 |
| 227 static void IterateBodyUsingLayoutDescriptor(Heap* heap, HeapObject* object, |
| 228 int start_offset, |
| 229 int end_offset) { |
| 230 ASSERT(FLAG_unbox_double_fields); |
| 231 ASSERT(IsAligned(start_offset, kPointerSize) && |
| 232 IsAligned(end_offset, kPointerSize)); |
| 233 |
| 234 InobjectPropertiesHelper helper(object->map()); |
| 235 ASSERT(!helper.all_fields_tagged()); |
| 236 |
| 237 for (int offset = start_offset; offset < end_offset; |
| 238 offset += kPointerSize) { |
| 239 // Visit tagged fields only. |
| 240 if (helper.IsTagged(offset)) { |
| 241 IterateRawPointers(heap, object, offset, offset + kPointerSize); |
| 242 } |
| 243 } |
203 } | 244 } |
204 }; | 245 }; |
205 | 246 |
206 | 247 |
207 template<typename StaticVisitor, typename BodyDescriptor, typename ReturnType> | 248 template<typename StaticVisitor, typename BodyDescriptor, typename ReturnType> |
208 class FlexibleBodyVisitor : public BodyVisitorBase<StaticVisitor> { | 249 class FlexibleBodyVisitor : public BodyVisitorBase<StaticVisitor> { |
209 public: | 250 public: |
210 INLINE(static ReturnType Visit(Map* map, HeapObject* object)) { | 251 INLINE(static ReturnType Visit(Map* map, HeapObject* object)) { |
211 int object_size = BodyDescriptor::SizeOf(map, object); | 252 int object_size = BodyDescriptor::SizeOf(map, object); |
212 BodyVisitorBase<StaticVisitor>::IteratePointers( | 253 BodyVisitorBase<StaticVisitor>::IterateBody( |
213 map->GetHeap(), | 254 map->GetHeap(), object, BodyDescriptor::kStartOffset, object_size); |
214 object, | |
215 BodyDescriptor::kStartOffset, | |
216 object_size); | |
217 return static_cast<ReturnType>(object_size); | 255 return static_cast<ReturnType>(object_size); |
218 } | 256 } |
219 | 257 |
220 template<int object_size> | 258 template<int object_size> |
221 static inline ReturnType VisitSpecialized(Map* map, HeapObject* object) { | 259 static inline ReturnType VisitSpecialized(Map* map, HeapObject* object) { |
222 ASSERT(BodyDescriptor::SizeOf(map, object) == object_size); | 260 ASSERT(BodyDescriptor::SizeOf(map, object) == object_size); |
223 BodyVisitorBase<StaticVisitor>::IteratePointers( | 261 BodyVisitorBase<StaticVisitor>::IteratePointers( |
224 map->GetHeap(), | 262 map->GetHeap(), |
225 object, | 263 object, |
226 BodyDescriptor::kStartOffset, | 264 BodyDescriptor::kStartOffset, |
227 object_size); | 265 object_size); |
228 return static_cast<ReturnType>(object_size); | 266 return static_cast<ReturnType>(object_size); |
229 } | 267 } |
230 }; | 268 }; |
231 | 269 |
232 | 270 |
233 template<typename StaticVisitor, typename BodyDescriptor, typename ReturnType> | 271 template<typename StaticVisitor, typename BodyDescriptor, typename ReturnType> |
234 class FixedBodyVisitor : public BodyVisitorBase<StaticVisitor> { | 272 class FixedBodyVisitor : public BodyVisitorBase<StaticVisitor> { |
235 public: | 273 public: |
236 INLINE(static ReturnType Visit(Map* map, HeapObject* object)) { | 274 INLINE(static ReturnType Visit(Map* map, HeapObject* object)) { |
237 BodyVisitorBase<StaticVisitor>::IteratePointers( | 275 BodyVisitorBase<StaticVisitor>::IterateBody(map->GetHeap(), object, |
238 map->GetHeap(), | 276 BodyDescriptor::kStartOffset, |
239 object, | 277 BodyDescriptor::kEndOffset); |
240 BodyDescriptor::kStartOffset, | |
241 BodyDescriptor::kEndOffset); | |
242 return static_cast<ReturnType>(BodyDescriptor::kSize); | 278 return static_cast<ReturnType>(BodyDescriptor::kSize); |
243 } | 279 } |
244 }; | 280 }; |
245 | 281 |
246 | 282 |
247 // Base class for visitors used for a linear new space iteration. | 283 // Base class for visitors used for a linear new space iteration. |
248 // IterateBody returns size of visited object. | 284 // IterateBody returns size of visited object. |
249 // Certain types of objects (i.e. Code objects) are not handled | 285 // Certain types of objects (i.e. Code objects) are not handled |
250 // by dispatch table of this visitor because they cannot appear | 286 // by dispatch table of this visitor because they cannot appear |
251 // in the new space. | 287 // in the new space. |
(...skipping 215 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
467 // the next element. Given the head of the list, this function removes dead | 503 // 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 | 504 // 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 | 505 // pointers. The template parameter T is a WeakListVisitor that defines how to |
470 // access the next-element pointers. | 506 // access the next-element pointers. |
471 template <class T> | 507 template <class T> |
472 Object* VisitWeakList(Heap* heap, Object* list, WeakObjectRetainer* retainer); | 508 Object* VisitWeakList(Heap* heap, Object* list, WeakObjectRetainer* retainer); |
473 | 509 |
474 } } // namespace v8::internal | 510 } } // namespace v8::internal |
475 | 511 |
476 #endif // V8_OBJECTS_VISITING_H_ | 512 #endif // V8_OBJECTS_VISITING_H_ |
OLD | NEW |