| 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 |