| 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 RUNTIME_VM_DATASTREAM_H_ | 5 #ifndef RUNTIME_VM_DATASTREAM_H_ |
| 6 #define RUNTIME_VM_DATASTREAM_H_ | 6 #define RUNTIME_VM_DATASTREAM_H_ |
| 7 | 7 |
| 8 #include "platform/assert.h" | 8 #include "platform/assert.h" |
| 9 #include "platform/utils.h" | 9 #include "platform/utils.h" |
| 10 #include "vm/allocation.h" | 10 #include "vm/allocation.h" |
| 11 #include "vm/exceptions.h" | 11 #include "vm/exceptions.h" |
| 12 #include "vm/globals.h" | 12 #include "vm/globals.h" |
| 13 #include "vm/os.h" | 13 #include "vm/os.h" |
| 14 | 14 |
| 15 namespace dart { | 15 namespace dart { |
| 16 | 16 |
| 17 static const int8_t kDataBitsPerByte = 7; | 17 static const int8_t kDataBitsPerByte = 7; |
| 18 static const int8_t kByteMask = (1 << kDataBitsPerByte) - 1; | 18 static const int8_t kByteMask = (1 << kDataBitsPerByte) - 1; |
| 19 static const int8_t kMaxUnsignedDataPerByte = kByteMask; | 19 static const int8_t kMaxUnsignedDataPerByte = kByteMask; |
| 20 static const int8_t kMinDataPerByte = -(1 << (kDataBitsPerByte - 1)); | 20 static const int8_t kMinDataPerByte = -(1 << (kDataBitsPerByte - 1)); |
| 21 static const int8_t kMaxDataPerByte = (~kMinDataPerByte & kByteMask); // NOLINT | 21 static const int8_t kMaxDataPerByte = (~kMinDataPerByte & kByteMask); // NOLINT |
| 22 static const uint8_t kEndByteMarker = (255 - kMaxDataPerByte); | 22 static const uint8_t kEndByteMarker = (255 - kMaxDataPerByte); |
| 23 static const uint8_t kEndUnsignedByteMarker = (255 - kMaxUnsignedDataPerByte); | 23 static const uint8_t kEndUnsignedByteMarker = (255 - kMaxUnsignedDataPerByte); |
| 24 | 24 |
| 25 typedef uint8_t* (*ReAlloc)(uint8_t* ptr, intptr_t old_size, intptr_t new_size); | 25 typedef uint8_t* (*ReAlloc)(uint8_t* ptr, intptr_t old_size, intptr_t new_size); |
| 26 | 26 |
| 27 // Stream for reading various types from a buffer. | 27 // Stream for reading various types from a buffer. |
| 28 class ReadStream : public ValueObject { | 28 class ReadStream : public ValueObject { |
| 29 public: | 29 public: |
| 30 ReadStream(const uint8_t* buffer, intptr_t size) : buffer_(buffer), | 30 ReadStream(const uint8_t* buffer, intptr_t size) |
| 31 current_(buffer), | 31 : buffer_(buffer), current_(buffer), end_(buffer + size) {} |
| 32 end_(buffer + size) {} | |
| 33 | 32 |
| 34 void SetStream(const uint8_t* buffer, intptr_t size) { | 33 void SetStream(const uint8_t* buffer, intptr_t size) { |
| 35 buffer_ = buffer; | 34 buffer_ = buffer; |
| 36 current_ = buffer; | 35 current_ = buffer; |
| 37 end_ = buffer + size; | 36 end_ = buffer + size; |
| 38 } | 37 } |
| 39 | 38 |
| 40 template<int N, typename T> | 39 template <int N, typename T> |
| 41 class Raw { }; | 40 class Raw {}; |
| 42 | 41 |
| 43 template<typename T> | 42 template <typename T> |
| 44 class Raw<1, T> { | 43 class Raw<1, T> { |
| 45 public: | 44 public: |
| 46 static T Read(ReadStream* st) { | 45 static T Read(ReadStream* st) { return bit_cast<T>(st->ReadByte()); } |
| 47 return bit_cast<T>(st->ReadByte()); | |
| 48 } | |
| 49 }; | 46 }; |
| 50 | 47 |
| 51 template<typename T> | 48 template <typename T> |
| 52 class Raw<2, T> { | 49 class Raw<2, T> { |
| 53 public: | 50 public: |
| 54 static T Read(ReadStream* st) { | 51 static T Read(ReadStream* st) { return bit_cast<T>(st->Read16()); } |
| 55 return bit_cast<T>(st->Read16()); | |
| 56 } | |
| 57 }; | 52 }; |
| 58 | 53 |
| 59 template<typename T> | 54 template <typename T> |
| 60 class Raw<4, T> { | 55 class Raw<4, T> { |
| 61 public: | 56 public: |
| 62 static T Read(ReadStream* st) { | 57 static T Read(ReadStream* st) { return bit_cast<T>(st->Read32()); } |
| 63 return bit_cast<T>(st->Read32()); | |
| 64 } | |
| 65 }; | 58 }; |
| 66 | 59 |
| 67 template<typename T> | 60 template <typename T> |
| 68 class Raw<8, T> { | 61 class Raw<8, T> { |
| 69 public: | 62 public: |
| 70 static T Read(ReadStream* st) { | 63 static T Read(ReadStream* st) { return bit_cast<T>(st->Read64()); } |
| 71 return bit_cast<T>(st->Read64()); | |
| 72 } | |
| 73 }; | 64 }; |
| 74 | 65 |
| 75 // Reads 'len' bytes from the stream. | 66 // Reads 'len' bytes from the stream. |
| 76 void ReadBytes(uint8_t* addr, intptr_t len) { | 67 void ReadBytes(uint8_t* addr, intptr_t len) { |
| 77 ASSERT((end_ - current_) >= len); | 68 ASSERT((end_ - current_) >= len); |
| 78 memmove(addr, current_, len); | 69 memmove(addr, current_, len); |
| 79 current_ += len; | 70 current_ += len; |
| 80 } | 71 } |
| 81 | 72 |
| 82 intptr_t ReadUnsigned() { | 73 intptr_t ReadUnsigned() { return Read<intptr_t>(kEndUnsignedByteMarker); } |
| 83 return Read<intptr_t>(kEndUnsignedByteMarker); | |
| 84 } | |
| 85 | 74 |
| 86 intptr_t Position() const { return current_ - buffer_; } | 75 intptr_t Position() const { return current_ - buffer_; } |
| 87 | 76 |
| 88 void SetPosition(intptr_t value) { | 77 void SetPosition(intptr_t value) { |
| 89 ASSERT((end_ - buffer_) > value); | 78 ASSERT((end_ - buffer_) > value); |
| 90 current_ = buffer_ + value; | 79 current_ = buffer_ + value; |
| 91 } | 80 } |
| 92 | 81 |
| 93 const uint8_t* AddressOfCurrentPosition() const { | 82 const uint8_t* AddressOfCurrentPosition() const { return current_; } |
| 94 return current_; | |
| 95 } | |
| 96 | 83 |
| 97 void Advance(intptr_t value) { | 84 void Advance(intptr_t value) { |
| 98 ASSERT((end_ - current_) > value); | 85 ASSERT((end_ - current_) > value); |
| 99 current_ = current_ + value; | 86 current_ = current_ + value; |
| 100 } | 87 } |
| 101 | 88 |
| 102 intptr_t PendingBytes() const { | 89 intptr_t PendingBytes() const { |
| 103 ASSERT(end_ >= current_); | 90 ASSERT(end_ >= current_); |
| 104 return (end_ - current_); | 91 return (end_ - current_); |
| 105 } | 92 } |
| 106 | 93 |
| 107 private: | 94 private: |
| 108 template<typename T> | 95 template <typename T> |
| 109 T Read() { | 96 T Read() { |
| 110 return Read<T>(kEndByteMarker); | 97 return Read<T>(kEndByteMarker); |
| 111 } | 98 } |
| 112 | 99 |
| 113 int16_t Read16() { | 100 int16_t Read16() { return Read16(kEndByteMarker); } |
| 114 return Read16(kEndByteMarker); | |
| 115 } | |
| 116 | 101 |
| 117 int32_t Read32() { | 102 int32_t Read32() { return Read32(kEndByteMarker); } |
| 118 return Read32(kEndByteMarker); | |
| 119 } | |
| 120 | 103 |
| 121 int64_t Read64() { | 104 int64_t Read64() { return Read64(kEndByteMarker); } |
| 122 return Read64(kEndByteMarker); | |
| 123 } | |
| 124 | 105 |
| 125 template<typename T> | 106 template <typename T> |
| 126 T Read(uint8_t end_byte_marker) { | 107 T Read(uint8_t end_byte_marker) { |
| 127 const uint8_t* c = current_; | 108 const uint8_t* c = current_; |
| 128 ASSERT(c < end_); | 109 ASSERT(c < end_); |
| 129 uint8_t b = *c++; | 110 uint8_t b = *c++; |
| 130 if (b > kMaxUnsignedDataPerByte) { | 111 if (b > kMaxUnsignedDataPerByte) { |
| 131 current_ = c; | 112 current_ = c; |
| 132 return static_cast<T>(b) - end_byte_marker; | 113 return static_cast<T>(b) - end_byte_marker; |
| 133 } | 114 } |
| 134 T r = 0; | 115 T r = 0; |
| 135 uint8_t s = 0; | 116 uint8_t s = 0; |
| (...skipping 166 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 302 const uint8_t* current_; | 283 const uint8_t* current_; |
| 303 const uint8_t* end_; | 284 const uint8_t* end_; |
| 304 | 285 |
| 305 DISALLOW_COPY_AND_ASSIGN(ReadStream); | 286 DISALLOW_COPY_AND_ASSIGN(ReadStream); |
| 306 }; | 287 }; |
| 307 | 288 |
| 308 | 289 |
| 309 // Stream for writing various types into a buffer. | 290 // Stream for writing various types into a buffer. |
| 310 class WriteStream : public ValueObject { | 291 class WriteStream : public ValueObject { |
| 311 public: | 292 public: |
| 312 WriteStream(uint8_t** buffer, ReAlloc alloc, intptr_t initial_size) : | 293 WriteStream(uint8_t** buffer, ReAlloc alloc, intptr_t initial_size) |
| 313 buffer_(buffer), | 294 : buffer_(buffer), |
| 314 end_(NULL), | 295 end_(NULL), |
| 315 current_(NULL), | 296 current_(NULL), |
| 316 current_size_(0), | 297 current_size_(0), |
| 317 alloc_(alloc), | 298 alloc_(alloc), |
| 318 initial_size_(initial_size) { | 299 initial_size_(initial_size) { |
| 319 ASSERT(buffer != NULL); | 300 ASSERT(buffer != NULL); |
| 320 ASSERT(alloc != NULL); | 301 ASSERT(alloc != NULL); |
| 321 *buffer_ = reinterpret_cast<uint8_t*>(alloc_(NULL, | 302 *buffer_ = reinterpret_cast<uint8_t*>(alloc_(NULL, 0, initial_size_)); |
| 322 0, | |
| 323 initial_size_)); | |
| 324 if (*buffer_ == NULL) { | 303 if (*buffer_ == NULL) { |
| 325 Exceptions::ThrowOOM(); | 304 Exceptions::ThrowOOM(); |
| 326 } | 305 } |
| 327 current_ = *buffer_; | 306 current_ = *buffer_; |
| 328 current_size_ = initial_size_; | 307 current_size_ = initial_size_; |
| 329 end_ = *buffer_ + initial_size_; | 308 end_ = *buffer_ + initial_size_; |
| 330 } | 309 } |
| 331 | 310 |
| 332 uint8_t* buffer() const { return *buffer_; } | 311 uint8_t* buffer() const { return *buffer_; } |
| 333 intptr_t bytes_written() const { return current_ - *buffer_; } | 312 intptr_t bytes_written() const { return current_ - *buffer_; } |
| 334 | 313 |
| 335 void set_current(uint8_t* value) { current_ = value; } | 314 void set_current(uint8_t* value) { current_ = value; } |
| 336 | 315 |
| 337 template<int N, typename T> | 316 template <int N, typename T> |
| 338 class Raw { }; | 317 class Raw {}; |
| 339 | 318 |
| 340 template<typename T> | 319 template <typename T> |
| 341 class Raw<1, T> { | 320 class Raw<1, T> { |
| 342 public: | 321 public: |
| 343 static void Write(WriteStream* st, T value) { | 322 static void Write(WriteStream* st, T value) { |
| 344 st->WriteByte(bit_cast<int8_t>(value)); | 323 st->WriteByte(bit_cast<int8_t>(value)); |
| 345 } | 324 } |
| 346 }; | 325 }; |
| 347 | 326 |
| 348 template<typename T> | 327 template <typename T> |
| 349 class Raw<2, T> { | 328 class Raw<2, T> { |
| 350 public: | 329 public: |
| 351 static void Write(WriteStream* st, T value) { | 330 static void Write(WriteStream* st, T value) { |
| 352 st->Write<int16_t>(bit_cast<int16_t>(value)); | 331 st->Write<int16_t>(bit_cast<int16_t>(value)); |
| 353 } | 332 } |
| 354 }; | 333 }; |
| 355 | 334 |
| 356 template<typename T> | 335 template <typename T> |
| 357 class Raw<4, T> { | 336 class Raw<4, T> { |
| 358 public: | 337 public: |
| 359 static void Write(WriteStream* st, T value) { | 338 static void Write(WriteStream* st, T value) { |
| 360 st->Write<int32_t>(bit_cast<int32_t>(value)); | 339 st->Write<int32_t>(bit_cast<int32_t>(value)); |
| 361 } | 340 } |
| 362 }; | 341 }; |
| 363 | 342 |
| 364 template<typename T> | 343 template <typename T> |
| 365 class Raw<8, T> { | 344 class Raw<8, T> { |
| 366 public: | 345 public: |
| 367 static void Write(WriteStream* st, T value) { | 346 static void Write(WriteStream* st, T value) { |
| 368 st->Write<int64_t>(bit_cast<int64_t>(value)); | 347 st->Write<int64_t>(bit_cast<int64_t>(value)); |
| 369 } | 348 } |
| 370 }; | 349 }; |
| 371 | 350 |
| 372 void WriteUnsigned(intptr_t value) { | 351 void WriteUnsigned(intptr_t value) { |
| 373 ASSERT((value >= 0) && (value <= kIntptrMax)); | 352 ASSERT((value >= 0) && (value <= kIntptrMax)); |
| 374 while (value > kMaxUnsignedDataPerByte) { | 353 while (value > kMaxUnsignedDataPerByte) { |
| (...skipping 22 matching lines...) Expand all Loading... |
| 397 current_ += len; | 376 current_ += len; |
| 398 } | 377 } |
| 399 | 378 |
| 400 void Print(const char* format, ...) { | 379 void Print(const char* format, ...) { |
| 401 va_list args; | 380 va_list args; |
| 402 va_start(args, format); | 381 va_start(args, format); |
| 403 VPrint(format, args); | 382 VPrint(format, args); |
| 404 } | 383 } |
| 405 | 384 |
| 406 private: | 385 private: |
| 407 template<typename T> | 386 template <typename T> |
| 408 void Write(T value) { | 387 void Write(T value) { |
| 409 T v = value; | 388 T v = value; |
| 410 while (v < kMinDataPerByte || | 389 while (v < kMinDataPerByte || v > kMaxDataPerByte) { |
| 411 v > kMaxDataPerByte) { | |
| 412 WriteByte(static_cast<uint8_t>(v & kByteMask)); | 390 WriteByte(static_cast<uint8_t>(v & kByteMask)); |
| 413 v = v >> kDataBitsPerByte; | 391 v = v >> kDataBitsPerByte; |
| 414 } | 392 } |
| 415 WriteByte(static_cast<uint8_t>(v + kEndByteMarker)); | 393 WriteByte(static_cast<uint8_t>(v + kEndByteMarker)); |
| 416 } | 394 } |
| 417 | 395 |
| 418 DART_FORCE_INLINE void WriteByte(uint8_t value) { | 396 DART_FORCE_INLINE void WriteByte(uint8_t value) { |
| 419 if (current_ >= end_) { | 397 if (current_ >= end_) { |
| 420 Resize(1); | 398 Resize(1); |
| 421 } | 399 } |
| 422 ASSERT(current_ < end_); | 400 ASSERT(current_ < end_); |
| 423 *current_++ = value; | 401 *current_++ = value; |
| 424 } | 402 } |
| 425 | 403 |
| 426 void Resize(intptr_t size_needed) { | 404 void Resize(intptr_t size_needed) { |
| 427 intptr_t position = current_ - *buffer_; | 405 intptr_t position = current_ - *buffer_; |
| 428 intptr_t increment_size = current_size_; | 406 intptr_t increment_size = current_size_; |
| 429 if (size_needed > increment_size) { | 407 if (size_needed > increment_size) { |
| 430 increment_size = Utils::RoundUp(size_needed, initial_size_); | 408 increment_size = Utils::RoundUp(size_needed, initial_size_); |
| 431 } | 409 } |
| 432 intptr_t new_size = current_size_ + increment_size; | 410 intptr_t new_size = current_size_ + increment_size; |
| 433 ASSERT(new_size > current_size_); | 411 ASSERT(new_size > current_size_); |
| 434 *buffer_ = reinterpret_cast<uint8_t*>(alloc_(*buffer_, | 412 *buffer_ = |
| 435 current_size_, | 413 reinterpret_cast<uint8_t*>(alloc_(*buffer_, current_size_, new_size)); |
| 436 new_size)); | |
| 437 if (*buffer_ == NULL) { | 414 if (*buffer_ == NULL) { |
| 438 Exceptions::ThrowOOM(); | 415 Exceptions::ThrowOOM(); |
| 439 } | 416 } |
| 440 current_ = *buffer_ + position; | 417 current_ = *buffer_ + position; |
| 441 current_size_ = new_size; | 418 current_size_ = new_size; |
| 442 end_ = *buffer_ + new_size; | 419 end_ = *buffer_ + new_size; |
| 443 ASSERT(end_ > *buffer_); | 420 ASSERT(end_ > *buffer_); |
| 444 } | 421 } |
| 445 | 422 |
| 446 void VPrint(const char* format, va_list args) { | 423 void VPrint(const char* format, va_list args) { |
| 447 // Measure. | 424 // Measure. |
| 448 va_list measure_args; | 425 va_list measure_args; |
| 449 va_copy(measure_args, args); | 426 va_copy(measure_args, args); |
| 450 intptr_t len = OS::VSNPrint(NULL, 0, format, measure_args); | 427 intptr_t len = OS::VSNPrint(NULL, 0, format, measure_args); |
| 451 va_end(measure_args); | 428 va_end(measure_args); |
| 452 | 429 |
| 453 // Alloc. | 430 // Alloc. |
| 454 if ((end_ - current_) < (len + 1)) { | 431 if ((end_ - current_) < (len + 1)) { |
| 455 Resize(len + 1); | 432 Resize(len + 1); |
| 456 } | 433 } |
| 457 ASSERT((end_ - current_) >= (len + 1)); | 434 ASSERT((end_ - current_) >= (len + 1)); |
| 458 | 435 |
| 459 // Print. | 436 // Print. |
| 460 va_list print_args; | 437 va_list print_args; |
| 461 va_copy(print_args, args); | 438 va_copy(print_args, args); |
| 462 OS::VSNPrint(reinterpret_cast<char*>(current_), | 439 OS::VSNPrint(reinterpret_cast<char*>(current_), len + 1, format, |
| 463 len + 1, format, print_args); | 440 print_args); |
| 464 va_end(print_args); | 441 va_end(print_args); |
| 465 current_ += len; // Not len + 1 to swallow the terminating NUL. | 442 current_ += len; // Not len + 1 to swallow the terminating NUL. |
| 466 } | 443 } |
| 467 | 444 |
| 468 private: | 445 private: |
| 469 uint8_t** const buffer_; | 446 uint8_t** const buffer_; |
| 470 uint8_t* end_; | 447 uint8_t* end_; |
| 471 uint8_t* current_; | 448 uint8_t* current_; |
| 472 intptr_t current_size_; | 449 intptr_t current_size_; |
| 473 ReAlloc alloc_; | 450 ReAlloc alloc_; |
| 474 intptr_t initial_size_; | 451 intptr_t initial_size_; |
| 475 | 452 |
| 476 DISALLOW_COPY_AND_ASSIGN(WriteStream); | 453 DISALLOW_COPY_AND_ASSIGN(WriteStream); |
| 477 }; | 454 }; |
| 478 | 455 |
| 479 } // namespace dart | 456 } // namespace dart |
| 480 | 457 |
| 481 #endif // RUNTIME_VM_DATASTREAM_H_ | 458 #endif // RUNTIME_VM_DATASTREAM_H_ |
| OLD | NEW |