OLD | NEW |
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
4 | 4 |
5 #include "vm/raw_object.h" | 5 #include "vm/raw_object.h" |
6 | 6 |
7 #include "vm/class_table.h" | 7 #include "vm/class_table.h" |
8 #include "vm/freelist.h" | 8 #include "vm/freelist.h" |
9 #include "vm/isolate.h" | 9 #include "vm/isolate.h" |
10 #include "vm/object.h" | 10 #include "vm/object.h" |
11 #include "vm/visitor.h" | 11 #include "vm/visitor.h" |
12 | 12 |
13 | 13 |
14 namespace dart { | 14 namespace dart { |
15 | 15 |
16 void RawObject::Validate(Isolate* isolate) const { | 16 void RawObject::Validate(Isolate* isolate) const { |
17 // Validation only happens in DEBUG builds. | 17 // Validation only happens in DEBUG builds. |
18 #if defined(DEBUG) | 18 #if defined(DEBUG) |
19 if (Object::null_class_ == reinterpret_cast<RawClass*>(kHeapObjectTag)) { | 19 if (Object::null_class_ == reinterpret_cast<RawClass*>(kHeapObjectTag)) { |
20 // Validation relies on properly initialized class classes. Skip if the | 20 // Validation relies on properly initialized class classes. Skip if the |
21 // VM is still being initialized. | 21 // VM is still being initialized. |
22 return; | 22 return; |
23 } | 23 } |
24 // All Smi values are valid. | 24 // All Smi values are valid. |
25 if (!IsHeapObject()) { | 25 if (!IsHeapObject()) { |
26 return; | 26 return; |
27 } | 27 } |
28 // Validate that the class_ field is sensible. | |
29 RawClass* raw_class = ptr()->class_; | |
30 ASSERT(raw_class->IsHeapObject()); | |
31 RawClass* raw_class_class = raw_class->ptr()->class_; | |
32 ASSERT(raw_class_class->IsHeapObject()); | |
33 ASSERT(raw_class_class->ptr()->instance_kind_ == kClass); | |
34 | |
35 // Validate that the tags_ field is sensible. | 28 // Validate that the tags_ field is sensible. |
36 uword tags = ptr()->tags_; | 29 uword tags = ptr()->tags_; |
37 ASSERT((tags & 0x000000f0) == 0); | 30 ASSERT((tags & 0x000000f0) == 0); |
38 intptr_t cid = ClassIdTag::decode(tags); | |
39 RawClass* tag_class = isolate->class_table()->At(cid); | |
40 ASSERT(tag_class == raw_class); | |
41 #endif | 31 #endif |
42 } | 32 } |
43 | 33 |
44 | 34 |
45 intptr_t RawObject::SizeFromClass() const { | 35 intptr_t RawObject::SizeFromClass() const { |
46 NoHandleScope no_handles(Isolate::Current()); | 36 NoHandleScope no_handles(Isolate::Current()); |
47 | 37 |
48 // Only reasonable to be called on heap objects. | 38 // Only reasonable to be called on heap objects. |
49 ASSERT(IsHeapObject()); | 39 ASSERT(IsHeapObject()); |
50 | 40 |
51 // TODO(vegorov): this should be moved to fast path when class_ is eliminated. | 41 // TODO(vegorov): this should be moved to fast path when class_ is eliminated. |
52 if (FreeBit::decode(ptr()->tags_)) { | 42 if (FreeBit::decode(ptr()->tags_)) { |
53 return reinterpret_cast<FreeListElement*>(ptr())->Size(); | 43 return reinterpret_cast<FreeListElement*>(ptr())->size(); |
54 } | 44 } |
55 | 45 |
56 RawClass* raw_class = Isolate::Current()->class_table()->At(GetClassId()); | 46 RawClass* raw_class = Isolate::Current()->class_table()->At(GetClassId()); |
57 intptr_t instance_size = raw_class->ptr()->instance_size_; | 47 intptr_t instance_size = raw_class->ptr()->instance_size_; |
58 ObjectKind instance_kind = raw_class->ptr()->instance_kind_; | 48 ObjectKind instance_kind = raw_class->ptr()->instance_kind_; |
59 | 49 |
60 if (instance_size == 0) { | 50 if (instance_size == 0) { |
61 switch (instance_kind) { | 51 switch (instance_kind) { |
62 case kTokenStream: { | 52 case kTokenStream: { |
63 const RawTokenStream* raw_tokens = | 53 const RawTokenStream* raw_tokens = |
(...skipping 172 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
236 const RawJSRegExp* raw_jsregexp = | 226 const RawJSRegExp* raw_jsregexp = |
237 reinterpret_cast<const RawJSRegExp*>(this); | 227 reinterpret_cast<const RawJSRegExp*>(this); |
238 intptr_t data_length = Smi::Value(raw_jsregexp->ptr()->data_length_); | 228 intptr_t data_length = Smi::Value(raw_jsregexp->ptr()->data_length_); |
239 instance_size = JSRegExp::InstanceSize(data_length); | 229 instance_size = JSRegExp::InstanceSize(data_length); |
240 break; | 230 break; |
241 } | 231 } |
242 case kFreeListElement: { | 232 case kFreeListElement: { |
243 ASSERT(FreeBit::decode(ptr()->tags_)); | 233 ASSERT(FreeBit::decode(ptr()->tags_)); |
244 uword addr = RawObject::ToAddr(const_cast<RawObject*>(this)); | 234 uword addr = RawObject::ToAddr(const_cast<RawObject*>(this)); |
245 FreeListElement* element = reinterpret_cast<FreeListElement*>(addr); | 235 FreeListElement* element = reinterpret_cast<FreeListElement*>(addr); |
246 instance_size = element->Size(); | 236 instance_size = element->size(); |
247 break; | 237 break; |
248 } | 238 } |
249 default: | 239 default: |
250 UNREACHABLE(); | 240 UNREACHABLE(); |
251 break; | 241 break; |
252 } | 242 } |
253 } | 243 } |
254 ASSERT(instance_size != 0); | 244 ASSERT(instance_size != 0); |
255 uword tags = ptr()->tags_; | 245 uword tags = ptr()->tags_; |
256 ASSERT((instance_size == SizeTag::decode(tags)) || | 246 ASSERT((instance_size == SizeTag::decode(tags)) || |
257 (SizeTag::decode(tags) == 0) || | 247 (SizeTag::decode(tags) == 0) || |
258 FreeBit::decode(tags)); | 248 FreeBit::decode(tags)); |
259 return instance_size; | 249 return instance_size; |
260 } | 250 } |
261 | 251 |
262 | 252 |
263 intptr_t RawObject::VisitPointers(ObjectPointerVisitor* visitor) { | 253 intptr_t RawObject::VisitPointers(ObjectPointerVisitor* visitor) { |
264 intptr_t size = 0; | 254 intptr_t size = 0; |
265 NoHandleScope no_handles(Isolate::Current()); | 255 NoHandleScope no_handles(Isolate::Current()); |
266 | 256 |
267 // Only reasonable to be called on heap objects. | 257 // Only reasonable to be called on heap objects. |
268 ASSERT(IsHeapObject()); | 258 ASSERT(IsHeapObject()); |
269 | 259 |
270 if (FreeBit::decode(ptr()->tags_)) { | 260 if (FreeBit::decode(ptr()->tags_)) { |
271 // Nothing to visit for free list elements. | 261 // Nothing to visit for free list elements. |
272 uword addr = RawObject::ToAddr(this); | 262 uword addr = RawObject::ToAddr(this); |
273 FreeListElement* element = reinterpret_cast<FreeListElement*>(addr); | 263 FreeListElement* element = reinterpret_cast<FreeListElement*>(addr); |
274 return element->Size(); | 264 return element->size(); |
275 } | 265 } |
276 | 266 |
277 // Read the necessary data out of the class before visting the class itself. | 267 // Read the necessary data out of the class before visting the class itself. |
278 intptr_t class_id = GetClassId(); | 268 intptr_t class_id = GetClassId(); |
279 ObjectKind kind; | 269 ObjectKind kind; |
280 | 270 |
281 if (class_id < kNumPredefinedKinds) { | 271 if (class_id < kNumPredefinedKinds) { |
282 kind = static_cast<ObjectKind>(class_id); | 272 kind = static_cast<ObjectKind>(class_id); |
283 } else { | 273 } else { |
284 RawClass* raw_class = Isolate::Current()->class_table()->At(class_id); | 274 RawClass* raw_class = Isolate::Current()->class_table()->At(class_id); |
285 kind = raw_class->ptr()->instance_kind_; | 275 kind = raw_class->ptr()->instance_kind_; |
286 } | 276 } |
287 | 277 |
288 // Visit the class before visting the fields. | |
289 visitor->VisitPointer(reinterpret_cast<RawObject**>(&ptr()->class_)); | |
290 | |
291 switch (kind) { | 278 switch (kind) { |
292 #define RAW_VISITPOINTERS(clazz) \ | 279 #define RAW_VISITPOINTERS(clazz) \ |
293 case clazz::kInstanceKind: { \ | 280 case clazz::kInstanceKind: { \ |
294 Raw##clazz* raw_obj = reinterpret_cast<Raw##clazz*>(this); \ | 281 Raw##clazz* raw_obj = reinterpret_cast<Raw##clazz*>(this); \ |
295 size = Raw##clazz::Visit##clazz##Pointers(raw_obj, visitor); \ | 282 size = Raw##clazz::Visit##clazz##Pointers(raw_obj, visitor); \ |
296 break; \ | 283 break; \ |
297 } | 284 } |
298 CLASS_LIST_NO_OBJECT(RAW_VISITPOINTERS) | 285 CLASS_LIST_NO_OBJECT(RAW_VISITPOINTERS) |
299 #undef RAW_VISITPOINTERS | 286 #undef RAW_VISITPOINTERS |
300 default: | 287 default: |
(...skipping 645 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
946 intptr_t RawJSRegExp::VisitJSRegExpPointers(RawJSRegExp* raw_obj, | 933 intptr_t RawJSRegExp::VisitJSRegExpPointers(RawJSRegExp* raw_obj, |
947 ObjectPointerVisitor* visitor) { | 934 ObjectPointerVisitor* visitor) { |
948 // Make sure that we got here with the tagged pointer as this. | 935 // Make sure that we got here with the tagged pointer as this. |
949 ASSERT(raw_obj->IsHeapObject()); | 936 ASSERT(raw_obj->IsHeapObject()); |
950 intptr_t length = Smi::Value(raw_obj->ptr()->data_length_); | 937 intptr_t length = Smi::Value(raw_obj->ptr()->data_length_); |
951 visitor->VisitPointers(raw_obj->from(), raw_obj->to()); | 938 visitor->VisitPointers(raw_obj->from(), raw_obj->to()); |
952 return JSRegExp::InstanceSize(length); | 939 return JSRegExp::InstanceSize(length); |
953 } | 940 } |
954 | 941 |
955 } // namespace dart | 942 } // namespace dart |
OLD | NEW |