| 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/exceptions.h" | 10 #include "vm/exceptions.h" |
| (...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 124 ASSERT(kObjectId == | 124 ASSERT(kObjectId == |
| 125 ((1 << RawObject::kFreeBit) | (1 << RawObject::kMarkBit))); | 125 ((1 << RawObject::kFreeBit) | (1 << RawObject::kMarkBit))); |
| 126 ASSERT((kObjectAlignmentMask & kObjectId) == kObjectId); | 126 ASSERT((kObjectAlignmentMask & kObjectId) == kObjectId); |
| 127 const Snapshot* snapshot = reinterpret_cast<const Snapshot*>(raw_memory); | 127 const Snapshot* snapshot = reinterpret_cast<const Snapshot*>(raw_memory); |
| 128 return snapshot; | 128 return snapshot; |
| 129 } | 129 } |
| 130 | 130 |
| 131 | 131 |
| 132 RawSmi* BaseReader::ReadAsSmi() { | 132 RawSmi* BaseReader::ReadAsSmi() { |
| 133 intptr_t value = ReadIntptrValue(); | 133 intptr_t value = ReadIntptrValue(); |
| 134 ASSERT((value & kSmiTagMask) == 0); | 134 ASSERT((value & kSmiTagMask) == kSmiTag); |
| 135 return reinterpret_cast<RawSmi*>(value); | 135 return reinterpret_cast<RawSmi*>(value); |
| 136 } | 136 } |
| 137 | 137 |
| 138 | 138 |
| 139 intptr_t BaseReader::ReadSmiValue() { | 139 intptr_t BaseReader::ReadSmiValue() { |
| 140 return Smi::Value(ReadAsSmi()); | 140 return Smi::Value(ReadAsSmi()); |
| 141 } | 141 } |
| 142 | 142 |
| 143 | 143 |
| 144 SnapshotReader::SnapshotReader(const uint8_t* buffer, | 144 SnapshotReader::SnapshotReader(const uint8_t* buffer, |
| (...skipping 27 matching lines...) Expand all Loading... |
| 172 } | 172 } |
| 173 } | 173 } |
| 174 return obj.raw(); | 174 return obj.raw(); |
| 175 } | 175 } |
| 176 | 176 |
| 177 | 177 |
| 178 RawClass* SnapshotReader::ReadClassId(intptr_t object_id) { | 178 RawClass* SnapshotReader::ReadClassId(intptr_t object_id) { |
| 179 ASSERT(kind_ != Snapshot::kFull); | 179 ASSERT(kind_ != Snapshot::kFull); |
| 180 // Read the class header information and lookup the class. | 180 // Read the class header information and lookup the class. |
| 181 intptr_t class_header = ReadIntptrValue(); | 181 intptr_t class_header = ReadIntptrValue(); |
| 182 ASSERT((class_header & kSmiTagMask) != 0); | 182 ASSERT((class_header & kSmiTagMask) != kSmiTag); |
| 183 Class& cls = Class::ZoneHandle(isolate(), Class::null()); | 183 Class& cls = Class::ZoneHandle(isolate(), Class::null()); |
| 184 cls = LookupInternalClass(class_header); | 184 cls = LookupInternalClass(class_header); |
| 185 AddBackRef(object_id, &cls, kIsDeserialized); | 185 AddBackRef(object_id, &cls, kIsDeserialized); |
| 186 if (cls.IsNull()) { | 186 if (cls.IsNull()) { |
| 187 // Read the library/class information and lookup the class. | 187 // Read the library/class information and lookup the class. |
| 188 str_ ^= ReadObjectImpl(class_header); | 188 str_ ^= ReadObjectImpl(class_header); |
| 189 library_ = Library::LookupLibrary(str_); | 189 library_ = Library::LookupLibrary(str_); |
| 190 ASSERT(!library_.IsNull()); | 190 ASSERT(!library_.IsNull()); |
| 191 str_ ^= ReadObjectImpl(); | 191 str_ ^= ReadObjectImpl(); |
| 192 cls = library_.LookupClass(str_); | 192 cls = library_.LookupClass(str_); |
| 193 } | 193 } |
| 194 ASSERT(!cls.IsNull()); | 194 ASSERT(!cls.IsNull()); |
| 195 return cls.raw(); | 195 return cls.raw(); |
| 196 } | 196 } |
| 197 | 197 |
| 198 | 198 |
| 199 RawObject* SnapshotReader::ReadObjectImpl() { | 199 RawObject* SnapshotReader::ReadObjectImpl() { |
| 200 int64_t value = Read<int64_t>(); | 200 int64_t value = Read<int64_t>(); |
| 201 if ((value & kSmiTagMask) == 0) { | 201 if ((value & kSmiTagMask) == kSmiTag) { |
| 202 return Integer::New((value >> kSmiTagShift), HEAP_SPACE(kind_)); | 202 return NewInteger(value); |
| 203 } | 203 } |
| 204 return ReadObjectImpl(value); | 204 return ReadObjectImpl(value); |
| 205 } | 205 } |
| 206 | 206 |
| 207 | 207 |
| 208 RawObject* SnapshotReader::ReadObjectImpl(intptr_t header_value) { | 208 RawObject* SnapshotReader::ReadObjectImpl(intptr_t header_value) { |
| 209 ASSERT((header_value <= kIntptrMax) && (header_value >= kIntptrMin)); | 209 ASSERT((header_value <= kIntptrMax) && (header_value >= kIntptrMin)); |
| 210 if (IsVMIsolateObject(header_value)) { | 210 if (IsVMIsolateObject(header_value)) { |
| 211 return ReadVMIsolateObject(header_value); | 211 return ReadVMIsolateObject(header_value); |
| 212 } else { | 212 } else { |
| 213 if (SerializedHeaderTag::decode(header_value) == kObjectId) { | 213 if (SerializedHeaderTag::decode(header_value) == kObjectId) { |
| 214 return ReadIndexedObject(SerializedHeaderData::decode(header_value)); | 214 return ReadIndexedObject(SerializedHeaderData::decode(header_value)); |
| 215 } | 215 } |
| 216 ASSERT(SerializedHeaderTag::decode(header_value) == kInlined); | 216 ASSERT(SerializedHeaderTag::decode(header_value) == kInlined); |
| 217 return ReadInlinedObject(SerializedHeaderData::decode(header_value)); | 217 return ReadInlinedObject(SerializedHeaderData::decode(header_value)); |
| 218 } | 218 } |
| 219 } | 219 } |
| 220 | 220 |
| 221 | 221 |
| 222 RawObject* SnapshotReader::ReadObjectRef() { | 222 RawObject* SnapshotReader::ReadObjectRef() { |
| 223 int64_t header_value = Read<int64_t>(); | 223 int64_t header_value = Read<int64_t>(); |
| 224 if ((header_value & kSmiTagMask) == 0) { | 224 if ((header_value & kSmiTagMask) == kSmiTag) { |
| 225 return Integer::New((header_value >> kSmiTagShift), HEAP_SPACE(kind_)); | 225 return NewInteger(header_value); |
| 226 } | 226 } |
| 227 ASSERT((header_value <= kIntptrMax) && (header_value >= kIntptrMin)); | 227 ASSERT((header_value <= kIntptrMax) && (header_value >= kIntptrMin)); |
| 228 if (IsVMIsolateObject(header_value)) { | 228 if (IsVMIsolateObject(header_value)) { |
| 229 return ReadVMIsolateObject(header_value); | 229 return ReadVMIsolateObject(header_value); |
| 230 } else if (SerializedHeaderTag::decode(header_value) == kObjectId) { | 230 } else if (SerializedHeaderTag::decode(header_value) == kObjectId) { |
| 231 return ReadIndexedObject(SerializedHeaderData::decode(header_value)); | 231 return ReadIndexedObject(SerializedHeaderData::decode(header_value)); |
| 232 } | 232 } |
| 233 ASSERT(SerializedHeaderTag::decode(header_value) == kInlined); | 233 ASSERT(SerializedHeaderTag::decode(header_value) == kInlined); |
| 234 intptr_t object_id = SerializedHeaderData::decode(header_value); | 234 intptr_t object_id = SerializedHeaderData::decode(header_value); |
| 235 ASSERT(GetBackRef(object_id) == NULL); | 235 ASSERT(GetBackRef(object_id) == NULL); |
| (...skipping 12 matching lines...) Expand all Loading... |
| 248 ASSERT(!cls_.IsNull()); | 248 ASSERT(!cls_.IsNull()); |
| 249 intptr_t instance_size = cls_.instance_size(); | 249 intptr_t instance_size = cls_.instance_size(); |
| 250 ASSERT(instance_size > 0); | 250 ASSERT(instance_size > 0); |
| 251 if (kind_ == Snapshot::kFull) { | 251 if (kind_ == Snapshot::kFull) { |
| 252 result ^= AllocateUninitialized(cls_, instance_size); | 252 result ^= AllocateUninitialized(cls_, instance_size); |
| 253 } else { | 253 } else { |
| 254 result ^= Object::Allocate(cls_.id(), instance_size, HEAP_SPACE(kind_)); | 254 result ^= Object::Allocate(cls_.id(), instance_size, HEAP_SPACE(kind_)); |
| 255 } | 255 } |
| 256 return result.raw(); | 256 return result.raw(); |
| 257 } | 257 } |
| 258 ASSERT((class_header & kSmiTagMask) != 0); | 258 ASSERT((class_header & kSmiTagMask) != kSmiTag); |
| 259 cls_ = LookupInternalClass(class_header); | 259 cls_ = LookupInternalClass(class_header); |
| 260 ASSERT(!cls_.IsNull()); | 260 ASSERT(!cls_.IsNull()); |
| 261 | 261 |
| 262 // Similarly Array and ImmutableArray objects are also similarly only | 262 // Similarly Array and ImmutableArray objects are also similarly only |
| 263 // allocated here, the individual array elements are read later. | 263 // allocated here, the individual array elements are read later. |
| 264 intptr_t class_id = cls_.id(); | 264 intptr_t class_id = cls_.id(); |
| 265 if (class_id == kArrayCid) { | 265 if (class_id == kArrayCid) { |
| 266 // Read the length and allocate an object based on the len. | 266 // Read the length and allocate an object based on the len. |
| 267 intptr_t len = ReadSmiValue(); | 267 intptr_t len = ReadSmiValue(); |
| 268 Array& array = Array::ZoneHandle( | 268 Array& array = Array::ZoneHandle( |
| (...skipping 298 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 567 RawApiError* SnapshotReader::NewApiError() { | 567 RawApiError* SnapshotReader::NewApiError() { |
| 568 ALLOC_NEW_OBJECT(ApiError, Object::api_error_class()); | 568 ALLOC_NEW_OBJECT(ApiError, Object::api_error_class()); |
| 569 } | 569 } |
| 570 | 570 |
| 571 | 571 |
| 572 RawLanguageError* SnapshotReader::NewLanguageError() { | 572 RawLanguageError* SnapshotReader::NewLanguageError() { |
| 573 ALLOC_NEW_OBJECT(LanguageError, Object::language_error_class()); | 573 ALLOC_NEW_OBJECT(LanguageError, Object::language_error_class()); |
| 574 } | 574 } |
| 575 | 575 |
| 576 | 576 |
| 577 RawObject* SnapshotReader::NewInteger(int64_t value) { |
| 578 ASSERT((value & kSmiTagMask) == kSmiTag); |
| 579 value = value >> kSmiTagShift; |
| 580 if ((value <= Smi::kMaxValue) && (value >= Smi::kMinValue)) { |
| 581 return Smi::New(value); |
| 582 } |
| 583 if (kind_ == Snapshot::kFull) { |
| 584 return NewMint(value); |
| 585 } |
| 586 return Mint::NewCanonical(value); |
| 587 } |
| 588 |
| 589 |
| 577 RawClass* SnapshotReader::LookupInternalClass(intptr_t class_header) { | 590 RawClass* SnapshotReader::LookupInternalClass(intptr_t class_header) { |
| 578 // If the header is an object Id, lookup singleton VM classes or classes | 591 // If the header is an object Id, lookup singleton VM classes or classes |
| 579 // stored in the object store. | 592 // stored in the object store. |
| 580 if (IsVMIsolateObject(class_header)) { | 593 if (IsVMIsolateObject(class_header)) { |
| 581 intptr_t class_id = GetVMIsolateObjectId(class_header); | 594 intptr_t class_id = GetVMIsolateObjectId(class_header); |
| 582 if (IsSingletonClassId(class_id)) { | 595 if (IsSingletonClassId(class_id)) { |
| 583 return isolate()->class_table()->At(class_id); // get singleton class. | 596 return isolate()->class_table()->At(class_id); // get singleton class. |
| 584 } | 597 } |
| 585 } else if (SerializedHeaderTag::decode(class_header) == kObjectId) { | 598 } else if (SerializedHeaderTag::decode(class_header) == kObjectId) { |
| 586 intptr_t class_id = SerializedHeaderData::decode(class_header); | 599 intptr_t class_id = SerializedHeaderData::decode(class_header); |
| (...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 697 result->SetFieldAtOffset(offset, obj_); | 710 result->SetFieldAtOffset(offset, obj_); |
| 698 offset += kWordSize; | 711 offset += kWordSize; |
| 699 } | 712 } |
| 700 if (kind_ == Snapshot::kFull) { | 713 if (kind_ == Snapshot::kFull) { |
| 701 result->SetCreatedFromSnapshot(); | 714 result->SetCreatedFromSnapshot(); |
| 702 } else if (result->IsCanonical()) { | 715 } else if (result->IsCanonical()) { |
| 703 *result = result->Canonicalize(); | 716 *result = result->Canonicalize(); |
| 704 } | 717 } |
| 705 return result->raw(); | 718 return result->raw(); |
| 706 } | 719 } |
| 707 ASSERT((class_header & kSmiTagMask) != 0); | 720 ASSERT((class_header & kSmiTagMask) != kSmiTag); |
| 708 cls_ = LookupInternalClass(class_header); | 721 cls_ = LookupInternalClass(class_header); |
| 709 ASSERT(!cls_.IsNull()); | 722 ASSERT(!cls_.IsNull()); |
| 710 switch (cls_.id()) { | 723 switch (cls_.id()) { |
| 711 #define SNAPSHOT_READ(clazz) \ | 724 #define SNAPSHOT_READ(clazz) \ |
| 712 case clazz::kClassId: { \ | 725 case clazz::kClassId: { \ |
| 713 obj_ = clazz::ReadFrom(this, object_id, tags, kind_); \ | 726 obj_ = clazz::ReadFrom(this, object_id, tags, kind_); \ |
| 714 break; \ | 727 break; \ |
| 715 } | 728 } |
| 716 CLASS_LIST_NO_OBJECT(SNAPSHOT_READ) | 729 CLASS_LIST_NO_OBJECT(SNAPSHOT_READ) |
| 717 #undef SNAPSHOT_READ | 730 #undef SNAPSHOT_READ |
| (...skipping 295 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1013 WriteIndexedObject(kTrueValue); | 1026 WriteIndexedObject(kTrueValue); |
| 1014 return true; | 1027 return true; |
| 1015 } | 1028 } |
| 1016 | 1029 |
| 1017 // Check if it is a singleton boolean false value. | 1030 // Check if it is a singleton boolean false value. |
| 1018 if (rawobj == object_store()->false_value()) { | 1031 if (rawobj == object_store()->false_value()) { |
| 1019 WriteIndexedObject(kFalseValue); | 1032 WriteIndexedObject(kFalseValue); |
| 1020 return true; | 1033 return true; |
| 1021 } | 1034 } |
| 1022 | 1035 |
| 1036 // Check if the object is a Mint and could potentially be a Smi |
| 1037 // on other architectures (64 bit), if so write it out as int64_t value. |
| 1038 if (rawobj->GetClassId() == kMintCid) { |
| 1039 int64_t value = reinterpret_cast<RawMint*>(rawobj)->ptr()->value_; |
| 1040 const intptr_t kSmi64Bits = 62; |
| 1041 const int64_t kSmi64Max = (static_cast<int64_t>(1) << kSmi64Bits) - 1; |
| 1042 const int64_t kSmi64Min = -(static_cast<int64_t>(1) << kSmi64Bits); |
| 1043 if (value <= kSmi64Max && value >= kSmi64Min) { |
| 1044 Write<int64_t>((value << kSmiTagShift) | kSmiTag); |
| 1045 return true; |
| 1046 } |
| 1047 } |
| 1048 |
| 1023 // Check if it is a code object in that case just write a Null object | 1049 // Check if it is a code object in that case just write a Null object |
| 1024 // as we do not want code objects in the snapshot. | 1050 // as we do not want code objects in the snapshot. |
| 1025 if (rawobj->GetClassId() == kCodeCid) { | 1051 if (rawobj->GetClassId() == kCodeCid) { |
| 1026 WriteVMIsolateObject(kNullObject); | 1052 WriteVMIsolateObject(kNullObject); |
| 1027 return true; | 1053 return true; |
| 1028 } | 1054 } |
| 1029 | 1055 |
| 1030 // Check if classes are not being serialized and it is preinitialized type. | 1056 // Check if classes are not being serialized and it is preinitialized type. |
| 1031 if (kind_ != Snapshot::kFull) { | 1057 if (kind_ != Snapshot::kFull) { |
| 1032 RawType* raw_type = reinterpret_cast<RawType*>(rawobj); | 1058 RawType* raw_type = reinterpret_cast<RawType*>(rawobj); |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1082 if (cls->ptr()->num_native_fields_ != 0) { | 1108 if (cls->ptr()->num_native_fields_ != 0) { |
| 1083 // We do not allow objects with native fields in an isolate message. | 1109 // We do not allow objects with native fields in an isolate message. |
| 1084 set_exception_type(Exceptions::kArgument); | 1110 set_exception_type(Exceptions::kArgument); |
| 1085 // TODO(6726): Allocate these constant strings once in the VM isolate. | 1111 // TODO(6726): Allocate these constant strings once in the VM isolate. |
| 1086 set_exception_msg("Illegal argument in isolate message" | 1112 set_exception_msg("Illegal argument in isolate message" |
| 1087 " : (object extends NativeWrapper)"); | 1113 " : (object extends NativeWrapper)"); |
| 1088 | 1114 |
| 1089 Isolate::Current()->long_jump_base()->Jump(1, *ErrorHandle()); | 1115 Isolate::Current()->long_jump_base()->Jump(1, *ErrorHandle()); |
| 1090 } | 1116 } |
| 1091 // Object is regular dart instance. | 1117 // Object is regular dart instance. |
| 1092 intptr_t instance_size = cls->ptr()->instance_size_; | 1118 intptr_t instance_size = |
| 1119 cls->ptr()->instance_size_in_words_ << kWordSizeLog2; |
| 1093 ASSERT(instance_size != 0); | 1120 ASSERT(instance_size != 0); |
| 1094 | 1121 |
| 1095 // Write out the serialization header value for this object. | 1122 // Write out the serialization header value for this object. |
| 1096 WriteInlinedObjectHeader(object_id); | 1123 WriteInlinedObjectHeader(object_id); |
| 1097 | 1124 |
| 1098 // Indicate this is an instance object. | 1125 // Indicate this is an instance object. |
| 1099 WriteIntptrValue(SerializedHeaderData::encode(kInstanceObjectId)); | 1126 WriteIntptrValue(SerializedHeaderData::encode(kInstanceObjectId)); |
| 1100 | 1127 |
| 1101 // Write out the tags. | 1128 // Write out the tags. |
| 1102 WriteIntptrValue(tags); | 1129 WriteIntptrValue(tags); |
| (...skipping 167 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1270 UnmarkAll(); | 1297 UnmarkAll(); |
| 1271 isolate->set_long_jump_base(base); | 1298 isolate->set_long_jump_base(base); |
| 1272 } else { | 1299 } else { |
| 1273 isolate->set_long_jump_base(base); | 1300 isolate->set_long_jump_base(base); |
| 1274 ThrowException(exception_type(), exception_msg()); | 1301 ThrowException(exception_type(), exception_msg()); |
| 1275 } | 1302 } |
| 1276 } | 1303 } |
| 1277 | 1304 |
| 1278 | 1305 |
| 1279 } // namespace dart | 1306 } // namespace dart |
| OLD | NEW |