| 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 #ifndef VM_SNAPSHOT_H_ | 5 #ifndef VM_SNAPSHOT_H_ |
| 6 #define VM_SNAPSHOT_H_ | 6 #define VM_SNAPSHOT_H_ |
| 7 | 7 |
| 8 #include "vm/allocation.h" | 8 #include "vm/allocation.h" |
| 9 #include "vm/assert.h" | 9 #include "vm/assert.h" |
| 10 #include "vm/bitfield.h" | 10 #include "vm/bitfield.h" |
| 11 #include "vm/globals.h" | 11 #include "vm/globals.h" |
| 12 #include "vm/growable_array.h" | 12 #include "vm/growable_array.h" |
| 13 #include "vm/isolate.h" | 13 #include "vm/isolate.h" |
| 14 #include "vm/visitor.h" | 14 #include "vm/visitor.h" |
| 15 | 15 |
| 16 namespace dart { | 16 namespace dart { |
| 17 | 17 |
| 18 // Forward declarations. | 18 // Forward declarations. |
| 19 class Heap; | 19 class Heap; |
| 20 class Library; |
| 21 class Object; |
| 20 class ObjectStore; | 22 class ObjectStore; |
| 21 class RawClass; | 23 class RawClass; |
| 22 class RawObject; | 24 class RawObject; |
| 23 class Object; | |
| 24 | 25 |
| 25 static const int8_t kSerializedBitsPerByte = 7; | 26 static const int8_t kSerializedBitsPerByte = 7; |
| 26 static const int8_t kMaxSerializedUnsignedValuePerByte = 127; | 27 static const int8_t kMaxSerializedUnsignedValuePerByte = 127; |
| 27 static const int8_t kMaxSerializedValuePerByte = 63; | 28 static const int8_t kMaxSerializedValuePerByte = 63; |
| 28 static const int8_t kMinSerializedValuePerByte = -64; | 29 static const int8_t kMinSerializedValuePerByte = -64; |
| 29 static const uint8_t kEndByteMarker = (255 - kMaxSerializedValuePerByte); | 30 static const uint8_t kEndByteMarker = (255 - kMaxSerializedValuePerByte); |
| 30 static const int8_t kSerializedByteMask = (1 << kSerializedBitsPerByte) - 1; | 31 static const int8_t kSerializedByteMask = (1 << kSerializedBitsPerByte) - 1; |
| 31 | 32 |
| 32 // Serialized object header encoding is as follows: | 33 // Serialized object header encoding is as follows: |
| 33 // - Smi: the Smi value is written as is (last bit is not tagged). | 34 // - Smi: the Smi value is written as is (last bit is not tagged). |
| (...skipping 14 matching lines...) Expand all Loading... |
| 48 }; | 49 }; |
| 49 | 50 |
| 50 | 51 |
| 51 class SerializedHeaderData : public BitField<intptr_t, 2, 30> { | 52 class SerializedHeaderData : public BitField<intptr_t, 2, 30> { |
| 52 }; | 53 }; |
| 53 | 54 |
| 54 | 55 |
| 55 // Structure capturing the raw snapshot. | 56 // Structure capturing the raw snapshot. |
| 56 class Snapshot { | 57 class Snapshot { |
| 57 public: | 58 public: |
| 59 enum Kind { |
| 60 kFull = 0, // Full snapshot of the current dart heap. |
| 61 kScript, // A partial snapshot of only the application script. |
| 62 kMessage, // A partial snapshot used only for isolate messaging. |
| 63 }; |
| 64 |
| 58 static const int kHeaderSize = 2 * sizeof(int32_t); | 65 static const int kHeaderSize = 2 * sizeof(int32_t); |
| 59 static const int kLengthIndex = 0; | 66 static const int kLengthIndex = 0; |
| 60 static const int kSnapshotFlagIndex = 1; | 67 static const int kSnapshotFlagIndex = 1; |
| 61 | 68 |
| 62 static const Snapshot* SetupFromBuffer(const void* raw_memory); | 69 static const Snapshot* SetupFromBuffer(const void* raw_memory); |
| 63 | 70 |
| 64 // Getters. | 71 // Getters. |
| 65 const uint8_t* content() const { return content_; } | 72 const uint8_t* content() const { return content_; } |
| 66 int32_t length() const { return length_; } | 73 int32_t length() const { return length_; } |
| 74 Kind kind() const { return static_cast<Kind>(kind_); } |
| 67 | 75 |
| 68 bool IsPartialSnapshot() const { return full_snapshot_ == 0; } | 76 bool IsMessageSnapshot() const { return kind_ == kMessage; } |
| 69 bool IsFullSnapshot() const { return full_snapshot_ != 0; } | 77 bool IsScriptSnapshot() const { return kind_ == kScript; } |
| 78 bool IsFullSnapshot() const { return kind_ == kFull; } |
| 70 int32_t Size() const { return length_ + sizeof(Snapshot); } | 79 int32_t Size() const { return length_ + sizeof(Snapshot); } |
| 71 uint8_t* Addr() { return reinterpret_cast<uint8_t*>(this); } | 80 uint8_t* Addr() { return reinterpret_cast<uint8_t*>(this); } |
| 72 | 81 |
| 73 static intptr_t length_offset() { return OFFSET_OF(Snapshot, length_); } | 82 static intptr_t length_offset() { return OFFSET_OF(Snapshot, length_); } |
| 74 static intptr_t full_snapshot_offset() { | 83 static intptr_t kind_offset() { |
| 75 return OFFSET_OF(Snapshot, full_snapshot_); | 84 return OFFSET_OF(Snapshot, kind_); |
| 76 } | 85 } |
| 77 | 86 |
| 78 private: | 87 private: |
| 79 Snapshot() : length_(0), full_snapshot_(0) {} | 88 Snapshot() : length_(0), kind_(kFull) {} |
| 80 | 89 |
| 81 int32_t length_; // Stream length. | 90 int32_t length_; // Stream length. |
| 82 int32_t full_snapshot_; // Classes are serialized too. | 91 int32_t kind_; // Kind of snapshot. |
| 83 uint8_t content_[]; // Stream content. | 92 uint8_t content_[]; // Stream content. |
| 84 | 93 |
| 85 DISALLOW_COPY_AND_ASSIGN(Snapshot); | 94 DISALLOW_COPY_AND_ASSIGN(Snapshot); |
| 86 }; | 95 }; |
| 87 | 96 |
| 88 | 97 |
| 89 // Stream for reading various types from a buffer. | 98 // Stream for reading various types from a buffer. |
| 90 class ReadStream : public ValueObject { | 99 class ReadStream : public ValueObject { |
| 91 public: | 100 public: |
| 92 ReadStream(const uint8_t* buffer, intptr_t size) : buffer_(buffer), | 101 ReadStream(const uint8_t* buffer, intptr_t size) : buffer_(buffer), |
| (...skipping 170 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 263 }; | 272 }; |
| 264 | 273 |
| 265 | 274 |
| 266 // Reads a snapshot into objects. | 275 // Reads a snapshot into objects. |
| 267 class SnapshotReader { | 276 class SnapshotReader { |
| 268 public: | 277 public: |
| 269 SnapshotReader(const Snapshot* snapshot, | 278 SnapshotReader(const Snapshot* snapshot, |
| 270 Heap* heap, | 279 Heap* heap, |
| 271 ObjectStore* object_store) | 280 ObjectStore* object_store) |
| 272 : stream_(snapshot->content(), snapshot->length()), | 281 : stream_(snapshot->content(), snapshot->length()), |
| 273 classes_serialized_(snapshot->IsFullSnapshot()), | 282 kind_(snapshot->kind()), |
| 274 heap_(heap), | 283 heap_(heap), |
| 275 object_store_(object_store), | 284 object_store_(object_store), |
| 276 backward_references_() { } | 285 backward_references_() { } |
| 277 ~SnapshotReader() { } | 286 ~SnapshotReader() { } |
| 278 | 287 |
| 279 // Reads raw data (for basic types). | 288 // Reads raw data (for basic types). |
| 280 // sizeof(T) must be in {1,2,4,8}. | 289 // sizeof(T) must be in {1,2,4,8}. |
| 281 template <typename T> | 290 template <typename T> |
| 282 T Read() { | 291 T Read() { |
| 283 return ReadStream::Raw<sizeof(T), T>::Read(&stream_); | 292 return ReadStream::Raw<sizeof(T), T>::Read(&stream_); |
| (...skipping 21 matching lines...) Expand all Loading... |
| 305 // or an object that was already serialized before). | 314 // or an object that was already serialized before). |
| 306 RawObject* ReadIndexedObject(intptr_t object_id); | 315 RawObject* ReadIndexedObject(intptr_t object_id); |
| 307 | 316 |
| 308 // Read an inlined object from the stream. | 317 // Read an inlined object from the stream. |
| 309 RawObject* ReadInlinedObject(intptr_t object_id); | 318 RawObject* ReadInlinedObject(intptr_t object_id); |
| 310 | 319 |
| 311 // Based on header field check to see if it is an internal VM class. | 320 // Based on header field check to see if it is an internal VM class. |
| 312 RawClass* LookupInternalClass(intptr_t class_header); | 321 RawClass* LookupInternalClass(intptr_t class_header); |
| 313 | 322 |
| 314 ReadStream stream_; // input stream. | 323 ReadStream stream_; // input stream. |
| 315 bool classes_serialized_; // Indicates if classes are serialized. | 324 Snapshot::Kind kind_; // Indicates type of snapshot(full, script, message). |
| 316 Heap* heap_; // Heap into which the objects are deserialized into. | 325 Heap* heap_; // Heap into which the objects are deserialized into. |
| 317 ObjectStore* object_store_; // Object store for common classes. | 326 ObjectStore* object_store_; // Object store for common classes. |
| 318 GrowableArray<Object*> backward_references_; | 327 GrowableArray<Object*> backward_references_; |
| 319 | 328 |
| 320 DISALLOW_COPY_AND_ASSIGN(SnapshotReader); | 329 DISALLOW_COPY_AND_ASSIGN(SnapshotReader); |
| 321 }; | 330 }; |
| 322 | 331 |
| 323 | 332 |
| 324 class MessageWriter { | 333 class MessageWriter { |
| 325 public: | 334 public: |
| (...skipping 21 matching lines...) Expand all Loading... |
| 347 value = SerializedHeaderData::update(id, value); | 356 value = SerializedHeaderData::update(id, value); |
| 348 Write<uword>(value); | 357 Write<uword>(value); |
| 349 } | 358 } |
| 350 | 359 |
| 351 // Finalize the serialized buffer by filling in the header information | 360 // Finalize the serialized buffer by filling in the header information |
| 352 // which comprises of a flag(full/partial snaphot) and the length of | 361 // which comprises of a flag(full/partial snaphot) and the length of |
| 353 // serialzed bytes. | 362 // serialzed bytes. |
| 354 void FinalizeBuffer() { | 363 void FinalizeBuffer() { |
| 355 int32_t* data = reinterpret_cast<int32_t*>(stream_.buffer()); | 364 int32_t* data = reinterpret_cast<int32_t*>(stream_.buffer()); |
| 356 data[Snapshot::kLengthIndex] = stream_.bytes_written(); | 365 data[Snapshot::kLengthIndex] = stream_.bytes_written(); |
| 357 data[Snapshot::kSnapshotFlagIndex] = false; | 366 data[Snapshot::kSnapshotFlagIndex] = Snapshot::kMessage; |
| 358 } | 367 } |
| 359 | 368 |
| 360 WriteStream stream_; | 369 WriteStream stream_; |
| 361 | 370 |
| 362 DISALLOW_COPY_AND_ASSIGN(MessageWriter); | 371 DISALLOW_COPY_AND_ASSIGN(MessageWriter); |
| 363 }; | 372 }; |
| 364 | 373 |
| 365 | 374 |
| 366 class SnapshotWriter { | 375 class SnapshotWriter { |
| 367 public: | 376 public: |
| 368 SnapshotWriter(bool full_snapshot, uint8_t** buffer, ReAlloc alloc) | 377 SnapshotWriter(Snapshot::Kind kind, uint8_t** buffer, ReAlloc alloc) |
| 369 : stream_(buffer, alloc), | 378 : stream_(buffer, alloc), |
| 370 serialize_classes_(full_snapshot), | 379 kind_(kind), |
| 371 object_store_(Isolate::Current()->object_store()), | 380 object_store_(Isolate::Current()->object_store()), |
| 372 forward_list_() { | 381 forward_list_() { |
| 373 ASSERT(buffer != NULL); | 382 ASSERT(buffer != NULL); |
| 374 ASSERT(alloc != NULL); | 383 ASSERT(alloc != NULL); |
| 375 } | 384 } |
| 376 ~SnapshotWriter() { } | 385 ~SnapshotWriter() { } |
| 377 | 386 |
| 378 // Size of the snapshot. | 387 // Size of the snapshot. |
| 379 intptr_t Size() const { return stream_.bytes_written(); } | 388 intptr_t Size() const { return stream_.bytes_written(); } |
| 380 | 389 |
| 381 // Finalize the serialized buffer by filling in the header information | 390 // Finalize the serialized buffer by filling in the header information |
| 382 // which comprises of a flag(full/partial snaphot) and the length of | 391 // which comprises of a flag(full/partial snaphot) and the length of |
| 383 // serialzed bytes. | 392 // serialzed bytes. |
| 384 void FinalizeBuffer() { | 393 void FinalizeBuffer() { |
| 385 int32_t* data = reinterpret_cast<int32_t*>(stream_.buffer()); | 394 int32_t* data = reinterpret_cast<int32_t*>(stream_.buffer()); |
| 386 data[Snapshot::kLengthIndex] = stream_.bytes_written(); | 395 data[Snapshot::kLengthIndex] = stream_.bytes_written(); |
| 387 data[Snapshot::kSnapshotFlagIndex] = serialize_classes_; | 396 data[Snapshot::kSnapshotFlagIndex] = kind_; |
| 388 UnmarkAll(); | 397 UnmarkAll(); |
| 389 } | 398 } |
| 390 | 399 |
| 391 // Writes raw data to the stream (basic type). | 400 // Writes raw data to the stream (basic type). |
| 392 // sizeof(T) must be in {1,2,4,8}. | 401 // sizeof(T) must be in {1,2,4,8}. |
| 393 template <typename T> | 402 template <typename T> |
| 394 void Write(T value) { | 403 void Write(T value) { |
| 395 WriteStream::Raw<sizeof(T), T>::Write(&stream_, value); | 404 WriteStream::Raw<sizeof(T), T>::Write(&stream_, value); |
| 396 } | 405 } |
| 397 | 406 |
| (...skipping 25 matching lines...) Expand all Loading... |
| 423 DISALLOW_COPY_AND_ASSIGN(ForwardObjectNode); | 432 DISALLOW_COPY_AND_ASSIGN(ForwardObjectNode); |
| 424 }; | 433 }; |
| 425 | 434 |
| 426 intptr_t MarkObject(RawObject* raw, RawClass* cls); | 435 intptr_t MarkObject(RawObject* raw, RawClass* cls); |
| 427 | 436 |
| 428 void WriteInlinedObject(RawObject* raw); | 437 void WriteInlinedObject(RawObject* raw); |
| 429 | 438 |
| 430 ObjectStore* object_store() const { return object_store_; } | 439 ObjectStore* object_store() const { return object_store_; } |
| 431 | 440 |
| 432 WriteStream stream_; | 441 WriteStream stream_; |
| 433 bool serialize_classes_; | 442 Snapshot::Kind kind_; |
| 434 ObjectStore* object_store_; // Object store for common classes. | 443 ObjectStore* object_store_; // Object store for common classes. |
| 435 GrowableArray<ForwardObjectNode*> forward_list_; | 444 GrowableArray<ForwardObjectNode*> forward_list_; |
| 436 | 445 |
| 437 DISALLOW_COPY_AND_ASSIGN(SnapshotWriter); | 446 DISALLOW_COPY_AND_ASSIGN(SnapshotWriter); |
| 438 }; | 447 }; |
| 439 | 448 |
| 440 | 449 |
| 450 class ScriptSnapshotWriter : public SnapshotWriter { |
| 451 public: |
| 452 ScriptSnapshotWriter(const Library& lib, uint8_t** buffer, ReAlloc alloc) |
| 453 : SnapshotWriter(Snapshot::kScript, buffer, alloc) { |
| 454 ASSERT(buffer != NULL); |
| 455 ASSERT(alloc != NULL); |
| 456 } |
| 457 ~ScriptSnapshotWriter() { } |
| 458 |
| 459 // Writes a partial snapshot of the script. |
| 460 void WriteScriptSnapshot(); |
| 461 |
| 462 private: |
| 463 DISALLOW_COPY_AND_ASSIGN(ScriptSnapshotWriter); |
| 464 }; |
| 465 |
| 466 |
| 441 // An object pointer visitor implementation which writes out | 467 // An object pointer visitor implementation which writes out |
| 442 // objects to a snap shot. | 468 // objects to a snap shot. |
| 443 class SnapshotWriterVisitor : public ObjectPointerVisitor { | 469 class SnapshotWriterVisitor : public ObjectPointerVisitor { |
| 444 public: | 470 public: |
| 445 explicit SnapshotWriterVisitor(SnapshotWriter* writer) : writer_(writer) {} | 471 explicit SnapshotWriterVisitor(SnapshotWriter* writer) : writer_(writer) {} |
| 446 | 472 |
| 447 virtual void VisitPointers(RawObject** first, RawObject** last); | 473 virtual void VisitPointers(RawObject** first, RawObject** last); |
| 448 | 474 |
| 449 private: | 475 private: |
| 450 SnapshotWriter* writer_; | 476 SnapshotWriter* writer_; |
| 451 | 477 |
| 452 DISALLOW_COPY_AND_ASSIGN(SnapshotWriterVisitor); | 478 DISALLOW_COPY_AND_ASSIGN(SnapshotWriterVisitor); |
| 453 }; | 479 }; |
| 454 | 480 |
| 455 } // namespace dart | 481 } // namespace dart |
| 456 | 482 |
| 457 #endif // VM_SNAPSHOT_H_ | 483 #endif // VM_SNAPSHOT_H_ |
| OLD | NEW |