| 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 151 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 162 intptr_t size, | 162 intptr_t size, |
| 163 Snapshot::Kind kind, | 163 Snapshot::Kind kind, |
| 164 Isolate* isolate) | 164 Isolate* isolate) |
| 165 : BaseReader(buffer, size), | 165 : BaseReader(buffer, size), |
| 166 kind_(kind), | 166 kind_(kind), |
| 167 isolate_(isolate), | 167 isolate_(isolate), |
| 168 heap_(isolate->heap()), | 168 heap_(isolate->heap()), |
| 169 old_space_(isolate->heap()->old_space()), | 169 old_space_(isolate->heap()->old_space()), |
| 170 cls_(Class::Handle(isolate)), | 170 cls_(Class::Handle(isolate)), |
| 171 obj_(Object::Handle(isolate)), | 171 obj_(Object::Handle(isolate)), |
| 172 pobj_(PassiveObject::Handle(isolate)), |
| 172 array_(Array::Handle(isolate)), | 173 array_(Array::Handle(isolate)), |
| 173 field_(Field::Handle(isolate)), | 174 field_(Field::Handle(isolate)), |
| 174 str_(String::Handle(isolate)), | 175 str_(String::Handle(isolate)), |
| 175 library_(Library::Handle(isolate)), | 176 library_(Library::Handle(isolate)), |
| 176 type_(AbstractType::Handle(isolate)), | 177 type_(AbstractType::Handle(isolate)), |
| 177 type_arguments_(TypeArguments::Handle(isolate)), | 178 type_arguments_(TypeArguments::Handle(isolate)), |
| 178 tokens_(Array::Handle(isolate)), | 179 tokens_(Array::Handle(isolate)), |
| 179 stream_(TokenStream::Handle(isolate)), | 180 stream_(TokenStream::Handle(isolate)), |
| 180 data_(ExternalTypedData::Handle(isolate)), | 181 data_(ExternalTypedData::Handle(isolate)), |
| 181 error_(UnhandledException::Handle(isolate)), | 182 error_(UnhandledException::Handle(isolate)), |
| (...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 329 AddBackRef(object_id, &array, kIsNotDeserialized); | 330 AddBackRef(object_id, &array, kIsNotDeserialized); |
| 330 | 331 |
| 331 return array.raw(); | 332 return array.raw(); |
| 332 } | 333 } |
| 333 | 334 |
| 334 // For all other internal VM classes we read the object inline. | 335 // For all other internal VM classes we read the object inline. |
| 335 intptr_t tags = ReadTags(); | 336 intptr_t tags = ReadTags(); |
| 336 switch (class_id) { | 337 switch (class_id) { |
| 337 #define SNAPSHOT_READ(clazz) \ | 338 #define SNAPSHOT_READ(clazz) \ |
| 338 case clazz::kClassId: { \ | 339 case clazz::kClassId: { \ |
| 339 obj_ = clazz::ReadFrom(this, object_id, tags, kind_); \ | 340 pobj_ = clazz::ReadFrom(this, object_id, tags, kind_); \ |
| 340 break; \ | 341 break; \ |
| 341 } | 342 } |
| 342 CLASS_LIST_NO_OBJECT(SNAPSHOT_READ) | 343 CLASS_LIST_NO_OBJECT(SNAPSHOT_READ) |
| 343 #undef SNAPSHOT_READ | 344 #undef SNAPSHOT_READ |
| 344 #define SNAPSHOT_READ(clazz) \ | 345 #define SNAPSHOT_READ(clazz) \ |
| 345 case kTypedData##clazz##Cid: \ | 346 case kTypedData##clazz##Cid: \ |
| 346 | 347 |
| 347 CLASS_LIST_TYPED_DATA(SNAPSHOT_READ) { | 348 CLASS_LIST_TYPED_DATA(SNAPSHOT_READ) { |
| 348 tags = RawObject::ClassIdTag::update(class_id, tags); | 349 tags = RawObject::ClassIdTag::update(class_id, tags); |
| 349 obj_ = TypedData::ReadFrom(this, object_id, tags, kind_); | 350 pobj_ = TypedData::ReadFrom(this, object_id, tags, kind_); |
| 350 break; | 351 break; |
| 351 } | 352 } |
| 352 #undef SNAPSHOT_READ | 353 #undef SNAPSHOT_READ |
| 353 #define SNAPSHOT_READ(clazz) \ | 354 #define SNAPSHOT_READ(clazz) \ |
| 354 case kExternalTypedData##clazz##Cid: \ | 355 case kExternalTypedData##clazz##Cid: \ |
| 355 | 356 |
| 356 CLASS_LIST_TYPED_DATA(SNAPSHOT_READ) { | 357 CLASS_LIST_TYPED_DATA(SNAPSHOT_READ) { |
| 357 tags = RawObject::ClassIdTag::update(class_id, tags); | 358 tags = RawObject::ClassIdTag::update(class_id, tags); |
| 358 obj_ = ExternalTypedData::ReadFrom(this, object_id, tags, kind_); | 359 pobj_ = ExternalTypedData::ReadFrom(this, object_id, tags, kind_); |
| 359 break; | 360 break; |
| 360 } | 361 } |
| 361 #undef SNAPSHOT_READ | 362 #undef SNAPSHOT_READ |
| 362 default: UNREACHABLE(); break; | 363 default: UNREACHABLE(); break; |
| 363 } | 364 } |
| 364 if (kind_ == Snapshot::kFull) { | 365 if (kind_ == Snapshot::kFull) { |
| 365 obj_.SetCreatedFromSnapshot(); | 366 pobj_.SetCreatedFromSnapshot(); |
| 366 } | 367 } |
| 367 return obj_.raw(); | 368 return pobj_.raw(); |
| 368 } | 369 } |
| 369 | 370 |
| 370 | 371 |
| 371 void SnapshotReader::AddBackRef(intptr_t id, | 372 void SnapshotReader::AddBackRef(intptr_t id, |
| 372 Object* obj, | 373 Object* obj, |
| 373 DeserializeState state) { | 374 DeserializeState state) { |
| 374 intptr_t index = (id - kMaxPredefinedObjectIds); | 375 intptr_t index = (id - kMaxPredefinedObjectIds); |
| 375 ASSERT(index == backward_references_.length()); | 376 ASSERT(index == backward_references_.length()); |
| 376 BackRefNode node(obj, state); | 377 BackRefNode node(obj, state); |
| 377 backward_references_.Add(node); | 378 backward_references_.Add(node); |
| (...skipping 503 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 881 instance_size = cls_.instance_size(); | 882 instance_size = cls_.instance_size(); |
| 882 } | 883 } |
| 883 intptr_t next_field_offset = cls_.next_field_offset(); | 884 intptr_t next_field_offset = cls_.next_field_offset(); |
| 884 intptr_t type_argument_field_offset = cls_.type_arguments_field_offset(); | 885 intptr_t type_argument_field_offset = cls_.type_arguments_field_offset(); |
| 885 ASSERT(next_field_offset > 0); | 886 ASSERT(next_field_offset > 0); |
| 886 // Instance::NextFieldOffset() returns the offset of the first field in | 887 // Instance::NextFieldOffset() returns the offset of the first field in |
| 887 // a Dart object. | 888 // a Dart object. |
| 888 intptr_t offset = Instance::NextFieldOffset(); | 889 intptr_t offset = Instance::NextFieldOffset(); |
| 889 intptr_t result_cid = result->GetClassId(); | 890 intptr_t result_cid = result->GetClassId(); |
| 890 while (offset < next_field_offset) { | 891 while (offset < next_field_offset) { |
| 891 obj_ = ReadObjectRef(); | 892 pobj_ = ReadObjectRef(); |
| 892 result->SetFieldAtOffset(offset, obj_); | 893 result->SetFieldAtOffset(offset, pobj_); |
| 893 if ((offset != type_argument_field_offset) && | 894 if ((offset != type_argument_field_offset) && |
| 894 (kind_ == Snapshot::kMessage)) { | 895 (kind_ == Snapshot::kMessage)) { |
| 895 // TODO(fschneider): Consider hoisting these lookups out of the loop. | 896 // TODO(fschneider): Consider hoisting these lookups out of the loop. |
| 896 // This would involve creating a handle, since cls_ can't be reused | 897 // This would involve creating a handle, since cls_ can't be reused |
| 897 // across the call to ReadObjectRef. | 898 // across the call to ReadObjectRef. |
| 898 cls_ = isolate()->class_table()->At(result_cid); | 899 cls_ = isolate()->class_table()->At(result_cid); |
| 899 array_ = cls_.OffsetToFieldMap(); | 900 array_ = cls_.OffsetToFieldMap(); |
| 900 field_ ^= array_.At(offset >> kWordSizeLog2); | 901 field_ ^= array_.At(offset >> kWordSizeLog2); |
| 901 ASSERT(!field_.IsNull()); | 902 ASSERT(!field_.IsNull()); |
| 902 ASSERT(field_.Offset() == offset); | 903 ASSERT(field_.Offset() == offset); |
| 904 obj_ = pobj_.raw(); |
| 903 field_.RecordStore(obj_); | 905 field_.RecordStore(obj_); |
| 904 } | 906 } |
| 905 // TODO(fschneider): Verify the guarded cid and length for other kinds of | 907 // TODO(fschneider): Verify the guarded cid and length for other kinds of |
| 906 // snapshot (kFull, kScript) with asserts. | 908 // snapshot (kFull, kScript) with asserts. |
| 907 offset += kWordSize; | 909 offset += kWordSize; |
| 908 } | 910 } |
| 909 if (kind_ == Snapshot::kFull) { | 911 if (kind_ == Snapshot::kFull) { |
| 910 // We create an uninitialized object in the case of full snapshots, so | 912 // We create an uninitialized object in the case of full snapshots, so |
| 911 // we need to initialize any remaining padding area with the Null object. | 913 // we need to initialize any remaining padding area with the Null object. |
| 912 while (offset < instance_size) { | 914 while (offset < instance_size) { |
| 913 result->SetFieldAtOffset(offset, Object::null_object()); | 915 result->SetFieldAtOffset(offset, Object::null_object()); |
| 914 offset += kWordSize; | 916 offset += kWordSize; |
| 915 } | 917 } |
| 916 result->SetCreatedFromSnapshot(); | 918 result->SetCreatedFromSnapshot(); |
| 917 } else if (result->IsCanonical()) { | 919 } else if (result->IsCanonical()) { |
| 918 *result = result->CheckAndCanonicalize(NULL); | 920 *result = result->CheckAndCanonicalize(NULL); |
| 919 ASSERT(!result->IsNull()); | 921 ASSERT(!result->IsNull()); |
| 920 } | 922 } |
| 921 return result->raw(); | 923 return result->raw(); |
| 922 } | 924 } |
| 923 ASSERT((class_header & kSmiTagMask) != kSmiTag); | 925 ASSERT((class_header & kSmiTagMask) != kSmiTag); |
| 924 cls_ = LookupInternalClass(class_header); | 926 cls_ = LookupInternalClass(class_header); |
| 925 ASSERT(!cls_.IsNull()); | 927 ASSERT(!cls_.IsNull()); |
| 926 switch (cls_.id()) { | 928 switch (cls_.id()) { |
| 927 #define SNAPSHOT_READ(clazz) \ | 929 #define SNAPSHOT_READ(clazz) \ |
| 928 case clazz::kClassId: { \ | 930 case clazz::kClassId: { \ |
| 929 obj_ = clazz::ReadFrom(this, object_id, tags, kind_); \ | 931 pobj_ = clazz::ReadFrom(this, object_id, tags, kind_); \ |
| 930 break; \ | 932 break; \ |
| 931 } | 933 } |
| 932 CLASS_LIST_NO_OBJECT(SNAPSHOT_READ) | 934 CLASS_LIST_NO_OBJECT(SNAPSHOT_READ) |
| 933 #undef SNAPSHOT_READ | 935 #undef SNAPSHOT_READ |
| 934 #define SNAPSHOT_READ(clazz) \ | 936 #define SNAPSHOT_READ(clazz) \ |
| 935 case kTypedData##clazz##Cid: \ | 937 case kTypedData##clazz##Cid: \ |
| 936 | 938 |
| 937 CLASS_LIST_TYPED_DATA(SNAPSHOT_READ) { | 939 CLASS_LIST_TYPED_DATA(SNAPSHOT_READ) { |
| 938 tags = RawObject::ClassIdTag::update(cls_.id(), tags); | 940 tags = RawObject::ClassIdTag::update(cls_.id(), tags); |
| 939 obj_ = TypedData::ReadFrom(this, object_id, tags, kind_); | 941 pobj_ = TypedData::ReadFrom(this, object_id, tags, kind_); |
| 940 break; | 942 break; |
| 941 } | 943 } |
| 942 #undef SNAPSHOT_READ | 944 #undef SNAPSHOT_READ |
| 943 #define SNAPSHOT_READ(clazz) \ | 945 #define SNAPSHOT_READ(clazz) \ |
| 944 case kExternalTypedData##clazz##Cid: \ | 946 case kExternalTypedData##clazz##Cid: \ |
| 945 | 947 |
| 946 CLASS_LIST_TYPED_DATA(SNAPSHOT_READ) { | 948 CLASS_LIST_TYPED_DATA(SNAPSHOT_READ) { |
| 947 tags = RawObject::ClassIdTag::update(cls_.id(), tags); | 949 tags = RawObject::ClassIdTag::update(cls_.id(), tags); |
| 948 obj_ = ExternalTypedData::ReadFrom(this, object_id, tags, kind_); | 950 pobj_ = ExternalTypedData::ReadFrom(this, object_id, tags, kind_); |
| 949 break; | 951 break; |
| 950 } | 952 } |
| 951 #undef SNAPSHOT_READ | 953 #undef SNAPSHOT_READ |
| 952 default: UNREACHABLE(); break; | 954 default: UNREACHABLE(); break; |
| 953 } | 955 } |
| 954 if (kind_ == Snapshot::kFull) { | 956 if (kind_ == Snapshot::kFull) { |
| 955 obj_.SetCreatedFromSnapshot(); | 957 pobj_.SetCreatedFromSnapshot(); |
| 956 } | 958 } |
| 957 return obj_.raw(); | 959 return pobj_.raw(); |
| 958 } | 960 } |
| 959 | 961 |
| 960 | 962 |
| 961 void SnapshotReader::ArrayReadFrom(const Array& result, | 963 void SnapshotReader::ArrayReadFrom(const Array& result, |
| 962 intptr_t len, | 964 intptr_t len, |
| 963 intptr_t tags) { | 965 intptr_t tags) { |
| 964 // Set the object tags. | 966 // Set the object tags. |
| 965 result.set_tags(tags); | 967 result.set_tags(tags); |
| 966 | 968 |
| 967 // Setup the object fields. | 969 // Setup the object fields. |
| 968 *TypeArgumentsHandle() ^= ReadObjectImpl(); | 970 *TypeArgumentsHandle() ^= ReadObjectImpl(); |
| 969 result.SetTypeArguments(*TypeArgumentsHandle()); | 971 result.SetTypeArguments(*TypeArgumentsHandle()); |
| 970 | 972 |
| 971 for (intptr_t i = 0; i < len; i++) { | 973 for (intptr_t i = 0; i < len; i++) { |
| 972 *ObjectHandle() = ReadObjectRef(); | 974 *PassiveObjectHandle() = ReadObjectRef(); |
| 973 result.SetAt(i, *ObjectHandle()); | 975 result.SetAt(i, *PassiveObjectHandle()); |
| 974 } | 976 } |
| 975 } | 977 } |
| 976 | 978 |
| 977 | 979 |
| 978 SnapshotWriter::SnapshotWriter(Snapshot::Kind kind, | 980 SnapshotWriter::SnapshotWriter(Snapshot::Kind kind, |
| 979 uint8_t** buffer, | 981 uint8_t** buffer, |
| 980 ReAlloc alloc, | 982 ReAlloc alloc, |
| 981 intptr_t initial_size) | 983 intptr_t initial_size) |
| 982 : BaseWriter(buffer, alloc, initial_size), | 984 : BaseWriter(buffer, alloc, initial_size), |
| 983 kind_(kind), | 985 kind_(kind), |
| (...skipping 666 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1650 NoGCScope no_gc; | 1652 NoGCScope no_gc; |
| 1651 WriteObject(obj.raw()); | 1653 WriteObject(obj.raw()); |
| 1652 UnmarkAll(); | 1654 UnmarkAll(); |
| 1653 } else { | 1655 } else { |
| 1654 ThrowException(exception_type(), exception_msg()); | 1656 ThrowException(exception_type(), exception_msg()); |
| 1655 } | 1657 } |
| 1656 } | 1658 } |
| 1657 | 1659 |
| 1658 | 1660 |
| 1659 } // namespace dart | 1661 } // namespace dart |
| OLD | NEW |