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 |