| OLD | NEW |
| 1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2011, 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 "vm/assert.h" | 7 #include "vm/assert.h" |
| 8 #include "vm/bootstrap.h" | 8 #include "vm/bootstrap.h" |
| 9 #include "vm/heap.h" | 9 #include "vm/heap.h" |
| 10 #include "vm/object.h" | 10 #include "vm/object.h" |
| (...skipping 25 matching lines...) Expand all Loading... |
| 36 index <= ObjectStore::kListInterface); | 36 index <= ObjectStore::kListInterface); |
| 37 } | 37 } |
| 38 | 38 |
| 39 | 39 |
| 40 // TODO(5411462): Temporary setup of snapshot for testing purposes, | 40 // TODO(5411462): Temporary setup of snapshot for testing purposes, |
| 41 // the actual creation of a snapshot maybe done differently. | 41 // the actual creation of a snapshot maybe done differently. |
| 42 const Snapshot* Snapshot::SetupFromBuffer(const void* raw_memory) { | 42 const Snapshot* Snapshot::SetupFromBuffer(const void* raw_memory) { |
| 43 ASSERT(raw_memory != NULL); | 43 ASSERT(raw_memory != NULL); |
| 44 ASSERT(kHeaderSize == sizeof(Snapshot)); | 44 ASSERT(kHeaderSize == sizeof(Snapshot)); |
| 45 ASSERT(kLengthIndex == length_offset()); | 45 ASSERT(kLengthIndex == length_offset()); |
| 46 ASSERT((kSnapshotFlagIndex * sizeof(int32_t)) == full_snapshot_offset()); | 46 ASSERT((kSnapshotFlagIndex * sizeof(int32_t)) == kind_offset()); |
| 47 ASSERT((kHeapObjectTag & kInlined)); | 47 ASSERT((kHeapObjectTag & kInlined)); |
| 48 ASSERT((kHeapObjectTag & kObjectId)); | 48 ASSERT((kHeapObjectTag & kObjectId)); |
| 49 ASSERT((kObjectAlignmentMask & kObjectId) == kObjectId); | 49 ASSERT((kObjectAlignmentMask & kObjectId) == kObjectId); |
| 50 const Snapshot* snapshot = reinterpret_cast<const Snapshot*>(raw_memory); | 50 const Snapshot* snapshot = reinterpret_cast<const Snapshot*>(raw_memory); |
| 51 return snapshot; | 51 return snapshot; |
| 52 } | 52 } |
| 53 | 53 |
| 54 | 54 |
| 55 RawObject* SnapshotReader::ReadObject() { | 55 RawObject* SnapshotReader::ReadObject() { |
| 56 intptr_t header = Read<intptr_t>(); | 56 intptr_t header = Read<intptr_t>(); |
| 57 if ((header & kSmiTagMask) == 0) { | 57 if ((header & kSmiTagMask) == 0) { |
| 58 return reinterpret_cast<RawObject*>(header); | 58 return reinterpret_cast<RawObject*>(header); |
| 59 } | 59 } |
| 60 return ReadObjectImpl(header); | 60 return ReadObjectImpl(header); |
| 61 } | 61 } |
| 62 | 62 |
| 63 | 63 |
| 64 RawClass* SnapshotReader::ReadClassId(intptr_t object_id) { | 64 RawClass* SnapshotReader::ReadClassId(intptr_t object_id) { |
| 65 ASSERT(!classes_serialized_); | 65 ASSERT(kind_ != Snapshot::kFull); |
| 66 // Read the class header information and lookup the class. | 66 // Read the class header information and lookup the class. |
| 67 intptr_t class_header = Read<intptr_t>(); | 67 intptr_t class_header = Read<intptr_t>(); |
| 68 ASSERT((class_header & kSmiTagMask) != 0); | 68 ASSERT((class_header & kSmiTagMask) != 0); |
| 69 Class& cls = Class::Handle(); | 69 Class& cls = Class::Handle(); |
| 70 cls ^= LookupInternalClass(class_header); | 70 cls ^= LookupInternalClass(class_header); |
| 71 AddBackwardReference(object_id, &cls); | 71 AddBackwardReference(object_id, &cls); |
| 72 if (cls.IsNull()) { | 72 if (cls.IsNull()) { |
| 73 // Read the library/class information and lookup the class. | 73 // Read the library/class information and lookup the class. |
| 74 String& library_url = String::Handle(); | 74 String& library_url = String::Handle(); |
| 75 library_url ^= ReadObjectImpl(class_header); | 75 library_url ^= ReadObjectImpl(class_header); |
| 76 String& class_name = String::Handle(); | 76 String& class_name = String::Handle(); |
| 77 class_name ^= ReadObject(); | 77 class_name ^= ReadObject(); |
| 78 const Library& library = | 78 const Library& library = |
| 79 Library::Handle(Library::LookupLibrary(library_url)); | 79 Library::Handle(Library::LookupLibrary(library_url)); |
| 80 ASSERT(!library.IsNull()); | 80 ASSERT(!library.IsNull()); |
| 81 cls ^= library.LookupClass(class_name); | 81 cls ^= library.LookupClass(class_name); |
| 82 } | 82 } |
| 83 ASSERT(!cls.IsNull()); | 83 ASSERT(!cls.IsNull()); |
| 84 return cls.raw(); | 84 return cls.raw(); |
| 85 } | 85 } |
| 86 | 86 |
| 87 | 87 |
| 88 void SnapshotReader::AddBackwardReference(intptr_t id, Object* obj) { | 88 void SnapshotReader::AddBackwardReference(intptr_t id, Object* obj) { |
| 89 ASSERT((id - kMaxPredefinedObjectIds) == backward_references_.length()); | 89 ASSERT((id - kMaxPredefinedObjectIds) == backward_references_.length()); |
| 90 backward_references_.Add(obj); | 90 backward_references_.Add(obj); |
| 91 } | 91 } |
| 92 | 92 |
| 93 | 93 |
| 94 void SnapshotReader::ReadFullSnapshot() { | 94 void SnapshotReader::ReadFullSnapshot() { |
| 95 ASSERT(classes_serialized_); | 95 ASSERT(kind_ == Snapshot::kFull); |
| 96 Isolate* isolate = Isolate::Current(); | 96 Isolate* isolate = Isolate::Current(); |
| 97 ASSERT(isolate != NULL); | 97 ASSERT(isolate != NULL); |
| 98 ObjectStore* object_store = isolate->object_store(); | 98 ObjectStore* object_store = isolate->object_store(); |
| 99 ASSERT(object_store != NULL); | 99 ASSERT(object_store != NULL); |
| 100 | 100 |
| 101 // Read in all the objects stored in the object store. | 101 // Read in all the objects stored in the object store. |
| 102 intptr_t num_flds = (object_store->to() - object_store->from()); | 102 intptr_t num_flds = (object_store->to() - object_store->from()); |
| 103 for (intptr_t i = 0; i <= num_flds; i++) { | 103 for (intptr_t i = 0; i <= num_flds; i++) { |
| 104 *(object_store->from() + i) = ReadObject(); | 104 *(object_store->from() + i) = ReadObject(); |
| 105 } | 105 } |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 147 return Object::sentinel(); | 147 return Object::sentinel(); |
| 148 } | 148 } |
| 149 if (IsSingletonClassId(object_id)) { | 149 if (IsSingletonClassId(object_id)) { |
| 150 return Object::GetSingletonClass(object_id); // return singleton object. | 150 return Object::GetSingletonClass(object_id); // return singleton object. |
| 151 } else if (IsObjectStoreClassId(object_id)) { | 151 } else if (IsObjectStoreClassId(object_id)) { |
| 152 return object_store()->GetClass(object_id); | 152 return object_store()->GetClass(object_id); |
| 153 } else if (object_id == ObjectStore::kTrueValue) { | 153 } else if (object_id == ObjectStore::kTrueValue) { |
| 154 return object_store()->true_value(); | 154 return object_store()->true_value(); |
| 155 } else if (object_id == ObjectStore::kFalseValue) { | 155 } else if (object_id == ObjectStore::kFalseValue) { |
| 156 return object_store()->false_value(); | 156 return object_store()->false_value(); |
| 157 } else if (!classes_serialized_) { | 157 } else if (kind_ != Snapshot::kFull) { |
| 158 if (IsObjectStoreTypeId(object_id)) { | 158 if (IsObjectStoreTypeId(object_id)) { |
| 159 return object_store()->GetType(object_id); // return type object. | 159 return object_store()->GetType(object_id); // return type object. |
| 160 } | 160 } |
| 161 } | 161 } |
| 162 | 162 |
| 163 ASSERT(object_id >= kMaxPredefinedObjectIds); | 163 ASSERT(object_id >= kMaxPredefinedObjectIds); |
| 164 intptr_t index = object_id - kMaxPredefinedObjectIds; | 164 intptr_t index = object_id - kMaxPredefinedObjectIds; |
| 165 ASSERT(index < backward_references_.length()); | 165 ASSERT(index < backward_references_.length()); |
| 166 return backward_references_[index]->raw(); | 166 return backward_references_[index]->raw(); |
| 167 } | 167 } |
| (...skipping 24 matching lines...) Expand all Loading... |
| 192 } | 192 } |
| 193 return result.raw(); | 193 return result.raw(); |
| 194 } else { | 194 } else { |
| 195 ASSERT((class_header & kSmiTagMask) != 0); | 195 ASSERT((class_header & kSmiTagMask) != 0); |
| 196 cls ^= LookupInternalClass(class_header); | 196 cls ^= LookupInternalClass(class_header); |
| 197 ASSERT(!cls.IsNull()); | 197 ASSERT(!cls.IsNull()); |
| 198 } | 198 } |
| 199 switch (cls.instance_kind()) { | 199 switch (cls.instance_kind()) { |
| 200 #define SNAPSHOT_READ(clazz) \ | 200 #define SNAPSHOT_READ(clazz) \ |
| 201 case clazz::kInstanceKind: { \ | 201 case clazz::kInstanceKind: { \ |
| 202 return clazz::ReadFrom(this, object_id, classes_serialized_); \ | 202 return clazz::ReadFrom(this, object_id, kind_); \ |
| 203 } | 203 } |
| 204 CLASS_LIST_NO_OBJECT(SNAPSHOT_READ) | 204 CLASS_LIST_NO_OBJECT(SNAPSHOT_READ) |
| 205 #undef SNAPSHOT_READ | 205 #undef SNAPSHOT_READ |
| 206 default: break; | 206 default: break; |
| 207 } | 207 } |
| 208 UNREACHABLE(); | 208 UNREACHABLE(); |
| 209 return Object::null(); | 209 return Object::null(); |
| 210 } | 210 } |
| 211 | 211 |
| 212 | 212 |
| (...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 278 return; | 278 return; |
| 279 } | 279 } |
| 280 | 280 |
| 281 // Check if it is a singleton boolean false value. | 281 // Check if it is a singleton boolean false value. |
| 282 if (rawobj == object_store()->false_value()) { | 282 if (rawobj == object_store()->false_value()) { |
| 283 WriteObjectHeader(kObjectId, ObjectStore::kFalseValue); | 283 WriteObjectHeader(kObjectId, ObjectStore::kFalseValue); |
| 284 return; | 284 return; |
| 285 } | 285 } |
| 286 | 286 |
| 287 // Check if classes are not being serialized and it is preinitialized type. | 287 // Check if classes are not being serialized and it is preinitialized type. |
| 288 if (!serialize_classes_) { | 288 if (kind_ != Snapshot::kFull) { |
| 289 RawType* raw_type = reinterpret_cast<RawType*>(rawobj); | 289 RawType* raw_type = reinterpret_cast<RawType*>(rawobj); |
| 290 index = object_store()->GetTypeIndex(raw_type); | 290 index = object_store()->GetTypeIndex(raw_type); |
| 291 if (index != ObjectStore::kInvalidIndex) { | 291 if (index != ObjectStore::kInvalidIndex) { |
| 292 WriteObjectHeader(kObjectId, index); | 292 WriteObjectHeader(kObjectId, index); |
| 293 return; | 293 return; |
| 294 } | 294 } |
| 295 } | 295 } |
| 296 | 296 |
| 297 // Now write the object out inline in the stream. | 297 // Now write the object out inline in the stream. |
| 298 WriteInlinedObject(rawobj); | 298 WriteInlinedObject(rawobj); |
| (...skipping 11 matching lines...) Expand all Loading... |
| 310 void SnapshotWriter::UnmarkAll() { | 310 void SnapshotWriter::UnmarkAll() { |
| 311 NoGCScope no_gc; | 311 NoGCScope no_gc; |
| 312 for (intptr_t i = 0; i < forward_list_.length(); i++) { | 312 for (intptr_t i = 0; i < forward_list_.length(); i++) { |
| 313 RawObject* raw = forward_list_[i]->raw(); | 313 RawObject* raw = forward_list_[i]->raw(); |
| 314 raw->ptr()->class_ = forward_list_[i]->cls(); // Restore original class. | 314 raw->ptr()->class_ = forward_list_[i]->cls(); // Restore original class. |
| 315 } | 315 } |
| 316 } | 316 } |
| 317 | 317 |
| 318 | 318 |
| 319 void SnapshotWriter::WriteFullSnapshot() { | 319 void SnapshotWriter::WriteFullSnapshot() { |
| 320 ASSERT(serialize_classes_); | 320 ASSERT(kind_ == Snapshot::kFull); |
| 321 Isolate* isolate = Isolate::Current(); | 321 Isolate* isolate = Isolate::Current(); |
| 322 ASSERT(isolate != NULL); | 322 ASSERT(isolate != NULL); |
| 323 ObjectStore* object_store = isolate->object_store(); | 323 ObjectStore* object_store = isolate->object_store(); |
| 324 ASSERT(object_store != NULL); | 324 ASSERT(object_store != NULL); |
| 325 | 325 |
| 326 // Write out all the objects in the object store of the isolate which | 326 // Write out all the objects in the object store of the isolate which |
| 327 // is the root set for all dart allocated objects at this point. | 327 // is the root set for all dart allocated objects at this point. |
| 328 SnapshotWriterVisitor visitor(this); | 328 SnapshotWriterVisitor visitor(this); |
| 329 object_store->VisitObjectPointers(&visitor); | 329 object_store->VisitObjectPointers(&visitor); |
| 330 | 330 |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 388 WriteObject(*reinterpret_cast<RawObject**>( | 388 WriteObject(*reinterpret_cast<RawObject**>( |
| 389 reinterpret_cast<uword>(raw->ptr()) + offset)); | 389 reinterpret_cast<uword>(raw->ptr()) + offset)); |
| 390 offset += kWordSize; | 390 offset += kWordSize; |
| 391 } | 391 } |
| 392 return; | 392 return; |
| 393 } | 393 } |
| 394 switch (kind) { | 394 switch (kind) { |
| 395 #define SNAPSHOT_WRITE(clazz) \ | 395 #define SNAPSHOT_WRITE(clazz) \ |
| 396 case clazz::kInstanceKind: { \ | 396 case clazz::kInstanceKind: { \ |
| 397 Raw##clazz* raw_obj = reinterpret_cast<Raw##clazz*>(raw); \ | 397 Raw##clazz* raw_obj = reinterpret_cast<Raw##clazz*>(raw); \ |
| 398 raw_obj->WriteTo(this, object_id, serialize_classes_); \ | 398 raw_obj->WriteTo(this, object_id, kind_); \ |
| 399 return; \ | 399 return; \ |
| 400 } \ | 400 } \ |
| 401 | 401 |
| 402 CLASS_LIST_NO_OBJECT(SNAPSHOT_WRITE) | 402 CLASS_LIST_NO_OBJECT(SNAPSHOT_WRITE) |
| 403 #undef SNAPSHOT_WRITE | 403 #undef SNAPSHOT_WRITE |
| 404 default: break; | 404 default: break; |
| 405 } | 405 } |
| 406 UNREACHABLE(); | 406 UNREACHABLE(); |
| 407 } | 407 } |
| 408 | 408 |
| 409 | 409 |
| 410 void SnapshotWriter::WriteClassId(RawClass* cls) { | 410 void SnapshotWriter::WriteClassId(RawClass* cls) { |
| 411 ASSERT(!serialize_classes_); | 411 ASSERT(kind_ != Snapshot::kFull); |
| 412 int id = object_store()->GetClassIndex(cls); | 412 int id = object_store()->GetClassIndex(cls); |
| 413 if (IsSingletonClassId(id) || IsObjectStoreClassId(id)) { | 413 if (IsSingletonClassId(id) || IsObjectStoreClassId(id)) { |
| 414 WriteObjectHeader(kObjectId, id); | 414 WriteObjectHeader(kObjectId, id); |
| 415 } else { | 415 } else { |
| 416 // TODO(5411462): Should restrict this to only core-lib classes in this | 416 // TODO(5411462): Should restrict this to only core-lib classes in this |
| 417 // case. | 417 // case. |
| 418 // Write out the class information. | 418 // Write out the class information. |
| 419 WriteObjectHeader(kObjectId, Object::kClassClass); | 419 WriteObjectHeader(kObjectId, Object::kClassClass); |
| 420 // Write out the library url and class name. | 420 // Write out the library url and class name. |
| 421 RawLibrary* library = cls->ptr()->library_; | 421 RawLibrary* library = cls->ptr()->library_; |
| 422 ASSERT(library != Library::null()); | 422 ASSERT(library != Library::null()); |
| 423 WriteObject(library->ptr()->url_); | 423 WriteObject(library->ptr()->url_); |
| 424 WriteObject(cls->ptr()->name_); | 424 WriteObject(cls->ptr()->name_); |
| 425 } | 425 } |
| 426 } | 426 } |
| 427 | 427 |
| 428 | 428 |
| 429 void ScriptSnapshotWriter::WriteScriptSnapshot() { |
| 430 // TODO(asiva): Need to implement this. |
| 431 UNIMPLEMENTED(); |
| 432 } |
| 433 |
| 434 |
| 429 void SnapshotWriterVisitor::VisitPointers(RawObject** first, RawObject** last) { | 435 void SnapshotWriterVisitor::VisitPointers(RawObject** first, RawObject** last) { |
| 430 for (RawObject** current = first; current <= last; current++) { | 436 for (RawObject** current = first; current <= last; current++) { |
| 431 RawObject* raw_obj = *current; | 437 RawObject* raw_obj = *current; |
| 432 writer_->WriteObject(raw_obj); | 438 writer_->WriteObject(raw_obj); |
| 433 } | 439 } |
| 434 } | 440 } |
| 435 | 441 |
| 436 } // namespace dart | 442 } // namespace dart |
| OLD | NEW |