diff options
-rw-r--r-- | compiler/optimizing/stack_map_stream.cc | 14 | ||||
-rw-r--r-- | libartbase/base/bit_memory_region.h | 41 | ||||
-rw-r--r-- | libartbase/base/bit_table.h | 4 | ||||
-rw-r--r-- | libartbase/base/bit_table_test.cc | 12 | ||||
-rw-r--r-- | runtime/oat.h | 4 | ||||
-rw-r--r-- | runtime/stack_map.cc | 14 | ||||
-rw-r--r-- | runtime/stack_map.h | 7 |
7 files changed, 51 insertions, 45 deletions
diff --git a/compiler/optimizing/stack_map_stream.cc b/compiler/optimizing/stack_map_stream.cc index cb988050ff..5d361953ba 100644 --- a/compiler/optimizing/stack_map_stream.cc +++ b/compiler/optimizing/stack_map_stream.cc @@ -339,22 +339,24 @@ size_t StackMapStream::PrepareForFillIn() { dex_register_maps_.Encode(out); dex_register_catalog_.Encode(out); - return UnsignedLeb128Size(out_.size()) + out_.size(); + return out_.size(); } void StackMapStream::FillInCodeInfo(MemoryRegion region) { DCHECK(in_stack_map_ == false) << "Mismatched Begin/End calls"; DCHECK(in_inline_info_ == false) << "Mismatched Begin/End calls"; DCHECK_NE(0u, out_.size()) << "PrepareForFillIn not called before FillIn"; - DCHECK_EQ(region.size(), UnsignedLeb128Size(out_.size()) + out_.size()); + DCHECK_EQ(region.size(), out_.size()); - uint8_t* ptr = EncodeUnsignedLeb128(region.begin(), out_.size()); - region.CopyFromVector(ptr - region.begin(), out_); + region.CopyFromVector(0, out_); + + // Verify that we can load the CodeInfo and check some essentials. + CodeInfo code_info(region); + CHECK_EQ(code_info.Size(), out_.size()); + CHECK_EQ(code_info.GetNumberOfStackMaps(), stack_maps_.size()); // Verify all written data (usually only in debug builds). if (kVerifyStackMaps) { - CodeInfo code_info(region); - CHECK_EQ(code_info.GetNumberOfStackMaps(), stack_maps_.size()); for (const auto& dcheck : dchecks_) { dcheck(code_info); } diff --git a/libartbase/base/bit_memory_region.h b/libartbase/base/bit_memory_region.h index 6e491b0868..07c1611c60 100644 --- a/libartbase/base/bit_memory_region.h +++ b/libartbase/base/bit_memory_region.h @@ -57,6 +57,15 @@ class BitMemoryRegion FINAL : public ValueObject { return result; } + // Increase the size of the region and return the newly added range (starting at the old end). + ALWAYS_INLINE BitMemoryRegion Extend(size_t bit_length) { + BitMemoryRegion result = *this; + result.bit_start_ += result.bit_size_; + result.bit_size_ = bit_length; + bit_size_ += bit_length; + return result; + } + // Load a single bit in the region. The bit at offset 0 is the least // significant bit in the first byte. ATTRIBUTE_NO_SANITIZE_ADDRESS // We might touch extra bytes due to the alignment. @@ -167,26 +176,26 @@ class BitMemoryRegion FINAL : public ValueObject { class BitMemoryReader { public: - explicit BitMemoryReader(BitMemoryRegion region, size_t bit_offset = 0) - : region_(region), bit_offset_(bit_offset) { } + explicit BitMemoryReader(const uint8_t* data, size_t bit_offset = 0) { + MemoryRegion region(const_cast<uint8_t*>(data), BitsToBytesRoundUp(bit_offset)); + finished_region_ = BitMemoryRegion(region, 0, bit_offset); + DCHECK_EQ(GetBitOffset(), bit_offset); + } - size_t GetBitOffset() const { return bit_offset_; } + size_t GetBitOffset() const { return finished_region_.size_in_bits(); } ALWAYS_INLINE BitMemoryRegion Skip(size_t bit_length) { - BitMemoryRegion result = region_.Subregion(bit_offset_, bit_length); - bit_offset_ += bit_length; - return result; + return finished_region_.Extend(bit_length); } ALWAYS_INLINE uint32_t ReadBits(size_t bit_length) { - uint32_t result = region_.LoadBits(bit_offset_, bit_length); - bit_offset_ += bit_length; - return result; + return finished_region_.Extend(bit_length).LoadBits(0, bit_length); } private: - BitMemoryRegion region_; - size_t bit_offset_; + // Represents all of the bits which were read so far. There is no upper bound. + // Therefore, by definition, the "cursor" is always at the end of the region. + BitMemoryRegion finished_region_; DISALLOW_COPY_AND_ASSIGN(BitMemoryReader); }; @@ -195,7 +204,11 @@ template<typename Vector> class BitMemoryWriter { public: explicit BitMemoryWriter(Vector* out, size_t bit_offset = 0) - : out_(out), bit_offset_(bit_offset) { } + : out_(out), bit_offset_(bit_offset) { + DCHECK_EQ(GetBitOffset(), bit_offset); + } + + const uint8_t* data() const { return out_->data(); } size_t GetBitOffset() const { return bit_offset_; } @@ -210,10 +223,6 @@ class BitMemoryWriter { Allocate(bit_length).StoreBits(0, value, bit_length); } - BitMemoryRegion GetWrittenRegion() const { - return BitMemoryRegion(MemoryRegion(out_->data(), out_->size()), 0, bit_offset_); - } - private: Vector* out_; size_t bit_offset_; diff --git a/libartbase/base/bit_table.h b/libartbase/base/bit_table.h index 418d7c4251..b0fc4d1d1b 100644 --- a/libartbase/base/bit_table.h +++ b/libartbase/base/bit_table.h @@ -355,7 +355,7 @@ class BitTableBuilderBase { // Verify the written data. if (kIsDebugBuild) { BitTableBase<kNumColumns> table; - BitMemoryReader reader(out.GetWrittenRegion(), initial_bit_offset); + BitMemoryReader reader(out.data(), initial_bit_offset); table.Decode(reader); DCHECK_EQ(size(), table.NumRows()); for (uint32_t c = 0; c < kNumColumns; c++) { @@ -441,7 +441,7 @@ class BitmapTableBuilder { // Verify the written data. if (kIsDebugBuild) { BitTableBase<1> table; - BitMemoryReader reader(out.GetWrittenRegion(), initial_bit_offset); + BitMemoryReader reader(out.data(), initial_bit_offset); table.Decode(reader); DCHECK_EQ(size(), table.NumRows()); DCHECK_EQ(max_num_bits_, table.NumColumnBits(0)); diff --git a/libartbase/base/bit_table_test.cc b/libartbase/base/bit_table_test.cc index a6941487b2..2fd9052516 100644 --- a/libartbase/base/bit_table_test.cc +++ b/libartbase/base/bit_table_test.cc @@ -34,7 +34,7 @@ TEST(BitTableTest, TestVarint) { BitMemoryWriter<std::vector<uint8_t>> writer(&buffer, start_bit_offset); EncodeVarintBits(writer, value); - BitMemoryReader reader(writer.GetWrittenRegion(), start_bit_offset); + BitMemoryReader reader(buffer.data(), start_bit_offset); uint32_t result = DecodeVarintBits(reader); EXPECT_EQ(writer.GetBitOffset(), reader.GetBitOffset()); EXPECT_EQ(value, result); @@ -52,7 +52,7 @@ TEST(BitTableTest, TestEmptyTable) { BitTableBuilderBase<1> builder(&allocator); builder.Encode(writer); - BitMemoryReader reader(writer.GetWrittenRegion()); + BitMemoryReader reader(buffer.data()); BitTableBase<1> table(reader); EXPECT_EQ(writer.GetBitOffset(), reader.GetBitOffset()); EXPECT_EQ(0u, table.NumRows()); @@ -73,7 +73,7 @@ TEST(BitTableTest, TestSingleColumnTable) { builder.Add({kNoValue}); builder.Encode(writer); - BitMemoryReader reader(writer.GetWrittenRegion()); + BitMemoryReader reader(buffer.data()); BitTableBase<1> table(reader); EXPECT_EQ(writer.GetBitOffset(), reader.GetBitOffset()); EXPECT_EQ(4u, table.NumRows()); @@ -96,7 +96,7 @@ TEST(BitTableTest, TestUnalignedTable) { builder.Add({42u}); builder.Encode(writer); - BitMemoryReader reader(writer.GetWrittenRegion(), start_bit_offset); + BitMemoryReader reader(buffer.data(), start_bit_offset); BitTableBase<1> table(reader); EXPECT_EQ(writer.GetBitOffset(), reader.GetBitOffset()); EXPECT_EQ(1u, table.NumRows()); @@ -117,7 +117,7 @@ TEST(BitTableTest, TestBigTable) { builder.Add({62u, kNoValue, 63u, static_cast<uint32_t>(-3)}); builder.Encode(writer); - BitMemoryReader reader(writer.GetWrittenRegion()); + BitMemoryReader reader(buffer.data()); BitTableBase<4> table(reader); EXPECT_EQ(writer.GetBitOffset(), reader.GetBitOffset()); EXPECT_EQ(2u, table.NumRows()); @@ -167,7 +167,7 @@ TEST(BitTableTest, TestBitmapTable) { builder.Encode(writer); EXPECT_EQ(1 + static_cast<uint32_t>(POPCOUNT(value)), builder.size()); - BitMemoryReader reader(writer.GetWrittenRegion()); + BitMemoryReader reader(buffer.data()); BitTableBase<1> table(reader); EXPECT_EQ(writer.GetBitOffset(), reader.GetBitOffset()); for (auto it : indicies) { diff --git a/runtime/oat.h b/runtime/oat.h index 02fad46a0d..6c3cc20032 100644 --- a/runtime/oat.h +++ b/runtime/oat.h @@ -32,8 +32,8 @@ class InstructionSetFeatures; class PACKED(4) OatHeader { public: static constexpr uint8_t kOatMagic[] = { 'o', 'a', 't', '\n' }; - // Last oat version changed reason: Add method frame info to CodeInfo. - static constexpr uint8_t kOatVersion[] = { '1', '5', '0', '\0' }; + // Last oat version changed reason: Remove explicit size from CodeInfo. + static constexpr uint8_t kOatVersion[] = { '1', '5', '1', '\0' }; static constexpr const char* kImageLocationKey = "image-location"; static constexpr const char* kDex2OatCmdLineKey = "dex2oat-cmdline"; diff --git a/runtime/stack_map.cc b/runtime/stack_map.cc index 42d24784de..a3c6e05045 100644 --- a/runtime/stack_map.cc +++ b/runtime/stack_map.cc @@ -32,15 +32,12 @@ CodeInfo::CodeInfo(const OatQuickMethodHeader* header) } void CodeInfo::Decode(const uint8_t* data) { - size_t non_header_size = DecodeUnsignedLeb128(&data); - size_ = UnsignedLeb128Size(non_header_size) + non_header_size; - const uint8_t* end = data + non_header_size; + const uint8_t* begin = data; frame_size_in_bytes_ = DecodeUnsignedLeb128(&data); core_spill_mask_ = DecodeUnsignedLeb128(&data); fp_spill_mask_ = DecodeUnsignedLeb128(&data); number_of_dex_registers_ = DecodeUnsignedLeb128(&data); - MemoryRegion region(const_cast<uint8_t*>(data), end - data); - BitMemoryReader reader(BitMemoryRegion(region), /* bit_offset */ 0); + BitMemoryReader reader(data, /* bit_offset */ 0); stack_maps_.Decode(reader); register_masks_.Decode(reader); stack_masks_.Decode(reader); @@ -49,7 +46,7 @@ void CodeInfo::Decode(const uint8_t* data) { dex_register_masks_.Decode(reader); dex_register_maps_.Decode(reader); dex_register_catalog_.Decode(reader); - CHECK_EQ(BitsToBytesRoundUp(reader.GetBitOffset()), region.size()) << "Invalid CodeInfo"; + size_in_bits_ = (data - begin) * kBitsPerByte + reader.GetBitOffset(); } BitTable<StackMap>::const_iterator CodeInfo::BinarySearchNativePc(uint32_t packed_pc) const { @@ -154,8 +151,7 @@ static void AddTableSizeStats(const char* table_name, void CodeInfo::AddSizeStats(/*out*/ Stats* parent) const { Stats* stats = parent->Child("CodeInfo"); - stats->AddBytes(size_); - stats->Child("Header")->AddBytes(UnsignedLeb128Size(size_)); + stats->AddBytes(Size()); AddTableSizeStats<StackMap>("StackMaps", stack_maps_, stats); AddTableSizeStats<RegisterMask>("RegisterMasks", register_masks_, stats); AddTableSizeStats<MaskInfo>("StackMasks", stack_masks_, stats); @@ -222,7 +218,7 @@ void CodeInfo::Dump(VariableIndentationOutputStream* vios, const MethodInfo& method_info) const { vios->Stream() << "CodeInfo" - << " BitSize=" << size_ * kBitsPerByte + << " BitSize=" << size_in_bits_ << "\n"; ScopedIndentation indent1(vios); DumpTable<StackMap>(vios, "StackMaps", stack_maps_, verbose); diff --git a/runtime/stack_map.h b/runtime/stack_map.h index cb43ced2a5..ad52f377cf 100644 --- a/runtime/stack_map.h +++ b/runtime/stack_map.h @@ -289,13 +289,13 @@ class CodeInfo { } explicit CodeInfo(MemoryRegion region) : CodeInfo(region.begin()) { - DCHECK_EQ(size_, region.size()); + DCHECK_EQ(Size(), region.size()); } explicit CodeInfo(const OatQuickMethodHeader* header); size_t Size() const { - return size_; + return BitsToBytesRoundUp(size_in_bits_); } bool HasInlineInfo() const { @@ -436,7 +436,6 @@ class CodeInfo { void AddSizeStats(/*out*/ Stats* parent) const; ALWAYS_INLINE static QuickMethodFrameInfo DecodeFrameInfo(const uint8_t* data) { - DecodeUnsignedLeb128(&data); return QuickMethodFrameInfo( DecodeUnsignedLeb128(&data), DecodeUnsignedLeb128(&data), @@ -455,7 +454,6 @@ class CodeInfo { void Decode(const uint8_t* data); - size_t size_; uint32_t frame_size_in_bytes_; uint32_t core_spill_mask_; uint32_t fp_spill_mask_; @@ -468,6 +466,7 @@ class CodeInfo { BitTable<MaskInfo> dex_register_masks_; BitTable<DexRegisterMapInfo> dex_register_maps_; BitTable<DexRegisterInfo> dex_register_catalog_; + uint32_t size_in_bits_; }; #undef ELEMENT_BYTE_OFFSET_AFTER |