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