Add owned section for CompactDex
The owned section is the part of the shared data section owned by
a given dex file. This enables efficiently attributing an offset to
a dex file.
Bug: 74443371
Bug: 63756964
Test: test-art-host
Change-Id: I2de9a281e18b02a20c3dcf5f484eacb591220cdc
diff --git a/dex2oat/dex2oat_test.cc b/dex2oat/dex2oat_test.cc
index 094dfee..09ff14e 100644
--- a/dex2oat/dex2oat_test.cc
+++ b/dex2oat/dex2oat_test.cc
@@ -1465,14 +1465,14 @@
// Test that generating compact dex works.
TEST_F(Dex2oatTest, GenerateCompactDex) {
- std::unique_ptr<const DexFile> dex(OpenTestDexFile("ManyMethods"));
// Generate a compact dex based odex.
const std::string dir = GetScratchDir();
const std::string oat_filename = dir + "/base.oat";
const std::string vdex_filename = dir + "/base.vdex";
+ const std::string dex_location = GetTestDexFileName("MultiDex");
std::string error_msg;
const int res = GenerateOdexForTestWithStatus(
- {dex->GetLocation()},
+ { dex_location },
oat_filename,
CompilerFilter::Filter::kQuicken,
&error_msg,
@@ -1485,16 +1485,43 @@
nullptr,
false,
/*low_4gb*/false,
- dex->GetLocation().c_str(),
+ dex_location.c_str(),
&error_msg));
ASSERT_TRUE(odex_file != nullptr);
std::vector<const OatDexFile*> oat_dex_files = odex_file->GetOatDexFiles();
- ASSERT_EQ(oat_dex_files.size(), 1u);
- // Check that each dex is a compact dex.
+ ASSERT_GT(oat_dex_files.size(), 1u);
+ // Check that each dex is a compact dex file.
+ std::vector<std::unique_ptr<const CompactDexFile>> compact_dex_files;
for (const OatDexFile* oat_dex : oat_dex_files) {
std::unique_ptr<const DexFile> dex_file(oat_dex->OpenDexFile(&error_msg));
ASSERT_TRUE(dex_file != nullptr) << error_msg;
ASSERT_TRUE(dex_file->IsCompactDexFile());
+ compact_dex_files.push_back(
+ std::unique_ptr<const CompactDexFile>(dex_file.release()->AsCompactDexFile()));
+ }
+ for (const std::unique_ptr<const CompactDexFile>& dex_file : compact_dex_files) {
+ // Test that every code item is in the owned section.
+ const CompactDexFile::Header& header = dex_file->GetHeader();
+ EXPECT_LE(header.OwnedDataBegin(), header.OwnedDataEnd());
+ EXPECT_LE(header.OwnedDataBegin(), header.data_size_);
+ EXPECT_LE(header.OwnedDataEnd(), header.data_size_);
+ for (uint32_t i = 0; i < dex_file->NumClassDefs(); ++i) {
+ const DexFile::ClassDef& class_def = dex_file->GetClassDef(i);
+ class_def.VisitMethods(dex_file.get(), [&](const ClassDataItemIterator& it) {
+ if (it.GetMethodCodeItemOffset() != 0u) {
+ ASSERT_GE(it.GetMethodCodeItemOffset(), header.OwnedDataBegin());
+ ASSERT_LT(it.GetMethodCodeItemOffset(), header.OwnedDataEnd());
+ }
+ });
+ }
+ // Test that the owned sections don't overlap.
+ for (const std::unique_ptr<const CompactDexFile>& other_dex : compact_dex_files) {
+ if (dex_file != other_dex) {
+ ASSERT_TRUE(
+ (dex_file->GetHeader().OwnedDataBegin() >= other_dex->GetHeader().OwnedDataEnd()) ||
+ (dex_file->GetHeader().OwnedDataEnd() <= other_dex->GetHeader().OwnedDataBegin()));
+ }
+ }
}
}