Move dex2oat_test to ClassAccessor
Bug: 79758018
Test: test-art-host-gtest
Change-Id: I8c35763178055863e915dab5d45ce36c423e772a
diff --git a/dex2oat/dex2oat_test.cc b/dex2oat/dex2oat_test.cc
index 1196d11..2b96684 100644
--- a/dex2oat/dex2oat_test.cc
+++ b/dex2oat/dex2oat_test.cc
@@ -33,6 +33,7 @@
#include "dex/art_dex_file_loader.h"
#include "dex/base64_test_util.h"
#include "dex/bytecode_utils.h"
+#include "dex/class_accessor-inl.h"
#include "dex/code_item_accessors-inl.h"
#include "dex/dex_file-inl.h"
#include "dex/dex_file_loader.h"
@@ -960,19 +961,10 @@
// Iterate over the dex files and ensure there is no quickened instruction.
for (const OatDexFile* oat_dex_file : odex_file->GetOatDexFiles()) {
std::unique_ptr<const DexFile> dex_file = oat_dex_file->OpenDexFile(&error_msg);
- for (uint32_t i = 0; i < dex_file->NumClassDefs(); ++i) {
- const DexFile::ClassDef& class_def = dex_file->GetClassDef(i);
- const uint8_t* class_data = dex_file->GetClassData(class_def);
- if (class_data != nullptr) {
- for (ClassDataItemIterator class_it(*dex_file, class_data);
- class_it.HasNext();
- class_it.Next()) {
- if (class_it.IsAtMethod() && class_it.GetMethodCodeItem() != nullptr) {
- for (const DexInstructionPcPair& inst :
- CodeItemInstructionAccessor(*dex_file, class_it.GetMethodCodeItem())) {
- ASSERT_FALSE(inst->IsQuickened()) << inst->Opcode() << " " << output_;
- }
- }
+ for (ClassAccessor accessor : dex_file->GetClasses()) {
+ for (const ClassAccessor::Method& method : accessor.GetMethods()) {
+ for (const DexInstructionPcPair& inst : method.GetInstructions()) {
+ ASSERT_FALSE(inst->IsQuickened()) << inst->Opcode() << " " << output_;
}
}
}
@@ -1276,19 +1268,16 @@
{
const DexFile::TypeId* type_id = dex->FindTypeId("LManyMethods;");
dex::TypeIndex type_idx = dex->GetIndexForTypeId(*type_id);
- const DexFile::ClassDef* class_def = dex->FindClassDef(type_idx);
- ClassDataItemIterator it(*dex, dex->GetClassData(*class_def));
- it.SkipAllFields();
+ ClassAccessor accessor(*dex, *dex->FindClassDef(type_idx));
std::set<size_t> code_item_offsets;
- for (; it.HasNextMethod(); it.Next()) {
- const uint16_t method_idx = it.GetMemberIndex();
- const size_t code_item_offset = it.GetMethodCodeItemOffset();
+ for (const ClassAccessor::Method& method : accessor.GetMethods()) {
+ const uint16_t method_idx = method.GetIndex();
+ const size_t code_item_offset = method.GetCodeItemOffset();
if (code_item_offsets.insert(code_item_offset).second) {
// Unique code item, add the method index.
methods.push_back(method_idx);
}
}
- DCHECK(!it.HasNext());
}
ASSERT_GE(methods.size(), 8u);
std::vector<uint16_t> hot_methods = {methods[1], methods[3], methods[5]};
@@ -1391,11 +1380,10 @@
size_t unused_count = 0;
// Visit all of the methdos of the main class and cross reference the method indices to their
// corresponding code item offsets to verify the layout.
- ClassDataItemIterator it(*dex_file, dex_file->GetClassData(*class_def));
- it.SkipAllFields();
- for (; it.HasNextMethod(); it.Next()) {
- const size_t method_idx = it.GetMemberIndex();
- const size_t code_item_offset = it.GetMethodCodeItemOffset();
+ ClassAccessor accessor(*dex_file, *class_def);
+ for (const ClassAccessor::Method& method : accessor.GetMethods()) {
+ const size_t method_idx = method.GetIndex();
+ const size_t code_item_offset = method.GetCodeItemOffset();
const bool is_hot = ContainsElement(hot_methods, method_idx);
const bool is_startup = ContainsElement(startup_methods, method_idx);
const bool is_post_startup = ContainsElement(post_methods, method_idx);
@@ -1417,17 +1405,14 @@
++unused_count;
} else {
// or this method is part of the last code item and the end is 4 byte aligned.
- ClassDataItemIterator it2(*dex_file, dex_file->GetClassData(*class_def));
- it2.SkipAllFields();
- for (; it2.HasNextMethod(); it2.Next()) {
- EXPECT_LE(it2.GetMethodCodeItemOffset(), code_item_offset);
+ for (const ClassAccessor::Method& method2 : accessor.GetMethods()) {
+ EXPECT_LE(method2.GetCodeItemOffset(), code_item_offset);
}
uint32_t code_item_size = dex_file->FindCodeItemOffset(*class_def, method_idx);
EXPECT_EQ((code_item_offset + code_item_size) % 4, 0u);
}
}
}
- DCHECK(!it.HasNext());
EXPECT_GT(hot_count, 0u);
EXPECT_GT(post_startup_count, 0u);
EXPECT_GT(startup_count, 0u);
@@ -1478,14 +1463,13 @@
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());
+ for (ClassAccessor accessor : dex_file->GetClasses()) {
+ for (const ClassAccessor::Method& method : accessor.GetMethods()) {
+ if (method.GetCodeItemOffset() != 0u) {
+ ASSERT_GE(method.GetCodeItemOffset(), header.OwnedDataBegin());
+ ASSERT_LT(method.GetCodeItemOffset(), header.OwnedDataEnd());
}
- });
+ }
}
// Test that the owned sections don't overlap.
for (const std::unique_ptr<const CompactDexFile>& other_dex : compact_dex_files) {
@@ -1916,26 +1900,15 @@
MutateDexFile(temp_dex.GetFile(), GetTestDexFileName("ManyMethods"), [] (DexFile* dex) {
bool mutated_successfully = false;
// Change the dex instructions to make an opcode that spans past the end of the code item.
- for (size_t i = 0; i < dex->NumClassDefs(); ++i) {
- const DexFile::ClassDef& def = dex->GetClassDef(i);
- const uint8_t* data = dex->GetClassData(def);
- if (data == nullptr) {
- continue;
- }
- ClassDataItemIterator it(*dex, data);
- it.SkipAllFields();
- while (it.HasNextMethod()) {
- DexFile::CodeItem* item = const_cast<DexFile::CodeItem*>(it.GetMethodCodeItem());
- if (item != nullptr) {
- CodeItemInstructionAccessor instructions(*dex, item);
- // Make a quickened instruction that doesn't run past the end of the code item.
- if (instructions.InsnsSizeInCodeUnits() > 2) {
- const_cast<Instruction&>(instructions.InstructionAt(0)).SetOpcode(
- Instruction::IGET_BYTE_QUICK);
- mutated_successfully = true;
- }
+ for (ClassAccessor accessor : dex->GetClasses()) {
+ for (const ClassAccessor::Method& method : accessor.GetMethods()) {
+ CodeItemInstructionAccessor instructions = method.GetInstructions();
+ // Make a quickened instruction that doesn't run past the end of the code item.
+ if (instructions.InsnsSizeInCodeUnits() > 2) {
+ const_cast<Instruction&>(instructions.InstructionAt(0)).SetOpcode(
+ Instruction::IGET_BYTE_QUICK);
+ mutated_successfully = true;
}
- it.Next();
}
}
CHECK(mutated_successfully)