summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--compiler/optimizing/stack_map_stream.cc14
-rw-r--r--libartbase/base/bit_memory_region.h41
-rw-r--r--libartbase/base/bit_table.h4
-rw-r--r--libartbase/base/bit_table_test.cc12
-rw-r--r--runtime/oat.h4
-rw-r--r--runtime/stack_map.cc14
-rw-r--r--runtime/stack_map.h7
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