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 |