| 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/dart.h" | 8 #include "vm/dart.h" |
| 9 #include "vm/freelist.h" | 9 #include "vm/freelist.h" |
| 10 #include "vm/isolate.h" | 10 #include "vm/isolate.h" |
| 11 #include "vm/object.h" | 11 #include "vm/object.h" |
| 12 #include "vm/visitor.h" | 12 #include "vm/visitor.h" |
| 13 | 13 |
| 14 | 14 |
| 15 namespace dart { | 15 namespace dart { |
| 16 | 16 |
| 17 #if defined(DEBUG) |
| 18 DEFINE_FLAG(bool, validate_overwrite, true, "Verify overwritten fields."); |
| 19 #endif // DEBUG |
| 17 | 20 |
| 18 const intptr_t RawPcDescriptors::kFullRecSize = | 21 const intptr_t RawPcDescriptors::kFullRecSize = |
| 19 sizeof(RawPcDescriptors::PcDescriptorRec); | 22 sizeof(RawPcDescriptors::PcDescriptorRec); |
| 20 const intptr_t RawPcDescriptors::kCompressedRecSize = | 23 const intptr_t RawPcDescriptors::kCompressedRecSize = |
| 21 sizeof(RawPcDescriptors::CompressedPcDescriptorRec); | 24 sizeof(RawPcDescriptors::CompressedPcDescriptorRec); |
| 22 | 25 |
| 23 bool RawObject::IsVMHeapObject() const { | 26 bool RawObject::IsVMHeapObject() const { |
| 24 return Dart::vm_isolate()->heap()->Contains(ToAddr(this)); | 27 return Dart::vm_isolate()->heap()->Contains(ToAddr(this)); |
| 25 } | 28 } |
| 26 | 29 |
| 27 | 30 |
| 28 void RawObject::Validate(Isolate* isolate) const { | 31 void RawObject::Validate(Isolate* isolate) const { |
| 29 if (Object::void_class_ == reinterpret_cast<RawClass*>(kHeapObjectTag)) { | 32 if (Object::void_class_ == reinterpret_cast<RawClass*>(kHeapObjectTag)) { |
| 30 // Validation relies on properly initialized class classes. Skip if the | 33 // Validation relies on properly initialized class classes. Skip if the |
| 31 // VM is still being initialized. | 34 // VM is still being initialized. |
| 32 return; | 35 return; |
| 33 } | 36 } |
| 34 // All Smi values are valid. | 37 // All Smi values are valid. |
| 35 if (!IsHeapObject()) { | 38 if (!IsHeapObject()) { |
| 36 return; | 39 return; |
| 37 } | 40 } |
| 41 // Slightly more readable than a segfault. |
| 42 if (this == reinterpret_cast<RawObject*>(kHeapObjectTag)) { |
| 43 FATAL("RAW_NULL encountered"); |
| 44 } |
| 38 // Validate that the tags_ field is sensible. | 45 // Validate that the tags_ field is sensible. |
| 39 uword tags = ptr()->tags_; | 46 uword tags = ptr()->tags_; |
| 40 intptr_t reserved = ReservedBits::decode(tags); | 47 intptr_t reserved = ReservedBits::decode(tags); |
| 41 if (reserved != 0) { | 48 if (reserved != 0) { |
| 42 FATAL1("Invalid tags field encountered %#" Px "\n", tags); | 49 FATAL1("Invalid tags field encountered %#" Px "\n", tags); |
| 43 } | 50 } |
| 44 intptr_t class_id = ClassIdTag::decode(tags); | 51 intptr_t class_id = ClassIdTag::decode(tags); |
| 45 if (!isolate->class_table()->IsValidIndex(class_id)) { | 52 if (!isolate->class_table()->IsValidIndex(class_id)) { |
| 46 FATAL1("Invalid class id encountered %" Pd "\n", class_id); | 53 FATAL1("Invalid class id encountered %" Pd "\n", class_id); |
| 47 } | 54 } |
| 55 if ((class_id == kNullCid) && |
| 56 (isolate->class_table()->At(class_id) == NULL)) { |
| 57 // Null class not yet initialized; skip. |
| 58 return; |
| 59 } |
| 48 intptr_t size = SizeTag::decode(tags); | 60 intptr_t size = SizeTag::decode(tags); |
| 49 if (size != 0 && size != SizeFromClass()) { | 61 if (size != 0 && size != SizeFromClass()) { |
| 50 FATAL1("Inconsistent class size encountered %" Pd "\n", size); | 62 FATAL1("Inconsistent class size encountered %" Pd "\n", size); |
| 51 } | 63 } |
| 52 } | 64 } |
| 53 | 65 |
| 54 | 66 |
| 55 intptr_t RawObject::SizeFromClass() const { | 67 intptr_t RawObject::SizeFromClass() const { |
| 56 Isolate* isolate = Isolate::Current(); | 68 Isolate* isolate = Isolate::Current(); |
| 57 NoHandleScope no_handles(isolate); | 69 NoHandleScope no_handles(isolate); |
| (...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 193 } | 205 } |
| 194 } | 206 } |
| 195 ASSERT(instance_size != 0); | 207 ASSERT(instance_size != 0); |
| 196 uword tags = ptr()->tags_; | 208 uword tags = ptr()->tags_; |
| 197 ASSERT((instance_size == SizeTag::decode(tags)) || | 209 ASSERT((instance_size == SizeTag::decode(tags)) || |
| 198 (SizeTag::decode(tags) == 0)); | 210 (SizeTag::decode(tags) == 0)); |
| 199 return instance_size; | 211 return instance_size; |
| 200 } | 212 } |
| 201 | 213 |
| 202 | 214 |
| 215 #if defined(DEBUG) |
| 216 void RawObject::ValidateOverwrittenPointer(RawObject* raw) { |
| 217 if (FLAG_validate_overwrite) { |
| 218 raw->Validate(Isolate::Current()); |
| 219 } |
| 220 } |
| 221 |
| 222 |
| 223 void RawObject::ValidateOverwrittenSmi(RawSmi* raw) { |
| 224 if (FLAG_validate_overwrite && raw->IsHeapObject() && raw != Object::null()) { |
| 225 FATAL1("Expected smi/null, found: %" Px "\n", reinterpret_cast<uword>(raw)); |
| 226 } |
| 227 } |
| 228 #endif // DEBUG |
| 229 |
| 230 |
| 203 intptr_t RawObject::VisitPointers(ObjectPointerVisitor* visitor) { | 231 intptr_t RawObject::VisitPointers(ObjectPointerVisitor* visitor) { |
| 204 intptr_t size = 0; | 232 intptr_t size = 0; |
| 205 NoHandleScope no_handles(visitor->isolate()); | 233 NoHandleScope no_handles(visitor->isolate()); |
| 206 | 234 |
| 207 // Only reasonable to be called on heap objects. | 235 // Only reasonable to be called on heap objects. |
| 208 ASSERT(IsHeapObject()); | 236 ASSERT(IsHeapObject()); |
| 209 | 237 |
| 210 // Read the necessary data out of the class before visting the class itself. | 238 // Read the necessary data out of the class before visting the class itself. |
| 211 intptr_t class_id = GetClassId(); | 239 intptr_t class_id = GetClassId(); |
| 212 | 240 |
| (...skipping 670 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 883 intptr_t RawUserTag::VisitUserTagPointers( | 911 intptr_t RawUserTag::VisitUserTagPointers( |
| 884 RawUserTag* raw_obj, ObjectPointerVisitor* visitor) { | 912 RawUserTag* raw_obj, ObjectPointerVisitor* visitor) { |
| 885 // Make sure that we got here with the tagged pointer as this. | 913 // Make sure that we got here with the tagged pointer as this. |
| 886 ASSERT(raw_obj->IsHeapObject()); | 914 ASSERT(raw_obj->IsHeapObject()); |
| 887 visitor->VisitPointers(raw_obj->from(), raw_obj->to()); | 915 visitor->VisitPointers(raw_obj->from(), raw_obj->to()); |
| 888 return UserTag::InstanceSize(); | 916 return UserTag::InstanceSize(); |
| 889 } | 917 } |
| 890 | 918 |
| 891 | 919 |
| 892 } // namespace dart | 920 } // namespace dart |
| OLD | NEW |