Revert "[vm] Switch datastream Write/WriteUnsigned to (S)LEB128." This reverts commit 80102c981b78594ceb6263a044e99e7233f7b365. Reason for revert: b/186359854 Original change's description: > [vm] Switch datastream Write/WriteUnsigned to (S)LEB128. > > This reduces the number of variable-length integer encodings in our > database from 2 to 1, and chooses the more standard one. > > TEST=Existing tests, in particular any that involve snapshots. > > Cq-Include-Trybots: luci.dart.try:vm-kernel-precomp-asan-linux-release-x64-try,vm-kernel-precomp-dwarf-linux-product-x64-try,vm-kernel-precomp-msan-linux-release-x64-try,vm-kernel-precomp-ubsan-linux-release-x64-try,vm-kernel-precomp-tsan-linux-release-x64-try,vm-kernel-precomp-nnbd-linux-debug-x64-try,vm-kernel-precomp-nnbd-linux-debug-simarm_x64-try,vm-kernel-precomp-linux-debug-simarm64c-try,vm-kernel-precomp-linux-debug-simarm_x64-try,vm-kernel-precomp-linux-debug-x64-try,vm-kernel-precomp-linux-debug-x64c-try,vm-kernel-precomp-linux-product-x64-try,vm-kernel-precomp-linux-release-x64-try > Change-Id: Ia700158ac873ad32ac28c1027a669895961bc715 > Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/196321 > Commit-Queue: Tess Strickland <sstrickl@google.com> > Reviewed-by: Ryan Macnak <rmacnak@google.com> > Reviewed-by: Martin Kustermann <kustermann@google.com> # Not skipping CQ checks because original CL landed > 1 day ago. Change-Id: Idf32bdd879cf8bb7407f6dae764312140ad6eeb2 Cq-Include-Trybots: luci.dart.try:vm-kernel-precomp-asan-linux-release-x64-try,vm-kernel-precomp-dwarf-linux-product-x64-try,vm-kernel-precomp-msan-linux-release-x64-try,vm-kernel-precomp-ubsan-linux-release-x64-try,vm-kernel-precomp-tsan-linux-release-x64-try,vm-kernel-precomp-nnbd-linux-debug-x64-try,vm-kernel-precomp-nnbd-linux-debug-simarm_x64-try,vm-kernel-precomp-linux-debug-simarm64c-try,vm-kernel-precomp-linux-debug-simarm_x64-try,vm-kernel-precomp-linux-debug-x64-try,vm-kernel-precomp-linux-debug-x64c-try,vm-kernel-precomp-linux-product-x64-try,vm-kernel-precomp-linux-release-x64-try Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/196920 Reviewed-by: Ivan Inozemtsev <iinozemtsev@google.com> Commit-Queue: Ivan Inozemtsev <iinozemtsev@google.com>
diff --git a/runtime/platform/utils.h b/runtime/platform/utils.h index 24f7e68..a73d6d9 100644 --- a/runtime/platform/utils.h +++ b/runtime/platform/utils.h
@@ -395,23 +395,29 @@ return ((-0x20000000000000LL <= value) && (value <= 0x20000000000000LL)); } + static constexpr uword NBitMaskUnsafe(uint32_t n) { + static_assert((sizeof(uword) * kBitsPerByte) == kBitsPerWord, + "Unexpected uword size"); + return n == kBitsPerWord ? std::numeric_limits<uword>::max() + : (static_cast<uword>(1) << n) - 1; + } + // The lowest n bits are 1, the others are 0. - template <typename T = uword> - static constexpr T NBitMask(size_t n) { - static_assert(std::is_integral<T>::value, "Must be integral type"); - using Unsigned = typename std::make_unsigned<T>::type; - assert(n <= sizeof(T) * kBitsPerByte); - return n == sizeof(T) * kBitsPerByte - ? static_cast<T>(-1) - : static_cast<T>((static_cast<Unsigned>(1) << n) - 1); + static uword NBitMask(uint32_t n) { + ASSERT(n <= kBitsPerWord); + return NBitMaskUnsafe(n); + } + + static word SignedNBitMask(uint32_t n) { + uword mask = NBitMask(n); + return bit_cast<word>(mask); } template <typename T = uword> - static constexpr T Bit(size_t n) { - static_assert(std::is_integral<T>::value, "Must be integral type"); - using Unsigned = typename std::make_unsigned<T>::type; - assert(n < sizeof(T) * kBitsPerByte); - return static_cast<T>(static_cast<Unsigned>(1) << n); + static T Bit(uint32_t n) { + ASSERT(n < sizeof(T) * kBitsPerByte); + T bit = 1; + return bit << n; } template <typename T>
diff --git a/runtime/vm/code_descriptors.cc b/runtime/vm/code_descriptors.cc index 50f2ec5..dd8bc1d 100644 --- a/runtime/vm/code_descriptors.cc +++ b/runtime/vm/code_descriptors.cc
@@ -54,8 +54,8 @@ UntaggedPcDescriptors::KindAndMetadata::Encode(kind, try_index, yield_index); - encoded_data_.Write(kind_and_metadata); - encoded_data_.Write(pc_offset - prev_pc_offset); + encoded_data_.WriteSLEB128(kind_and_metadata); + encoded_data_.WriteSLEB128(pc_offset - prev_pc_offset); prev_pc_offset = pc_offset; if (!FLAG_precompiled_mode) { @@ -80,8 +80,8 @@ } } const int32_t encoded_pos = token_pos.Serialize(); - encoded_data_.Write(deopt_id - prev_deopt_id); - encoded_data_.Write( + encoded_data_.WriteSLEB128(deopt_id - prev_deopt_id); + encoded_data_.WriteSLEB128( Utils::SubWithWrapAround(encoded_pos, prev_token_pos)); prev_deopt_id = deopt_id; prev_token_pos = encoded_pos; @@ -106,9 +106,9 @@ const uword pc_delta = pc_offset - last_pc_offset_; const uword non_spill_slot_bit_count = bitmap->Length() - spill_slot_bit_count; - encoded_bytes_.WriteUnsigned(pc_delta); - encoded_bytes_.WriteUnsigned(spill_slot_bit_count); - encoded_bytes_.WriteUnsigned(non_spill_slot_bit_count); + encoded_bytes_.WriteLEB128(pc_delta); + encoded_bytes_.WriteLEB128(spill_slot_bit_count); + encoded_bytes_.WriteLEB128(non_spill_slot_bit_count); bitmap->AppendAsBytesTo(&encoded_bytes_); last_pc_offset_ = pc_offset; }
diff --git a/runtime/vm/code_descriptors.h b/runtime/vm/code_descriptors.h index adf53b0..0d15c38 100644 --- a/runtime/vm/code_descriptors.h +++ b/runtime/vm/code_descriptors.h
@@ -209,7 +209,7 @@ using ArgField = BitField<int32_t, int32_t, OpField::kNextBit>; static constexpr int32_t kMaxArgValue = - Utils::NBitMask(ArgField::bitsize() - 1); + Utils::NBitMaskUnsafe(ArgField::bitsize() - 1); static constexpr int32_t kMinArgValue = ~kMaxArgValue; static constexpr int32_t kSignBits = static_cast<uint32_t>(kMinArgValue) << 1; };
diff --git a/runtime/vm/compiler/backend/il_arm.cc b/runtime/vm/compiler/backend/il_arm.cc index 8782aec..70f7fb0 100644 --- a/runtime/vm/compiler/backend/il_arm.cc +++ b/runtime/vm/compiler/backend/il_arm.cc
@@ -778,8 +778,8 @@ const intptr_t kCpuRegistersToPreserve = kDartAvailableCpuRegs & ~kNonChangeableInputRegs; const intptr_t kFpuRegistersToPreserve = - Utils::NBitMask<word>(kNumberOfFpuRegisters) & - ~(Utils::NBitMask<word>(kAbiPreservedFpuRegCount) + Utils::SignedNBitMask(kNumberOfFpuRegisters) & + ~(Utils::SignedNBitMask(kAbiPreservedFpuRegCount) << kAbiFirstPreservedFpuReg) & ~(1 << FpuTMP);
diff --git a/runtime/vm/compiler/backend/il_arm64.cc b/runtime/vm/compiler/backend/il_arm64.cc index e79bfbc..d375c59 100644 --- a/runtime/vm/compiler/backend/il_arm64.cc +++ b/runtime/vm/compiler/backend/il_arm64.cc
@@ -689,7 +689,7 @@ const intptr_t kCpuRegistersToPreserve = kDartAvailableCpuRegs & ~kNonChangeableInputRegs; const intptr_t kFpuRegistersToPreserve = - Utils::NBitMask<word>(kNumberOfFpuRegisters) & ~Utils::Bit(FpuTMP); + Utils::SignedNBitMask(kNumberOfFpuRegisters) & ~(1l << FpuTMP); const intptr_t kNumTemps = (Utils::CountOneBits64(kCpuRegistersToPreserve) + Utils::CountOneBits64(kFpuRegistersToPreserve));
diff --git a/runtime/vm/datastream.cc b/runtime/vm/datastream.cc index 397f9c7..6d398fe 100644 --- a/runtime/vm/datastream.cc +++ b/runtime/vm/datastream.cc
@@ -4,126 +4,11 @@ #include "vm/datastream.h" -#include "platform/text_buffer.h" #include "vm/compiler/runtime_api.h" -#include "vm/os.h" #include "vm/zone.h" namespace dart { -// Setting up needed variables for the unrolled loop sections below. -#define UNROLLED_INIT() \ - using Unsigned = typename std::make_unsigned<T>::type; \ - Unsigned b = ReadByte(); \ - if ((b & C::kMoreDataMask) == 0) { \ - if ((b & C::kSignMask) != 0) { \ - b |= ~Utils::NBitMask<Unsigned>(C::kDataBitsPerByte); \ - } \ - return static_cast<T>(b); \ - } \ - T r = static_cast<T>(b & C::kDataByteMask); - -// Part of the unrolled loop where the loop may stop, having read the last part, -// or continue reading. -#define UNROLLED_BODY(bit_start) \ - static_assert(bit_start % C::kDataBitsPerByte == 0, \ - "Bit start must be a multiple of the data bits per byte"); \ - static_assert(bit_start >= 0 && bit_start < kBitsPerByte * sizeof(T), \ - "Starting unrolled body at invalid bit position"); \ - static_assert(bit_start + C::kDataBitsPerByte < kBitsPerByte * sizeof(T), \ - "Unrolled body should not contain final bits in value"); \ - b = ReadByte(); \ - r |= static_cast<Unsigned>(b & C::kDataByteMask) << bit_start; \ - if ((b & C::kMoreDataMask) == 0) { \ - if ((b & C::kSignMask) != 0) { \ - r |= ~Utils::NBitMask<T>(bit_start + C::kDataBitsPerByte); \ - } \ - return r; \ - } - -// The end of the unrolled loop. Does not need to handle sign extension, as the -// last bits fill the rest of the bitspace. -#define UNROLLED_END(bit_start) \ - static_assert(bit_start % C::kDataBitsPerByte == 0, \ - "Bit start must be a multiple of the data bits per byte"); \ - static_assert(bit_start >= 0 && bit_start < kBitsPerByte * sizeof(T), \ - "Starting unrolled end at invalid bit position"); \ - static_assert(bit_start + C::kDataBitsPerByte >= kBitsPerByte * sizeof(T), \ - "Unrolled end does not contain final bits in value"); \ - b = ReadByte(); \ - ASSERT_EQUAL((b & C::kMoreDataMask), 0); \ - r |= static_cast<Unsigned>(b & C::kDataByteMask) << bit_start; \ - return r; - -uint16_t ReadStream::Read16() { - using T = uint16_t; - UNROLLED_INIT(); - UNROLLED_BODY(7); - UNROLLED_END(14); -} - -uint32_t ReadStream::Read32() { - using T = uint32_t; - UNROLLED_INIT(); - UNROLLED_BODY(7); - UNROLLED_BODY(14); - UNROLLED_BODY(21); - UNROLLED_END(28); -} - -uint64_t ReadStream::Read64() { - using T = uint64_t; - UNROLLED_INIT(); - UNROLLED_BODY(7); - UNROLLED_BODY(14); - UNROLLED_BODY(21); - UNROLLED_BODY(28); - UNROLLED_BODY(35); - UNROLLED_BODY(42); - UNROLLED_BODY(49); - UNROLLED_BODY(56); - UNROLLED_END(63); -} -#undef UNROLLED_INIT -#undef UNROLLED_BODY -#undef UNROLLED_END - -static constexpr intptr_t kRowSize = 16; - -void ReadStream::WriteWindow(BaseTextBuffer* buffer, - intptr_t start, - intptr_t window_size) { - const intptr_t buffer_size = end_ - buffer_; - ASSERT(0 <= start && start <= buffer_size); - intptr_t window_start = start - (window_size / 2); - intptr_t window_end = start + (window_size / 2); - if (window_start < 0) window_start = 0; - if (buffer_size < window_start + window_end) window_end = buffer_size; - for (intptr_t i = window_start - (window_start % kRowSize); i < window_end; - i += kRowSize) { - buffer->Printf("%016" Px " ", i); - intptr_t j = i; - if (j < window_start) { - while (j < window_start) { - buffer->AddString(" "); - ++j; - } - } - for (; j < Utils::Minimum(window_end, i + kRowSize); j++) { - buffer->AddChar(j == start ? '|' : ' '); - buffer->Printf("%02x", static_cast<uint8_t>(buffer_[j] % kMaxUint8)); - buffer->AddChar(j == start ? '|' : ' '); - } - buffer->AddChar('\n'); - } -} - -void ReadStream::PrintWindow(intptr_t start, intptr_t window_size) { - TextBuffer buffer(1024); - WriteWindow(&buffer, start, window_size); - OS::Print("%s", buffer.buffer()); -} - void BaseWriteStream::WriteTargetWord(word value) { ASSERT(compiler::target::kBitsPerWord == kBitsPerWord || Utils::IsAbsoluteUint(compiler::target::kBitsPerWord, value));
diff --git a/runtime/vm/datastream.h b/runtime/vm/datastream.h index fd343cd..7da4532 100644 --- a/runtime/vm/datastream.h +++ b/runtime/vm/datastream.h
@@ -15,7 +15,14 @@ namespace dart { -class BaseTextBuffer; +static const int8_t kDataBitsPerByte = 7; +static const int8_t kByteMask = (1 << kDataBitsPerByte) - 1; +static const int8_t kMaxUnsignedDataPerByte = kByteMask; +static const int8_t kMinDataPerByte = -(1 << (kDataBitsPerByte - 1)); +static const int8_t kMaxDataPerByte = (~kMinDataPerByte & kByteMask); // NOLINT +static const uint8_t kEndByteMarker = (255 - kMaxDataPerByte); +static const uint8_t kEndUnsignedByteMarker = (255 - kMaxUnsignedDataPerByte); + struct LEB128Constants : AllStatic { // Convenience template for ensuring non-signed types trigger SFINAE. template <typename T, typename S> @@ -28,13 +35,12 @@ typename std::enable_if<std::is_unsigned<T>::value, S>::type; // (S)LEB128 encodes 7 bits of data per byte (hence 128). - static constexpr size_t kDataBitsPerByte = 7; - static constexpr auto kDataByteMask = - Utils::NBitMask<uint8_t>(kDataBitsPerByte); + static constexpr uint8_t kDataBitsPerByte = 7; + static constexpr uint8_t kDataByteMask = (1 << kDataBitsPerByte) - 1; // If more data follows a given data byte, the high bit is set. - static constexpr auto kMoreDataMask = Utils::Bit<uint8_t>(kDataBitsPerByte); + static constexpr uint8_t kMoreDataMask = (1 << kDataBitsPerByte); // For SLEB128, the high bit in the data of the last byte is the sign bit. - static constexpr auto kSignMask = Utils::Bit<uint8_t>(kDataBitsPerByte - 1); + static constexpr uint8_t kSignMask = (1 << (kDataBitsPerByte - 1)); }; class NonStreamingWriteStream; @@ -87,6 +93,11 @@ current_ += len; } + template <typename T = intptr_t> + T ReadUnsigned() { + return Read<T>(kEndUnsignedByteMarker); + } + intptr_t Position() const { return current_ - buffer_; } void SetPosition(intptr_t value) { ASSERT((end_ - buffer_) >= value); @@ -111,6 +122,11 @@ return (end_ - current_); } + template <typename T> + T Read() { + return Read<T>(kEndByteMarker); + } + uword ReadWordWith32BitReads() { constexpr intptr_t kNumRead32PerWord = kBitsPerWord / kBitsPerInt32; @@ -127,7 +143,7 @@ public: template <typename T = uintptr_t> - C::only_if_unsigned<T, T> ReadUnsigned() { + C::only_if_unsigned<T, T> ReadLEB128() { constexpr intptr_t kBitsPerT = kBitsPerByte * sizeof(T); T r = 0; uint8_t s = 0; @@ -143,12 +159,12 @@ } template <typename T> - C::only_if_signed<T, T> ReadUnsigned() { - return bit_cast<T>(ReadUnsigned<typename std::make_unsigned<T>::type>()); + C::only_if_signed<T, T> ReadLEB128() { + return bit_cast<T>(ReadLEB128<typename std::make_unsigned<T>::type>()); } template <typename T> - C::only_if_unsigned<T, T> Read() { + C::only_if_unsigned<T, T> ReadSLEB128() { constexpr intptr_t kBitsPerT = kBitsPerByte * sizeof(T); T r = 0; uint8_t s = 0; @@ -164,33 +180,114 @@ // value. If the value is negative and the count of data bits is less than // the size of the value, then we need to extend the sign by setting the // remaining (unset) most significant bits (MSBs). + T sign_bits = 0; if ((b & C::kSignMask) != 0 && s < kBitsPerT) { // Create a bitmask for the current data bits and invert it. - r |= ~Utils::NBitMask<T>(s); + sign_bits = ~((static_cast<T>(1) << s) - 1); } - return r; + return r | sign_bits; } template <typename T = intptr_t> - C::only_if_signed<T, T> Read() { - return bit_cast<T>(Read<typename std::make_unsigned<T>::type>()); + C::only_if_signed<T, T> ReadSLEB128() { + return bit_cast<T>(ReadSLEB128<typename std::make_unsigned<T>::type>()); } private: - uint16_t Read16(); - uint32_t Read32(); - uint64_t Read64(); + uint16_t Read16() { return Read16(kEndByteMarker); } + + uint32_t Read32() { return Read32(kEndByteMarker); } + + uint64_t Read64() { return Read64(kEndByteMarker); } + + template <typename T> + T Read(uint8_t end_byte_marker) { + using Unsigned = typename std::make_unsigned<T>::type; + Unsigned b = ReadByte(); + if (b > kMaxUnsignedDataPerByte) { + return b - end_byte_marker; + } + T r = 0; + uint8_t s = 0; + do { + r |= static_cast<Unsigned>(b) << s; + s += kDataBitsPerByte; + b = ReadByte(); + } while (b <= kMaxUnsignedDataPerByte); + return r | (static_cast<Unsigned>(b - end_byte_marker) << s); + } + +// Setting up needed variables for the unrolled loop sections below. +#define UNROLLED_INIT() \ + using Unsigned = typename std::make_unsigned<T>::type; \ + Unsigned b = ReadByte(); \ + if (b > kMaxUnsignedDataPerByte) { \ + return b - end_byte_marker; \ + } \ + T r = b; + +// Part of the unrolled loop where the loop may stop, having read the last part, +// or continue reading. +#define UNROLLED_BODY(bit_start) \ + static_assert(bit_start % kDataBitsPerByte == 0, \ + "Bit start must be a multiple of the data bits per byte"); \ + static_assert(bit_start >= 0 && bit_start < kBitsPerByte * sizeof(T), \ + "Starting unrolled body at invalid bit position"); \ + static_assert(bit_start + kDataBitsPerByte < kBitsPerByte * sizeof(T), \ + "Unrolled body should not contain final bits in value"); \ + b = ReadByte(); \ + if (b > kMaxUnsignedDataPerByte) { \ + return r | (static_cast<T>(b - end_byte_marker) << bit_start); \ + } \ + r |= b << bit_start; + +// The end of the unrolled loop. +#define UNROLLED_END(bit_start) \ + static_assert(bit_start % kDataBitsPerByte == 0, \ + "Bit start must be a multiple of the data bits per byte"); \ + static_assert(bit_start >= 0 && bit_start < kBitsPerByte * sizeof(T), \ + "Starting unrolled end at invalid bit position"); \ + static_assert(bit_start + kDataBitsPerByte >= kBitsPerByte * sizeof(T), \ + "Unrolled end does not contain final bits in value"); \ + b = ReadByte(); \ + ASSERT(b > kMaxUnsignedDataPerByte); \ + return r | (static_cast<T>(b - end_byte_marker) << bit_start); + + uint16_t Read16(uint8_t end_byte_marker) { + using T = uint16_t; + UNROLLED_INIT(); + UNROLLED_BODY(7); + UNROLLED_END(14); + } + + uint32_t Read32(uint8_t end_byte_marker) { + using T = uint32_t; + UNROLLED_INIT(); + UNROLLED_BODY(7); + UNROLLED_BODY(14); + UNROLLED_BODY(21); + UNROLLED_END(28); + } + + uint64_t Read64(uint8_t end_byte_marker) { + using T = uint64_t; + UNROLLED_INIT(); + UNROLLED_BODY(7); + UNROLLED_BODY(14); + UNROLLED_BODY(21); + UNROLLED_BODY(28); + UNROLLED_BODY(35); + UNROLLED_BODY(42); + UNROLLED_BODY(49); + UNROLLED_BODY(56); + UNROLLED_END(63); + } DART_FORCE_INLINE uint8_t ReadByte() { ASSERT(current_ < end_); return *current_++; } - void WriteWindow(BaseTextBuffer* buffer, - intptr_t start, - intptr_t window_size = 64); - void PrintWindow(intptr_t start, intptr_t window_size = 64); - private: const uint8_t* buffer_; const uint8_t* current_; @@ -267,6 +364,16 @@ } } + template <typename T> + void WriteUnsigned(T value) { + ASSERT(value >= 0); + while (value > kMaxUnsignedDataPerByte) { + WriteByte(static_cast<uint8_t>(value & kByteMask)); + value = value >> kDataBitsPerByte; + } + WriteByte(static_cast<uint8_t>(value + kEndUnsignedByteMarker)); + } + void WriteBytes(const void* addr, intptr_t len) { if (len != 0) { EnsureSpace(len); @@ -306,6 +413,16 @@ } template <typename T> + void Write(T value) { + T v = value; + while (v < kMinDataPerByte || v > kMaxDataPerByte) { + WriteByte(static_cast<uint8_t>(v & kByteMask)); + v = v >> kDataBitsPerByte; + } + WriteByte(static_cast<uint8_t>(v + kEndByteMarker)); + } + + template <typename T> void WriteFixed(T value) { WriteBytes(&value, sizeof(value)); } @@ -322,7 +439,7 @@ public: template <typename T> - C::only_if_unsigned<T, void> WriteUnsigned(T value) { + C::only_if_unsigned<T, void> WriteLEB128(T value) { T remainder = value; bool is_last_part; do { @@ -339,15 +456,15 @@ } template <typename T> - C::only_if_signed<T, void> WriteUnsigned(T value) { + C::only_if_signed<T, void> WriteLEB128(T value) { // If we're trying to LEB128 encode a negative value, chances are we should // be using SLEB128 instead. ASSERT(value >= 0); - return WriteUnsigned(bit_cast<typename std::make_unsigned<T>::type>(value)); + return WriteLEB128(bit_cast<typename std::make_unsigned<T>::type>(value)); } template <typename T> - C::only_if_signed<T, void> Write(T value) { + C::only_if_signed<T, void> WriteSLEB128(T value) { constexpr intptr_t kBitsPerT = kBitsPerByte * sizeof(T); using Unsigned = typename std::make_unsigned<T>::type; // Record whether the original value was negative. @@ -392,8 +509,8 @@ } template <typename T> - C::only_if_unsigned<T, void> Write(T value) { - return Write(bit_cast<typename std::make_signed<T>::type>(value)); + C::only_if_unsigned<T, void> WriteSLEB128(T value) { + return WriteSLEB128(bit_cast<typename std::make_signed<T>::type>(value)); } protected:
diff --git a/runtime/vm/datastream_test.cc b/runtime/vm/datastream_test.cc index ec8eb5b..0b9ba6c 100644 --- a/runtime/vm/datastream_test.cc +++ b/runtime/vm/datastream_test.cc
@@ -126,4 +126,60 @@ TestRaw<int64_t>(); } +TEST_CASE(BaseWriteStream_WriteLEB128) { + MallocWriteStream writer(1 * KB); + for (uintptr_t i = 0; i < kUnsignedEnd; i++) { + writer.WriteLEB128(i); + } + DEFINE_LARGE_CONSTANTS(uintptr_t); + writer.WriteLEB128(all_ones); + writer.WriteLEB128(min); + writer.WriteLEB128(max); + writer.WriteLEB128(half_min); + writer.WriteLEB128(half_max); + ReadStream reader(writer.buffer(), writer.bytes_written()); + for (uintptr_t i = 0; i < kUnsignedEnd; i++) { + const uintptr_t r = reader.ReadLEB128(); + EXPECT_EQ(i, r); + } + const uintptr_t read_all_ones = reader.ReadLEB128(); + EXPECT_EQ(all_ones, read_all_ones); + const uintptr_t read_min = reader.ReadLEB128(); + EXPECT_EQ(min, read_min); + const uintptr_t read_max = reader.ReadLEB128(); + EXPECT_EQ(max, read_max); + const uintptr_t read_half_min = reader.ReadLEB128(); + EXPECT_EQ(half_min, read_half_min); + const uintptr_t read_half_max = reader.ReadLEB128(); + EXPECT_EQ(half_max, read_half_max); +} + +TEST_CASE(BaseWriteStream_WriteSLEB128) { + MallocWriteStream writer(1 * KB); + for (intptr_t i = kSignedStart; i < kSignedEnd; i++) { + writer.WriteSLEB128(i); + } + DEFINE_LARGE_CONSTANTS(intptr_t); + writer.WriteSLEB128(all_ones); + writer.WriteSLEB128(min); + writer.WriteSLEB128(max); + writer.WriteSLEB128(half_min); + writer.WriteSLEB128(half_max); + ReadStream reader(writer.buffer(), writer.bytes_written()); + for (intptr_t i = kSignedStart; i < kSignedEnd; i++) { + const intptr_t r = reader.ReadSLEB128(); + EXPECT_EQ(i, r); + } + const intptr_t read_all_ones = reader.ReadSLEB128(); + EXPECT_EQ(all_ones, read_all_ones); + const intptr_t read_min = reader.ReadSLEB128(); + EXPECT_EQ(min, read_min); + const intptr_t read_max = reader.ReadSLEB128(); + EXPECT_EQ(max, read_max); + const intptr_t read_half_min = reader.ReadSLEB128(); + EXPECT_EQ(half_min, read_half_min); + const intptr_t read_half_max = reader.ReadSLEB128(); + EXPECT_EQ(half_max, read_half_max); +} + } // namespace dart
diff --git a/runtime/vm/elf.cc b/runtime/vm/elf.cc index dd11e4d..7f17df5 100644 --- a/runtime/vm/elf.cc +++ b/runtime/vm/elf.cc
@@ -1106,8 +1106,8 @@ stream_(ASSERT_NOTNULL(stream)), table_(table) {} - void sleb128(intptr_t value) { stream_->Write(value); } - void uleb128(uintptr_t value) { stream_->WriteUnsigned(value); } + void sleb128(intptr_t value) { stream_->WriteSLEB128(value); } + void uleb128(uintptr_t value) { stream_->WriteLEB128(value); } void u1(uint8_t value) { stream_->WriteByte(value); } void u2(uint16_t value) { stream_->WriteFixed(value); } void u4(uint32_t value) { stream_->WriteFixed(value); }
diff --git a/runtime/vm/kernel_binary.h b/runtime/vm/kernel_binary.h index c14919a..38ca8fa 100644 --- a/runtime/vm/kernel_binary.h +++ b/runtime/vm/kernel_binary.h
@@ -309,14 +309,14 @@ intptr_t ReadSLEB128() { ReadStream stream(this->buffer(), size_, offset_); - const intptr_t result = stream.Read(); + const intptr_t result = stream.ReadSLEB128(); offset_ = stream.Position(); return result; } int64_t ReadSLEB128AsInt64() { ReadStream stream(this->buffer(), size_, offset_); - const int64_t result = stream.Read<int64_t>(); + const int64_t result = stream.ReadSLEB128<int64_t>(); offset_ = stream.Position(); return result; }
diff --git a/runtime/vm/object.cc b/runtime/vm/object.cc index 4a9f094..e163b57 100644 --- a/runtime/vm/object.cc +++ b/runtime/vm/object.cc
@@ -14667,7 +14667,7 @@ NoSafepointScope scope; ReadStream stream(maps_.untag()->data(), maps_.payload_size(), next_offset_); - auto const pc_delta = stream.ReadUnsigned(); + auto const pc_delta = stream.ReadLEB128(); ASSERT(pc_delta <= (kMaxUint32 - current_pc_offset_)); current_pc_offset_ += pc_delta; @@ -14675,7 +14675,7 @@ // the post-delta part of inlined entries has the same information as // global table entries. if (maps_.UsesGlobalTable()) { - current_global_table_offset_ = stream.ReadUnsigned(); + current_global_table_offset_ = stream.ReadLEB128(); ASSERT(current_global_table_offset_ < bits_container_.payload_size()); // Since generally we only use entries in the GC and the GC only needs @@ -14688,10 +14688,10 @@ next_offset_ = stream.Position(); } else { - current_spill_slot_bit_count_ = stream.ReadUnsigned(); + current_spill_slot_bit_count_ = stream.ReadLEB128(); ASSERT(current_spill_slot_bit_count_ >= 0); - current_non_spill_slot_bit_count_ = stream.ReadUnsigned(); + current_non_spill_slot_bit_count_ = stream.ReadLEB128(); ASSERT(current_non_spill_slot_bit_count_ >= 0); const auto stackmap_bits = @@ -14737,10 +14737,10 @@ bits_container_.payload_size(), current_global_table_offset_); - current_spill_slot_bit_count_ = stream.ReadUnsigned(); + current_spill_slot_bit_count_ = stream.ReadLEB128(); ASSERT(current_spill_slot_bit_count_ >= 0); - current_non_spill_slot_bit_count_ = stream.ReadUnsigned(); + current_non_spill_slot_bit_count_ = stream.ReadLEB128(); ASSERT(current_non_spill_slot_bit_count_ >= 0); const auto stackmap_bits = Length();
diff --git a/runtime/vm/object.h b/runtime/vm/object.h index a03be0a3c..9ddb727 100644 --- a/runtime/vm/object.h +++ b/runtime/vm/object.h
@@ -5641,7 +5641,7 @@ byte_index_); // Moves to record that matches kind_mask_. while (byte_index_ < descriptors_.Length()) { - const int32_t kind_and_metadata = stream.Read<int32_t>(); + const int32_t kind_and_metadata = stream.ReadSLEB128<int32_t>(); cur_kind_ = UntaggedPcDescriptors::KindAndMetadata::DecodeKind( kind_and_metadata); cur_try_index_ = UntaggedPcDescriptors::KindAndMetadata::DecodeTryIndex( @@ -5650,12 +5650,12 @@ UntaggedPcDescriptors::KindAndMetadata::DecodeYieldIndex( kind_and_metadata); - cur_pc_offset_ += stream.Read(); + cur_pc_offset_ += stream.ReadSLEB128(); if (!FLAG_precompiled_mode) { - cur_deopt_id_ += stream.Read(); - cur_token_pos_ = - Utils::AddWithWrapAround(cur_token_pos_, stream.Read<int32_t>()); + cur_deopt_id_ += stream.ReadSLEB128(); + cur_token_pos_ = Utils::AddWithWrapAround( + cur_token_pos_, stream.ReadSLEB128<int32_t>()); } byte_index_ = stream.Position();
diff --git a/runtime/vm/program_visitor.cc b/runtime/vm/program_visitor.cc index e90c8ad..4bb663a 100644 --- a/runtime/vm/program_visitor.cc +++ b/runtime/vm/program_visitor.cc
@@ -502,8 +502,8 @@ // initial offset of the entry in the array. intptr_t EncodeTo(NonStreamingWriteStream* stream) { auto const current_offset = stream->Position(); - stream->WriteUnsigned(spill_slot_bit_count_); - stream->WriteUnsigned(non_spill_slot_bit_count_); + stream->WriteLEB128(spill_slot_bit_count_); + stream->WriteLEB128(non_spill_slot_bit_count_); { NoSafepointScope scope; stream->WriteBytes(PayloadData(), PayloadLength()); @@ -711,8 +711,8 @@ StackMapEntry entry(zone_, it); const intptr_t entry_offset = entry_offsets_.LookupValue(&entry); const intptr_t pc_delta = it.pc_offset() - last_offset; - new_payload.WriteUnsigned(pc_delta); - new_payload.WriteUnsigned(entry_offset); + new_payload.WriteLEB128(pc_delta); + new_payload.WriteLEB128(entry_offset); last_offset = it.pc_offset(); } return CompressedStackMaps::NewUsingTable(new_payload.buffer(),
diff --git a/runtime/vm/v8_snapshot_writer.h b/runtime/vm/v8_snapshot_writer.h index 99ba832..ea0a0e7 100644 --- a/runtime/vm/v8_snapshot_writer.h +++ b/runtime/vm/v8_snapshot_writer.h
@@ -58,7 +58,7 @@ private: static constexpr size_t kIdSpaceBits = Utils::BitLength(static_cast<int64_t>(IdSpace::kArtificial)); - static constexpr int64_t kIdSpaceMask = Utils::NBitMask(kIdSpaceBits); + static constexpr int64_t kIdSpaceMask = Utils::NBitMaskUnsafe(kIdSpaceBits); static const char* IdSpaceToCString(IdSpace space); int64_t encoded_;