| 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 |