| 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 #ifndef VM_SNAPSHOT_H_ | 5 #ifndef VM_SNAPSHOT_H_ |
| 6 #define VM_SNAPSHOT_H_ | 6 #define VM_SNAPSHOT_H_ |
| 7 | 7 |
| 8 #include "platform/assert.h" | 8 #include "platform/assert.h" |
| 9 #include "vm/allocation.h" | 9 #include "vm/allocation.h" |
| 10 #include "vm/bitfield.h" | 10 #include "vm/bitfield.h" |
| (...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 94 }; | 94 }; |
| 95 | 95 |
| 96 | 96 |
| 97 enum SerializeState { | 97 enum SerializeState { |
| 98 kIsSerialized = 0, | 98 kIsSerialized = 0, |
| 99 kIsNotSerialized = 1, | 99 kIsNotSerialized = 1, |
| 100 }; | 100 }; |
| 101 | 101 |
| 102 | 102 |
| 103 // Structure capturing the raw snapshot. | 103 // Structure capturing the raw snapshot. |
| 104 // |
| 105 // TODO(turnidge): Remove this class once the snapshot does not have a |
| 106 // header anymore. This is pending on making the embedder pass in the |
| 107 // length of their snapshot. |
| 104 class Snapshot { | 108 class Snapshot { |
| 105 public: | 109 public: |
| 106 enum Kind { | 110 enum Kind { |
| 107 kFull = 0, // Full snapshot of the current dart heap. | 111 kFull = 0, // Full snapshot of the current dart heap. |
| 108 kScript, // A partial snapshot of only the application script. | 112 kScript, // A partial snapshot of only the application script. |
| 109 kMessage, // A partial snapshot used only for isolate messaging. | 113 kMessage, // A partial snapshot used only for isolate messaging. |
| 110 }; | 114 }; |
| 111 | 115 |
| 112 static const int kHeaderSize = 2 * sizeof(int32_t); | 116 static const int kHeaderSize = 2 * sizeof(int32_t); |
| 113 static const int kLengthIndex = 0; | 117 static const int kLengthIndex = 0; |
| 114 static const int kSnapshotFlagIndex = 1; | 118 static const int kSnapshotFlagIndex = 1; |
| 115 | 119 |
| 116 static const Snapshot* SetupFromBuffer(const void* raw_memory); | 120 static const Snapshot* SetupFromBuffer(const void* raw_memory); |
| 117 | 121 |
| 118 // Getters. | 122 // Getters. |
| 119 const uint8_t* content() const { return content_; } | 123 const uint8_t* content() const { return content_; } |
| 120 int32_t length() const { return length_; } | 124 int32_t length() const { return length_; } |
| 121 Kind kind() const { return static_cast<Kind>(kind_); } | 125 Kind kind() const { return static_cast<Kind>(kind_); } |
| 122 | 126 |
| 123 bool IsMessageSnapshot() const { return kind_ == kMessage; } | 127 bool IsMessageSnapshot() const { return kind_ == kMessage; } |
| 124 bool IsScriptSnapshot() const { return kind_ == kScript; } | 128 bool IsScriptSnapshot() const { return kind_ == kScript; } |
| 125 bool IsFullSnapshot() const { return kind_ == kFull; } | 129 bool IsFullSnapshot() const { return kind_ == kFull; } |
| 126 int32_t Size() const { return length_ + sizeof(Snapshot); } | |
| 127 uint8_t* Addr() { return reinterpret_cast<uint8_t*>(this); } | 130 uint8_t* Addr() { return reinterpret_cast<uint8_t*>(this); } |
| 128 | 131 |
| 129 static intptr_t length_offset() { return OFFSET_OF(Snapshot, length_); } | 132 static intptr_t length_offset() { return OFFSET_OF(Snapshot, length_); } |
| 130 static intptr_t kind_offset() { | 133 static intptr_t kind_offset() { |
| 131 return OFFSET_OF(Snapshot, kind_); | 134 return OFFSET_OF(Snapshot, kind_); |
| 132 } | 135 } |
| 133 | 136 |
| 134 private: | 137 private: |
| 135 Snapshot() : length_(0), kind_(kFull) {} | 138 Snapshot() : length_(0), kind_(kFull) {} |
| 136 | 139 |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 176 } | 179 } |
| 177 | 180 |
| 178 private: | 181 private: |
| 179 ReadStream stream_; // input stream. | 182 ReadStream stream_; // input stream. |
| 180 }; | 183 }; |
| 181 | 184 |
| 182 | 185 |
| 183 // Reads a snapshot into objects. | 186 // Reads a snapshot into objects. |
| 184 class SnapshotReader : public BaseReader { | 187 class SnapshotReader : public BaseReader { |
| 185 public: | 188 public: |
| 186 SnapshotReader(const Snapshot* snapshot, Isolate* isolate); | 189 SnapshotReader(const uint8_t* buffer, |
| 190 intptr_t size, |
| 191 Snapshot::Kind kind, |
| 192 Isolate* isolate); |
| 187 ~SnapshotReader() { } | 193 ~SnapshotReader() { } |
| 188 | 194 |
| 189 Isolate* isolate() const { return isolate_; } | 195 Isolate* isolate() const { return isolate_; } |
| 190 Heap* heap() const { return isolate_->heap(); } | 196 Heap* heap() const { return isolate_->heap(); } |
| 191 ObjectStore* object_store() const { return isolate_->object_store(); } | 197 ObjectStore* object_store() const { return isolate_->object_store(); } |
| 192 ClassTable* class_table() const { return isolate_->class_table(); } | 198 ClassTable* class_table() const { return isolate_->class_table(); } |
| 193 Object* ObjectHandle() { return &obj_; } | 199 Object* ObjectHandle() { return &obj_; } |
| 194 String* StringHandle() { return &str_; } | 200 String* StringHandle() { return &str_; } |
| 195 AbstractType* TypeHandle() { return &type_; } | 201 AbstractType* TypeHandle() { return &type_; } |
| 196 AbstractTypeArguments* TypeArgumentsHandle() { return &type_arguments_; } | 202 AbstractTypeArguments* TypeArgumentsHandle() { return &type_arguments_; } |
| (...skipping 160 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 357 value = SerializedHeaderTag::update(kInlined, value); | 363 value = SerializedHeaderTag::update(kInlined, value); |
| 358 value = SerializedHeaderData::update(id, value); | 364 value = SerializedHeaderData::update(id, value); |
| 359 WriteIntptrValue(value); | 365 WriteIntptrValue(value); |
| 360 } | 366 } |
| 361 | 367 |
| 362 // Write out a buffer of bytes. | 368 // Write out a buffer of bytes. |
| 363 void WriteBytes(const uint8_t* addr, intptr_t len) { | 369 void WriteBytes(const uint8_t* addr, intptr_t len) { |
| 364 stream_.WriteBytes(addr, len); | 370 stream_.WriteBytes(addr, len); |
| 365 } | 371 } |
| 366 | 372 |
| 367 // Finalize the serialized buffer by filling in the header information | |
| 368 // which comprises of a flag(snaphot kind) and the length of | |
| 369 // serialzed bytes. | |
| 370 void FinalizeBuffer(Snapshot::Kind kind) { | |
| 371 int32_t* data = reinterpret_cast<int32_t*>(stream_.buffer()); | |
| 372 data[Snapshot::kLengthIndex] = stream_.bytes_written(); | |
| 373 data[Snapshot::kSnapshotFlagIndex] = kind; | |
| 374 } | |
| 375 | |
| 376 protected: | 373 protected: |
| 377 BaseWriter(uint8_t** buffer, ReAlloc alloc) : stream_(buffer, alloc) { | 374 BaseWriter(uint8_t** buffer, ReAlloc alloc) : stream_(buffer, alloc) { |
| 378 ASSERT(buffer != NULL); | 375 ASSERT(buffer != NULL); |
| 379 ASSERT(alloc != NULL); | 376 ASSERT(alloc != NULL); |
| 380 // Make room for recording snapshot buffer size. | |
| 381 stream_.set_current(*buffer + Snapshot::kHeaderSize); | |
| 382 } | 377 } |
| 383 ~BaseWriter() { } | 378 ~BaseWriter() { } |
| 384 | 379 |
| 380 void ReserveHeader() { |
| 381 // Make room for recording snapshot buffer size. |
| 382 stream_.set_current(stream_.buffer() + Snapshot::kHeaderSize); |
| 383 } |
| 384 |
| 385 void FillHeader(Snapshot::Kind kind) { |
| 386 int32_t* data = reinterpret_cast<int32_t*>(stream_.buffer()); |
| 387 data[Snapshot::kLengthIndex] = stream_.bytes_written(); |
| 388 data[Snapshot::kSnapshotFlagIndex] = kind; |
| 389 } |
| 390 |
| 385 private: | 391 private: |
| 386 WriteStream stream_; | 392 WriteStream stream_; |
| 387 | 393 |
| 388 DISALLOW_IMPLICIT_CONSTRUCTORS(BaseWriter); | 394 DISALLOW_IMPLICIT_CONSTRUCTORS(BaseWriter); |
| 389 }; | 395 }; |
| 390 | 396 |
| 391 | 397 |
| 392 class SnapshotWriter : public BaseWriter { | 398 class SnapshotWriter : public BaseWriter { |
| 393 public: | 399 protected: |
| 394 SnapshotWriter(Snapshot::Kind kind, uint8_t** buffer, ReAlloc alloc) | 400 SnapshotWriter(Snapshot::Kind kind, uint8_t** buffer, ReAlloc alloc) |
| 395 : BaseWriter(buffer, alloc), | 401 : BaseWriter(buffer, alloc), |
| 396 kind_(kind), | 402 kind_(kind), |
| 397 object_store_(Isolate::Current()->object_store()), | 403 object_store_(Isolate::Current()->object_store()), |
| 398 class_table_(Isolate::Current()->class_table()), | 404 class_table_(Isolate::Current()->class_table()), |
| 399 forward_list_() { | 405 forward_list_() { |
| 400 } | 406 } |
| 401 ~SnapshotWriter() { } | |
| 402 | 407 |
| 408 public: |
| 403 // Snapshot kind. | 409 // Snapshot kind. |
| 404 Snapshot::Kind kind() const { return kind_; } | 410 Snapshot::Kind kind() const { return kind_; } |
| 405 | 411 |
| 406 // Finalize the serialized buffer by filling in the header information | |
| 407 // which comprises of a flag(full/partial snaphot) and the length of | |
| 408 // serialzed bytes. | |
| 409 void FinalizeBuffer() { | |
| 410 BaseWriter::FinalizeBuffer(kind_); | |
| 411 UnmarkAll(); | |
| 412 } | |
| 413 | |
| 414 // Serialize an object into the buffer. | 412 // Serialize an object into the buffer. |
| 415 void WriteObject(RawObject* raw); | 413 void WriteObject(RawObject* raw); |
| 416 | 414 |
| 417 // Writes a full snapshot of the Isolate. | |
| 418 void WriteFullSnapshot(); | |
| 419 | |
| 420 uword GetObjectTags(RawObject* raw); | 415 uword GetObjectTags(RawObject* raw); |
| 421 | 416 |
| 422 private: | 417 protected: |
| 423 class ForwardObjectNode : public ZoneAllocated { | 418 class ForwardObjectNode : public ZoneAllocated { |
| 424 public: | 419 public: |
| 425 ForwardObjectNode(RawObject* raw, uword tags, SerializeState state) | 420 ForwardObjectNode(RawObject* raw, uword tags, SerializeState state) |
| 426 : raw_(raw), tags_(tags), state_(state) {} | 421 : raw_(raw), tags_(tags), state_(state) {} |
| 427 RawObject* raw() const { return raw_; } | 422 RawObject* raw() const { return raw_; } |
| 428 uword tags() const { return tags_; } | 423 uword tags() const { return tags_; } |
| 429 bool is_serialized() const { return state_ == kIsSerialized; } | 424 bool is_serialized() const { return state_ == kIsSerialized; } |
| 430 void set_state(SerializeState value) { state_ = value; } | 425 void set_state(SerializeState value) { state_ = value; } |
| 431 | 426 |
| 432 private: | 427 private: |
| (...skipping 17 matching lines...) Expand all Loading... |
| 450 void WriteForwardedObjects(); | 445 void WriteForwardedObjects(); |
| 451 void ArrayWriteTo(intptr_t object_id, | 446 void ArrayWriteTo(intptr_t object_id, |
| 452 intptr_t array_kind, | 447 intptr_t array_kind, |
| 453 intptr_t tags, | 448 intptr_t tags, |
| 454 RawSmi* length, | 449 RawSmi* length, |
| 455 RawAbstractTypeArguments* type_arguments, | 450 RawAbstractTypeArguments* type_arguments, |
| 456 RawObject* data[]); | 451 RawObject* data[]); |
| 457 | 452 |
| 458 ObjectStore* object_store() const { return object_store_; } | 453 ObjectStore* object_store() const { return object_store_; } |
| 459 | 454 |
| 455 private: |
| 460 Snapshot::Kind kind_; | 456 Snapshot::Kind kind_; |
| 461 ObjectStore* object_store_; // Object store for common classes. | 457 ObjectStore* object_store_; // Object store for common classes. |
| 462 ClassTable* class_table_; // Class table for the class index to class lookup. | 458 ClassTable* class_table_; // Class table for the class index to class lookup. |
| 463 GrowableArray<ForwardObjectNode*> forward_list_; | 459 GrowableArray<ForwardObjectNode*> forward_list_; |
| 464 | 460 |
| 465 friend class RawArray; | 461 friend class RawArray; |
| 466 friend class RawClass; | 462 friend class RawClass; |
| 467 friend class RawGrowableObjectArray; | 463 friend class RawGrowableObjectArray; |
| 468 friend class RawImmutableArray; | 464 friend class RawImmutableArray; |
| 469 friend class RawJSRegExp; | 465 friend class RawJSRegExp; |
| 470 friend class RawLibrary; | 466 friend class RawLibrary; |
| 471 friend class RawLiteralToken; | 467 friend class RawLiteralToken; |
| 472 friend class RawScript; | 468 friend class RawScript; |
| 473 friend class RawTokenStream; | 469 friend class RawTokenStream; |
| 474 friend class RawTypeArguments; | 470 friend class RawTypeArguments; |
| 475 friend class SnapshotWriterVisitor; | 471 friend class SnapshotWriterVisitor; |
| 476 DISALLOW_COPY_AND_ASSIGN(SnapshotWriter); | 472 DISALLOW_COPY_AND_ASSIGN(SnapshotWriter); |
| 477 }; | 473 }; |
| 478 | 474 |
| 479 | 475 |
| 476 class FullSnapshotWriter : public SnapshotWriter { |
| 477 public: |
| 478 FullSnapshotWriter(uint8_t** buffer, ReAlloc alloc) |
| 479 : SnapshotWriter(Snapshot::kFull, buffer, alloc) { |
| 480 ASSERT(buffer != NULL); |
| 481 ASSERT(alloc != NULL); |
| 482 } |
| 483 ~FullSnapshotWriter() { } |
| 484 |
| 485 // Writes a full snapshot of the Isolate. |
| 486 void WriteFullSnapshot(); |
| 487 |
| 488 private: |
| 489 DISALLOW_COPY_AND_ASSIGN(FullSnapshotWriter); |
| 490 }; |
| 491 |
| 492 |
| 480 class ScriptSnapshotWriter : public SnapshotWriter { | 493 class ScriptSnapshotWriter : public SnapshotWriter { |
| 481 public: | 494 public: |
| 482 ScriptSnapshotWriter(uint8_t** buffer, ReAlloc alloc) | 495 ScriptSnapshotWriter(uint8_t** buffer, ReAlloc alloc) |
| 483 : SnapshotWriter(Snapshot::kScript, buffer, alloc) { | 496 : SnapshotWriter(Snapshot::kScript, buffer, alloc) { |
| 484 ASSERT(buffer != NULL); | 497 ASSERT(buffer != NULL); |
| 485 ASSERT(alloc != NULL); | 498 ASSERT(alloc != NULL); |
| 486 } | 499 } |
| 487 ~ScriptSnapshotWriter() { } | 500 ~ScriptSnapshotWriter() { } |
| 488 | 501 |
| 489 // Writes a partial snapshot of the script. | 502 // Writes a partial snapshot of the script. |
| 490 void WriteScriptSnapshot(const Library& lib); | 503 void WriteScriptSnapshot(const Library& lib); |
| 491 | 504 |
| 492 private: | 505 private: |
| 493 DISALLOW_COPY_AND_ASSIGN(ScriptSnapshotWriter); | 506 DISALLOW_COPY_AND_ASSIGN(ScriptSnapshotWriter); |
| 494 }; | 507 }; |
| 495 | 508 |
| 496 | 509 |
| 510 class MessageWriter : public SnapshotWriter { |
| 511 public: |
| 512 MessageWriter(uint8_t** buffer, ReAlloc alloc) |
| 513 : SnapshotWriter(Snapshot::kMessage, buffer, alloc) { |
| 514 ASSERT(buffer != NULL); |
| 515 ASSERT(alloc != NULL); |
| 516 } |
| 517 ~MessageWriter() { } |
| 518 |
| 519 void WriteMessage(const Object& obj); |
| 520 |
| 521 private: |
| 522 DISALLOW_COPY_AND_ASSIGN(MessageWriter); |
| 523 }; |
| 524 |
| 525 |
| 497 // An object pointer visitor implementation which writes out | 526 // An object pointer visitor implementation which writes out |
| 498 // objects to a snap shot. | 527 // objects to a snap shot. |
| 499 class SnapshotWriterVisitor : public ObjectPointerVisitor { | 528 class SnapshotWriterVisitor : public ObjectPointerVisitor { |
| 500 public: | 529 public: |
| 501 explicit SnapshotWriterVisitor(SnapshotWriter* writer) | 530 explicit SnapshotWriterVisitor(SnapshotWriter* writer) |
| 502 : ObjectPointerVisitor(Isolate::Current()), | 531 : ObjectPointerVisitor(Isolate::Current()), |
| 503 writer_(writer), | 532 writer_(writer), |
| 504 as_references_(true) {} | 533 as_references_(true) {} |
| 505 | 534 |
| 506 SnapshotWriterVisitor(SnapshotWriter* writer, bool as_references) | 535 SnapshotWriterVisitor(SnapshotWriter* writer, bool as_references) |
| 507 : ObjectPointerVisitor(Isolate::Current()), | 536 : ObjectPointerVisitor(Isolate::Current()), |
| 508 writer_(writer), | 537 writer_(writer), |
| 509 as_references_(as_references) {} | 538 as_references_(as_references) {} |
| 510 | 539 |
| 511 virtual void VisitPointers(RawObject** first, RawObject** last); | 540 virtual void VisitPointers(RawObject** first, RawObject** last); |
| 512 | 541 |
| 513 private: | 542 private: |
| 514 SnapshotWriter* writer_; | 543 SnapshotWriter* writer_; |
| 515 bool as_references_; | 544 bool as_references_; |
| 516 | 545 |
| 517 DISALLOW_COPY_AND_ASSIGN(SnapshotWriterVisitor); | 546 DISALLOW_COPY_AND_ASSIGN(SnapshotWriterVisitor); |
| 518 }; | 547 }; |
| 519 | 548 |
| 520 } // namespace dart | 549 } // namespace dart |
| 521 | 550 |
| 522 #endif // VM_SNAPSHOT_H_ | 551 #endif // VM_SNAPSHOT_H_ |
| OLD | NEW |