Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
app_snapshot.h
Go to the documentation of this file.
1// Copyright (c) 2016, 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_APP_SNAPSHOT_H_
6#define RUNTIME_VM_APP_SNAPSHOT_H_
7
8#include "platform/assert.h"
9#include "vm/allocation.h"
10#include "vm/bitfield.h"
11#include "vm/datastream.h"
12#include "vm/globals.h"
13#include "vm/growable_array.h"
14#include "vm/hash_map.h"
15#include "vm/object.h"
16#include "vm/snapshot.h"
17
18namespace dart {
19
20// For full snapshots, we use a clustered snapshot format that trades longer
21// serialization time for faster deserialization time and smaller snapshots.
22// Objects are clustered by class to allow writing type information once per
23// class instead once per object, and to allow filling the objects in a tight
24// loop. The snapshot has two major sections: the first describes how to
25// allocate the objects and the second describes how to initialize them.
26// Deserialization starts by allocating a reference array large enough to hold
27// the base objects (objects already available to both the serializer and
28// deserializer) and the objects written in the snapshot. The allocation section
29// is then read for each cluster, filling the reference array. Then the
30// initialization/fill secton is read for each cluster, using the indices into
31// the reference array to fill pointers. At this point, every object has been
32// touched exactly once and in order, making this approach very cache friendly.
33// Finally, each cluster is given an opportunity to perform some fix-ups that
34// require the graph has been fully loaded, such as rehashing, though most
35// clusters do not require fixups.
36
37// Forward declarations.
38class V8SnapshotProfileWriter;
39class ImageWriter;
40class Heap;
41
43 public:
46 : id_(id), parent_(parent), deferred_objects_(), objects_(nullptr) {}
47
48 intptr_t id() const { return id_; }
49 LoadingUnitSerializationData* parent() const { return parent_; }
50 void AddDeferredObject(CodePtr obj) {
51 deferred_objects_.Add(&Code::ZoneHandle(obj));
52 }
53 GrowableArray<Code*>* deferred_objects() { return &deferred_objects_; }
55 ASSERT(objects_ != nullptr);
56 return objects_;
57 }
59 ASSERT(objects_ == nullptr);
60 objects_ = objects;
61 }
62
63 private:
64 intptr_t id_;
66 GrowableArray<Code*> deferred_objects_;
68};
69
70// This class can be used to read version and features from a snapshot before
71// the VM has been initialized.
73 public:
74 static char* InitializeGlobalVMFlagsFromSnapshot(const Snapshot* snapshot);
75
76 explicit SnapshotHeaderReader(const Snapshot* snapshot)
77 : SnapshotHeaderReader(snapshot->kind(),
78 snapshot->Addr(),
79 snapshot->length()) {}
80
82 const uint8_t* buffer,
83 intptr_t size)
84 : kind_(kind), stream_(buffer, size) {
86 }
87
88 // Verifies the version and features in the snapshot are compatible with the
89 // current VM. If isolate is non-null it validates isolate-specific features.
90 //
91 // Returns null on success and a malloc()ed error on failure.
92 // The [offset] will be the next position in the snapshot stream after the
93 // features.
94 char* VerifyVersionAndFeatures(IsolateGroup* isolate_group, intptr_t* offset);
95
96 private:
97 char* VerifyVersion();
98 char* ReadFeatures(const char** features, intptr_t* features_length);
99 char* VerifyFeatures(IsolateGroup* isolate_group);
100 char* BuildError(const char* message);
101
102 Snapshot::Kind kind_;
103 ReadStream stream_;
104};
105
107 public:
108 static constexpr intptr_t kInitialSize = 64 * KB;
110 NonStreamingWriteStream* vm_snapshot_data,
111 NonStreamingWriteStream* isolate_snapshot_data,
112 ImageWriter* vm_image_writer,
113 ImageWriter* iso_image_writer);
115
116 // Writes a full snapshot of the program(VM isolate, regular isolate group).
121 uint32_t program_hash);
122
123 intptr_t VmIsolateSnapshotSize() const { return vm_isolate_snapshot_size_; }
124 intptr_t IsolateSnapshotSize() const { return isolate_snapshot_size_; }
125
126 private:
127 Thread* thread() const { return thread_; }
128 Zone* zone() const { return thread_->zone(); }
129 IsolateGroup* isolate_group() const { return thread_->isolate_group(); }
130 Heap* heap() const { return isolate_group()->heap(); }
131
132 // Writes a snapshot of the VM Isolate.
133 ZoneGrowableArray<Object*>* WriteVMSnapshot();
134
135 // Writes a full snapshot of regular Dart isolate group.
136 void WriteProgramSnapshot(ZoneGrowableArray<Object*>* objects,
137 GrowableArray<LoadingUnitSerializationData*>* data);
138
139 Thread* thread_;
140 Snapshot::Kind kind_;
141 NonStreamingWriteStream* const vm_snapshot_data_;
142 NonStreamingWriteStream* const isolate_snapshot_data_;
143 intptr_t vm_isolate_snapshot_size_;
144 intptr_t isolate_snapshot_size_;
145 ImageWriter* vm_image_writer_;
146 ImageWriter* isolate_image_writer_;
147
148 // Stats for benchmarking.
149 intptr_t clustered_vm_size_ = 0;
150 intptr_t clustered_isolate_size_ = 0;
151 intptr_t mapped_data_size_ = 0;
152 intptr_t mapped_text_size_ = 0;
153 intptr_t heap_vm_size_ = 0;
154 intptr_t heap_isolate_size_ = 0;
155
156 V8SnapshotProfileWriter* profile_writer_ = nullptr;
157
158 DISALLOW_COPY_AND_ASSIGN(FullSnapshotWriter);
159};
160
162 public:
163 FullSnapshotReader(const Snapshot* snapshot,
164 const uint8_t* instructions_buffer,
165 Thread* thread);
167
168 ApiErrorPtr ReadVMSnapshot();
169 ApiErrorPtr ReadProgramSnapshot();
170 ApiErrorPtr ReadUnitSnapshot(const LoadingUnit& unit);
171
172 private:
173 IsolateGroup* isolate_group() const { return thread_->isolate_group(); }
174
175 ApiErrorPtr ConvertToApiError(char* message);
176 void InitializeBSS();
177
178 Snapshot::Kind kind_;
179 Thread* thread_;
180 const uint8_t* buffer_;
181 intptr_t size_;
182 const uint8_t* data_image_;
183 const uint8_t* instructions_image_;
184
185 DISALLOW_COPY_AND_ASSIGN(FullSnapshotReader);
186};
187
188} // namespace dart
189
190#endif // RUNTIME_VM_APP_SNAPSHOT_H_
ApiErrorPtr ReadUnitSnapshot(const LoadingUnit &unit)
ApiErrorPtr ReadProgramSnapshot()
intptr_t VmIsolateSnapshotSize() const
void WriteFullSnapshot(GrowableArray< LoadingUnitSerializationData * > *data=nullptr)
intptr_t IsolateSnapshotSize() const
void WriteUnitSnapshot(GrowableArray< LoadingUnitSerializationData * > *units, LoadingUnitSerializationData *unit, uint32_t program_hash)
static constexpr intptr_t kInitialSize
Heap * heap() const
Definition isolate.h:295
void set_objects(ZoneGrowableArray< Object * > *objects)
ZoneGrowableArray< Object * > * objects()
LoadingUnitSerializationData * parent() const
GrowableArray< Code * > * deferred_objects()
LoadingUnitSerializationData(intptr_t id, LoadingUnitSerializationData *parent)
static Object & ZoneHandle()
Definition object.h:419
void SetPosition(intptr_t value)
Definition datastream.h:128
SnapshotHeaderReader(Snapshot::Kind kind, const uint8_t *buffer, intptr_t size)
SnapshotHeaderReader(const Snapshot *snapshot)
char * VerifyVersionAndFeatures(IsolateGroup *isolate_group, intptr_t *offset)
static char * InitializeGlobalVMFlagsFromSnapshot(const Snapshot *snapshot)
static constexpr intptr_t kHeaderSize
Definition snapshot.h:43
Zone * zone() const
IsolateGroup * isolate_group() const
Definition thread.h:540
#define ASSERT(E)
static const uint8_t buffer[]
size_t length
Win32Message message
constexpr intptr_t KB
Definition globals.h:528
static int8_t data[kExtLength]
#define DISALLOW_COPY_AND_ASSIGN(TypeName)
Definition globals.h:581
Point offset