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