2012-01-16 12:28:10 +00:00
|
|
|
// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
|
2011-10-05 05:20:07 +00:00
|
|
|
// for details. All rights reserved. Use of this source code is governed by a
|
|
|
|
// BSD-style license that can be found in the LICENSE file.
|
|
|
|
|
|
|
|
#ifndef VM_SNAPSHOT_H_
|
|
|
|
#define VM_SNAPSHOT_H_
|
|
|
|
|
2012-01-16 12:28:10 +00:00
|
|
|
#include "platform/assert.h"
|
2011-10-05 05:20:07 +00:00
|
|
|
#include "vm/allocation.h"
|
|
|
|
#include "vm/bitfield.h"
|
2012-06-22 20:37:01 +00:00
|
|
|
#include "vm/datastream.h"
|
2011-10-05 05:20:07 +00:00
|
|
|
#include "vm/globals.h"
|
|
|
|
#include "vm/growable_array.h"
|
|
|
|
#include "vm/isolate.h"
|
|
|
|
#include "vm/visitor.h"
|
|
|
|
|
|
|
|
namespace dart {
|
|
|
|
|
|
|
|
// Forward declarations.
|
2012-01-13 00:38:19 +00:00
|
|
|
class AbstractType;
|
|
|
|
class AbstractTypeArguments;
|
2012-06-11 21:39:05 +00:00
|
|
|
class Array;
|
2012-01-13 00:38:19 +00:00
|
|
|
class Class;
|
2012-07-20 22:24:49 +00:00
|
|
|
class ClassTable;
|
2012-07-11 00:11:58 +00:00
|
|
|
class GrowableObjectArray;
|
2011-10-05 05:20:07 +00:00
|
|
|
class Heap;
|
2011-12-06 00:34:49 +00:00
|
|
|
class Library;
|
|
|
|
class Object;
|
2011-10-05 05:20:07 +00:00
|
|
|
class ObjectStore;
|
2012-06-11 21:39:05 +00:00
|
|
|
class RawAbstractTypeArguments;
|
2012-01-18 00:20:17 +00:00
|
|
|
class RawArray;
|
2012-03-24 02:42:56 +00:00
|
|
|
class RawBigint;
|
2011-10-05 05:20:07 +00:00
|
|
|
class RawClass;
|
2012-01-18 00:20:17 +00:00
|
|
|
class RawContext;
|
|
|
|
class RawDouble;
|
|
|
|
class RawField;
|
|
|
|
class RawFourByteString;
|
|
|
|
class RawFunction;
|
2012-03-07 19:14:02 +00:00
|
|
|
class RawGrowableObjectArray;
|
2012-01-18 00:20:17 +00:00
|
|
|
class RawImmutableArray;
|
|
|
|
class RawLibrary;
|
|
|
|
class RawLibraryPrefix;
|
2012-02-29 02:46:29 +00:00
|
|
|
class RawLiteralToken;
|
2012-01-18 00:20:17 +00:00
|
|
|
class RawMint;
|
2011-10-05 05:20:07 +00:00
|
|
|
class RawObject;
|
2012-01-18 00:20:17 +00:00
|
|
|
class RawOneByteString;
|
2012-08-14 00:38:01 +00:00
|
|
|
class RawPatchClass;
|
2012-01-18 00:20:17 +00:00
|
|
|
class RawScript;
|
2012-01-30 08:29:31 +00:00
|
|
|
class RawSmi;
|
2012-01-18 00:20:17 +00:00
|
|
|
class RawTokenStream;
|
|
|
|
class RawType;
|
|
|
|
class RawTypeParameter;
|
|
|
|
class RawTypeArguments;
|
|
|
|
class RawTwoByteString;
|
|
|
|
class RawUnresolvedClass;
|
2012-01-13 00:38:19 +00:00
|
|
|
class String;
|
2011-10-05 05:20:07 +00:00
|
|
|
|
|
|
|
// Serialized object header encoding is as follows:
|
|
|
|
// - Smi: the Smi value is written as is (last bit is not tagged).
|
2012-08-06 21:56:39 +00:00
|
|
|
// - VM object (from VM isolate): (object id in vm isolate | 0x3)
|
|
|
|
// This valus is serialized as a negative number.
|
|
|
|
// (note VM objects are never serialized they are expected to be found
|
|
|
|
// using ths unique ID assigned to them).
|
|
|
|
// - Reference to object that has already been written: (object id | 0x3)
|
|
|
|
// This valus is serialized as a positive number.
|
2011-10-05 05:20:07 +00:00
|
|
|
// - Object that is seen for the first time (inlined in the stream):
|
|
|
|
// (a unique id for this object | 0x1)
|
|
|
|
enum SerializedHeaderType {
|
2012-08-06 21:56:39 +00:00
|
|
|
kInlined = 0x1,
|
2011-10-05 05:20:07 +00:00
|
|
|
kObjectId = 0x3,
|
|
|
|
};
|
2011-12-27 23:54:30 +00:00
|
|
|
static const int8_t kHeaderTagBits = 2;
|
2012-08-06 21:56:39 +00:00
|
|
|
static const int8_t kObjectIdBits = (kBitsPerWord - (kHeaderTagBits + 1));
|
|
|
|
static const intptr_t kMaxObjectId = (kUwordMax >> (kHeaderTagBits + 1));
|
|
|
|
|
2011-10-05 05:20:07 +00:00
|
|
|
|
2011-12-27 23:54:30 +00:00
|
|
|
class SerializedHeaderTag : public BitField<enum SerializedHeaderType,
|
|
|
|
0,
|
|
|
|
kHeaderTagBits> {
|
2011-10-05 05:20:07 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
|
2011-12-27 23:54:30 +00:00
|
|
|
class SerializedHeaderData : public BitField<intptr_t,
|
|
|
|
kHeaderTagBits,
|
2012-08-06 21:56:39 +00:00
|
|
|
kObjectIdBits> {
|
2011-10-05 05:20:07 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
|
2012-06-11 21:39:05 +00:00
|
|
|
enum DeserializeState {
|
|
|
|
kIsDeserialized = 0,
|
|
|
|
kIsNotDeserialized = 1,
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
enum SerializeState {
|
|
|
|
kIsSerialized = 0,
|
|
|
|
kIsNotSerialized = 1,
|
|
|
|
};
|
|
|
|
|
|
|
|
|
2011-10-05 05:20:07 +00:00
|
|
|
// Structure capturing the raw snapshot.
|
|
|
|
class Snapshot {
|
|
|
|
public:
|
2011-12-06 00:34:49 +00:00
|
|
|
enum Kind {
|
|
|
|
kFull = 0, // Full snapshot of the current dart heap.
|
|
|
|
kScript, // A partial snapshot of only the application script.
|
|
|
|
kMessage, // A partial snapshot used only for isolate messaging.
|
|
|
|
};
|
|
|
|
|
2011-10-05 05:20:07 +00:00
|
|
|
static const int kHeaderSize = 2 * sizeof(int32_t);
|
|
|
|
static const int kLengthIndex = 0;
|
|
|
|
static const int kSnapshotFlagIndex = 1;
|
|
|
|
|
2011-10-11 00:37:11 +00:00
|
|
|
static const Snapshot* SetupFromBuffer(const void* raw_memory);
|
2011-10-05 05:20:07 +00:00
|
|
|
|
|
|
|
// Getters.
|
2011-10-11 00:37:11 +00:00
|
|
|
const uint8_t* content() const { return content_; }
|
2011-10-05 05:20:07 +00:00
|
|
|
int32_t length() const { return length_; }
|
2011-12-06 00:34:49 +00:00
|
|
|
Kind kind() const { return static_cast<Kind>(kind_); }
|
2011-10-05 05:20:07 +00:00
|
|
|
|
2011-12-06 00:34:49 +00:00
|
|
|
bool IsMessageSnapshot() const { return kind_ == kMessage; }
|
|
|
|
bool IsScriptSnapshot() const { return kind_ == kScript; }
|
|
|
|
bool IsFullSnapshot() const { return kind_ == kFull; }
|
2011-10-05 05:20:07 +00:00
|
|
|
int32_t Size() const { return length_ + sizeof(Snapshot); }
|
|
|
|
uint8_t* Addr() { return reinterpret_cast<uint8_t*>(this); }
|
|
|
|
|
|
|
|
static intptr_t length_offset() { return OFFSET_OF(Snapshot, length_); }
|
2011-12-06 00:34:49 +00:00
|
|
|
static intptr_t kind_offset() {
|
|
|
|
return OFFSET_OF(Snapshot, kind_);
|
2011-10-05 05:20:07 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
private:
|
2011-12-06 00:34:49 +00:00
|
|
|
Snapshot() : length_(0), kind_(kFull) {}
|
2011-10-05 05:20:07 +00:00
|
|
|
|
|
|
|
int32_t length_; // Stream length.
|
2011-12-06 00:34:49 +00:00
|
|
|
int32_t kind_; // Kind of snapshot.
|
2011-10-05 05:20:07 +00:00
|
|
|
uint8_t content_[]; // Stream content.
|
|
|
|
|
|
|
|
DISALLOW_COPY_AND_ASSIGN(Snapshot);
|
|
|
|
};
|
|
|
|
|
|
|
|
|
2012-01-30 08:29:31 +00:00
|
|
|
class BaseReader {
|
2011-10-05 05:20:07 +00:00
|
|
|
public:
|
2012-01-30 08:29:31 +00:00
|
|
|
BaseReader(const uint8_t* buffer, intptr_t size) : stream_(buffer, size) {}
|
2011-10-05 05:20:07 +00:00
|
|
|
// Reads raw data (for basic types).
|
|
|
|
// sizeof(T) must be in {1,2,4,8}.
|
|
|
|
template <typename T>
|
|
|
|
T Read() {
|
|
|
|
return ReadStream::Raw<sizeof(T), T>::Read(&stream_);
|
|
|
|
}
|
|
|
|
|
2011-12-27 23:54:30 +00:00
|
|
|
// Reads an intptr_t type value.
|
|
|
|
intptr_t ReadIntptrValue() {
|
|
|
|
int64_t value = Read<int64_t>();
|
|
|
|
ASSERT((value <= kIntptrMax) && (value >= kIntptrMin));
|
|
|
|
return value;
|
|
|
|
}
|
|
|
|
|
2012-05-31 23:50:32 +00:00
|
|
|
void ReadBytes(uint8_t* addr, intptr_t len) {
|
|
|
|
stream_.ReadBytes(addr, len);
|
|
|
|
}
|
|
|
|
|
2012-01-30 08:29:31 +00:00
|
|
|
RawSmi* ReadAsSmi();
|
|
|
|
intptr_t ReadSmiValue();
|
|
|
|
|
2012-08-06 21:56:39 +00:00
|
|
|
// Negative header value indicates VM isolate object id.
|
|
|
|
bool IsVMIsolateObject(intptr_t header_value) { return (header_value < 0); }
|
|
|
|
intptr_t GetVMIsolateObjectId(intptr_t header_val) {
|
|
|
|
ASSERT(IsVMIsolateObject(header_val));
|
|
|
|
intptr_t value = -header_val; // Header is negative for VM isolate objects.
|
|
|
|
ASSERT(SerializedHeaderTag::decode(value) == kObjectId);
|
|
|
|
return SerializedHeaderData::decode(value);
|
|
|
|
}
|
|
|
|
|
2012-01-30 08:29:31 +00:00
|
|
|
private:
|
|
|
|
ReadStream stream_; // input stream.
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
// Reads a snapshot into objects.
|
|
|
|
class SnapshotReader : public BaseReader {
|
|
|
|
public:
|
|
|
|
SnapshotReader(const Snapshot* snapshot, Isolate* isolate);
|
|
|
|
~SnapshotReader() { }
|
|
|
|
|
2012-01-10 18:47:38 +00:00
|
|
|
Isolate* isolate() const { return isolate_; }
|
|
|
|
Heap* heap() const { return isolate_->heap(); }
|
|
|
|
ObjectStore* object_store() const { return isolate_->object_store(); }
|
2012-07-20 22:24:49 +00:00
|
|
|
ClassTable* class_table() const { return isolate_->class_table(); }
|
2012-01-13 00:38:19 +00:00
|
|
|
Object* ObjectHandle() { return &obj_; }
|
|
|
|
String* StringHandle() { return &str_; }
|
|
|
|
AbstractType* TypeHandle() { return &type_; }
|
|
|
|
AbstractTypeArguments* TypeArgumentsHandle() { return &type_arguments_; }
|
2012-07-11 00:11:58 +00:00
|
|
|
Array* TokensHandle() { return &tokens_; }
|
2011-10-05 05:20:07 +00:00
|
|
|
|
|
|
|
// Reads an object.
|
|
|
|
RawObject* ReadObject();
|
|
|
|
|
|
|
|
// Add object to backward references.
|
2012-06-11 21:39:05 +00:00
|
|
|
void AddBackRef(intptr_t id, Object* obj, DeserializeState state);
|
|
|
|
|
|
|
|
// Get an object from the backward references list.
|
|
|
|
Object* GetBackRef(intptr_t id);
|
2011-10-05 05:20:07 +00:00
|
|
|
|
|
|
|
// Read a full snap shot.
|
|
|
|
void ReadFullSnapshot();
|
|
|
|
|
2012-01-18 00:20:17 +00:00
|
|
|
// Helper functions for creating uninitialized versions
|
|
|
|
// of various object types. These are used when reading a
|
|
|
|
// full snapshot.
|
|
|
|
RawArray* NewArray(intptr_t len);
|
|
|
|
RawImmutableArray* NewImmutableArray(intptr_t len);
|
|
|
|
RawOneByteString* NewOneByteString(intptr_t len);
|
|
|
|
RawTwoByteString* NewTwoByteString(intptr_t len);
|
|
|
|
RawFourByteString* NewFourByteString(intptr_t len);
|
|
|
|
RawTypeArguments* NewTypeArguments(intptr_t len);
|
|
|
|
RawTokenStream* NewTokenStream(intptr_t len);
|
|
|
|
RawContext* NewContext(intptr_t num_variables);
|
2012-08-08 19:46:23 +00:00
|
|
|
RawClass* NewClass(intptr_t class_id, bool is_signature_class);
|
2012-01-18 00:20:17 +00:00
|
|
|
RawMint* NewMint(int64_t value);
|
2012-03-24 02:42:56 +00:00
|
|
|
RawBigint* NewBigint(const char* hex_string);
|
2012-01-18 00:20:17 +00:00
|
|
|
RawDouble* NewDouble(double value);
|
|
|
|
RawUnresolvedClass* NewUnresolvedClass();
|
|
|
|
RawType* NewType();
|
|
|
|
RawTypeParameter* NewTypeParameter();
|
2012-08-14 00:38:01 +00:00
|
|
|
RawPatchClass* NewPatchClass();
|
2012-01-18 00:20:17 +00:00
|
|
|
RawFunction* NewFunction();
|
|
|
|
RawField* NewField();
|
|
|
|
RawLibrary* NewLibrary();
|
|
|
|
RawLibraryPrefix* NewLibraryPrefix();
|
|
|
|
RawScript* NewScript();
|
2012-02-29 02:46:29 +00:00
|
|
|
RawLiteralToken* NewLiteralToken();
|
2012-03-07 19:14:02 +00:00
|
|
|
RawGrowableObjectArray* NewGrowableObjectArray();
|
2012-01-18 00:20:17 +00:00
|
|
|
|
2011-10-05 05:20:07 +00:00
|
|
|
private:
|
2012-06-11 21:39:05 +00:00
|
|
|
class BackRefNode : public ZoneAllocated {
|
|
|
|
public:
|
|
|
|
BackRefNode(Object* reference, DeserializeState state)
|
|
|
|
: reference_(reference), state_(state) {}
|
|
|
|
Object* reference() const { return reference_; }
|
|
|
|
bool is_deserialized() const { return state_ == kIsDeserialized; }
|
|
|
|
void set_state(DeserializeState state) { state_ = state; }
|
|
|
|
|
|
|
|
private:
|
|
|
|
Object* reference_;
|
|
|
|
DeserializeState state_;
|
|
|
|
|
|
|
|
DISALLOW_COPY_AND_ASSIGN(BackRefNode);
|
|
|
|
};
|
|
|
|
|
2012-01-18 00:20:17 +00:00
|
|
|
// Allocate uninitialized objects, this is used when reading a full snapshot.
|
|
|
|
RawObject* AllocateUninitialized(const Class& cls, intptr_t size);
|
|
|
|
|
2012-06-11 21:39:05 +00:00
|
|
|
RawClass* ReadClassId(intptr_t object_id);
|
|
|
|
RawObject* ReadObjectImpl();
|
2011-10-05 05:20:07 +00:00
|
|
|
RawObject* ReadObjectImpl(intptr_t header);
|
2012-06-11 21:39:05 +00:00
|
|
|
RawObject* ReadObjectRef();
|
2011-10-05 05:20:07 +00:00
|
|
|
|
2012-08-06 21:56:39 +00:00
|
|
|
// Read a VM isolate object that was serialized as an Id.
|
|
|
|
RawObject* ReadVMIsolateObject(intptr_t object_id);
|
|
|
|
|
|
|
|
// Read an object that was serialized as an Id (singleton in object store,
|
2011-10-05 05:20:07 +00:00
|
|
|
// or an object that was already serialized before).
|
|
|
|
RawObject* ReadIndexedObject(intptr_t object_id);
|
|
|
|
|
|
|
|
// Read an inlined object from the stream.
|
|
|
|
RawObject* ReadInlinedObject(intptr_t object_id);
|
|
|
|
|
|
|
|
// Based on header field check to see if it is an internal VM class.
|
|
|
|
RawClass* LookupInternalClass(intptr_t class_header);
|
|
|
|
|
2012-06-11 21:39:05 +00:00
|
|
|
void ArrayReadFrom(const Array& result, intptr_t len, intptr_t tags);
|
|
|
|
|
2011-12-06 00:34:49 +00:00
|
|
|
Snapshot::Kind kind_; // Indicates type of snapshot(full, script, message).
|
2012-01-10 18:47:38 +00:00
|
|
|
Isolate* isolate_; // Current isolate.
|
2012-01-13 00:38:19 +00:00
|
|
|
Class& cls_; // Temporary Class handle.
|
|
|
|
Object& obj_; // Temporary Object handle.
|
|
|
|
String& str_; // Temporary String handle.
|
|
|
|
Library& library_; // Temporary library handle.
|
|
|
|
AbstractType& type_; // Temporary type handle.
|
|
|
|
AbstractTypeArguments& type_arguments_; // Temporary type argument handle.
|
2012-07-11 00:11:58 +00:00
|
|
|
Array& tokens_; // Temporary tokens handle.
|
2012-06-11 21:39:05 +00:00
|
|
|
GrowableArray<BackRefNode*> backward_references_;
|
|
|
|
|
|
|
|
friend class Array;
|
|
|
|
friend class Class;
|
|
|
|
friend class Context;
|
|
|
|
friend class ContextScope;
|
|
|
|
friend class Field;
|
|
|
|
friend class Function;
|
|
|
|
friend class GrowableObjectArray;
|
|
|
|
friend class ImmutableArray;
|
|
|
|
friend class InstantiatedTypeArguments;
|
|
|
|
friend class JSRegExp;
|
|
|
|
friend class Library;
|
|
|
|
friend class LibraryPrefix;
|
|
|
|
friend class LiteralToken;
|
2012-08-14 00:38:01 +00:00
|
|
|
friend class PatchClass;
|
2012-06-11 21:39:05 +00:00
|
|
|
friend class Script;
|
|
|
|
friend class TokenStream;
|
|
|
|
friend class Type;
|
|
|
|
friend class TypeArguments;
|
|
|
|
friend class TypeParameter;
|
|
|
|
friend class UnresolvedClass;
|
2012-08-17 01:17:39 +00:00
|
|
|
friend class WeakProperty;
|
2011-10-05 05:20:07 +00:00
|
|
|
DISALLOW_COPY_AND_ASSIGN(SnapshotReader);
|
|
|
|
};
|
|
|
|
|
|
|
|
|
2011-12-21 19:37:37 +00:00
|
|
|
class BaseWriter {
|
2011-10-05 05:20:07 +00:00
|
|
|
public:
|
2011-12-21 19:37:37 +00:00
|
|
|
// Size of the snapshot.
|
|
|
|
intptr_t BytesWritten() const { return stream_.bytes_written(); }
|
2011-10-05 05:20:07 +00:00
|
|
|
|
|
|
|
// Writes raw data to the stream (basic type).
|
|
|
|
// sizeof(T) must be in {1,2,4,8}.
|
|
|
|
template <typename T>
|
|
|
|
void Write(T value) {
|
|
|
|
WriteStream::Raw<sizeof(T), T>::Write(&stream_, value);
|
|
|
|
}
|
|
|
|
|
2011-12-27 23:54:30 +00:00
|
|
|
// Writes an intptr_t type value out.
|
|
|
|
void WriteIntptrValue(intptr_t value) {
|
|
|
|
Write<int64_t>(value);
|
|
|
|
}
|
|
|
|
|
2012-08-06 21:56:39 +00:00
|
|
|
// Write an object that is serialized as an Id (singleton in object store,
|
2011-12-14 18:09:18 +00:00
|
|
|
// or an object that was already serialized before).
|
|
|
|
void WriteIndexedObject(intptr_t object_id) {
|
2012-08-06 21:56:39 +00:00
|
|
|
ASSERT(object_id <= kMaxObjectId);
|
|
|
|
intptr_t value = 0;
|
|
|
|
value = SerializedHeaderTag::update(kObjectId, value);
|
|
|
|
value = SerializedHeaderData::update(object_id, value);
|
|
|
|
WriteIntptrValue(value);
|
2011-12-14 18:09:18 +00:00
|
|
|
}
|
|
|
|
|
2012-08-06 21:56:39 +00:00
|
|
|
// Write a VM Isolateobject that is serialized as an Id.
|
|
|
|
void WriteVMIsolateObject(intptr_t object_id) {
|
|
|
|
ASSERT(object_id <= kMaxObjectId);
|
|
|
|
intptr_t value = 0;
|
|
|
|
value = SerializedHeaderTag::update(kObjectId, value);
|
|
|
|
value = SerializedHeaderData::update(object_id, value);
|
|
|
|
WriteIntptrValue(-value); // Write as a negative value.
|
2011-12-14 18:09:18 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// Write serialization header information for an object.
|
2012-08-06 21:56:39 +00:00
|
|
|
void WriteInlinedObjectHeader(intptr_t id) {
|
2011-12-27 23:54:30 +00:00
|
|
|
ASSERT(id <= kMaxObjectId);
|
|
|
|
intptr_t value = 0;
|
2012-08-06 21:56:39 +00:00
|
|
|
value = SerializedHeaderTag::update(kInlined, value);
|
2011-10-05 05:20:07 +00:00
|
|
|
value = SerializedHeaderData::update(id, value);
|
2011-12-27 23:54:30 +00:00
|
|
|
WriteIntptrValue(value);
|
2011-10-05 05:20:07 +00:00
|
|
|
}
|
|
|
|
|
2012-06-26 00:18:14 +00:00
|
|
|
// Write out a buffer of bytes.
|
|
|
|
void WriteBytes(const uint8_t* addr, intptr_t len) {
|
|
|
|
stream_.WriteBytes(addr, len);
|
|
|
|
}
|
|
|
|
|
2011-10-05 05:20:07 +00:00
|
|
|
// Finalize the serialized buffer by filling in the header information
|
2011-12-21 19:37:37 +00:00
|
|
|
// which comprises of a flag(snaphot kind) and the length of
|
2011-10-05 05:20:07 +00:00
|
|
|
// serialzed bytes.
|
2011-12-21 19:37:37 +00:00
|
|
|
void FinalizeBuffer(Snapshot::Kind kind) {
|
2011-10-05 05:20:07 +00:00
|
|
|
int32_t* data = reinterpret_cast<int32_t*>(stream_.buffer());
|
|
|
|
data[Snapshot::kLengthIndex] = stream_.bytes_written();
|
2011-12-21 19:37:37 +00:00
|
|
|
data[Snapshot::kSnapshotFlagIndex] = kind;
|
|
|
|
}
|
|
|
|
|
|
|
|
protected:
|
|
|
|
BaseWriter(uint8_t** buffer, ReAlloc alloc) : stream_(buffer, alloc) {
|
|
|
|
ASSERT(buffer != NULL);
|
|
|
|
ASSERT(alloc != NULL);
|
2012-06-22 20:37:01 +00:00
|
|
|
// Make room for recording snapshot buffer size.
|
|
|
|
stream_.set_current(*buffer + Snapshot::kHeaderSize);
|
2011-10-05 05:20:07 +00:00
|
|
|
}
|
2011-12-21 19:37:37 +00:00
|
|
|
~BaseWriter() { }
|
2011-10-05 05:20:07 +00:00
|
|
|
|
2011-12-21 19:37:37 +00:00
|
|
|
private:
|
2011-10-05 05:20:07 +00:00
|
|
|
WriteStream stream_;
|
|
|
|
|
2011-12-21 19:37:37 +00:00
|
|
|
DISALLOW_IMPLICIT_CONSTRUCTORS(BaseWriter);
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
class SnapshotWriter : public BaseWriter {
|
2011-10-05 05:20:07 +00:00
|
|
|
public:
|
2011-12-06 00:34:49 +00:00
|
|
|
SnapshotWriter(Snapshot::Kind kind, uint8_t** buffer, ReAlloc alloc)
|
2011-12-21 19:37:37 +00:00
|
|
|
: BaseWriter(buffer, alloc),
|
2011-12-06 00:34:49 +00:00
|
|
|
kind_(kind),
|
2011-10-05 05:20:07 +00:00
|
|
|
object_store_(Isolate::Current()->object_store()),
|
2012-05-30 11:42:55 +00:00
|
|
|
class_table_(Isolate::Current()->class_table()),
|
2011-10-05 05:20:07 +00:00
|
|
|
forward_list_() {
|
|
|
|
}
|
|
|
|
~SnapshotWriter() { }
|
|
|
|
|
2011-12-20 02:04:24 +00:00
|
|
|
// Snapshot kind.
|
|
|
|
Snapshot::Kind kind() const { return kind_; }
|
|
|
|
|
2011-10-05 05:20:07 +00:00
|
|
|
// Finalize the serialized buffer by filling in the header information
|
|
|
|
// which comprises of a flag(full/partial snaphot) and the length of
|
|
|
|
// serialzed bytes.
|
|
|
|
void FinalizeBuffer() {
|
2011-12-21 19:37:37 +00:00
|
|
|
BaseWriter::FinalizeBuffer(kind_);
|
2011-10-05 05:20:07 +00:00
|
|
|
UnmarkAll();
|
|
|
|
}
|
|
|
|
|
|
|
|
// Serialize an object into the buffer.
|
|
|
|
void WriteObject(RawObject* raw);
|
|
|
|
|
|
|
|
// Writes a full snapshot of the Isolate.
|
|
|
|
void WriteFullSnapshot();
|
|
|
|
|
2012-05-30 11:42:55 +00:00
|
|
|
uword GetObjectTags(RawObject* raw);
|
|
|
|
|
2011-10-05 05:20:07 +00:00
|
|
|
private:
|
|
|
|
class ForwardObjectNode : public ZoneAllocated {
|
|
|
|
public:
|
2012-06-11 21:39:05 +00:00
|
|
|
ForwardObjectNode(RawObject* raw, uword tags, SerializeState state)
|
|
|
|
: raw_(raw), tags_(tags), state_(state) {}
|
2011-10-05 05:20:07 +00:00
|
|
|
RawObject* raw() const { return raw_; }
|
2012-05-30 11:42:55 +00:00
|
|
|
uword tags() const { return tags_; }
|
2012-06-11 21:39:05 +00:00
|
|
|
bool is_serialized() const { return state_ == kIsSerialized; }
|
|
|
|
void set_state(SerializeState value) { state_ = value; }
|
2011-10-05 05:20:07 +00:00
|
|
|
|
|
|
|
private:
|
|
|
|
RawObject* raw_;
|
2012-05-30 11:42:55 +00:00
|
|
|
uword tags_;
|
2012-06-11 21:39:05 +00:00
|
|
|
SerializeState state_;
|
2011-10-05 05:20:07 +00:00
|
|
|
|
|
|
|
DISALLOW_COPY_AND_ASSIGN(ForwardObjectNode);
|
|
|
|
};
|
|
|
|
|
2012-06-11 21:39:05 +00:00
|
|
|
intptr_t MarkObject(RawObject* raw, SerializeState state);
|
|
|
|
void UnmarkAll();
|
2012-06-01 00:15:30 +00:00
|
|
|
|
|
|
|
bool CheckAndWritePredefinedObject(RawObject* raw);
|
2012-08-06 21:56:39 +00:00
|
|
|
void HandleVMIsolateObject(RawObject* raw);
|
2011-10-05 05:20:07 +00:00
|
|
|
|
2012-06-11 21:39:05 +00:00
|
|
|
void WriteObjectRef(RawObject* raw);
|
|
|
|
void WriteClassId(RawClass* cls);
|
|
|
|
void WriteObjectImpl(RawObject* raw);
|
2011-10-05 05:20:07 +00:00
|
|
|
void WriteInlinedObject(RawObject* raw);
|
2012-06-11 21:39:05 +00:00
|
|
|
void WriteForwardedObjects();
|
|
|
|
void ArrayWriteTo(intptr_t object_id,
|
|
|
|
intptr_t array_kind,
|
|
|
|
intptr_t tags,
|
|
|
|
RawSmi* length,
|
|
|
|
RawAbstractTypeArguments* type_arguments,
|
|
|
|
RawObject* data[]);
|
2011-10-05 05:20:07 +00:00
|
|
|
|
|
|
|
ObjectStore* object_store() const { return object_store_; }
|
|
|
|
|
2011-12-06 00:34:49 +00:00
|
|
|
Snapshot::Kind kind_;
|
2011-10-05 05:20:07 +00:00
|
|
|
ObjectStore* object_store_; // Object store for common classes.
|
2012-05-30 11:42:55 +00:00
|
|
|
ClassTable* class_table_; // Class table for the class index to class lookup.
|
2011-10-05 05:20:07 +00:00
|
|
|
GrowableArray<ForwardObjectNode*> forward_list_;
|
|
|
|
|
2012-06-11 21:39:05 +00:00
|
|
|
friend class RawArray;
|
|
|
|
friend class RawClass;
|
|
|
|
friend class RawGrowableObjectArray;
|
|
|
|
friend class RawImmutableArray;
|
|
|
|
friend class RawJSRegExp;
|
|
|
|
friend class RawLibrary;
|
|
|
|
friend class RawLiteralToken;
|
|
|
|
friend class RawScript;
|
|
|
|
friend class RawTokenStream;
|
|
|
|
friend class RawTypeArguments;
|
|
|
|
friend class SnapshotWriterVisitor;
|
2011-10-05 05:20:07 +00:00
|
|
|
DISALLOW_COPY_AND_ASSIGN(SnapshotWriter);
|
|
|
|
};
|
|
|
|
|
|
|
|
|
2011-12-06 00:34:49 +00:00
|
|
|
class ScriptSnapshotWriter : public SnapshotWriter {
|
|
|
|
public:
|
2011-12-20 02:04:24 +00:00
|
|
|
ScriptSnapshotWriter(uint8_t** buffer, ReAlloc alloc)
|
2011-12-06 00:34:49 +00:00
|
|
|
: SnapshotWriter(Snapshot::kScript, buffer, alloc) {
|
|
|
|
ASSERT(buffer != NULL);
|
|
|
|
ASSERT(alloc != NULL);
|
|
|
|
}
|
|
|
|
~ScriptSnapshotWriter() { }
|
|
|
|
|
|
|
|
// Writes a partial snapshot of the script.
|
2011-12-20 02:04:24 +00:00
|
|
|
void WriteScriptSnapshot(const Library& lib);
|
2011-12-06 00:34:49 +00:00
|
|
|
|
|
|
|
private:
|
|
|
|
DISALLOW_COPY_AND_ASSIGN(ScriptSnapshotWriter);
|
|
|
|
};
|
|
|
|
|
|
|
|
|
2011-10-05 05:20:07 +00:00
|
|
|
// An object pointer visitor implementation which writes out
|
|
|
|
// objects to a snap shot.
|
|
|
|
class SnapshotWriterVisitor : public ObjectPointerVisitor {
|
|
|
|
public:
|
2012-06-06 14:47:17 +00:00
|
|
|
explicit SnapshotWriterVisitor(SnapshotWriter* writer)
|
2012-06-11 21:39:05 +00:00
|
|
|
: ObjectPointerVisitor(Isolate::Current()),
|
|
|
|
writer_(writer),
|
|
|
|
as_references_(true) {}
|
|
|
|
|
|
|
|
SnapshotWriterVisitor(SnapshotWriter* writer, bool as_references)
|
|
|
|
: ObjectPointerVisitor(Isolate::Current()),
|
|
|
|
writer_(writer),
|
|
|
|
as_references_(as_references) {}
|
2011-10-05 05:20:07 +00:00
|
|
|
|
|
|
|
virtual void VisitPointers(RawObject** first, RawObject** last);
|
|
|
|
|
|
|
|
private:
|
|
|
|
SnapshotWriter* writer_;
|
2012-06-11 21:39:05 +00:00
|
|
|
bool as_references_;
|
2011-10-05 05:20:07 +00:00
|
|
|
|
|
|
|
DISALLOW_COPY_AND_ASSIGN(SnapshotWriterVisitor);
|
|
|
|
};
|
|
|
|
|
|
|
|
} // namespace dart
|
|
|
|
|
|
|
|
#endif // VM_SNAPSHOT_H_
|