Generalize CompactDexDebugInfo offset table
Renamed the class to CompactOffsetTable.
Motivation: Use this table for quicken info offsets too.
Bug: 72608794
Bug: 63756964
Test: test-art-host-gtest
Change-Id: Idcb5355d8a5e4354bc3694152a7270047bed9d0a
diff --git a/dexlayout/compact_dex_writer.cc b/dexlayout/compact_dex_writer.cc
index 39cf86d..bd76bf1 100644
--- a/dexlayout/compact_dex_writer.cc
+++ b/dexlayout/compact_dex_writer.cc
@@ -19,8 +19,8 @@
#include "android-base/stringprintf.h"
#include "base/logging.h"
#include "base/time_utils.h"
-#include "dex/compact_dex_debug_info.h"
#include "dex/compact_dex_file.h"
+#include "dex/compact_offset_table.h"
#include "dexlayout.h"
namespace art {
@@ -76,12 +76,12 @@
std::vector<uint8_t> data;
debug_info_base_ = 0u;
debug_info_offsets_table_offset_ = 0u;
- CompactDexDebugInfoOffsetTable::Build(debug_info_offsets,
- &data,
- &debug_info_base_,
- &debug_info_offsets_table_offset_);
+ CompactOffsetTable::Build(debug_info_offsets,
+ &data,
+ &debug_info_base_,
+ &debug_info_offsets_table_offset_);
// Align the table and write it out.
- stream->AlignTo(CompactDexDebugInfoOffsetTable::kAlignment);
+ stream->AlignTo(CompactOffsetTable::kAlignment);
debug_info_offsets_pos_ = stream->Tell();
stream->Write(data.data(), data.size());
@@ -90,12 +90,12 @@
if (kMeasureAndTestOutput && !debug_info_offsets.empty()) {
uint64_t start_time = NanoTime();
stream->Begin();
- CompactDexDebugInfoOffsetTable::Accessor accessor(stream->Begin() + debug_info_offsets_pos_,
- debug_info_base_,
- debug_info_offsets_table_offset_);
+ CompactOffsetTable::Accessor accessor(stream->Begin() + debug_info_offsets_pos_,
+ debug_info_base_,
+ debug_info_offsets_table_offset_);
for (size_t i = 0; i < debug_info_offsets.size(); ++i) {
- CHECK_EQ(accessor.GetDebugInfoOffset(i), debug_info_offsets[i]);
+ CHECK_EQ(accessor.GetOffset(i), debug_info_offsets[i]);
}
uint64_t end_time = NanoTime();
VLOG(dex) << "Average lookup time (ns) for debug info offsets: "
diff --git a/libdexfile/Android.bp b/libdexfile/Android.bp
index 90c603f..382a46a 100644
--- a/libdexfile/Android.bp
+++ b/libdexfile/Android.bp
@@ -19,8 +19,8 @@
defaults: ["art_defaults"],
host_supported: true,
srcs: [
- "dex/compact_dex_debug_info.cc",
"dex/compact_dex_file.cc",
+ "dex/compact_offset_table.cc",
"dex/descriptors_names.cc",
"dex/dex_file.cc",
"dex/dex_file_exception_helpers.cc",
@@ -108,8 +108,8 @@
],
srcs: [
"dex/code_item_accessors_test.cc",
- "dex/compact_dex_debug_info_test.cc",
"dex/compact_dex_file_test.cc",
+ "dex/compact_offset_table_test.cc",
"dex/dex_file_loader_test.cc",
"dex/dex_file_verifier_test.cc",
"dex/dex_instruction_test.cc",
diff --git a/libdexfile/dex/compact_dex_file.h b/libdexfile/dex/compact_dex_file.h
index 47b170c..2bea071 100644
--- a/libdexfile/dex/compact_dex_file.h
+++ b/libdexfile/dex/compact_dex_file.h
@@ -19,7 +19,7 @@
#include "base/casts.h"
#include "dex_file.h"
-#include "dex/compact_dex_debug_info.h"
+#include "dex/compact_offset_table.h"
namespace art {
@@ -260,7 +260,7 @@
uint32_t GetCodeItemSize(const DexFile::CodeItem& item) const OVERRIDE;
uint32_t GetDebugInfoOffset(uint32_t dex_method_index) const {
- return debug_info_offsets_.GetDebugInfoOffset(dex_method_index);
+ return debug_info_offsets_.GetOffset(dex_method_index);
}
static uint32_t CalculateChecksum(const uint8_t* base_begin,
@@ -279,7 +279,7 @@
const OatDexFile* oat_dex_file,
DexFileContainer* container);
- CompactDexDebugInfoOffsetTable::Accessor debug_info_offsets_;
+ CompactOffsetTable::Accessor debug_info_offsets_;
friend class DexFile;
friend class DexFileLoader;
diff --git a/libdexfile/dex/compact_dex_debug_info.cc b/libdexfile/dex/compact_offset_table.cc
similarity index 61%
rename from libdexfile/dex/compact_dex_debug_info.cc
rename to libdexfile/dex/compact_offset_table.cc
index 19495ca..8cee0e3 100644
--- a/libdexfile/dex/compact_dex_debug_info.cc
+++ b/libdexfile/dex/compact_offset_table.cc
@@ -14,25 +14,25 @@
* limitations under the License.
*/
-#include "compact_dex_debug_info.h"
+#include "compact_offset_table.h"
#include "compact_dex_utils.h"
#include "leb128.h"
namespace art {
-constexpr size_t CompactDexDebugInfoOffsetTable::kElementsPerIndex;
+constexpr size_t CompactOffsetTable::kElementsPerIndex;
-CompactDexDebugInfoOffsetTable::Accessor::Accessor(const uint8_t* data_begin,
- uint32_t debug_info_base,
- uint32_t debug_info_table_offset)
- : table_(reinterpret_cast<const uint32_t*>(data_begin + debug_info_table_offset)),
- debug_info_base_(debug_info_base),
+CompactOffsetTable::Accessor::Accessor(const uint8_t* data_begin,
+ uint32_t minimum_offset,
+ uint32_t table_offset)
+ : table_(reinterpret_cast<const uint32_t*>(data_begin + table_offset)),
+ minimum_offset_(minimum_offset),
data_begin_(data_begin) {}
-uint32_t CompactDexDebugInfoOffsetTable::Accessor::GetDebugInfoOffset(uint32_t method_idx) const {
- const uint32_t offset = table_[method_idx / kElementsPerIndex];
- const size_t bit_index = method_idx % kElementsPerIndex;
+uint32_t CompactOffsetTable::Accessor::GetOffset(uint32_t index) const {
+ const uint32_t offset = table_[index / kElementsPerIndex];
+ const size_t bit_index = index % kElementsPerIndex;
const uint8_t* block = data_begin_ + offset;
uint16_t bit_mask = *block;
@@ -40,14 +40,14 @@
bit_mask = (bit_mask << kBitsPerByte) | *block;
++block;
if ((bit_mask & (1 << bit_index)) == 0) {
- // Bit is not set means the offset is 0 for the debug info.
+ // Bit is not set means the offset is 0.
return 0u;
}
// Trim off the bits above the index we want and count how many bits are set. This is how many
// lebs we need to decode.
size_t count = POPCOUNT(static_cast<uintptr_t>(bit_mask) << (kBitsPerIntPtrT - 1 - bit_index));
DCHECK_GT(count, 0u);
- uint32_t current_offset = debug_info_base_;
+ uint32_t current_offset = minimum_offset_;
do {
current_offset += DecodeUnsignedLeb128(&block);
--count;
@@ -55,15 +55,15 @@
return current_offset;
}
-void CompactDexDebugInfoOffsetTable::Build(const std::vector<uint32_t>& debug_info_offsets,
- std::vector<uint8_t>* out_data,
- uint32_t* out_min_offset,
- uint32_t* out_table_offset) {
+void CompactOffsetTable::Build(const std::vector<uint32_t>& offsets,
+ std::vector<uint8_t>* out_data,
+ uint32_t* out_min_offset,
+ uint32_t* out_table_offset) {
DCHECK(out_data != nullptr);
DCHECK(out_data->empty());
// Calculate the base offset and return it.
*out_min_offset = std::numeric_limits<uint32_t>::max();
- for (const uint32_t offset : debug_info_offsets) {
+ for (const uint32_t offset : offsets) {
if (offset != 0u) {
*out_min_offset = std::min(*out_min_offset, offset);
}
@@ -74,17 +74,17 @@
std::vector<uint32_t> offset_table;
// Write data first then the table.
- while (block_start < debug_info_offsets.size()) {
+ while (block_start < offsets.size()) {
// Write the offset of the block for each block.
offset_table.push_back(out_data->size());
// Block size of up to kElementsPerIndex
- const size_t block_size = std::min(debug_info_offsets.size() - block_start, kElementsPerIndex);
+ const size_t block_size = std::min(offsets.size() - block_start, kElementsPerIndex);
// Calculate bit mask since need to write that first.
uint16_t bit_mask = 0u;
for (size_t i = 0; i < block_size; ++i) {
- if (debug_info_offsets[block_start + i] != 0u) {
+ if (offsets[block_start + i] != 0u) {
bit_mask |= 1 << i;
}
}
@@ -92,14 +92,14 @@
out_data->push_back(static_cast<uint8_t>(bit_mask >> kBitsPerByte));
out_data->push_back(static_cast<uint8_t>(bit_mask));
- // Write debug info offsets relative to the current offset.
- uint32_t current_offset = *out_min_offset;
+ // Write offsets relative to the previous offset.
+ uint32_t prev_offset = *out_min_offset;
for (size_t i = 0; i < block_size; ++i) {
- const uint32_t debug_info_offset = debug_info_offsets[block_start + i];
- if (debug_info_offset != 0u) {
- uint32_t delta = debug_info_offset - current_offset;
+ const uint32_t offset = offsets[block_start + i];
+ if (offset != 0u) {
+ uint32_t delta = offset - prev_offset;
EncodeUnsignedLeb128(out_data, delta);
- current_offset = debug_info_offset;
+ prev_offset = offset;
}
}
diff --git a/libdexfile/dex/compact_dex_debug_info.h b/libdexfile/dex/compact_offset_table.h
similarity index 63%
rename from libdexfile/dex/compact_dex_debug_info.h
rename to libdexfile/dex/compact_offset_table.h
index bfd0bbe..17e6bb4 100644
--- a/libdexfile/dex/compact_dex_debug_info.h
+++ b/libdexfile/dex/compact_offset_table.h
@@ -14,44 +14,44 @@
* limitations under the License.
*/
-#ifndef ART_LIBDEXFILE_DEX_COMPACT_DEX_DEBUG_INFO_H_
-#define ART_LIBDEXFILE_DEX_COMPACT_DEX_DEBUG_INFO_H_
+#ifndef ART_LIBDEXFILE_DEX_COMPACT_OFFSET_TABLE_H_
+#define ART_LIBDEXFILE_DEX_COMPACT_OFFSET_TABLE_H_
#include <cstdint>
#include <vector>
namespace art {
-// Debug offset table for compact dex, aims to minimize size while still providing reasonable
-// speed (10-20ns average time per lookup on host).
-class CompactDexDebugInfoOffsetTable {
+// Compact offset table that aims to minimize size while still providing reasonable speed (10-20ns
+// average time per lookup on host).
+class CompactOffsetTable {
public:
// This value is coupled with the leb chunk bitmask. That logic must also be adjusted when the
// integer is modified.
static constexpr size_t kElementsPerIndex = 16;
// Leb block format:
- // [uint16_t] 16 bit mask for what method ids actually have a debug info offset for the chunk.
+ // [uint16_t] 16 bit mask for what indexes actually have a non zero offset for the chunk.
// [lebs] Up to 16 lebs encoded using leb128, one leb bit. The leb specifies how the offset
// changes compared to the previous index.
class Accessor {
public:
Accessor(const uint8_t* data_begin,
- uint32_t debug_info_base,
- uint32_t debug_info_table_offset);
+ uint32_t minimum_offset,
+ uint32_t table_offset);
- // Return the debug info for a method index (or 0 if it doesn't have one).
- uint32_t GetDebugInfoOffset(uint32_t method_idx) const;
+ // Return the offset for the index.
+ uint32_t GetOffset(uint32_t index) const;
private:
const uint32_t* const table_;
- const uint32_t debug_info_base_;
+ const uint32_t minimum_offset_;
const uint8_t* const data_begin_;
};
- // Returned offsets are all relative to debug_info_offsets.
- static void Build(const std::vector<uint32_t>& debug_info_offsets,
+ // Returned offsets are all relative to out_min_offset.
+ static void Build(const std::vector<uint32_t>& offsets,
std::vector<uint8_t>* out_data,
uint32_t* out_min_offset,
uint32_t* out_table_offset);
@@ -62,4 +62,4 @@
} // namespace art
-#endif // ART_LIBDEXFILE_DEX_COMPACT_DEX_DEBUG_INFO_H_
+#endif // ART_LIBDEXFILE_DEX_COMPACT_OFFSET_TABLE_H_
diff --git a/libdexfile/dex/compact_dex_debug_info_test.cc b/libdexfile/dex/compact_offset_table_test.cc
similarity index 72%
rename from libdexfile/dex/compact_dex_debug_info_test.cc
rename to libdexfile/dex/compact_offset_table_test.cc
index 7911a86..7eb0156 100644
--- a/libdexfile/dex/compact_dex_debug_info_test.cc
+++ b/libdexfile/dex/compact_offset_table_test.cc
@@ -17,12 +17,12 @@
#include <vector>
#include <android-base/logging.h>
-#include "dex/compact_dex_debug_info.h"
+#include "dex/compact_offset_table.h"
#include "gtest/gtest.h"
namespace art {
-TEST(CompactDexDebugInfoTest, TestBuildAndAccess) {
+TEST(CompactOffsetTableTest, TestBuildAndAccess) {
const size_t kDebugInfoMinOffset = 1234567;
std::vector<uint32_t> offsets = {
0, 17, 2, 3, 11, 0, 0, 0, 0, 1, 0, 1552, 100, 122, 44, 1234567, 0, 0,
@@ -38,13 +38,10 @@
}
std::vector<uint8_t> data;
- uint32_t base_offset = 0;
+ uint32_t min_offset = 0;
uint32_t table_offset = 0;
- CompactDexDebugInfoOffsetTable::Build(offsets,
- /*out*/ &data,
- /*out*/ &base_offset,
- /*out*/ &table_offset);
- EXPECT_GE(base_offset, kDebugInfoMinOffset);
+ CompactOffsetTable::Build(offsets, /*out*/ &data, /*out*/ &min_offset, /*out*/ &table_offset);
+ EXPECT_GE(min_offset, kDebugInfoMinOffset);
EXPECT_LT(table_offset, data.size());
ASSERT_GT(data.size(), 0u);
const size_t before_size = offsets.size() * sizeof(offsets.front());
@@ -57,21 +54,19 @@
std::vector<uint8_t> fake_dex(data.size() + kExtraOffset);
std::copy(data.begin(), data.end(), fake_dex.data() + kExtraOffset);
- CompactDexDebugInfoOffsetTable::Accessor accessor(fake_dex.data() + kExtraOffset,
- base_offset,
- table_offset);
+ CompactOffsetTable::Accessor accessor(fake_dex.data() + kExtraOffset, min_offset, table_offset);
for (size_t i = 0; i < offsets.size(); ++i) {
- EXPECT_EQ(offsets[i], accessor.GetDebugInfoOffset(i));
+ EXPECT_EQ(offsets[i], accessor.GetOffset(i));
}
// Sort to produce a try and produce a smaller table. This happens because the leb diff is smaller
// for sorted increasing order.
std::sort(offsets.begin(), offsets.end());
std::vector<uint8_t> sorted_data;
- CompactDexDebugInfoOffsetTable::Build(offsets,
- /*out*/ &sorted_data,
- /*out*/ &base_offset,
- /*out*/ &table_offset);
+ CompactOffsetTable::Build(offsets,
+ /*out*/ &sorted_data,
+ /*out*/ &min_offset,
+ /*out*/ &table_offset);
EXPECT_LT(sorted_data.size(), data.size());
{
android::base::ScopedLogSeverity sls(android::base::LogSeverity::INFO);