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
3// BSD-style license that can be found in the LICENSE file.
4
5#ifndef RUNTIME_VM_SNAPSHOT_H_
6#define RUNTIME_VM_SNAPSHOT_H_
7
8#include <memory>
9#include <utility>
10
11#include "platform/assert.h"
12#include "vm/allocation.h"
13#include "vm/bitfield.h"
14#include "vm/datastream.h"
15#include "vm/finalizable_data.h"
16#include "vm/globals.h"
17#include "vm/growable_array.h"
18#include "vm/isolate.h"
19#include "vm/message.h"
20#include "vm/visitor.h"
21
22namespace dart {
23
24// Forward declarations.
25class AbstractType;
26class Array;
27class Class;
28class ClassTable;
29class Closure;
30class Code;
31class ExternalTypedData;
32class TypedDataBase;
33class GrowableObjectArray;
34class Heap;
35class Instance;
36class Instructions;
37class LanguageError;
38class Library;
39class LinkedHashMap;
40class Object;
41class PassiveObject;
42class ObjectStore;
43class MegamorphicCache;
44class PageSpace;
45class TypedDataView;
46class String;
47class TypeArguments;
48class TypedData;
49class UnhandledException;
50
51// Serialized object header encoding is as follows:
52// - Smi: the Smi value is written as is (last bit is not tagged).
53// - VM object (from VM isolate): (object id in vm isolate | 0x3)
54// This value is serialized as a negative number.
55// (note VM objects are never serialized, they are expected to be found
56// using ths unique ID assigned to them).
57// - Reference to object that has already been written: (object id | 0x3)
58// This valus is serialized as a positive number.
59// - Object that is seen for the first time (inlined in the stream):
60// (a unique id for this object | 0x1)
61enum SerializedHeaderType {
62 kInlined = 0x1,
63 kObjectId = 0x3,
64};
65static const int8_t kHeaderTagBits = 2;
66static const int8_t kObjectIdBits = (kBitsPerInt32 - (kHeaderTagBits + 1));
67static const intptr_t kMaxObjectId = (kMaxUint32 >> (kHeaderTagBits + 1));
68static const bool kAsReference = true;
69static const bool kAsInlinedObject = false;
70static const intptr_t kInvalidPatchIndex = -1;
71
72class SerializedHeaderTag
73 : public BitField<intptr_t, enum SerializedHeaderType, 0, kHeaderTagBits> {
74};
75
76class SerializedHeaderData
77 : public BitField<intptr_t, intptr_t, kHeaderTagBits, kObjectIdBits> {};
78
79enum DeserializeState {
80 kIsDeserialized = 0,
81 kIsNotDeserialized = 1,
82};
83
84enum SerializeState {
85 kIsSerialized = 0,
86 kIsNotSerialized = 1,
87};
88
89// Structure capturing the raw snapshot.
90//
91class Snapshot {
92 public:
93 enum Kind {
94 kFull, // Full snapshot of core libraries or an application.
95 kFullJIT, // Full + JIT code
96 kFullAOT, // Full + AOT code
97 kMessage, // A partial snapshot used only for isolate messaging.
98 kNone, // gen_snapshot
99 kInvalid
100 };
101 static const char* KindToCString(Kind kind);
102
103 static const Snapshot* SetupFromBuffer(const void* raw_memory);
104
105 static const int32_t kMagicValue = 0xdcdcf5f5;
106 static const intptr_t kMagicOffset = 0;
107 static const intptr_t kMagicSize = sizeof(int32_t);
108 static const intptr_t kLengthOffset = kMagicOffset + kMagicSize;
109 static const intptr_t kLengthSize = sizeof(int64_t);
110 static const intptr_t kKindOffset = kLengthOffset + kLengthSize;
111 static const intptr_t kKindSize = sizeof(int64_t);
112 static const intptr_t kHeaderSize = kKindOffset + kKindSize;
113
114 // Accessors.
115 bool check_magic() const {
116 return Read<int32_t>(kMagicOffset) == kMagicValue;
117 }
118 void set_magic() { return Write<int32_t>(kMagicOffset, kMagicValue); }
119 // Excluding the magic value from the size written in the buffer is needed
120 // so we give a proper version mismatch error for snapshots create before
121 // magic value was written by the VM instead of the embedder.
122 int64_t large_length() const {
123 return Read<int64_t>(kLengthOffset) + kMagicSize;
124 }
125 intptr_t length() const { return static_cast<intptr_t>(large_length()); }
126 void set_length(intptr_t value) {
127 return Write<int64_t>(kLengthOffset, value - kMagicSize);
128 }
129 Kind kind() const { return static_cast<Kind>(Read<int64_t>(kKindOffset)); }
130 void set_kind(Kind value) { return Write<int64_t>(kKindOffset, value); }
131
132 static bool IsFull(Kind kind) {
133 return (kind == kFull) || (kind == kFullJIT) || (kind == kFullAOT);
134 }
135 static bool IncludesCode(Kind kind) {
136 return (kind == kFullJIT) || (kind == kFullAOT);
137 }
138 static bool IncludesBytecode(Kind kind) {
139 return (kind == kFull) || (kind == kFullJIT);
140 }
141
142 const uint8_t* Addr() const { return reinterpret_cast<const uint8_t*>(this); }
143
144 const uint8_t* DataImage() const {
145 if (!IncludesCode(kind())) {
146 return NULL;
147 }
148 uword offset = Utils::RoundUp(length(), kMaxObjectAlignment);
149 return Addr() + offset;
150 }
151
152 private:
153 // Prevent Snapshot from ever being allocated directly.
154 Snapshot();
155
156 template <typename T>
157 T Read(intptr_t offset) const {
158 return LoadUnaligned(
159 reinterpret_cast<const T*>(reinterpret_cast<uword>(this) + offset));
160 }
161
162 template <typename T>
163 void Write(intptr_t offset, T value) {
164 return StoreUnaligned(
165 reinterpret_cast<T*>(reinterpret_cast<uword>(this) + offset), value);
166 }
167
168 DISALLOW_COPY_AND_ASSIGN(Snapshot);
169};
170
171inline static bool IsSnapshotCompatible(Snapshot::Kind vm_kind,
172 Snapshot::Kind isolate_kind) {
173 if (vm_kind == isolate_kind) return true;
174 if (vm_kind == Snapshot::kFull && isolate_kind == Snapshot::kFullJIT)
175 return true;
176 return Snapshot::IsFull(isolate_kind);
177}
178
179class BaseReader {
180 public:
181 BaseReader(const uint8_t* buffer, intptr_t size) : stream_(buffer, size) {}
182 // Reads raw data (for basic types).
183 // sizeof(T) must be in {1,2,4,8}.
184 template <typename T>
185 T Read() {
186 return ReadStream::Raw<sizeof(T), T>::Read(&stream_);
187 }
188
189 classid_t ReadClassIDValue() {
190 uint32_t value = Read<uint32_t>();
191 return static_cast<classid_t>(value);
192 }
193 COMPILE_ASSERT(sizeof(uint32_t) >= sizeof(classid_t));
194
195 void ReadBytes(uint8_t* addr, intptr_t len) { stream_.ReadBytes(addr, len); }
196
197 double ReadDouble() {
198 double result;
199 stream_.ReadBytes(reinterpret_cast<uint8_t*>(&result), sizeof(result));
200 return result;
201 }
202
203 intptr_t ReadTags() {
204 const intptr_t tags = static_cast<intptr_t>(Read<int8_t>()) & 0xff;
205 return tags;
206 }
207
208 const uint8_t* CurrentBufferAddress() const {
209 return stream_.AddressOfCurrentPosition();
210 }
211
212 void Align(intptr_t value) { stream_.Align(value); }
213 void Advance(intptr_t value) { stream_.Advance(value); }
214
215 intptr_t PendingBytes() const { return stream_.PendingBytes(); }
216
217 SmiPtr ReadAsSmi();
218 intptr_t ReadSmiValue();
219
220 // Negative header value indicates VM isolate object id.
221 bool IsVMIsolateObject(intptr_t header_value) { return (header_value < 0); }
222 intptr_t GetVMIsolateObjectId(intptr_t header_val) {
223 ASSERT(IsVMIsolateObject(header_val));
224 intptr_t value = -header_val; // Header is negative for VM isolate objects.
225 ASSERT(SerializedHeaderTag::decode(value) == kObjectId);
226 return SerializedHeaderData::decode(value);
227 }
228
229 uword ReadWordWith32BitReads() { return stream_.ReadWordWith32BitReads(); }
230
231 private:
232 ReadStream stream_; // input stream.
233};
234
235class BackRefNode : public ValueObject {
236 public:
237 BackRefNode(Object* reference, DeserializeState state)
238 : reference_(reference), state_(state) {}
239 Object* reference() const { return reference_; }
240 bool is_deserialized() const { return state_ == kIsDeserialized; }
241 void set_state(DeserializeState state) { state_ = state; }
242
243 BackRefNode& operator=(const BackRefNode& other) {
244 reference_ = other.reference_;
245 state_ = other.state_;
246 return *this;
247 }
248
249 private:
250 Object* reference_;
251 DeserializeState state_;
252};
253
254// Reads a snapshot into objects.
255class SnapshotReader : public BaseReader {
256 public:
257 Thread* thread() const { return thread_; }
258 Zone* zone() const { return zone_; }
259 Isolate* isolate() const { return thread_->isolate(); }
260 Heap* heap() const { return heap_; }
261 ObjectStore* object_store() const { return isolate()->object_store(); }
262 ClassTable* class_table() const { return isolate()->class_table(); }
263 PassiveObject* PassiveObjectHandle() { return &pobj_; }
264 Array* ArrayHandle() { return &array_; }
265 Class* ClassHandle() { return &cls_; }
266 Code* CodeHandle() { return &code_; }
267 Instance* InstanceHandle() { return &instance_; }
268 Instructions* InstructionsHandle() { return &instructions_; }
269 String* StringHandle() { return &str_; }
270 AbstractType* TypeHandle() { return &type_; }
271 TypeArguments* TypeArgumentsHandle() { return &type_arguments_; }
272 GrowableObjectArray* TokensHandle() { return &tokens_; }
273 ExternalTypedData* DataHandle() { return &data_; }
274 TypedDataBase* TypedDataBaseHandle() { return &typed_data_base_; }
275 TypedData* TypedDataHandle() { return &typed_data_; }
276 TypedDataView* TypedDataViewHandle() { return &typed_data_view_; }
277 Function* FunctionHandle() { return &function_; }
278 Snapshot::Kind kind() const { return kind_; }
279
280 // Reads an object.
281 ObjectPtr ReadObject();
282
283 // Add object to backward references.
284 void AddBackRef(intptr_t id, Object* obj, DeserializeState state);
285
286 // Get an object from the backward references list.
287 Object* GetBackRef(intptr_t id);
288
289 // Read version number of snapshot and verify.
290 ApiErrorPtr VerifyVersionAndFeatures(Isolate* isolate);
291
292 ObjectPtr NewInteger(int64_t value);
293
294 protected:
295 SnapshotReader(const uint8_t* buffer,
296 intptr_t size,
297 Snapshot::Kind kind,
298 ZoneGrowableArray<BackRefNode>* backward_references,
299 Thread* thread);
300 ~SnapshotReader() {}
301
302 ZoneGrowableArray<BackRefNode>* GetBackwardReferenceTable() const {
303 return backward_references_;
304 }
305 void ResetBackwardReferenceTable() { backward_references_ = NULL; }
306 PageSpace* old_space() const { return old_space_; }
307
308 private:
309 void EnqueueTypePostprocessing(const AbstractType& type);
310 void RunDelayedTypePostprocessing();
311
312 void EnqueueRehashingOfMap(const LinkedHashMap& map);
313 void EnqueueRehashingOfSet(const Object& set);
314 ObjectPtr RunDelayedRehashingOfMaps();
315
316 ClassPtr ReadClassId(intptr_t object_id);
317 ObjectPtr ReadStaticImplicitClosure(intptr_t object_id, intptr_t cls_header);
318
319 // Implementation to read an object.
320 ObjectPtr ReadObjectImpl(bool as_reference);
321 ObjectPtr ReadObjectImpl(intptr_t header, bool as_reference);
322
323 // Read a Dart Instance object.
324 ObjectPtr ReadInstance(intptr_t object_id, intptr_t tags, bool as_reference);
325
326 // Read a VM isolate object that was serialized as an Id.
327 ObjectPtr ReadVMIsolateObject(intptr_t object_id);
328
329 // Read an object that was serialized as an Id (singleton in object store,
330 // or an object that was already serialized before).
331 ObjectPtr ReadIndexedObject(intptr_t object_id);
332
333 // Decode class id from the header field.
334 intptr_t LookupInternalClass(intptr_t class_header);
335
336 void ArrayReadFrom(intptr_t object_id,
337 const Array& result,
338 intptr_t len,
339 intptr_t tags);
340
341 intptr_t NextAvailableObjectId() const;
342
343 void SetReadException(const char* msg);
344
345 ObjectPtr VmIsolateSnapshotObject(intptr_t index) const;
346
347 bool is_vm_isolate() const;
348
349 Snapshot::Kind kind_; // Indicates type of the snapshot.
350 Thread* thread_; // Current thread.
351 Zone* zone_; // Zone for allocations while reading.
352 Heap* heap_; // Heap of the current isolate.
353 PageSpace* old_space_; // Old space of the current isolate.
354 Class& cls_; // Temporary Class handle.
355 Code& code_; // Temporary Code handle.
356 Instance& instance_; // Temporary Instance handle
357 Instructions& instructions_; // Temporary Instructions handle
358 Object& obj_; // Temporary Object handle.
359 PassiveObject& pobj_; // Temporary PassiveObject handle.
360 Array& array_; // Temporary Array handle.
361 Field& field_; // Temporary Field handle.
362 String& str_; // Temporary String handle.
363 Library& library_; // Temporary library handle.
364 AbstractType& type_; // Temporary type handle.
365 TypeArguments& type_arguments_; // Temporary type argument handle.
366 GrowableObjectArray& tokens_; // Temporary tokens handle.
367 ExternalTypedData& data_; // Temporary stream data handle.
368 TypedDataBase& typed_data_base_; // Temporary typed data base handle.
369 TypedData& typed_data_; // Temporary typed data handle.
370 TypedDataView& typed_data_view_; // Temporary typed data view handle.
371 Function& function_; // Temporary function handle.
372 UnhandledException& error_; // Error handle.
373 const Class& set_class_; // The LinkedHashSet class.
374 intptr_t max_vm_isolate_object_id_;
375 ZoneGrowableArray<BackRefNode>* backward_references_;
376 GrowableObjectArray& types_to_postprocess_;
377 GrowableObjectArray& objects_to_rehash_;
378
379 friend class ApiError;
380 friend class Array;
381 friend class Class;
382 friend class Closure;
383 friend class ClosureData;
384 friend class Context;
385 friend class ContextScope;
386 friend class ExceptionHandlers;
387 friend class Field;
388 friend class Function;
389 friend class GrowableObjectArray;
390 friend class ICData;
391 friend class ImmutableArray;
392 friend class KernelProgramInfo;
393 friend class LanguageError;
394 friend class Library;
395 friend class LibraryPrefix;
396 friend class LinkedHashMap;
397 friend class MirrorReference;
398 friend class Namespace;
399 friend class PatchClass;
400 friend class RedirectionData;
401 friend class RegExp;
402 friend class Script;
403 friend class SignatureData;
404 friend class SubtypeTestCache;
405 friend class TransferableTypedData;
406 friend class Type;
407 friend class TypedDataView;
408 friend class TypeArguments;
409 friend class TypeParameter;
410 friend class TypeRef;
411 friend class UnhandledException;
412 friend class WeakProperty;
413 friend class WeakSerializationReference;
414 DISALLOW_COPY_AND_ASSIGN(SnapshotReader);
415};
416
417class MessageSnapshotReader : public SnapshotReader {
418 public:
419 MessageSnapshotReader(Message* message, Thread* thread);
420 ~MessageSnapshotReader();
421
422 MessageFinalizableData* finalizable_data() const { return finalizable_data_; }
423
424 private:
425 MessageFinalizableData* finalizable_data_;
426
427 DISALLOW_COPY_AND_ASSIGN(MessageSnapshotReader);
428};
429
430class BaseWriter : public StackResource {
431 public:
432 uint8_t* buffer() { return stream_.buffer(); }
433 intptr_t BytesWritten() const { return stream_.bytes_written(); }
434
435 // Writes raw data to the stream (basic type).
436 // sizeof(T) must be in {1,2,4,8}.
437 template <typename T>
438 void Write(T value) {
439 WriteStream::Raw<sizeof(T), T>::Write(&stream_, value);
440 }
441
442 void WriteClassIDValue(classid_t value) { Write<uint32_t>(value); }
443 COMPILE_ASSERT(sizeof(uint32_t) >= sizeof(classid_t));
444
445 // Write an object that is serialized as an Id (singleton in object store,
446 // or an object that was already serialized before).
447 void WriteIndexedObject(intptr_t object_id) {
448 ASSERT(object_id <= kMaxObjectId);
449 intptr_t value = 0;
450 value = SerializedHeaderTag::update(kObjectId, value);
451 value = SerializedHeaderData::update(object_id, value);
452 Write<int32_t>(value);
453 }
454
455 // Write a VM Isolateobject that is serialized as an Id.
456 void WriteVMIsolateObject(intptr_t object_id) {
457 ASSERT(object_id <= kMaxObjectId);
458 intptr_t value = 0;
459 value = SerializedHeaderTag::update(kObjectId, value);
460 value = SerializedHeaderData::update(object_id, value);
461 Write<int32_t>(-value); // Write as a negative value.
462 }
463
464 // Write serialization header information for an object.
465 void WriteInlinedObjectHeader(intptr_t id) {
466 ASSERT(id <= kMaxObjectId);
467 intptr_t value = 0;
468 value = SerializedHeaderTag::update(kInlined, value);
469 value = SerializedHeaderData::update(id, value);
470 Write<int32_t>(value);
471 }
472
473 void WriteTags(intptr_t tags) {
474 const intptr_t flags = tags & 0xff;
475 Write<int8_t>(static_cast<int8_t>(flags));
476 }
477
478 void Align(intptr_t value) { stream_.Align(value); }
479
480 // Write out a buffer of bytes.
481 void WriteBytes(const uint8_t* addr, intptr_t len) {
482 stream_.WriteBytes(addr, len);
483 }
484
485 void WriteDouble(double value) {
486 stream_.WriteBytes(reinterpret_cast<const uint8_t*>(&value), sizeof(value));
487 }
488
489 void WriteWordWith32BitWrites(uword value) {
490 stream_.WriteWordWith32BitWrites(value);
491 }
492
493 protected:
494 BaseWriter(ReAlloc alloc, DeAlloc dealloc, intptr_t initial_size)
495 : StackResource(Thread::Current()),
496 buffer_(NULL),
497 stream_(&buffer_, alloc, initial_size),
498 dealloc_(dealloc) {
499 ASSERT(alloc != NULL);
500 }
501 ~BaseWriter() {}
502
503 void ReserveHeader() {
504 // Make room for recording snapshot buffer size.
505 stream_.SetPosition(Snapshot::kHeaderSize);
506 }
507
508 void FillHeader(Snapshot::Kind kind) {
509 Snapshot* header = reinterpret_cast<Snapshot*>(stream_.buffer());
510 header->set_magic();
511 header->set_length(stream_.bytes_written());
512 header->set_kind(kind);
513 }
514
515 void FreeBuffer() {
516 dealloc_(stream_.buffer());
517 stream_.set_buffer(NULL);
518 }
519
520 private:
521 uint8_t* buffer_;
522 WriteStream stream_;
523 DeAlloc dealloc_;
524
525 DISALLOW_IMPLICIT_CONSTRUCTORS(BaseWriter);
526};
527
528class ForwardList {
529 public:
530 explicit ForwardList(Thread* thread, intptr_t first_object_id);
531 ~ForwardList();
532
533 class Node : public ZoneAllocated {
534 public:
535 Node(const Object* obj, SerializeState state) : obj_(obj), state_(state) {}
536 const Object* obj() const { return obj_; }
537 bool is_serialized() const { return state_ == kIsSerialized; }
538
539 private:
540 // Private to ensure the invariant of first_unprocessed_object_id_.
541 void set_state(SerializeState value) { state_ = value; }
542
543 const Object* obj_;
544 SerializeState state_;
545
546 friend class ForwardList;
547 DISALLOW_COPY_AND_ASSIGN(Node);
548 };
549
550 Node* NodeForObjectId(intptr_t object_id) const {
551 return nodes_[object_id - first_object_id_];
552 }
553
554 // Returns the id for the added object.
555 intptr_t AddObject(Zone* zone, ObjectPtr raw, SerializeState state);
556
557 // Returns the id for the object it it exists in the list.
558 intptr_t FindObject(ObjectPtr raw);
559
560 // Exhaustively processes all unserialized objects in this list. 'writer' may
561 // concurrently add more objects.
562 void SerializeAll(ObjectVisitor* writer);
563
564 // Set state of object in forward list.
565 void SetState(intptr_t object_id, SerializeState state) {
566 NodeForObjectId(object_id)->set_state(state);
567 }
568
569 private:
570 intptr_t first_object_id() const { return first_object_id_; }
571 intptr_t next_object_id() const { return nodes_.length() + first_object_id_; }
572 Isolate* isolate() const { return thread_->isolate(); }
573
574 Thread* thread_;
575 const intptr_t first_object_id_;
576 GrowableArray<Node*> nodes_;
577 intptr_t first_unprocessed_object_id_;
578
579 void SetObjectId(ObjectPtr object, intptr_t id);
580 intptr_t GetObjectId(ObjectPtr object);
581
582 DISALLOW_COPY_AND_ASSIGN(ForwardList);
583};
584
585class SnapshotWriter : public BaseWriter {
586 protected:
587 SnapshotWriter(Thread* thread,
588 Snapshot::Kind kind,
589 ReAlloc alloc,
590 DeAlloc dealloc,
591 intptr_t initial_size,
592 ForwardList* forward_list,
593 bool can_send_any_object);
594
595 public:
596 // Snapshot kind.
597 Snapshot::Kind kind() const { return kind_; }
598 Thread* thread() const { return thread_; }
599 Zone* zone() const { return thread_->zone(); }
600 Isolate* isolate() const { return thread_->isolate(); }
601 Heap* heap() const { return isolate()->heap(); }
602
603 // Serialize an object into the buffer.
604 void WriteObject(ObjectPtr raw);
605
606 static uint32_t GetObjectTags(ObjectPtr raw);
607 static uint32_t GetObjectTags(ObjectLayout* raw);
608 static uword GetObjectTagsAndHash(ObjectPtr raw);
609
610 Exceptions::ExceptionType exception_type() const { return exception_type_; }
611 void set_exception_type(Exceptions::ExceptionType type) {
612 exception_type_ = type;
613 }
614 const char* exception_msg() const { return exception_msg_; }
615 void set_exception_msg(const char* msg) { exception_msg_ = msg; }
616 bool can_send_any_object() const { return can_send_any_object_; }
617 void ThrowException(Exceptions::ExceptionType type, const char* msg);
618
619 // Write a version string for the snapshot.
620 void WriteVersionAndFeatures();
621
622 FunctionPtr IsSerializableClosure(ClosurePtr closure);
623
624 void WriteStaticImplicitClosure(intptr_t object_id,
625 FunctionPtr func,
626 intptr_t tags);
627
628 protected:
629 bool CheckAndWritePredefinedObject(ObjectPtr raw);
630 bool HandleVMIsolateObject(ObjectPtr raw);
631
632 void WriteClassId(ClassLayout* cls);
633 void WriteObjectImpl(ObjectPtr raw, bool as_reference);
634 void WriteMarkedObjectImpl(ObjectPtr raw,
635 intptr_t tags,
636 intptr_t object_id,
637 bool as_reference);
638 void WriteForwardedObjects();
639 void ArrayWriteTo(intptr_t object_id,
640 intptr_t array_kind,
641 intptr_t tags,
642 SmiPtr length,
643 TypeArgumentsPtr type_arguments,
644 ObjectPtr data[],
645 bool as_reference);
646 ClassPtr GetFunctionOwner(FunctionPtr func);
647 void CheckForNativeFields(ClassPtr cls);
648 void SetWriteException(Exceptions::ExceptionType type, const char* msg);
649 void WriteInstance(ObjectPtr raw,
650 ClassPtr cls,
651 intptr_t tags,
652 intptr_t object_id,
653 bool as_reference);
654 bool AllowObjectsInDartLibrary(LibraryPtr library);
655 intptr_t FindVmSnapshotObject(ObjectPtr rawobj);
656
657 ObjectStore* object_store() const { return object_store_; }
658
659 private:
660 Thread* thread_;
661 Snapshot::Kind kind_;
662 ObjectStore* object_store_; // Object store for common classes.
663 ClassTable* class_table_; // Class table for the class index to class lookup.
664 ForwardList* forward_list_;
665 Exceptions::ExceptionType exception_type_; // Exception type.
666 const char* exception_msg_; // Message associated with exception.
667 bool can_send_any_object_; // True if any Dart instance can be sent.
668
669 friend class ArrayLayout;
670 friend class ClassLayout;
671 friend class ClosureDataLayout;
672 friend class CodeLayout;
673 friend class ContextScopeLayout;
674 friend class DynamicLibraryLayout;
675 friend class ExceptionHandlersLayout;
676 friend class FieldLayout;
677 friend class FunctionLayout;
678 friend class GrowableObjectArrayLayout;
679 friend class ImmutableArrayLayout;
680 friend class InstructionsLayout;
681 friend class LibraryLayout;
682 friend class LinkedHashMapLayout;
683 friend class LocalVarDescriptorsLayout;
684 friend class MirrorReferenceLayout;
685 friend class ObjectPoolLayout;
686 friend class PointerLayout;
687 friend class ReceivePortLayout;
688 friend class RegExpLayout;
689 friend class ScriptLayout;
690 friend class StackTraceLayout;
691 friend class SubtypeTestCacheLayout;
692 friend class TransferableTypedDataLayout;
693 friend class TypeLayout;
694 friend class TypeArgumentsLayout;
695 friend class TypeParameterLayout;
696 friend class TypeRefLayout;
697 friend class TypedDataViewLayout;
698 friend class UserTagLayout;
699 friend class WeakSerializationReferenceLayout;
700 friend class SnapshotWriterVisitor;
701 friend class WriteInlinedObjectVisitor;
702 DISALLOW_COPY_AND_ASSIGN(SnapshotWriter);
703};
704
705class SerializedObjectBuffer : public StackResource {
706 public:
707 SerializedObjectBuffer()
708 : StackResource(Thread::Current()), message_(nullptr) {}
709
710 void set_message(std::unique_ptr<Message> message) {
711 ASSERT(message_ == nullptr);
712 message_ = std::move(message);
713 }
714 std::unique_ptr<Message> StealMessage() { return std::move(message_); }
715
716 private:
717 std::unique_ptr<Message> message_;
718};
719
720class MessageWriter : public SnapshotWriter {
721 public:
722 static const intptr_t kInitialSize = 512;
723 explicit MessageWriter(bool can_send_any_object);
724 ~MessageWriter();
725
726 std::unique_ptr<Message> WriteMessage(const Object& obj,
727 Dart_Port dest_port,
728 Message::Priority priority);
729
730 MessageFinalizableData* finalizable_data() const { return finalizable_data_; }
731
732 private:
733 ForwardList forward_list_;
734 MessageFinalizableData* finalizable_data_;
735
736 DISALLOW_COPY_AND_ASSIGN(MessageWriter);
737};
738
739// An object pointer visitor implementation which writes out
740// objects to a snapshot.
741class SnapshotWriterVisitor : public ObjectPointerVisitor {
742 public:
743 SnapshotWriterVisitor(SnapshotWriter* writer, bool as_references)
744 : ObjectPointerVisitor(Isolate::Current()->group()),
745 writer_(writer),
746 as_references_(as_references) {}
747
748 virtual void VisitPointers(ObjectPtr* first, ObjectPtr* last);
749
750 private:
751 SnapshotWriter* writer_;
752 bool as_references_;
753
754 DISALLOW_COPY_AND_ASSIGN(SnapshotWriterVisitor);
755};
756
757} // namespace dart
758
759#endif // RUNTIME_VM_SNAPSHOT_H_
760