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 |