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/bootstrap.h" | 8 #include "vm/bootstrap.h" |
9 #include "vm/class_finalizer.h" | 9 #include "vm/class_finalizer.h" |
| 10 #include "vm/dart.h" |
10 #include "vm/dart_entry.h" | 11 #include "vm/dart_entry.h" |
11 #include "vm/exceptions.h" | 12 #include "vm/exceptions.h" |
12 #include "vm/heap.h" | 13 #include "vm/heap.h" |
13 #include "vm/lockers.h" | 14 #include "vm/lockers.h" |
14 #include "vm/longjump.h" | 15 #include "vm/longjump.h" |
15 #include "vm/object.h" | 16 #include "vm/object.h" |
16 #include "vm/object_store.h" | 17 #include "vm/object_store.h" |
17 #include "vm/snapshot_ids.h" | 18 #include "vm/snapshot_ids.h" |
18 #include "vm/symbols.h" | 19 #include "vm/symbols.h" |
19 #include "vm/verified_memory.h" | 20 #include "vm/verified_memory.h" |
20 #include "vm/version.h" | 21 #include "vm/version.h" |
21 | 22 |
22 namespace dart { | 23 namespace dart { |
23 | 24 |
| 25 static const int kNumVmIsolateSnapshotReferences = 32 * KB; |
24 static const int kNumInitialReferencesInFullSnapshot = 160 * KB; | 26 static const int kNumInitialReferencesInFullSnapshot = 160 * KB; |
25 static const int kNumInitialReferences = 64; | 27 static const int kNumInitialReferences = 64; |
26 | 28 |
27 | 29 |
28 static bool IsSingletonClassId(intptr_t class_id) { | 30 static bool IsSingletonClassId(intptr_t class_id) { |
29 // Check if this is a singleton object class which is shared by all isolates. | 31 // Check if this is a singleton object class which is shared by all isolates. |
30 return ((class_id >= kClassCid && class_id <= kUnwindErrorCid) || | 32 return ((class_id >= kClassCid && class_id <= kUnwindErrorCid) || |
31 (class_id >= kNullCid && class_id <= kVoidCid)); | 33 (class_id >= kNullCid && class_id <= kVoidCid)); |
32 } | 34 } |
33 | 35 |
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
154 ASSERT((value & kSmiTagMask) == kSmiTag); | 156 ASSERT((value & kSmiTagMask) == kSmiTag); |
155 return reinterpret_cast<RawSmi*>(value); | 157 return reinterpret_cast<RawSmi*>(value); |
156 } | 158 } |
157 | 159 |
158 | 160 |
159 intptr_t BaseReader::ReadSmiValue() { | 161 intptr_t BaseReader::ReadSmiValue() { |
160 return Smi::Value(ReadAsSmi()); | 162 return Smi::Value(ReadAsSmi()); |
161 } | 163 } |
162 | 164 |
163 | 165 |
164 SnapshotReader::SnapshotReader(const uint8_t* buffer, | 166 SnapshotReader::SnapshotReader( |
165 intptr_t size, | 167 const uint8_t* buffer, |
166 Snapshot::Kind kind, | 168 intptr_t size, |
167 Isolate* isolate, | 169 Snapshot::Kind kind, |
168 Zone* zone) | 170 ZoneGrowableArray<BackRefNode>* backward_refs, |
| 171 Isolate* isolate, |
| 172 Zone* zone) |
169 : BaseReader(buffer, size), | 173 : BaseReader(buffer, size), |
170 kind_(kind), | 174 kind_(kind), |
171 isolate_(isolate), | 175 isolate_(isolate), |
172 zone_(zone), | 176 zone_(zone), |
173 heap_(isolate->heap()), | 177 heap_(isolate->heap()), |
174 old_space_(isolate->heap()->old_space()), | 178 old_space_(isolate->heap()->old_space()), |
175 cls_(Class::Handle(isolate)), | 179 cls_(Class::Handle(isolate)), |
176 obj_(Object::Handle(isolate)), | 180 obj_(Object::Handle(isolate)), |
177 pobj_(PassiveObject::Handle(isolate)), | 181 pobj_(PassiveObject::Handle(isolate)), |
178 array_(Array::Handle(isolate)), | 182 array_(Array::Handle(isolate)), |
179 field_(Field::Handle(isolate)), | 183 field_(Field::Handle(isolate)), |
180 str_(String::Handle(isolate)), | 184 str_(String::Handle(isolate)), |
181 library_(Library::Handle(isolate)), | 185 library_(Library::Handle(isolate)), |
182 type_(AbstractType::Handle(isolate)), | 186 type_(AbstractType::Handle(isolate)), |
183 type_arguments_(TypeArguments::Handle(isolate)), | 187 type_arguments_(TypeArguments::Handle(isolate)), |
184 tokens_(Array::Handle(isolate)), | 188 tokens_(Array::Handle(isolate)), |
185 stream_(TokenStream::Handle(isolate)), | 189 stream_(TokenStream::Handle(isolate)), |
186 data_(ExternalTypedData::Handle(isolate)), | 190 data_(ExternalTypedData::Handle(isolate)), |
187 error_(UnhandledException::Handle(isolate)), | 191 error_(UnhandledException::Handle(isolate)), |
188 backward_references_((kind == Snapshot::kFull) ? | 192 max_vm_isolate_object_id_( |
189 kNumInitialReferencesInFullSnapshot : | 193 Object::vm_isolate_snapshot_object_table().Length()), |
190 kNumInitialReferences) { | 194 backward_references_(backward_refs) { |
191 } | 195 } |
192 | 196 |
193 | 197 |
194 RawObject* SnapshotReader::ReadObject() { | 198 RawObject* SnapshotReader::ReadObject() { |
195 // Setup for long jump in case there is an exception while reading. | 199 // Setup for long jump in case there is an exception while reading. |
196 LongJumpScope jump; | 200 LongJumpScope jump; |
197 if (setjmp(*jump.Set()) == 0) { | 201 if (setjmp(*jump.Set()) == 0) { |
198 PassiveObject& obj = PassiveObject::Handle(isolate(), ReadObjectImpl()); | 202 PassiveObject& obj = PassiveObject::Handle(isolate(), ReadObjectImpl()); |
199 for (intptr_t i = 0; i < backward_references_.length(); i++) { | 203 for (intptr_t i = 0; i < backward_references_->length(); i++) { |
200 if (!backward_references_[i].is_deserialized()) { | 204 if (!(*backward_references_)[i].is_deserialized()) { |
201 ReadObjectImpl(); | 205 ReadObjectImpl(); |
202 backward_references_[i].set_state(kIsDeserialized); | 206 (*backward_references_)[i].set_state(kIsDeserialized); |
203 } | 207 } |
204 } | 208 } |
205 return obj.raw(); | 209 return obj.raw(); |
206 } else { | 210 } else { |
207 // An error occurred while reading, return the error object. | 211 // An error occurred while reading, return the error object. |
208 const Error& err = Error::Handle(isolate()->object_store()->sticky_error()); | 212 const Error& err = Error::Handle(isolate()->object_store()->sticky_error()); |
209 isolate()->object_store()->clear_sticky_error(); | 213 isolate()->object_store()->clear_sticky_error(); |
210 return err.raw(); | 214 return err.raw(); |
211 } | 215 } |
212 } | 216 } |
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
285 int64_t value = Read<int64_t>(); | 289 int64_t value = Read<int64_t>(); |
286 if ((value & kSmiTagMask) == kSmiTag) { | 290 if ((value & kSmiTagMask) == kSmiTag) { |
287 return NewInteger(value); | 291 return NewInteger(value); |
288 } | 292 } |
289 ASSERT((value <= kIntptrMax) && (value >= kIntptrMin)); | 293 ASSERT((value <= kIntptrMax) && (value >= kIntptrMin)); |
290 return ReadObjectImpl(static_cast<intptr_t>(value)); | 294 return ReadObjectImpl(static_cast<intptr_t>(value)); |
291 } | 295 } |
292 | 296 |
293 | 297 |
294 intptr_t SnapshotReader::NextAvailableObjectId() const { | 298 intptr_t SnapshotReader::NextAvailableObjectId() const { |
295 return backward_references_.length() + kMaxPredefinedObjectIds; | 299 return backward_references_->length() + |
| 300 kMaxPredefinedObjectIds + max_vm_isolate_object_id_; |
296 } | 301 } |
297 | 302 |
298 | 303 |
299 void SnapshotReader::SetReadException(const char* msg) { | 304 void SnapshotReader::SetReadException(const char* msg) { |
300 Isolate* isolate = Isolate::Current(); | 305 Isolate* isolate = Isolate::Current(); |
301 const String& error_str = String::Handle(isolate, String::New(msg)); | 306 const String& error_str = String::Handle(isolate, String::New(msg)); |
302 const Array& args = Array::Handle(isolate, Array::New(1)); | 307 const Array& args = Array::Handle(isolate, Array::New(1)); |
303 args.SetAt(0, error_str); | 308 args.SetAt(0, error_str); |
304 Object& result = Object::Handle(isolate); | 309 Object& result = Object::Handle(isolate); |
305 const Library& library = Library::Handle(isolate, Library::CoreLibrary()); | 310 const Library& library = Library::Handle(isolate, Library::CoreLibrary()); |
306 result = DartLibraryCalls::InstanceCreate(library, | 311 result = DartLibraryCalls::InstanceCreate(library, |
307 Symbols::ArgumentError(), | 312 Symbols::ArgumentError(), |
308 Symbols::Dot(), | 313 Symbols::Dot(), |
309 args); | 314 args); |
310 const Stacktrace& stacktrace = Stacktrace::Handle(isolate); | 315 const Stacktrace& stacktrace = Stacktrace::Handle(isolate); |
311 const UnhandledException& error = UnhandledException::Handle( | 316 const UnhandledException& error = UnhandledException::Handle( |
312 isolate, UnhandledException::New(Instance::Cast(result), stacktrace)); | 317 isolate, UnhandledException::New(Instance::Cast(result), stacktrace)); |
313 isolate->long_jump_base()->Jump(1, error); | 318 isolate->long_jump_base()->Jump(1, error); |
314 } | 319 } |
315 | 320 |
316 | 321 |
| 322 RawObject* SnapshotReader::VmIsolateSnapshotObject(intptr_t index) const { |
| 323 return Object::vm_isolate_snapshot_object_table().At(index); |
| 324 } |
| 325 |
| 326 |
317 RawObject* SnapshotReader::ReadObjectImpl(intptr_t header_value) { | 327 RawObject* SnapshotReader::ReadObjectImpl(intptr_t header_value) { |
318 if (IsVMIsolateObject(header_value)) { | 328 if (IsVMIsolateObject(header_value)) { |
319 return ReadVMIsolateObject(header_value); | 329 return ReadVMIsolateObject(header_value); |
320 } else { | 330 } else { |
321 if (SerializedHeaderTag::decode(header_value) == kObjectId) { | 331 if (SerializedHeaderTag::decode(header_value) == kObjectId) { |
322 return ReadIndexedObject(SerializedHeaderData::decode(header_value)); | 332 return ReadIndexedObject(SerializedHeaderData::decode(header_value)); |
323 } | 333 } |
324 ASSERT(SerializedHeaderTag::decode(header_value) == kInlined); | 334 ASSERT(SerializedHeaderTag::decode(header_value) == kInlined); |
325 intptr_t object_id = SerializedHeaderData::decode(header_value); | 335 intptr_t object_id = SerializedHeaderData::decode(header_value); |
326 if (object_id == kOmittedObjectId) { | 336 if (object_id == kOmittedObjectId) { |
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
440 pobj_.SetCreatedFromSnapshot(); | 450 pobj_.SetCreatedFromSnapshot(); |
441 } | 451 } |
442 return pobj_.raw(); | 452 return pobj_.raw(); |
443 } | 453 } |
444 | 454 |
445 | 455 |
446 void SnapshotReader::AddBackRef(intptr_t id, | 456 void SnapshotReader::AddBackRef(intptr_t id, |
447 Object* obj, | 457 Object* obj, |
448 DeserializeState state) { | 458 DeserializeState state) { |
449 intptr_t index = (id - kMaxPredefinedObjectIds); | 459 intptr_t index = (id - kMaxPredefinedObjectIds); |
450 ASSERT(index == backward_references_.length()); | 460 ASSERT(index >= max_vm_isolate_object_id_); |
| 461 index -= max_vm_isolate_object_id_; |
| 462 ASSERT(index == backward_references_->length()); |
451 BackRefNode node(obj, state); | 463 BackRefNode node(obj, state); |
452 backward_references_.Add(node); | 464 backward_references_->Add(node); |
453 } | 465 } |
454 | 466 |
455 | 467 |
456 Object* SnapshotReader::GetBackRef(intptr_t id) { | 468 Object* SnapshotReader::GetBackRef(intptr_t id) { |
457 ASSERT(id >= kMaxPredefinedObjectIds); | 469 ASSERT(id >= kMaxPredefinedObjectIds); |
458 intptr_t index = (id - kMaxPredefinedObjectIds); | 470 intptr_t index = (id - kMaxPredefinedObjectIds); |
459 if (index < backward_references_.length()) { | 471 ASSERT(index >= max_vm_isolate_object_id_); |
460 return backward_references_[index].reference(); | 472 index -= max_vm_isolate_object_id_; |
| 473 if (index < backward_references_->length()) { |
| 474 return (*backward_references_)[index].reference(); |
461 } | 475 } |
462 return NULL; | 476 return NULL; |
463 } | 477 } |
464 | 478 |
465 | 479 |
466 class HeapLocker : public StackResource { | 480 class HeapLocker : public StackResource { |
467 public: | 481 public: |
468 HeapLocker(Isolate* isolate, PageSpace* page_space) | 482 HeapLocker(Isolate* isolate, PageSpace* page_space) |
469 : StackResource(isolate), page_space_(page_space) { | 483 : StackResource(isolate), page_space_(page_space) { |
470 page_space_->AcquireDataLock(); | 484 page_space_->AcquireDataLock(); |
(...skipping 26 matching lines...) Expand all Loading... |
497 // size for the full snapshot being read. | 511 // size for the full snapshot being read. |
498 { | 512 { |
499 NoSafepointScope no_safepoint; | 513 NoSafepointScope no_safepoint; |
500 HeapLocker hl(isolate, old_space()); | 514 HeapLocker hl(isolate, old_space()); |
501 | 515 |
502 // Read in all the objects stored in the object store. | 516 // Read in all the objects stored in the object store. |
503 intptr_t num_flds = (object_store->to() - object_store->from()); | 517 intptr_t num_flds = (object_store->to() - object_store->from()); |
504 for (intptr_t i = 0; i <= num_flds; i++) { | 518 for (intptr_t i = 0; i <= num_flds; i++) { |
505 *(object_store->from() + i) = ReadObjectImpl(); | 519 *(object_store->from() + i) = ReadObjectImpl(); |
506 } | 520 } |
507 for (intptr_t i = 0; i < backward_references_.length(); i++) { | 521 for (intptr_t i = 0; i < backward_references_->length(); i++) { |
508 if (!backward_references_[i].is_deserialized()) { | 522 if (!(*backward_references_)[i].is_deserialized()) { |
509 ReadObjectImpl(); | 523 ReadObjectImpl(); |
510 backward_references_[i].set_state(kIsDeserialized); | 524 (*backward_references_)[i].set_state(kIsDeserialized); |
511 } | 525 } |
512 } | 526 } |
513 | 527 |
514 // Validate the class table. | 528 // Validate the class table. |
515 #if defined(DEBUG) | 529 #if defined(DEBUG) |
516 isolate->ValidateClassTable(); | 530 isolate->ValidateClassTable(); |
517 #endif | 531 #endif |
518 | 532 |
519 // Setup native resolver for bootstrap impl. | 533 // Setup native resolver for bootstrap impl. |
520 Bootstrap::SetupNativeResolver(); | 534 Bootstrap::SetupNativeResolver(); |
(...skipping 451 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
972 RawObject* SnapshotReader::ReadIndexedObject(intptr_t object_id) { | 986 RawObject* SnapshotReader::ReadIndexedObject(intptr_t object_id) { |
973 intptr_t class_id = ClassIdFromObjectId(object_id); | 987 intptr_t class_id = ClassIdFromObjectId(object_id); |
974 if (IsObjectStoreClassId(class_id)) { | 988 if (IsObjectStoreClassId(class_id)) { |
975 return isolate()->class_table()->At(class_id); // get singleton class. | 989 return isolate()->class_table()->At(class_id); // get singleton class. |
976 } | 990 } |
977 if (kind_ != Snapshot::kFull) { | 991 if (kind_ != Snapshot::kFull) { |
978 if (IsObjectStoreTypeId(object_id)) { | 992 if (IsObjectStoreTypeId(object_id)) { |
979 return GetType(object_store(), object_id); // return type obj. | 993 return GetType(object_store(), object_id); // return type obj. |
980 } | 994 } |
981 } | 995 } |
982 Object* object = GetBackRef(object_id); | 996 ASSERT(object_id >= kMaxPredefinedObjectIds); |
983 return object->raw(); | 997 intptr_t index = (object_id - kMaxPredefinedObjectIds); |
| 998 if (index < max_vm_isolate_object_id_) { |
| 999 return VmIsolateSnapshotObject(index); |
| 1000 } |
| 1001 return GetBackRef(object_id)->raw(); |
984 } | 1002 } |
985 | 1003 |
986 | 1004 |
987 RawObject* SnapshotReader::ReadInlinedObject(intptr_t object_id) { | 1005 RawObject* SnapshotReader::ReadInlinedObject(intptr_t object_id) { |
988 // Read the class header information and lookup the class. | 1006 // Read the class header information and lookup the class. |
989 intptr_t class_header = Read<int32_t>(); | 1007 intptr_t class_header = Read<int32_t>(); |
990 intptr_t tags = ReadTags(); | 1008 intptr_t tags = ReadTags(); |
991 intptr_t header_id = SerializedHeaderData::decode(class_header); | 1009 intptr_t header_id = SerializedHeaderData::decode(class_header); |
992 if (header_id == kInstanceObjectId) { | 1010 if (header_id == kInstanceObjectId) { |
993 // Object is regular dart instance. | 1011 // Object is regular dart instance. |
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1101 intptr_t len, | 1119 intptr_t len, |
1102 intptr_t tags) { | 1120 intptr_t tags) { |
1103 // Set the object tags. | 1121 // Set the object tags. |
1104 result.set_tags(tags); | 1122 result.set_tags(tags); |
1105 | 1123 |
1106 // Setup the object fields. | 1124 // Setup the object fields. |
1107 *TypeArgumentsHandle() ^= ReadObjectImpl(); | 1125 *TypeArgumentsHandle() ^= ReadObjectImpl(); |
1108 result.SetTypeArguments(*TypeArgumentsHandle()); | 1126 result.SetTypeArguments(*TypeArgumentsHandle()); |
1109 | 1127 |
1110 bool is_canonical = RawObject::IsCanonical(tags); | 1128 bool is_canonical = RawObject::IsCanonical(tags); |
| 1129 Object& obj = Object::Handle(isolate()); |
1111 | 1130 |
1112 for (intptr_t i = 0; i < len; i++) { | 1131 for (intptr_t i = 0; i < len; i++) { |
1113 *PassiveObjectHandle() = is_canonical ? ReadObjectImpl() : ReadObjectRef(); | 1132 *PassiveObjectHandle() = is_canonical ? ReadObjectImpl() : ReadObjectRef(); |
| 1133 obj = (*PassiveObjectHandle()).raw(); |
1114 result.SetAt(i, *PassiveObjectHandle()); | 1134 result.SetAt(i, *PassiveObjectHandle()); |
1115 } | 1135 } |
1116 } | 1136 } |
1117 | 1137 |
1118 | 1138 |
| 1139 VmIsolateSnapshotReader::VmIsolateSnapshotReader(const uint8_t* buffer, |
| 1140 intptr_t size, |
| 1141 Zone* zone) |
| 1142 : SnapshotReader(buffer, |
| 1143 size, |
| 1144 Snapshot::kFull, |
| 1145 new ZoneGrowableArray<BackRefNode>( |
| 1146 kNumVmIsolateSnapshotReferences), |
| 1147 Dart::vm_isolate(), |
| 1148 zone) { |
| 1149 } |
| 1150 |
| 1151 |
| 1152 VmIsolateSnapshotReader::~VmIsolateSnapshotReader() { |
| 1153 intptr_t len = GetBackwardReferenceTable()->length(); |
| 1154 Object::InitVmIsolateSnapshotObjectTable(len); |
| 1155 ZoneGrowableArray<BackRefNode>* backrefs = GetBackwardReferenceTable(); |
| 1156 for (intptr_t i = 0; i < len; i++) { |
| 1157 Object::vm_isolate_snapshot_object_table().SetAt( |
| 1158 i, *(backrefs->At(i).reference())); |
| 1159 } |
| 1160 ResetBackwardReferenceTable(); |
| 1161 } |
| 1162 |
| 1163 |
| 1164 RawApiError* VmIsolateSnapshotReader::ReadVmIsolateSnapshot() { |
| 1165 ASSERT(kind() == Snapshot::kFull); |
| 1166 Isolate* isolate = Isolate::Current(); |
| 1167 ASSERT(isolate != NULL); |
| 1168 ASSERT(isolate == Dart::vm_isolate()); |
| 1169 ObjectStore* object_store = isolate->object_store(); |
| 1170 ASSERT(object_store != NULL); |
| 1171 |
| 1172 // First read the version string, and check that it matches. |
| 1173 RawApiError* error = VerifyVersion(); |
| 1174 if (error != ApiError::null()) { |
| 1175 return error; |
| 1176 } |
| 1177 |
| 1178 // The version string matches. Read the rest of the snapshot. |
| 1179 |
| 1180 { |
| 1181 NoSafepointScope no_safepoint; |
| 1182 HeapLocker hl(isolate, old_space()); |
| 1183 |
| 1184 // Read in the symbol table. |
| 1185 object_store->symbol_table_ = reinterpret_cast<RawArray*>(ReadObject()); |
| 1186 |
| 1187 // Validate the class table. |
| 1188 #if defined(DEBUG) |
| 1189 isolate->ValidateClassTable(); |
| 1190 #endif |
| 1191 |
| 1192 return ApiError::null(); |
| 1193 } |
| 1194 } |
| 1195 |
| 1196 |
| 1197 IsolateSnapshotReader::IsolateSnapshotReader(const uint8_t* buffer, |
| 1198 intptr_t size, |
| 1199 Isolate* isolate, |
| 1200 Zone* zone) |
| 1201 : SnapshotReader(buffer, |
| 1202 size, |
| 1203 Snapshot::kFull, |
| 1204 new ZoneGrowableArray<BackRefNode>( |
| 1205 kNumInitialReferencesInFullSnapshot), |
| 1206 isolate, |
| 1207 zone) { |
| 1208 } |
| 1209 |
| 1210 |
| 1211 IsolateSnapshotReader::~IsolateSnapshotReader() { |
| 1212 ResetBackwardReferenceTable(); |
| 1213 } |
| 1214 |
| 1215 |
| 1216 ScriptSnapshotReader::ScriptSnapshotReader(const uint8_t* buffer, |
| 1217 intptr_t size, |
| 1218 Isolate* isolate, |
| 1219 Zone* zone) |
| 1220 : SnapshotReader(buffer, |
| 1221 size, |
| 1222 Snapshot::kScript, |
| 1223 new ZoneGrowableArray<BackRefNode>(kNumInitialReferences), |
| 1224 isolate, |
| 1225 zone) { |
| 1226 } |
| 1227 |
| 1228 |
| 1229 ScriptSnapshotReader::~ScriptSnapshotReader() { |
| 1230 ResetBackwardReferenceTable(); |
| 1231 } |
| 1232 |
| 1233 |
| 1234 MessageSnapshotReader::MessageSnapshotReader(const uint8_t* buffer, |
| 1235 intptr_t size, |
| 1236 Isolate* isolate, |
| 1237 Zone* zone) |
| 1238 : SnapshotReader(buffer, |
| 1239 size, |
| 1240 Snapshot::kMessage, |
| 1241 new ZoneGrowableArray<BackRefNode>(kNumInitialReferences), |
| 1242 isolate, |
| 1243 zone) { |
| 1244 } |
| 1245 |
| 1246 |
| 1247 MessageSnapshotReader::~MessageSnapshotReader() { |
| 1248 ResetBackwardReferenceTable(); |
| 1249 } |
| 1250 |
| 1251 |
1119 SnapshotWriter::SnapshotWriter(Snapshot::Kind kind, | 1252 SnapshotWriter::SnapshotWriter(Snapshot::Kind kind, |
1120 uint8_t** buffer, | 1253 uint8_t** buffer, |
1121 ReAlloc alloc, | 1254 ReAlloc alloc, |
1122 intptr_t initial_size, | 1255 intptr_t initial_size, |
| 1256 ForwardList* forward_list, |
1123 bool can_send_any_object) | 1257 bool can_send_any_object) |
1124 : BaseWriter(buffer, alloc, initial_size), | 1258 : BaseWriter(buffer, alloc, initial_size), |
1125 kind_(kind), | 1259 kind_(kind), |
1126 isolate_(Isolate::Current()), | 1260 isolate_(Isolate::Current()), |
1127 object_store_(isolate_->object_store()), | 1261 object_store_(isolate_->object_store()), |
1128 class_table_(isolate_->class_table()), | 1262 class_table_(isolate_->class_table()), |
1129 forward_list_(kMaxPredefinedObjectIds), | 1263 forward_list_(forward_list), |
1130 exception_type_(Exceptions::kNone), | 1264 exception_type_(Exceptions::kNone), |
1131 exception_msg_(NULL), | 1265 exception_msg_(NULL), |
1132 unmarked_objects_(false), | 1266 unmarked_objects_(false), |
1133 can_send_any_object_(can_send_any_object) { | 1267 can_send_any_object_(can_send_any_object) { |
| 1268 ASSERT(forward_list_ != NULL); |
1134 } | 1269 } |
1135 | 1270 |
1136 | 1271 |
1137 void SnapshotWriter::WriteObject(RawObject* rawobj) { | 1272 void SnapshotWriter::WriteObject(RawObject* rawobj) { |
1138 WriteObjectImpl(rawobj); | 1273 WriteObjectImpl(rawobj); |
1139 WriteForwardedObjects(); | 1274 WriteForwardedObjects(); |
1140 } | 1275 } |
1141 | 1276 |
1142 | 1277 |
1143 void SnapshotWriter::HandleVMIsolateObject(RawObject* rawobj) { | 1278 void SnapshotWriter::HandleVMIsolateObject(RawObject* rawobj) { |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1195 if (id == kClassCid) { | 1330 if (id == kClassCid) { |
1196 RawClass* raw_class = reinterpret_cast<RawClass*>(rawobj); | 1331 RawClass* raw_class = reinterpret_cast<RawClass*>(rawobj); |
1197 intptr_t class_id = raw_class->ptr()->id_; | 1332 intptr_t class_id = raw_class->ptr()->id_; |
1198 if (IsSingletonClassId(class_id)) { | 1333 if (IsSingletonClassId(class_id)) { |
1199 intptr_t object_id = ObjectIdFromClassId(class_id); | 1334 intptr_t object_id = ObjectIdFromClassId(class_id); |
1200 WriteVMIsolateObject(object_id); | 1335 WriteVMIsolateObject(object_id); |
1201 return; | 1336 return; |
1202 } | 1337 } |
1203 } | 1338 } |
1204 | 1339 |
1205 | |
1206 // Check it is a predefined symbol in the VM isolate. | 1340 // Check it is a predefined symbol in the VM isolate. |
1207 id = Symbols::LookupVMSymbol(rawobj); | 1341 id = Symbols::LookupVMSymbol(rawobj); |
1208 if (id != kInvalidIndex) { | 1342 if (id != kInvalidIndex) { |
1209 WriteVMIsolateObject(id); | 1343 WriteVMIsolateObject(id); |
1210 return; | 1344 return; |
1211 } | 1345 } |
1212 | 1346 |
| 1347 // Check if it is an object from the vm isolate snapshot object table. |
| 1348 id = FindVmSnapshotObject(rawobj); |
| 1349 if (id != kInvalidIndex) { |
| 1350 WriteIndexedObject(id); |
| 1351 return; |
| 1352 } |
1213 UNREACHABLE(); | 1353 UNREACHABLE(); |
1214 } | 1354 } |
1215 | 1355 |
1216 | 1356 |
1217 void SnapshotWriter::WriteObjectRef(RawObject* raw) { | 1357 void SnapshotWriter::WriteObjectRef(RawObject* raw) { |
1218 // First check if object can be written as a simple predefined type. | 1358 // First check if object can be written as a simple predefined type. |
1219 if (CheckAndWritePredefinedObject(raw)) { | 1359 if (CheckAndWritePredefinedObject(raw)) { |
1220 return; | 1360 return; |
1221 } | 1361 } |
1222 | 1362 |
1223 NoSafepointScope no_safepoint; | 1363 NoSafepointScope no_safepoint; |
1224 RawClass* cls = class_table_->At(raw->GetClassId()); | 1364 RawClass* cls = class_table_->At(raw->GetClassId()); |
1225 intptr_t class_id = cls->ptr()->id_; | 1365 intptr_t class_id = cls->ptr()->id_; |
1226 ASSERT(class_id == raw->GetClassId()); | 1366 ASSERT(class_id == raw->GetClassId()); |
1227 if (class_id >= kNumPredefinedCids) { | 1367 if (class_id >= kNumPredefinedCids) { |
1228 WriteInstanceRef(raw, cls); | 1368 WriteInstanceRef(raw, cls); |
1229 return; | 1369 return; |
1230 } | 1370 } |
1231 if (class_id == kArrayCid) { | 1371 if (class_id == kArrayCid) { |
1232 // Object is being referenced, add it to the forward ref list and mark | 1372 // Object is being referenced, add it to the forward ref list and mark |
1233 // it so that future references to this object in the snapshot will use | 1373 // it so that future references to this object in the snapshot will use |
1234 // this object id. Mark it as not having been serialized yet so that we | 1374 // this object id. Mark it as not having been serialized yet so that we |
1235 // will serialize the object when we go through the forward list. | 1375 // will serialize the object when we go through the forward list. |
1236 forward_list_.MarkAndAddObject(raw, kIsNotSerialized); | 1376 forward_list_->MarkAndAddObject(raw, kIsNotSerialized); |
1237 | 1377 |
1238 RawArray* rawarray = reinterpret_cast<RawArray*>(raw); | 1378 RawArray* rawarray = reinterpret_cast<RawArray*>(raw); |
1239 | 1379 |
1240 // Write out the serialization header value for this object. | 1380 // Write out the serialization header value for this object. |
1241 WriteInlinedObjectHeader(kOmittedObjectId); | 1381 WriteInlinedObjectHeader(kOmittedObjectId); |
1242 | 1382 |
1243 // Write out the class information. | 1383 // Write out the class information. |
1244 WriteIndexedObject(kArrayCid); | 1384 WriteIndexedObject(kArrayCid); |
1245 | 1385 |
1246 // Write out the length field. | 1386 // Write out the length field. |
1247 Write<RawObject*>(rawarray->ptr()->length_); | 1387 Write<RawObject*>(rawarray->ptr()->length_); |
1248 | 1388 |
1249 return; | 1389 return; |
1250 } | 1390 } |
1251 if (class_id == kImmutableArrayCid) { | 1391 if (class_id == kImmutableArrayCid) { |
1252 // Object is being referenced, add it to the forward ref list and mark | 1392 // Object is being referenced, add it to the forward ref list and mark |
1253 // it so that future references to this object in the snapshot will use | 1393 // it so that future references to this object in the snapshot will use |
1254 // this object id. Mark it as not having been serialized yet so that we | 1394 // this object id. Mark it as not having been serialized yet so that we |
1255 // will serialize the object when we go through the forward list. | 1395 // will serialize the object when we go through the forward list. |
1256 forward_list_.MarkAndAddObject(raw, kIsNotSerialized); | 1396 forward_list_->MarkAndAddObject(raw, kIsNotSerialized); |
1257 | 1397 |
1258 RawArray* rawarray = reinterpret_cast<RawArray*>(raw); | 1398 RawArray* rawarray = reinterpret_cast<RawArray*>(raw); |
1259 | 1399 |
1260 // Write out the serialization header value for this object. | 1400 // Write out the serialization header value for this object. |
1261 WriteInlinedObjectHeader(kOmittedObjectId); | 1401 WriteInlinedObjectHeader(kOmittedObjectId); |
1262 | 1402 |
1263 // Write out the class information. | 1403 // Write out the class information. |
1264 WriteIndexedObject(kImmutableArrayCid); | 1404 WriteIndexedObject(kImmutableArrayCid); |
1265 | 1405 |
1266 // Write out the length field. | 1406 // Write out the length field. |
1267 Write<RawObject*>(rawarray->ptr()->length_); | 1407 Write<RawObject*>(rawarray->ptr()->length_); |
1268 | 1408 |
1269 return; | 1409 return; |
1270 } | 1410 } |
1271 if (RawObject::IsImplicitFieldClassId(class_id)) { | 1411 if (RawObject::IsImplicitFieldClassId(class_id)) { |
1272 WriteInstanceRef(raw, cls); | 1412 WriteInstanceRef(raw, cls); |
1273 return; | 1413 return; |
1274 } | 1414 } |
1275 // Add object to the forward ref list and mark it so that future references | 1415 // Add object to the forward ref list and mark it so that future references |
1276 // to this object in the snapshot will use this object id. Mark it as having | 1416 // to this object in the snapshot will use this object id. Mark it as having |
1277 // been serialized so that we do not serialize the object when we go through | 1417 // been serialized so that we do not serialize the object when we go through |
1278 // the forward list. | 1418 // the forward list. |
1279 forward_list_.MarkAndAddObject(raw, kIsSerialized); | 1419 forward_list_->MarkAndAddObject(raw, kIsSerialized); |
1280 switch (class_id) { | 1420 switch (class_id) { |
1281 #define SNAPSHOT_WRITE(clazz) \ | 1421 #define SNAPSHOT_WRITE(clazz) \ |
1282 case clazz::kClassId: { \ | 1422 case clazz::kClassId: { \ |
1283 Raw##clazz* raw_obj = reinterpret_cast<Raw##clazz*>(raw); \ | 1423 Raw##clazz* raw_obj = reinterpret_cast<Raw##clazz*>(raw); \ |
1284 raw_obj->WriteTo(this, kOmittedObjectId, kind_); \ | 1424 raw_obj->WriteTo(this, kOmittedObjectId, kind_); \ |
1285 return; \ | 1425 return; \ |
1286 } \ | 1426 } \ |
1287 | 1427 |
1288 CLASS_LIST_NO_OBJECT(SNAPSHOT_WRITE) | 1428 CLASS_LIST_NO_OBJECT(SNAPSHOT_WRITE) |
1289 #undef SNAPSHOT_WRITE | 1429 #undef SNAPSHOT_WRITE |
(...skipping 15 matching lines...) Expand all Loading... |
1305 raw_obj->WriteTo(this, kOmittedObjectId, kind_); | 1445 raw_obj->WriteTo(this, kOmittedObjectId, kind_); |
1306 return; | 1446 return; |
1307 } | 1447 } |
1308 #undef SNAPSHOT_WRITE | 1448 #undef SNAPSHOT_WRITE |
1309 default: break; | 1449 default: break; |
1310 } | 1450 } |
1311 UNREACHABLE(); | 1451 UNREACHABLE(); |
1312 } | 1452 } |
1313 | 1453 |
1314 | 1454 |
1315 void FullSnapshotWriter::WriteFullSnapshot() { | 1455 FullSnapshotWriter::FullSnapshotWriter(uint8_t** vm_isolate_snapshot_buffer, |
1316 ASSERT(isolate() != NULL); | 1456 uint8_t** isolate_snapshot_buffer, |
1317 ObjectStore* object_store = isolate()->object_store(); | 1457 ReAlloc alloc) |
| 1458 : vm_isolate_snapshot_buffer_(vm_isolate_snapshot_buffer), |
| 1459 isolate_snapshot_buffer_(isolate_snapshot_buffer), |
| 1460 alloc_(alloc), |
| 1461 vm_isolate_snapshot_size_(0), |
| 1462 isolate_snapshot_size_(0), |
| 1463 forward_list_(SnapshotWriter::FirstObjectId()) { |
| 1464 ASSERT(isolate_snapshot_buffer_ != NULL); |
| 1465 ASSERT(alloc_ != NULL); |
| 1466 } |
| 1467 |
| 1468 |
| 1469 void FullSnapshotWriter::WriteVmIsolateSnapshot() { |
| 1470 ASSERT(vm_isolate_snapshot_buffer_ != NULL); |
| 1471 SnapshotWriter writer(Snapshot::kFull, |
| 1472 vm_isolate_snapshot_buffer_, |
| 1473 alloc_, |
| 1474 kInitialSize, |
| 1475 &forward_list_, |
| 1476 true); // Can send any kind of object. |
| 1477 Isolate* isolate = writer.isolate(); |
| 1478 ASSERT(isolate != NULL); |
| 1479 ObjectStore* object_store = isolate->object_store(); |
1318 ASSERT(object_store != NULL); | 1480 ASSERT(object_store != NULL); |
1319 ASSERT(ClassFinalizer::AllClassesFinalized()); | 1481 ASSERT(ClassFinalizer::AllClassesFinalized()); |
1320 | 1482 |
1321 // Ensure the class table is valid. | 1483 // Ensure the class table is valid. |
1322 #if defined(DEBUG) | 1484 #if defined(DEBUG) |
1323 isolate()->ValidateClassTable(); | 1485 isolate->ValidateClassTable(); |
1324 #endif | 1486 #endif |
1325 | 1487 |
| 1488 // Write full snapshot for a regular isolate. |
1326 // Setup for long jump in case there is an exception while writing | 1489 // Setup for long jump in case there is an exception while writing |
1327 // the snapshot. | 1490 // the snapshot. |
1328 LongJumpScope jump; | 1491 LongJumpScope jump; |
1329 if (setjmp(*jump.Set()) == 0) { | 1492 if (setjmp(*jump.Set()) == 0) { |
1330 // Reserve space in the output buffer for a snapshot header. | 1493 // Reserve space in the output buffer for a snapshot header. |
1331 ReserveHeader(); | 1494 writer.ReserveHeader(); |
1332 | 1495 |
1333 // Write out the version string. | 1496 // Write out the version string. |
1334 WriteVersion(); | 1497 writer.WriteVersion(); |
| 1498 |
| 1499 // Write out the symbol table. |
| 1500 { |
| 1501 NoSafepointScope no_safepoint; |
| 1502 |
| 1503 // Write out the symbol table and reset the symbol table for the |
| 1504 // regular isolate so that we do not write these symbols into the |
| 1505 // snapshot of a regular dart isolate. |
| 1506 writer.WriteObject(object_store->symbol_table()); |
| 1507 |
| 1508 writer.FillHeader(writer.kind()); |
| 1509 } |
| 1510 vm_isolate_snapshot_size_ = writer.BytesWritten(); |
| 1511 // Reset the symbol table for the regular isolate so that we do not |
| 1512 // write these symbols into the snapshot of a regular dart isolate. |
| 1513 Symbols::SetupSymbolTable(isolate); |
| 1514 } else { |
| 1515 writer.ThrowException(writer.exception_type(), writer.exception_msg()); |
| 1516 } |
| 1517 } |
| 1518 |
| 1519 |
| 1520 void FullSnapshotWriter::WriteIsolateFullSnapshot() { |
| 1521 SnapshotWriter writer(Snapshot::kFull, |
| 1522 isolate_snapshot_buffer_, |
| 1523 alloc_, |
| 1524 kInitialSize, |
| 1525 &forward_list_, |
| 1526 true); |
| 1527 Isolate* isolate = writer.isolate(); |
| 1528 ASSERT(isolate != NULL); |
| 1529 ObjectStore* object_store = isolate->object_store(); |
| 1530 ASSERT(object_store != NULL); |
| 1531 ASSERT(ClassFinalizer::AllClassesFinalized()); |
| 1532 |
| 1533 // Ensure the class table is valid. |
| 1534 #if defined(DEBUG) |
| 1535 isolate->ValidateClassTable(); |
| 1536 #endif |
| 1537 |
| 1538 // Write full snapshot for a regular isolate. |
| 1539 // Setup for long jump in case there is an exception while writing |
| 1540 // the snapshot. |
| 1541 LongJumpScope jump; |
| 1542 if (setjmp(*jump.Set()) == 0) { |
| 1543 // Reserve space in the output buffer for a snapshot header. |
| 1544 writer.ReserveHeader(); |
| 1545 |
| 1546 // Write out the version string. |
| 1547 writer.WriteVersion(); |
1335 | 1548 |
1336 // Write out the full snapshot. | 1549 // Write out the full snapshot. |
1337 { | 1550 { |
1338 NoSafepointScope no_safepoint; | 1551 NoSafepointScope no_safepoint; |
1339 | 1552 |
1340 // Write out all the objects in the object store of the isolate which | 1553 // Write out all the objects in the object store of the isolate which |
1341 // is the root set for all dart allocated objects at this point. | 1554 // is the root set for all dart allocated objects at this point. |
1342 SnapshotWriterVisitor visitor(this, false); | 1555 SnapshotWriterVisitor visitor(&writer, false); |
1343 object_store->VisitObjectPointers(&visitor); | 1556 object_store->VisitObjectPointers(&visitor); |
1344 | 1557 |
1345 // Write out all forwarded objects. | 1558 // Write out all forwarded objects. |
1346 WriteForwardedObjects(); | 1559 writer.WriteForwardedObjects(); |
1347 | 1560 |
1348 FillHeader(kind()); | 1561 writer.FillHeader(writer.kind()); |
1349 UnmarkAll(); | 1562 writer.UnmarkAll(); |
1350 } | 1563 } |
| 1564 isolate_snapshot_size_ = writer.BytesWritten(); |
1351 } else { | 1565 } else { |
1352 ThrowException(exception_type(), exception_msg()); | 1566 writer.ThrowException(writer.exception_type(), writer.exception_msg()); |
1353 } | 1567 } |
1354 } | 1568 } |
1355 | 1569 |
1356 | 1570 |
| 1571 void FullSnapshotWriter::WriteFullSnapshot() { |
| 1572 if (vm_isolate_snapshot_buffer() != NULL) { |
| 1573 WriteVmIsolateSnapshot(); |
| 1574 } |
| 1575 WriteIsolateFullSnapshot(); |
| 1576 } |
| 1577 |
| 1578 |
1357 uword SnapshotWriter::GetObjectTags(RawObject* raw) { | 1579 uword SnapshotWriter::GetObjectTags(RawObject* raw) { |
1358 uword tags = raw->ptr()->tags_; | 1580 uword tags = raw->ptr()->tags_; |
1359 if (SerializedHeaderTag::decode(tags) == kObjectId) { | 1581 if (SerializedHeaderTag::decode(tags) == kObjectId) { |
1360 intptr_t id = SerializedHeaderData::decode(tags); | 1582 intptr_t id = SerializedHeaderData::decode(tags); |
1361 return forward_list_.NodeForObjectId(id)->tags(); | 1583 return forward_list_->NodeForObjectId(id)->tags(); |
1362 } else { | 1584 } else { |
1363 return tags; | 1585 return tags; |
1364 } | 1586 } |
1365 } | 1587 } |
1366 | 1588 |
1367 | 1589 |
1368 ForwardList::ForwardList(intptr_t first_object_id) | 1590 ForwardList::ForwardList(intptr_t first_object_id) |
1369 : first_object_id_(first_object_id), | 1591 : first_object_id_(first_object_id), |
1370 nodes_(), | 1592 nodes_(), |
1371 first_unprocessed_object_id_(first_object_id) { | 1593 first_unprocessed_object_id_(first_object_id) { |
(...skipping 13 matching lines...) Expand all Loading... |
1385 MonitorLocker ml(page_space->tasks_lock()); | 1607 MonitorLocker ml(page_space->tasks_lock()); |
1386 ASSERT(page_space->tasks() == 1); | 1608 ASSERT(page_space->tasks() == 1); |
1387 page_space->set_tasks(0); | 1609 page_space->set_tasks(0); |
1388 ml.Notify(); | 1610 ml.Notify(); |
1389 } | 1611 } |
1390 | 1612 |
1391 | 1613 |
1392 intptr_t ForwardList::MarkAndAddObject(RawObject* raw, SerializeState state) { | 1614 intptr_t ForwardList::MarkAndAddObject(RawObject* raw, SerializeState state) { |
1393 NoSafepointScope no_safepoint; | 1615 NoSafepointScope no_safepoint; |
1394 intptr_t object_id = next_object_id(); | 1616 intptr_t object_id = next_object_id(); |
1395 ASSERT(object_id <= kMaxObjectId); | 1617 ASSERT(object_id > 0 && object_id <= kMaxObjectId); |
1396 uword value = 0; | 1618 uword value = 0; |
1397 value = SerializedHeaderTag::update(kObjectId, value); | 1619 value = SerializedHeaderTag::update(kObjectId, value); |
1398 value = SerializedHeaderData::update(object_id, value); | 1620 value = SerializedHeaderData::update(object_id, value); |
1399 uword tags = raw->ptr()->tags_; | 1621 uword tags = raw->ptr()->tags_; |
1400 ASSERT(SerializedHeaderTag::decode(tags) != kObjectId); | 1622 ASSERT(SerializedHeaderTag::decode(tags) != kObjectId); |
1401 raw->ptr()->tags_ = value; | 1623 raw->ptr()->tags_ = value; |
1402 Node* node = new Node(raw, tags, state); | 1624 Node* node = new Node(raw, tags, state); |
1403 ASSERT(node != NULL); | 1625 ASSERT(node != NULL); |
1404 nodes_.Add(node); | 1626 nodes_.Add(node); |
1405 return object_id; | 1627 return object_id; |
1406 } | 1628 } |
1407 | 1629 |
1408 | 1630 |
1409 void ForwardList::UnmarkAll() const { | 1631 void ForwardList::UnmarkAll() const { |
1410 NoSafepointScope no_safepoint; | 1632 { |
1411 for (intptr_t id = first_object_id(); id < next_object_id(); ++id) { | 1633 NoSafepointScope no_safepoint; |
1412 const Node* node = NodeForObjectId(id); | 1634 for (intptr_t id = first_object_id(); id < next_object_id(); ++id) { |
1413 RawObject* raw = node->raw(); | 1635 const Node* node = NodeForObjectId(id); |
1414 raw->ptr()->tags_ = node->tags(); // Restore original tags. | 1636 RawObject* raw = node->raw(); |
| 1637 raw->ptr()->tags_ = node->tags(); // Restore original tags. |
| 1638 } |
1415 } | 1639 } |
1416 } | 1640 } |
1417 | 1641 |
1418 | 1642 |
1419 bool SnapshotWriter::CheckAndWritePredefinedObject(RawObject* rawobj) { | 1643 bool SnapshotWriter::CheckAndWritePredefinedObject(RawObject* rawobj) { |
1420 // Check if object can be written in one of the following ways: | 1644 // Check if object can be written in one of the following ways: |
1421 // - Smi: the Smi value is written as is (last bit is not tagged). | 1645 // - Smi: the Smi value is written as is (last bit is not tagged). |
1422 // - VM internal class (from VM isolate): (index of class in vm isolate | 0x3) | 1646 // - VM internal class (from VM isolate): (index of class in vm isolate | 0x3) |
1423 // - Object that has already been written: (negative id in stream | 0x3) | 1647 // - Object that has already been written: (negative id in stream | 0x3) |
1424 | 1648 |
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1505 | 1729 |
1506 void SnapshotWriter::WriteObjectImpl(RawObject* raw) { | 1730 void SnapshotWriter::WriteObjectImpl(RawObject* raw) { |
1507 // First check if object can be written as a simple predefined type. | 1731 // First check if object can be written as a simple predefined type. |
1508 if (CheckAndWritePredefinedObject(raw)) { | 1732 if (CheckAndWritePredefinedObject(raw)) { |
1509 return; | 1733 return; |
1510 } | 1734 } |
1511 | 1735 |
1512 // Object is being serialized, add it to the forward ref list and mark | 1736 // Object is being serialized, add it to the forward ref list and mark |
1513 // it so that future references to this object in the snapshot will use | 1737 // it so that future references to this object in the snapshot will use |
1514 // an object id, instead of trying to serialize it again. | 1738 // an object id, instead of trying to serialize it again. |
1515 forward_list_.MarkAndAddObject(raw, kIsSerialized); | 1739 forward_list_->MarkAndAddObject(raw, kIsSerialized); |
1516 | 1740 |
1517 WriteInlinedObject(raw); | 1741 WriteInlinedObject(raw); |
1518 } | 1742 } |
1519 | 1743 |
1520 | 1744 |
1521 void SnapshotWriter::WriteInlinedObject(RawObject* raw) { | 1745 void SnapshotWriter::WriteInlinedObject(RawObject* raw) { |
1522 // Now write the object out inline in the stream as follows: | 1746 // Now write the object out inline in the stream as follows: |
1523 // - Object is seen for the first time (inlined as follows): | 1747 // - Object is seen for the first time (inlined as follows): |
1524 // (object size in multiples of kObjectAlignment | 0x1) | 1748 // (object size in multiples of kObjectAlignment | 0x1) |
1525 // serialized fields of the object | 1749 // serialized fields of the object |
1526 // ...... | 1750 // ...... |
1527 NoSafepointScope no_safepoint; | 1751 NoSafepointScope no_safepoint; |
1528 uword tags = raw->ptr()->tags_; | 1752 uword tags = raw->ptr()->tags_; |
1529 ASSERT(SerializedHeaderTag::decode(tags) == kObjectId); | 1753 ASSERT(SerializedHeaderTag::decode(tags) == kObjectId); |
1530 intptr_t object_id = SerializedHeaderData::decode(tags); | 1754 intptr_t object_id = SerializedHeaderData::decode(tags); |
1531 tags = forward_list_.NodeForObjectId(object_id)->tags(); | 1755 tags = forward_list_->NodeForObjectId(object_id)->tags(); |
1532 RawClass* cls = class_table_->At(RawObject::ClassIdTag::decode(tags)); | 1756 RawClass* cls = class_table_->At(RawObject::ClassIdTag::decode(tags)); |
1533 intptr_t class_id = cls->ptr()->id_; | 1757 intptr_t class_id = cls->ptr()->id_; |
1534 | 1758 |
1535 if (!IsSplitClassId(class_id)) { | 1759 if (!IsSplitClassId(class_id)) { |
1536 object_id = kOmittedObjectId; | 1760 object_id = kOmittedObjectId; |
1537 } | 1761 } |
1538 | 1762 |
1539 if (class_id >= kNumPredefinedCids) { | 1763 if (class_id >= kNumPredefinedCids) { |
1540 WriteInstance(object_id, raw, cls, tags); | 1764 WriteInstance(object_id, raw, cls, tags); |
1541 return; | 1765 return; |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1593 writer_->WriteInlinedObject(obj); | 1817 writer_->WriteInlinedObject(obj); |
1594 } | 1818 } |
1595 | 1819 |
1596 private: | 1820 private: |
1597 SnapshotWriter* writer_; | 1821 SnapshotWriter* writer_; |
1598 }; | 1822 }; |
1599 | 1823 |
1600 | 1824 |
1601 void SnapshotWriter::WriteForwardedObjects() { | 1825 void SnapshotWriter::WriteForwardedObjects() { |
1602 WriteInlinedObjectVisitor visitor(this); | 1826 WriteInlinedObjectVisitor visitor(this); |
1603 forward_list_.SerializeAll(&visitor); | 1827 forward_list_->SerializeAll(&visitor); |
1604 } | 1828 } |
1605 | 1829 |
1606 | 1830 |
1607 void ForwardList::SerializeAll(ObjectVisitor* writer) { | 1831 void ForwardList::SerializeAll(ObjectVisitor* writer) { |
1608 // Write out all objects that were added to the forward list and have | 1832 // Write out all objects that were added to the forward list and have |
1609 // not been serialized yet. These would typically be fields of instance | 1833 // not been serialized yet. These would typically be fields of instance |
1610 // objects, arrays or immutable arrays (this is done in order to avoid | 1834 // objects, arrays or immutable arrays (this is done in order to avoid |
1611 // deep recursive calls to WriteObjectImpl). | 1835 // deep recursive calls to WriteObjectImpl). |
1612 // NOTE: The forward list might grow as we process the list. | 1836 // NOTE: The forward list might grow as we process the list. |
1613 #ifdef DEBUG | 1837 #ifdef DEBUG |
(...skipping 221 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1835 CheckForNativeFields(cls); | 2059 CheckForNativeFields(cls); |
1836 | 2060 |
1837 // Check if object is a closure that is serializable, if the object is a | 2061 // Check if object is a closure that is serializable, if the object is a |
1838 // closure that is not serializable this will throw an exception. | 2062 // closure that is not serializable this will throw an exception. |
1839 RawFunction* func = IsSerializableClosure(cls, raw); | 2063 RawFunction* func = IsSerializableClosure(cls, raw); |
1840 if (func != Function::null()) { | 2064 if (func != Function::null()) { |
1841 // Add object to the forward ref list and mark it so that future references | 2065 // Add object to the forward ref list and mark it so that future references |
1842 // to this object in the snapshot will use this object id. Mark it as having | 2066 // to this object in the snapshot will use this object id. Mark it as having |
1843 // been serialized so that we do not serialize the object when we go through | 2067 // been serialized so that we do not serialize the object when we go through |
1844 // the forward list. | 2068 // the forward list. |
1845 forward_list_.MarkAndAddObject(raw, kIsSerialized); | 2069 forward_list_->MarkAndAddObject(raw, kIsSerialized); |
1846 uword tags = raw->ptr()->tags_; | 2070 uword tags = raw->ptr()->tags_; |
1847 ASSERT(SerializedHeaderTag::decode(tags) == kObjectId); | 2071 ASSERT(SerializedHeaderTag::decode(tags) == kObjectId); |
1848 intptr_t object_id = SerializedHeaderData::decode(tags); | 2072 intptr_t object_id = SerializedHeaderData::decode(tags); |
1849 tags = forward_list_.NodeForObjectId(object_id)->tags(); | 2073 tags = forward_list_->NodeForObjectId(object_id)->tags(); |
1850 WriteStaticImplicitClosure(object_id, func, tags); | 2074 WriteStaticImplicitClosure(object_id, func, tags); |
1851 return; | 2075 return; |
1852 } | 2076 } |
1853 | 2077 |
1854 // Object is being referenced, add it to the forward ref list and mark | 2078 // Object is being referenced, add it to the forward ref list and mark |
1855 // it so that future references to this object in the snapshot will use | 2079 // it so that future references to this object in the snapshot will use |
1856 // this object id. Mark it as not having been serialized yet so that we | 2080 // this object id. Mark it as not having been serialized yet so that we |
1857 // will serialize the object when we go through the forward list. | 2081 // will serialize the object when we go through the forward list. |
1858 forward_list_.MarkAndAddObject(raw, kIsNotSerialized); | 2082 forward_list_->MarkAndAddObject(raw, kIsNotSerialized); |
1859 | 2083 |
1860 // Write out the serialization header value for this object. | 2084 // Write out the serialization header value for this object. |
1861 WriteInlinedObjectHeader(kOmittedObjectId); | 2085 WriteInlinedObjectHeader(kOmittedObjectId); |
1862 | 2086 |
1863 // Indicate this is an instance object. | 2087 // Indicate this is an instance object. |
1864 Write<int32_t>(SerializedHeaderData::encode(kInstanceObjectId)); | 2088 Write<int32_t>(SerializedHeaderData::encode(kInstanceObjectId)); |
1865 | 2089 |
1866 // Write out the class information for this object. | 2090 // Write out the class information for this object. |
1867 WriteObjectImpl(cls); | 2091 WriteObjectImpl(cls); |
1868 } | 2092 } |
1869 | 2093 |
1870 | 2094 |
1871 bool SnapshotWriter::AllowObjectsInDartLibrary(RawLibrary* library) { | 2095 bool SnapshotWriter::AllowObjectsInDartLibrary(RawLibrary* library) { |
1872 return (library == object_store()->collection_library() || | 2096 return (library == object_store()->collection_library() || |
1873 library == object_store()->typed_data_library()); | 2097 library == object_store()->typed_data_library()); |
1874 } | 2098 } |
1875 | 2099 |
1876 | 2100 |
| 2101 intptr_t SnapshotWriter::FindVmSnapshotObject(RawObject* rawobj) { |
| 2102 intptr_t length = Object::vm_isolate_snapshot_object_table().Length(); |
| 2103 for (intptr_t i = 0; i < length; i++) { |
| 2104 if (Object::vm_isolate_snapshot_object_table().At(i) == rawobj) { |
| 2105 return (i + kMaxPredefinedObjectIds); |
| 2106 } |
| 2107 } |
| 2108 return kInvalidIndex; |
| 2109 } |
| 2110 |
| 2111 |
1877 void SnapshotWriter::ThrowException(Exceptions::ExceptionType type, | 2112 void SnapshotWriter::ThrowException(Exceptions::ExceptionType type, |
1878 const char* msg) { | 2113 const char* msg) { |
1879 object_store()->clear_sticky_error(); | 2114 object_store()->clear_sticky_error(); |
1880 UnmarkAll(); | 2115 UnmarkAll(); |
1881 if (msg != NULL) { | 2116 if (msg != NULL) { |
1882 const String& msg_obj = String::Handle(String::New(msg)); | 2117 const String& msg_obj = String::Handle(String::New(msg)); |
1883 const Array& args = Array::Handle(Array::New(1)); | 2118 const Array& args = Array::Handle(Array::New(1)); |
1884 args.SetAt(0, msg_obj); | 2119 args.SetAt(0, msg_obj); |
1885 Exceptions::ThrowByType(type, args); | 2120 Exceptions::ThrowByType(type, args); |
1886 } else { | 2121 } else { |
1887 Exceptions::ThrowByType(type, Object::empty_array()); | 2122 Exceptions::ThrowByType(type, Object::empty_array()); |
1888 } | 2123 } |
1889 UNREACHABLE(); | 2124 UNREACHABLE(); |
1890 } | 2125 } |
1891 | 2126 |
1892 | 2127 |
1893 void SnapshotWriter::WriteVersion() { | 2128 void SnapshotWriter::WriteVersion() { |
1894 const char* expected_version = Version::SnapshotString(); | 2129 const char* expected_version = Version::SnapshotString(); |
1895 ASSERT(expected_version != NULL); | 2130 ASSERT(expected_version != NULL); |
1896 const intptr_t version_len = strlen(expected_version); | 2131 const intptr_t version_len = strlen(expected_version); |
1897 WriteBytes(reinterpret_cast<const uint8_t*>(expected_version), version_len); | 2132 WriteBytes(reinterpret_cast<const uint8_t*>(expected_version), version_len); |
1898 } | 2133 } |
1899 | 2134 |
1900 | 2135 |
| 2136 intptr_t SnapshotWriter::FirstObjectId() { |
| 2137 intptr_t max_vm_isolate_object_id = |
| 2138 Object::vm_isolate_snapshot_object_table().Length(); |
| 2139 return kMaxPredefinedObjectIds + max_vm_isolate_object_id; |
| 2140 } |
| 2141 |
| 2142 |
| 2143 ScriptSnapshotWriter::ScriptSnapshotWriter(uint8_t** buffer, |
| 2144 ReAlloc alloc) |
| 2145 : SnapshotWriter(Snapshot::kScript, |
| 2146 buffer, |
| 2147 alloc, |
| 2148 kInitialSize, |
| 2149 &forward_list_, |
| 2150 true), |
| 2151 forward_list_(SnapshotWriter::FirstObjectId()) { |
| 2152 ASSERT(buffer != NULL); |
| 2153 ASSERT(alloc != NULL); |
| 2154 } |
| 2155 |
| 2156 |
1901 void ScriptSnapshotWriter::WriteScriptSnapshot(const Library& lib) { | 2157 void ScriptSnapshotWriter::WriteScriptSnapshot(const Library& lib) { |
1902 ASSERT(kind() == Snapshot::kScript); | 2158 ASSERT(kind() == Snapshot::kScript); |
1903 ASSERT(isolate() != NULL); | 2159 ASSERT(isolate() != NULL); |
1904 ASSERT(ClassFinalizer::AllClassesFinalized()); | 2160 ASSERT(ClassFinalizer::AllClassesFinalized()); |
1905 | 2161 |
1906 // Setup for long jump in case there is an exception while writing | 2162 // Setup for long jump in case there is an exception while writing |
1907 // the snapshot. | 2163 // the snapshot. |
1908 LongJumpScope jump; | 2164 LongJumpScope jump; |
1909 if (setjmp(*jump.Set()) == 0) { | 2165 if (setjmp(*jump.Set()) == 0) { |
1910 // Reserve space in the output buffer for a snapshot header. | 2166 // Reserve space in the output buffer for a snapshot header. |
(...skipping 23 matching lines...) Expand all Loading... |
1934 RawObject* raw_obj = *current; | 2190 RawObject* raw_obj = *current; |
1935 if (as_references_) { | 2191 if (as_references_) { |
1936 writer_->WriteObjectRef(raw_obj); | 2192 writer_->WriteObjectRef(raw_obj); |
1937 } else { | 2193 } else { |
1938 writer_->WriteObjectImpl(raw_obj); | 2194 writer_->WriteObjectImpl(raw_obj); |
1939 } | 2195 } |
1940 } | 2196 } |
1941 } | 2197 } |
1942 | 2198 |
1943 | 2199 |
| 2200 MessageWriter::MessageWriter(uint8_t** buffer, |
| 2201 ReAlloc alloc, |
| 2202 bool can_send_any_object) |
| 2203 : SnapshotWriter(Snapshot::kMessage, |
| 2204 buffer, |
| 2205 alloc, |
| 2206 kInitialSize, |
| 2207 &forward_list_, |
| 2208 can_send_any_object), |
| 2209 forward_list_(SnapshotWriter::FirstObjectId()) { |
| 2210 ASSERT(buffer != NULL); |
| 2211 ASSERT(alloc != NULL); |
| 2212 } |
| 2213 |
| 2214 |
1944 void MessageWriter::WriteMessage(const Object& obj) { | 2215 void MessageWriter::WriteMessage(const Object& obj) { |
1945 ASSERT(kind() == Snapshot::kMessage); | 2216 ASSERT(kind() == Snapshot::kMessage); |
1946 ASSERT(isolate() != NULL); | 2217 ASSERT(isolate() != NULL); |
1947 | 2218 |
1948 // Setup for long jump in case there is an exception while writing | 2219 // Setup for long jump in case there is an exception while writing |
1949 // the message. | 2220 // the message. |
1950 LongJumpScope jump; | 2221 LongJumpScope jump; |
1951 if (setjmp(*jump.Set()) == 0) { | 2222 if (setjmp(*jump.Set()) == 0) { |
1952 NoSafepointScope no_safepoint; | 2223 NoSafepointScope no_safepoint; |
1953 WriteObject(obj.raw()); | 2224 WriteObject(obj.raw()); |
1954 UnmarkAll(); | 2225 UnmarkAll(); |
1955 } else { | 2226 } else { |
1956 ThrowException(exception_type(), exception_msg()); | 2227 ThrowException(exception_type(), exception_msg()); |
1957 } | 2228 } |
1958 } | 2229 } |
1959 | 2230 |
1960 | 2231 |
1961 } // namespace dart | 2232 } // namespace dart |
OLD | NEW |