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" |
| 11 #include "vm/datastream.h" |
11 #include "vm/globals.h" | 12 #include "vm/globals.h" |
12 #include "vm/growable_array.h" | 13 #include "vm/growable_array.h" |
13 #include "vm/isolate.h" | 14 #include "vm/isolate.h" |
14 #include "vm/visitor.h" | 15 #include "vm/visitor.h" |
15 | 16 |
16 namespace dart { | 17 namespace dart { |
17 | 18 |
18 // Forward declarations. | 19 // Forward declarations. |
19 class AbstractType; | 20 class AbstractType; |
20 class AbstractTypeArguments; | 21 class AbstractTypeArguments; |
(...skipping 23 matching lines...) Expand all Loading... |
44 class RawScript; | 45 class RawScript; |
45 class RawSmi; | 46 class RawSmi; |
46 class RawTokenStream; | 47 class RawTokenStream; |
47 class RawType; | 48 class RawType; |
48 class RawTypeParameter; | 49 class RawTypeParameter; |
49 class RawTypeArguments; | 50 class RawTypeArguments; |
50 class RawTwoByteString; | 51 class RawTwoByteString; |
51 class RawUnresolvedClass; | 52 class RawUnresolvedClass; |
52 class String; | 53 class String; |
53 | 54 |
54 static const int8_t kSerializedBitsPerByte = 7; | |
55 static const int8_t kMaxSerializedUnsignedValuePerByte = 127; | |
56 static const int8_t kMaxSerializedValuePerByte = 63; | |
57 static const int8_t kMinSerializedValuePerByte = -64; | |
58 static const uint8_t kEndByteMarker = (255 - kMaxSerializedValuePerByte); | |
59 static const int8_t kSerializedByteMask = (1 << kSerializedBitsPerByte) - 1; | |
60 | |
61 // Serialized object header encoding is as follows: | 55 // Serialized object header encoding is as follows: |
62 // - Smi: the Smi value is written as is (last bit is not tagged). | 56 // - Smi: the Smi value is written as is (last bit is not tagged). |
63 // - VM internal type (from VM isolate): (index of type in vm isolate | 0x3) | 57 // - VM internal type (from VM isolate): (index of type in vm isolate | 0x3) |
64 // - Object that has already been written: (negative id in stream | 0x3) | 58 // - Object that has already been written: (negative id in stream | 0x3) |
65 // - Object that is seen for the first time (inlined in the stream): | 59 // - Object that is seen for the first time (inlined in the stream): |
66 // (a unique id for this object | 0x1) | 60 // (a unique id for this object | 0x1) |
67 enum SerializedHeaderType { | 61 enum SerializedHeaderType { |
68 kInlined = 0x1, | 62 kInlined = 0x1, |
69 kObjectId = 0x3, | 63 kObjectId = 0x3, |
70 }; | 64 }; |
71 static const int8_t kHeaderTagBits = 2; | 65 static const int8_t kHeaderTagBits = 2; |
72 static const int8_t kObjectIdTagBits = (kBitsPerWord - kHeaderTagBits); | 66 static const int8_t kObjectIdTagBits = (kBitsPerWord - kHeaderTagBits); |
73 static const intptr_t kMaxObjectId = (kIntptrMax >> kHeaderTagBits); | 67 static const intptr_t kMaxObjectId = (kIntptrMax >> kHeaderTagBits); |
74 | 68 |
75 typedef uint8_t* (*ReAlloc)(uint8_t* ptr, intptr_t old_size, intptr_t new_size); | |
76 | |
77 class SerializedHeaderTag : public BitField<enum SerializedHeaderType, | 69 class SerializedHeaderTag : public BitField<enum SerializedHeaderType, |
78 0, | 70 0, |
79 kHeaderTagBits> { | 71 kHeaderTagBits> { |
80 }; | 72 }; |
81 | 73 |
82 | 74 |
83 class SerializedHeaderData : public BitField<intptr_t, | 75 class SerializedHeaderData : public BitField<intptr_t, |
84 kHeaderTagBits, | 76 kHeaderTagBits, |
85 kObjectIdTagBits> { | 77 kObjectIdTagBits> { |
86 }; | 78 }; |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
133 Snapshot() : length_(0), kind_(kFull) {} | 125 Snapshot() : length_(0), kind_(kFull) {} |
134 | 126 |
135 int32_t length_; // Stream length. | 127 int32_t length_; // Stream length. |
136 int32_t kind_; // Kind of snapshot. | 128 int32_t kind_; // Kind of snapshot. |
137 uint8_t content_[]; // Stream content. | 129 uint8_t content_[]; // Stream content. |
138 | 130 |
139 DISALLOW_COPY_AND_ASSIGN(Snapshot); | 131 DISALLOW_COPY_AND_ASSIGN(Snapshot); |
140 }; | 132 }; |
141 | 133 |
142 | 134 |
143 // Stream for reading various types from a buffer. | |
144 class ReadStream : public ValueObject { | |
145 public: | |
146 ReadStream(const uint8_t* buffer, intptr_t size) : buffer_(buffer), | |
147 current_(buffer), | |
148 end_(buffer + size) {} | |
149 | |
150 private: | |
151 template<typename T> | |
152 T Read() { | |
153 uint8_t b = ReadByte(); | |
154 if (b > kMaxSerializedUnsignedValuePerByte) { | |
155 return static_cast<T>(b) - kEndByteMarker; | |
156 } | |
157 T r = 0; | |
158 uint8_t s = 0; | |
159 do { | |
160 r |= static_cast<T>(b) << s; | |
161 s += kSerializedBitsPerByte; | |
162 b = ReadByte(); | |
163 } while (b <= kMaxSerializedUnsignedValuePerByte); | |
164 return r | ((static_cast<T>(b) - kEndByteMarker) << s); | |
165 } | |
166 | |
167 template<int N, typename T> | |
168 class Raw { }; | |
169 | |
170 template<typename T> | |
171 class Raw<1, T> { | |
172 public: | |
173 static T Read(ReadStream* st) { | |
174 return bit_cast<T>(st->ReadByte()); | |
175 } | |
176 }; | |
177 | |
178 template<typename T> | |
179 class Raw<2, T> { | |
180 public: | |
181 static T Read(ReadStream* st) { | |
182 return bit_cast<T>(st->Read<int16_t>()); | |
183 } | |
184 }; | |
185 | |
186 template<typename T> | |
187 class Raw<4, T> { | |
188 public: | |
189 static T Read(ReadStream* st) { | |
190 return bit_cast<T>(st->Read<int32_t>()); | |
191 } | |
192 }; | |
193 | |
194 template<typename T> | |
195 class Raw<8, T> { | |
196 public: | |
197 static T Read(ReadStream* st) { | |
198 return bit_cast<T>(st->Read<int64_t>()); | |
199 } | |
200 }; | |
201 | |
202 uint8_t ReadByte() { | |
203 ASSERT(current_ < end_); | |
204 return *current_++; | |
205 } | |
206 | |
207 void ReadBytes(uint8_t* addr, intptr_t len) { | |
208 ASSERT((current_ + len) < end_); | |
209 memmove(addr, current_, len); | |
210 current_ += len; | |
211 } | |
212 | |
213 private: | |
214 const uint8_t* buffer_; | |
215 const uint8_t* current_; | |
216 const uint8_t* end_; | |
217 | |
218 // SnapshotReader needs access to the private Raw classes. | |
219 friend class SnapshotReader; | |
220 friend class BaseReader; | |
221 DISALLOW_COPY_AND_ASSIGN(ReadStream); | |
222 }; | |
223 | |
224 | |
225 // Stream for writing various types into a buffer. | |
226 class WriteStream : public ValueObject { | |
227 public: | |
228 static const int kBufferIncrementSize = 64 * KB; | |
229 | |
230 WriteStream(uint8_t** buffer, ReAlloc alloc) : | |
231 buffer_(buffer), | |
232 end_(NULL), | |
233 current_(NULL), | |
234 current_size_(0), | |
235 alloc_(alloc) { | |
236 ASSERT(buffer != NULL); | |
237 ASSERT(alloc != NULL); | |
238 *buffer_ = reinterpret_cast<uint8_t*>(alloc_(NULL, | |
239 0, | |
240 kBufferIncrementSize)); | |
241 ASSERT(*buffer_ != NULL); | |
242 current_ = *buffer_ + Snapshot::kHeaderSize; | |
243 current_size_ = kBufferIncrementSize; | |
244 end_ = *buffer_ + kBufferIncrementSize; | |
245 } | |
246 | |
247 uint8_t* buffer() const { return *buffer_; } | |
248 int bytes_written() const { return current_ - *buffer_; } | |
249 | |
250 private: | |
251 template<typename T> | |
252 void Write(T value) { | |
253 T v = value; | |
254 while (v < kMinSerializedValuePerByte || | |
255 v > kMaxSerializedValuePerByte) { | |
256 WriteByte(static_cast<uint8_t>(v & kSerializedByteMask)); | |
257 v = v >> kSerializedBitsPerByte; | |
258 } | |
259 WriteByte(static_cast<uint8_t>(v + kEndByteMarker)); | |
260 } | |
261 | |
262 template<int N, typename T> | |
263 class Raw { }; | |
264 | |
265 template<typename T> | |
266 class Raw<1, T> { | |
267 public: | |
268 static void Write(WriteStream* st, T value) { | |
269 st->WriteByte(bit_cast<int8_t>(value)); | |
270 } | |
271 }; | |
272 | |
273 template<typename T> | |
274 class Raw<2, T> { | |
275 public: | |
276 static void Write(WriteStream* st, T value) { | |
277 st->Write<int16_t>(bit_cast<int16_t>(value)); | |
278 } | |
279 }; | |
280 | |
281 template<typename T> | |
282 class Raw<4, T> { | |
283 public: | |
284 static void Write(WriteStream* st, T value) { | |
285 st->Write<int32_t>(bit_cast<int32_t>(value)); | |
286 } | |
287 }; | |
288 | |
289 template<typename T> | |
290 class Raw<8, T> { | |
291 public: | |
292 static void Write(WriteStream* st, T value) { | |
293 st->Write<int64_t>(bit_cast<int64_t>(value)); | |
294 } | |
295 }; | |
296 | |
297 void WriteByte(uint8_t value) { | |
298 if (current_ >= end_) { | |
299 intptr_t new_size = (current_size_ + kBufferIncrementSize); | |
300 *buffer_ = reinterpret_cast<uint8_t*>(alloc_(*buffer_, | |
301 current_size_, | |
302 new_size)); | |
303 ASSERT(*buffer_ != NULL); | |
304 current_ = *buffer_ + current_size_; | |
305 current_size_ = new_size; | |
306 end_ = *buffer_ + new_size; | |
307 } | |
308 ASSERT(current_ < end_); | |
309 *current_++ = value; | |
310 } | |
311 | |
312 private: | |
313 uint8_t** const buffer_; | |
314 uint8_t* end_; | |
315 uint8_t* current_; | |
316 intptr_t current_size_; | |
317 ReAlloc alloc_; | |
318 | |
319 // MessageWriter and SnapshotWriter needs access to the private Raw | |
320 // classes. | |
321 friend class BaseWriter; | |
322 DISALLOW_COPY_AND_ASSIGN(WriteStream); | |
323 }; | |
324 | |
325 | |
326 class BaseReader { | 135 class BaseReader { |
327 public: | 136 public: |
328 BaseReader(const uint8_t* buffer, intptr_t size) : stream_(buffer, size) {} | 137 BaseReader(const uint8_t* buffer, intptr_t size) : stream_(buffer, size) {} |
329 // Reads raw data (for basic types). | 138 // Reads raw data (for basic types). |
330 // sizeof(T) must be in {1,2,4,8}. | 139 // sizeof(T) must be in {1,2,4,8}. |
331 template <typename T> | 140 template <typename T> |
332 T Read() { | 141 T Read() { |
333 return ReadStream::Raw<sizeof(T), T>::Read(&stream_); | 142 return ReadStream::Raw<sizeof(T), T>::Read(&stream_); |
334 } | 143 } |
335 | 144 |
(...skipping 183 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
519 void FinalizeBuffer(Snapshot::Kind kind) { | 328 void FinalizeBuffer(Snapshot::Kind kind) { |
520 int32_t* data = reinterpret_cast<int32_t*>(stream_.buffer()); | 329 int32_t* data = reinterpret_cast<int32_t*>(stream_.buffer()); |
521 data[Snapshot::kLengthIndex] = stream_.bytes_written(); | 330 data[Snapshot::kLengthIndex] = stream_.bytes_written(); |
522 data[Snapshot::kSnapshotFlagIndex] = kind; | 331 data[Snapshot::kSnapshotFlagIndex] = kind; |
523 } | 332 } |
524 | 333 |
525 protected: | 334 protected: |
526 BaseWriter(uint8_t** buffer, ReAlloc alloc) : stream_(buffer, alloc) { | 335 BaseWriter(uint8_t** buffer, ReAlloc alloc) : stream_(buffer, alloc) { |
527 ASSERT(buffer != NULL); | 336 ASSERT(buffer != NULL); |
528 ASSERT(alloc != NULL); | 337 ASSERT(alloc != NULL); |
| 338 // Make room for recording snapshot buffer size. |
| 339 stream_.set_current(*buffer + Snapshot::kHeaderSize); |
529 } | 340 } |
530 ~BaseWriter() { } | 341 ~BaseWriter() { } |
531 | 342 |
532 private: | 343 private: |
533 WriteStream stream_; | 344 WriteStream stream_; |
534 | 345 |
535 DISALLOW_IMPLICIT_CONSTRUCTORS(BaseWriter); | 346 DISALLOW_IMPLICIT_CONSTRUCTORS(BaseWriter); |
536 }; | 347 }; |
537 | 348 |
538 | 349 |
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
659 private: | 470 private: |
660 SnapshotWriter* writer_; | 471 SnapshotWriter* writer_; |
661 bool as_references_; | 472 bool as_references_; |
662 | 473 |
663 DISALLOW_COPY_AND_ASSIGN(SnapshotWriterVisitor); | 474 DISALLOW_COPY_AND_ASSIGN(SnapshotWriterVisitor); |
664 }; | 475 }; |
665 | 476 |
666 } // namespace dart | 477 } // namespace dart |
667 | 478 |
668 #endif // VM_SNAPSHOT_H_ | 479 #endif // VM_SNAPSHOT_H_ |
OLD | NEW |