| 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/snapshot.h" | 5 #include "vm/snapshot.h" |
| 6 | 6 |
| 7 #include "platform/assert.h" | 7 #include "platform/assert.h" |
| 8 #include "vm/bigint_operations.h" | 8 #include "vm/bigint_operations.h" |
| 9 #include "vm/bootstrap.h" | 9 #include "vm/bootstrap.h" |
| 10 #include "vm/class_finalizer.h" | 10 #include "vm/class_finalizer.h" |
| (...skipping 14 matching lines...) Expand all Loading... |
| 25 static bool IsSingletonClassId(intptr_t class_id) { | 25 static bool IsSingletonClassId(intptr_t class_id) { |
| 26 // Check if this is a singleton object class which is shared by all isolates. | 26 // Check if this is a singleton object class which is shared by all isolates. |
| 27 return ((class_id >= kClassCid && class_id <= kUnwindErrorCid) || | 27 return ((class_id >= kClassCid && class_id <= kUnwindErrorCid) || |
| 28 (class_id >= kNullCid && class_id <= kVoidCid)); | 28 (class_id >= kNullCid && class_id <= kVoidCid)); |
| 29 } | 29 } |
| 30 | 30 |
| 31 | 31 |
| 32 static bool IsObjectStoreClassId(intptr_t class_id) { | 32 static bool IsObjectStoreClassId(intptr_t class_id) { |
| 33 // Check if this is a class which is stored in the object store. | 33 // Check if this is a class which is stored in the object store. |
| 34 return (class_id == kObjectCid || | 34 return (class_id == kObjectCid || |
| 35 (class_id >= kInstanceCid && class_id <= kUint32x4Cid) || | 35 (class_id >= kInstanceCid && class_id <= kInt32x4Cid) || |
| 36 class_id == kArrayCid || | 36 class_id == kArrayCid || |
| 37 class_id == kImmutableArrayCid || | 37 class_id == kImmutableArrayCid || |
| 38 RawObject::IsStringClassId(class_id) || | 38 RawObject::IsStringClassId(class_id) || |
| 39 RawObject::IsTypedDataClassId(class_id) || | 39 RawObject::IsTypedDataClassId(class_id) || |
| 40 RawObject::IsExternalTypedDataClassId(class_id)); | 40 RawObject::IsExternalTypedDataClassId(class_id)); |
| 41 } | 41 } |
| 42 | 42 |
| 43 | 43 |
| 44 static bool IsObjectStoreTypeId(intptr_t index) { | 44 static bool IsObjectStoreTypeId(intptr_t index) { |
| 45 // Check if this is a type which is stored in the object store. | 45 // Check if this is a type which is stored in the object store. |
| (...skipping 569 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 615 RawFloat32x4* obj = reinterpret_cast<RawFloat32x4*>( | 615 RawFloat32x4* obj = reinterpret_cast<RawFloat32x4*>( |
| 616 AllocateUninitialized(cls_, Float32x4::InstanceSize())); | 616 AllocateUninitialized(cls_, Float32x4::InstanceSize())); |
| 617 obj->ptr()->value_[0] = v0; | 617 obj->ptr()->value_[0] = v0; |
| 618 obj->ptr()->value_[1] = v1; | 618 obj->ptr()->value_[1] = v1; |
| 619 obj->ptr()->value_[2] = v2; | 619 obj->ptr()->value_[2] = v2; |
| 620 obj->ptr()->value_[3] = v3; | 620 obj->ptr()->value_[3] = v3; |
| 621 return obj; | 621 return obj; |
| 622 } | 622 } |
| 623 | 623 |
| 624 | 624 |
| 625 RawUint32x4* SnapshotReader::NewUint32x4(uint32_t v0, uint32_t v1, uint32_t v2, | 625 RawInt32x4* SnapshotReader::NewInt32x4(uint32_t v0, uint32_t v1, uint32_t v2, |
| 626 uint32_t v3) { | 626 uint32_t v3) { |
| 627 ASSERT(kind_ == Snapshot::kFull); | 627 ASSERT(kind_ == Snapshot::kFull); |
| 628 ASSERT(isolate()->no_gc_scope_depth() != 0); | 628 ASSERT(isolate()->no_gc_scope_depth() != 0); |
| 629 cls_ = object_store()->uint32x4_class(); | 629 cls_ = object_store()->int32x4_class(); |
| 630 RawUint32x4* obj = reinterpret_cast<RawUint32x4*>( | 630 RawInt32x4* obj = reinterpret_cast<RawInt32x4*>( |
| 631 AllocateUninitialized(cls_, Uint32x4::InstanceSize())); | 631 AllocateUninitialized(cls_, Int32x4::InstanceSize())); |
| 632 obj->ptr()->value_[0] = v0; | 632 obj->ptr()->value_[0] = v0; |
| 633 obj->ptr()->value_[1] = v1; | 633 obj->ptr()->value_[1] = v1; |
| 634 obj->ptr()->value_[2] = v2; | 634 obj->ptr()->value_[2] = v2; |
| 635 obj->ptr()->value_[3] = v3; | 635 obj->ptr()->value_[3] = v3; |
| 636 return obj; | 636 return obj; |
| 637 } | 637 } |
| 638 | 638 |
| 639 | 639 |
| 640 RawApiError* SnapshotReader::NewApiError() { | 640 RawApiError* SnapshotReader::NewApiError() { |
| 641 ALLOC_NEW_OBJECT(ApiError, Object::api_error_class()); | 641 ALLOC_NEW_OBJECT(ApiError, Object::api_error_class()); |
| (...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 783 } else { | 783 } else { |
| 784 *result ^= Object::Allocate(cls_.id(), | 784 *result ^= Object::Allocate(cls_.id(), |
| 785 instance_size, | 785 instance_size, |
| 786 HEAP_SPACE(kind_)); | 786 HEAP_SPACE(kind_)); |
| 787 } | 787 } |
| 788 } else { | 788 } else { |
| 789 cls_ ^= ReadObjectImpl(); | 789 cls_ ^= ReadObjectImpl(); |
| 790 ASSERT(!cls_.IsNull()); | 790 ASSERT(!cls_.IsNull()); |
| 791 instance_size = cls_.instance_size(); | 791 instance_size = cls_.instance_size(); |
| 792 } | 792 } |
| 793 intptr_t offset = Object::InstanceSize(); | 793 intptr_t next_field_offset = cls_.next_field_offset(); |
| 794 intptr_t type_argument_field_offset = cls_.type_arguments_field_offset(); |
| 795 ASSERT(next_field_offset > 0); |
| 796 // Instance::NextFieldOffset() returns the offset of the first field in |
| 797 // a Dart object. |
| 798 intptr_t offset = Instance::NextFieldOffset(); |
| 794 intptr_t result_cid = result->GetClassId(); | 799 intptr_t result_cid = result->GetClassId(); |
| 795 while (offset < instance_size) { | 800 while (offset < next_field_offset) { |
| 796 obj_ = ReadObjectRef(); | 801 obj_ = ReadObjectRef(); |
| 797 result->SetFieldAtOffset(offset, obj_); | 802 result->SetFieldAtOffset(offset, obj_); |
| 798 if (kind_ == Snapshot::kMessage) { | 803 if ((offset != type_argument_field_offset) && |
| 804 (kind_ == Snapshot::kMessage)) { |
| 799 // TODO(fschneider): Consider hoisting these lookups out of the loop. | 805 // TODO(fschneider): Consider hoisting these lookups out of the loop. |
| 800 // This would involve creating a handle, since cls_ can't be reused | 806 // This would involve creating a handle, since cls_ can't be reused |
| 801 // across the call to ReadObjectRef. | 807 // across the call to ReadObjectRef. |
| 802 cls_ = isolate()->class_table()->At(result_cid); | 808 cls_ = isolate()->class_table()->At(result_cid); |
| 803 array_ = cls_.OffsetToFieldMap(); | 809 array_ = cls_.OffsetToFieldMap(); |
| 804 field_ ^= array_.At(offset >> kWordSizeLog2); | 810 field_ ^= array_.At(offset >> kWordSizeLog2); |
| 805 // Entries can be null because offset can be outside of instance fields | 811 ASSERT(!field_.IsNull()); |
| 806 // due to rounded allocation size. | 812 ASSERT(field_.Offset() == offset); |
| 807 if (!field_.IsNull()) { | 813 field_.UpdateGuardedCidAndLength(obj_); |
| 808 ASSERT(field_.Offset() == offset); | |
| 809 field_.UpdateGuardedCidAndLength(obj_); | |
| 810 } | |
| 811 } | 814 } |
| 812 // TODO(fschneider): Verify the guarded cid and length for other kinds of | 815 // TODO(fschneider): Verify the guarded cid and length for other kinds of |
| 813 // snapshot (kFull, kScript) with asserts. | 816 // snapshot (kFull, kScript) with asserts. |
| 814 offset += kWordSize; | 817 offset += kWordSize; |
| 815 } | 818 } |
| 816 if (kind_ == Snapshot::kFull) { | 819 if (kind_ == Snapshot::kFull) { |
| 820 // We create an uninitialized object in the case of full snapshots, so |
| 821 // we need to initialize any remaining padding area with the Null object. |
| 822 while (offset < instance_size) { |
| 823 result->SetFieldAtOffset(offset, Object::null_object()); |
| 824 offset += kWordSize; |
| 825 } |
| 817 result->SetCreatedFromSnapshot(); | 826 result->SetCreatedFromSnapshot(); |
| 818 } else if (result->IsCanonical()) { | 827 } else if (result->IsCanonical()) { |
| 819 *result = result->CheckAndCanonicalize(NULL); | 828 *result = result->CheckAndCanonicalize(NULL); |
| 820 ASSERT(!result->IsNull()); | 829 ASSERT(!result->IsNull()); |
| 821 } | 830 } |
| 822 return result->raw(); | 831 return result->raw(); |
| 823 } | 832 } |
| 824 ASSERT((class_header & kSmiTagMask) != kSmiTag); | 833 ASSERT((class_header & kSmiTagMask) != kSmiTag); |
| 825 cls_ = LookupInternalClass(class_header); | 834 cls_ = LookupInternalClass(class_header); |
| 826 ASSERT(!cls_.IsNull()); | 835 ASSERT(!cls_.IsNull()); |
| (...skipping 553 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1380 | 1389 |
| 1381 | 1390 |
| 1382 void SnapshotWriter::WriteInstance(intptr_t object_id, | 1391 void SnapshotWriter::WriteInstance(intptr_t object_id, |
| 1383 RawObject* raw, | 1392 RawObject* raw, |
| 1384 RawClass* cls, | 1393 RawClass* cls, |
| 1385 intptr_t tags) { | 1394 intptr_t tags) { |
| 1386 // First check if object is a closure or has native fields. | 1395 // First check if object is a closure or has native fields. |
| 1387 CheckIfSerializable(cls); | 1396 CheckIfSerializable(cls); |
| 1388 | 1397 |
| 1389 // Object is regular dart instance. | 1398 // Object is regular dart instance. |
| 1390 intptr_t instance_size = | 1399 intptr_t next_field_offset = |
| 1391 cls->ptr()->instance_size_in_words_ << kWordSizeLog2; | 1400 cls->ptr()->next_field_offset_in_words_ << kWordSizeLog2; |
| 1392 ASSERT(instance_size != 0); | 1401 ASSERT(next_field_offset > 0); |
| 1393 | 1402 |
| 1394 // Write out the serialization header value for this object. | 1403 // Write out the serialization header value for this object. |
| 1395 WriteInlinedObjectHeader(object_id); | 1404 WriteInlinedObjectHeader(object_id); |
| 1396 | 1405 |
| 1397 // Indicate this is an instance object. | 1406 // Indicate this is an instance object. |
| 1398 WriteIntptrValue(SerializedHeaderData::encode(kInstanceObjectId)); | 1407 WriteIntptrValue(SerializedHeaderData::encode(kInstanceObjectId)); |
| 1399 | 1408 |
| 1400 // Write out the tags. | 1409 // Write out the tags. |
| 1401 WriteIntptrValue(tags); | 1410 WriteIntptrValue(tags); |
| 1402 | 1411 |
| 1403 // Write out the class information for this object. | 1412 // Write out the class information for this object. |
| 1404 WriteObjectImpl(cls); | 1413 WriteObjectImpl(cls); |
| 1405 | 1414 |
| 1406 // Write out all the fields for the object. | 1415 // Write out all the fields for the object. |
| 1407 intptr_t offset = Object::InstanceSize(); | 1416 // Instance::NextFieldOffset() returns the offset of the first field in |
| 1408 while (offset < instance_size) { | 1417 // a Dart object. |
| 1418 intptr_t offset = Instance::NextFieldOffset(); |
| 1419 while (offset < next_field_offset) { |
| 1409 WriteObjectRef(*reinterpret_cast<RawObject**>( | 1420 WriteObjectRef(*reinterpret_cast<RawObject**>( |
| 1410 reinterpret_cast<uword>(raw->ptr()) + offset)); | 1421 reinterpret_cast<uword>(raw->ptr()) + offset)); |
| 1411 offset += kWordSize; | 1422 offset += kWordSize; |
| 1412 } | 1423 } |
| 1413 return; | 1424 return; |
| 1414 } | 1425 } |
| 1415 | 1426 |
| 1416 | 1427 |
| 1417 void SnapshotWriter::WriteInstanceRef(RawObject* raw, RawClass* cls) { | 1428 void SnapshotWriter::WriteInstanceRef(RawObject* raw, RawClass* cls) { |
| 1418 // First check if object is a closure or has native fields. | 1429 // First check if object is a closure or has native fields. |
| (...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1505 UnmarkAll(); | 1516 UnmarkAll(); |
| 1506 isolate->set_long_jump_base(base); | 1517 isolate->set_long_jump_base(base); |
| 1507 } else { | 1518 } else { |
| 1508 isolate->set_long_jump_base(base); | 1519 isolate->set_long_jump_base(base); |
| 1509 ThrowException(exception_type(), exception_msg()); | 1520 ThrowException(exception_type(), exception_msg()); |
| 1510 } | 1521 } |
| 1511 } | 1522 } |
| 1512 | 1523 |
| 1513 | 1524 |
| 1514 } // namespace dart | 1525 } // namespace dart |
| OLD | NEW |