| OLD | NEW |
| 1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2011, 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/freelist.h" | 7 #include "vm/freelist.h" |
| 8 #include "vm/isolate.h" | 8 #include "vm/isolate.h" |
| 9 #include "vm/object.h" | 9 #include "vm/object.h" |
| 10 #include "vm/visitor.h" | 10 #include "vm/visitor.h" |
| 11 | 11 |
| 12 | 12 |
| 13 namespace dart { | 13 namespace dart { |
| 14 | 14 |
| 15 void RawObject::Validate() const { | 15 void RawObject::Validate() const { |
| 16 if (Object::null_class_ == reinterpret_cast<RawClass*>(kHeapObjectTag)) { |
| 17 // Validation relies on properly initialized class classes. Skip if the |
| 18 // VM is still being initialized. |
| 19 return; |
| 20 } |
| 16 // All Smi values are valid. | 21 // All Smi values are valid. |
| 17 if (!IsHeapObject()) { | 22 if (!IsHeapObject()) { |
| 18 return; | 23 return; |
| 19 } | 24 } |
| 20 // Validate that the class_ field is sensible. | 25 // Validate that the class_ field is sensible. |
| 21 RawClass* raw_class = ptr()->class_; | 26 RawClass* raw_class = ptr()->class_; |
| 22 ASSERT(raw_class->IsHeapObject()); | 27 ASSERT(raw_class->IsHeapObject()); |
| 23 RawClass* raw_class_class = raw_class->ptr()->class_; | 28 RawClass* raw_class_class = raw_class->ptr()->class_; |
| 24 ASSERT(raw_class_class->IsHeapObject()); | 29 ASSERT(raw_class_class->IsHeapObject()); |
| 25 ASSERT(raw_class_class->ptr()->instance_kind_ == kClass); | 30 ASSERT(raw_class_class->ptr()->instance_kind_ == kClass); |
| 26 | 31 |
| 27 // Validate that the tags_ field is sensible. | 32 // Validate that the tags_ field is sensible. |
| 28 intptr_t tags = ptr()->tags_; | 33 intptr_t tags = ptr()->tags_; |
| 29 ASSERT((tags & 0xfffffff0) == 0); | 34 ASSERT((tags & 0xffff00f0) == 0); |
| 30 } | 35 } |
| 31 | 36 |
| 32 | 37 |
| 33 intptr_t RawObject::Size() const { | 38 intptr_t RawObject::SizeFromClass() const { |
| 34 NoHandleScope no_handles(Isolate::Current()); | 39 NoHandleScope no_handles(Isolate::Current()); |
| 35 | 40 |
| 36 // Only reasonable to be called on heap objects. | 41 // Only reasonable to be called on heap objects. |
| 37 ASSERT(IsHeapObject()); | 42 ASSERT(IsHeapObject()); |
| 38 | 43 |
| 39 RawClass* raw_class = ptr()->class_; | 44 RawClass* raw_class = ptr()->class_; |
| 40 intptr_t instance_size = raw_class->ptr()->instance_size_; | 45 intptr_t instance_size = raw_class->ptr()->instance_size_; |
| 41 ObjectKind instance_kind = raw_class->ptr()->instance_kind_; | 46 ObjectKind instance_kind = raw_class->ptr()->instance_kind_; |
| 42 | 47 |
| 43 if (instance_size == 0) { | 48 if (instance_size == 0) { |
| (...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 140 break; | 145 break; |
| 141 } | 146 } |
| 142 case kJSRegExp: { | 147 case kJSRegExp: { |
| 143 const RawJSRegExp* raw_jsregexp = | 148 const RawJSRegExp* raw_jsregexp = |
| 144 reinterpret_cast<const RawJSRegExp*>(this); | 149 reinterpret_cast<const RawJSRegExp*>(this); |
| 145 intptr_t data_length = Smi::Value(raw_jsregexp->ptr()->data_length_); | 150 intptr_t data_length = Smi::Value(raw_jsregexp->ptr()->data_length_); |
| 146 instance_size = JSRegExp::InstanceSize(data_length); | 151 instance_size = JSRegExp::InstanceSize(data_length); |
| 147 break; | 152 break; |
| 148 } | 153 } |
| 149 case kFreeListElement: { | 154 case kFreeListElement: { |
| 155 ASSERT(FreeBit::decode(ptr()->tags_)); |
| 150 uword addr = RawObject::ToAddr(const_cast<RawObject*>(this)); | 156 uword addr = RawObject::ToAddr(const_cast<RawObject*>(this)); |
| 151 FreeListElement* element = reinterpret_cast<FreeListElement*>(addr); | 157 FreeListElement* element = reinterpret_cast<FreeListElement*>(addr); |
| 152 instance_size = element->Size(); | 158 instance_size = element->Size(); |
| 153 break; | 159 break; |
| 154 } | 160 } |
| 155 default: | 161 default: |
| 156 UNREACHABLE(); | 162 UNREACHABLE(); |
| 157 break; | 163 break; |
| 158 } | 164 } |
| 159 } | 165 } |
| 160 ASSERT(instance_size != 0); | 166 ASSERT(instance_size != 0); |
| 167 intptr_t tags = ptr()->tags_; |
| 168 ASSERT((instance_size == (SizeTag::decode(tags))) || |
| 169 (SizeTag::decode(tags) == 0) || |
| 170 FreeBit::decode(tags)); |
| 161 return instance_size; | 171 return instance_size; |
| 162 } | 172 } |
| 163 | 173 |
| 164 | 174 |
| 165 intptr_t RawObject::VisitPointers(ObjectPointerVisitor* visitor) { | 175 intptr_t RawObject::VisitPointers(ObjectPointerVisitor* visitor) { |
| 166 intptr_t size = 0; | 176 intptr_t size = 0; |
| 167 NoHandleScope no_handles(Isolate::Current()); | 177 NoHandleScope no_handles(Isolate::Current()); |
| 168 | 178 |
| 169 // Only reasonable to be called on heap objects. | 179 // Only reasonable to be called on heap objects. |
| 170 ASSERT(IsHeapObject()); | 180 ASSERT(IsHeapObject()); |
| 171 | 181 |
| 172 // Read the necessary data out of the class before visting the class itself. | 182 // Read the necessary data out of the class before visting the class itself. |
| 173 RawClass* raw_class = ptr()->class_; | 183 RawClass* raw_class = ptr()->class_; |
| 174 ObjectKind kind = raw_class->ptr()->instance_kind_; | 184 ObjectKind kind = raw_class->ptr()->instance_kind_; |
| 175 | 185 |
| 176 // Visit the class before visting the fields. | 186 // Visit the class before visting the fields. |
| 177 visitor->VisitPointer(reinterpret_cast<RawObject**>(&ptr()->class_)); | 187 visitor->VisitPointer(reinterpret_cast<RawObject**>(&ptr()->class_)); |
| 178 | 188 |
| 179 switch (kind) { | 189 switch (kind) { |
| 180 #define RAW_VISITPOINTERS(clazz) \ | 190 #define RAW_VISITPOINTERS(clazz) \ |
| 181 case clazz::kInstanceKind: { \ | 191 case clazz::kInstanceKind: { \ |
| 182 Raw##clazz* raw_obj = reinterpret_cast<Raw##clazz*>(this); \ | 192 Raw##clazz* raw_obj = reinterpret_cast<Raw##clazz*>(this); \ |
| 183 size = Raw##clazz::Visit##clazz##Pointers(raw_obj, visitor); \ | 193 size = Raw##clazz::Visit##clazz##Pointers(raw_obj, visitor); \ |
| 184 break; \ | 194 break; \ |
| 185 } | 195 } |
| 186 CLASS_LIST_NO_OBJECT(RAW_VISITPOINTERS) | 196 CLASS_LIST_NO_OBJECT(RAW_VISITPOINTERS) |
| 187 #undef RAW_VISITPOINTERS | 197 #undef RAW_VISITPOINTERS |
| 188 case kFreeListElement: { | 198 case kFreeListElement: { |
| 199 ASSERT(FreeBit::decode(ptr()->tags_)); |
| 189 // Nothing to visit for free list elements. | 200 // Nothing to visit for free list elements. |
| 190 uword addr = RawObject::ToAddr(this); | 201 uword addr = RawObject::ToAddr(this); |
| 191 FreeListElement* element = reinterpret_cast<FreeListElement*>(addr); | 202 FreeListElement* element = reinterpret_cast<FreeListElement*>(addr); |
| 192 size = element->Size(); | 203 size = element->Size(); |
| 193 break; | 204 break; |
| 194 } | 205 } |
| 195 default: | 206 default: |
| 196 OS::Print("Kind: %d\n", kind); | 207 OS::Print("Kind: %d\n", kind); |
| 197 UNREACHABLE(); | 208 UNREACHABLE(); |
| 198 break; | 209 break; |
| 199 } | 210 } |
| 200 | 211 |
| 201 ASSERT(size != 0); | 212 ASSERT(size != 0); |
| 213 ASSERT(size == Size()); |
| 202 return size; | 214 return size; |
| 203 } | 215 } |
| 204 | 216 |
| 205 | 217 |
| 206 intptr_t RawClass::VisitClassPointers(RawClass* raw_obj, | 218 intptr_t RawClass::VisitClassPointers(RawClass* raw_obj, |
| 207 ObjectPointerVisitor* visitor) { | 219 ObjectPointerVisitor* visitor) { |
| 208 visitor->VisitPointers(raw_obj->from(), raw_obj->to()); | 220 visitor->VisitPointers(raw_obj->from(), raw_obj->to()); |
| 209 return Class::InstanceSize(); | 221 return Class::InstanceSize(); |
| 210 } | 222 } |
| 211 | 223 |
| (...skipping 360 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 572 intptr_t RawJSRegExp::VisitJSRegExpPointers(RawJSRegExp* raw_obj, | 584 intptr_t RawJSRegExp::VisitJSRegExpPointers(RawJSRegExp* raw_obj, |
| 573 ObjectPointerVisitor* visitor) { | 585 ObjectPointerVisitor* visitor) { |
| 574 // Make sure that we got here with the tagged pointer as this. | 586 // Make sure that we got here with the tagged pointer as this. |
| 575 ASSERT(raw_obj->IsHeapObject()); | 587 ASSERT(raw_obj->IsHeapObject()); |
| 576 intptr_t length = Smi::Value(raw_obj->ptr()->data_length_); | 588 intptr_t length = Smi::Value(raw_obj->ptr()->data_length_); |
| 577 visitor->VisitPointers(raw_obj->from(), raw_obj->to()); | 589 visitor->VisitPointers(raw_obj->from(), raw_obj->to()); |
| 578 return JSRegExp::InstanceSize(length); | 590 return JSRegExp::InstanceSize(length); |
| 579 } | 591 } |
| 580 | 592 |
| 581 } // namespace dart | 593 } // namespace dart |
| OLD | NEW |