Move dexdump, dexlist, openjdkjvmti to ClassAccessor
Test: test-art-host
Bug: 79758018
Change-Id: Iecdcf81b9dd2fa5cd938579847d4934467abf813
diff --git a/dexdump/dexdump.cc b/dexdump/dexdump.cc
index 060d079..f8274e2 100644
--- a/dexdump/dexdump.cc
+++ b/dexdump/dexdump.cc
@@ -1212,18 +1212,19 @@
/*
* Dumps a method.
*/
-static void dumpMethod(const DexFile* pDexFile, u4 idx, u4 flags,
- const DexFile::CodeItem* pCode, u4 codeOffset, int i) {
+static void dumpMethod(const ClassAccessor::Method& method, int i) {
// Bail for anything private if export only requested.
+ const uint32_t flags = method.GetRawAccessFlags();
if (gOptions.exportsOnly && (flags & (kAccPublic | kAccProtected)) == 0) {
return;
}
- const DexFile::MethodId& pMethodId = pDexFile->GetMethodId(idx);
- const char* name = pDexFile->StringDataByIdx(pMethodId.name_idx_);
- const Signature signature = pDexFile->GetMethodSignature(pMethodId);
+ const DexFile& dex_file = method.GetDexFile();
+ const DexFile::MethodId& pMethodId = dex_file.GetMethodId(method.GetIndex());
+ const char* name = dex_file.StringDataByIdx(pMethodId.name_idx_);
+ const Signature signature = dex_file.GetMethodSignature(pMethodId);
char* typeDescriptor = strdup(signature.ToString().c_str());
- const char* backDescriptor = pDexFile->StringByTypeIdx(pMethodId.class_idx_);
+ const char* backDescriptor = dex_file.StringByTypeIdx(pMethodId.class_idx_);
char* accessStr = createAccessFlagStr(flags, kAccessForMethod);
if (gOptions.outputFormat == OUTPUT_PLAIN) {
@@ -1231,11 +1232,15 @@
fprintf(gOutFile, " name : '%s'\n", name);
fprintf(gOutFile, " type : '%s'\n", typeDescriptor);
fprintf(gOutFile, " access : 0x%04x (%s)\n", flags, accessStr);
- if (pCode == nullptr) {
+ if (method.GetCodeItem() == nullptr) {
fprintf(gOutFile, " code : (none)\n");
} else {
fprintf(gOutFile, " code -\n");
- dumpCode(pDexFile, idx, flags, pCode, codeOffset);
+ dumpCode(&dex_file,
+ method.GetIndex(),
+ flags,
+ method.GetCodeItem(),
+ method.GetCodeItemOffset());
}
if (gOptions.disassemble) {
fputc('\n', gOutFile);
@@ -1316,18 +1321,20 @@
}
/*
- * Dumps a static (class) field.
+ * Dumps a static or instance (class) field.
*/
-static void dumpSField(const DexFile* pDexFile, u4 idx, u4 flags, int i, const u1** data) {
+static void dumpField(const ClassAccessor::Field& field, int i, const u1** data = nullptr) {
// Bail for anything private if export only requested.
+ const uint32_t flags = field.GetRawAccessFlags();
if (gOptions.exportsOnly && (flags & (kAccPublic | kAccProtected)) == 0) {
return;
}
- const DexFile::FieldId& pFieldId = pDexFile->GetFieldId(idx);
- const char* name = pDexFile->StringDataByIdx(pFieldId.name_idx_);
- const char* typeDescriptor = pDexFile->StringByTypeIdx(pFieldId.type_idx_);
- const char* backDescriptor = pDexFile->StringByTypeIdx(pFieldId.class_idx_);
+ const DexFile& dex_file = field.GetDexFile();
+ const DexFile::FieldId& field_id = dex_file.GetFieldId(field.GetIndex());
+ const char* name = dex_file.StringDataByIdx(field_id.name_idx_);
+ const char* typeDescriptor = dex_file.StringByTypeIdx(field_id.type_idx_);
+ const char* backDescriptor = dex_file.StringByTypeIdx(field_id.class_idx_);
char* accessStr = createAccessFlagStr(flags, kAccessForField);
if (gOptions.outputFormat == OUTPUT_PLAIN) {
@@ -1337,7 +1344,7 @@
fprintf(gOutFile, " access : 0x%04x (%s)\n", flags, accessStr);
if (data != nullptr) {
fputs(" value : ", gOutFile);
- dumpEncodedValue(pDexFile, data);
+ dumpEncodedValue(&dex_file, data);
fputs("\n", gOutFile);
}
} else if (gOptions.outputFormat == OUTPUT_XML) {
@@ -1353,7 +1360,7 @@
fprintf(gOutFile, " visibility=%s\n", quotedVisibility(flags));
if (data != nullptr) {
fputs(" value=\"", gOutFile);
- dumpEncodedValue(pDexFile, data);
+ dumpEncodedValue(&dex_file, data);
fputs("\"\n", gOutFile);
}
fputs(">\n</field>\n", gOutFile);
@@ -1363,41 +1370,16 @@
}
/*
- * Dumps an instance field.
+ * Dumping a CFG.
*/
-static void dumpIField(const DexFile* pDexFile, u4 idx, u4 flags, int i) {
- dumpSField(pDexFile, idx, flags, i, nullptr);
-}
-
-/*
- * Dumping a CFG. Note that this will do duplicate work. utils.h doesn't expose the code-item
- * version, so the DumpMethodCFG code will have to iterate again to find it. But dexdump is a
- * tool, so this is not performance-critical.
- */
-
-static void dumpCfg(const DexFile* dex_file,
- u4 dex_method_idx,
- const DexFile::CodeItem* code_item) {
- if (code_item != nullptr) {
- std::ostringstream oss;
- DumpMethodCFG(dex_file, dex_method_idx, oss);
- fputs(oss.str().c_str(), gOutFile);
- }
-}
-
static void dumpCfg(const DexFile* dex_file, int idx) {
- const DexFile::ClassDef& class_def = dex_file->GetClassDef(idx);
- const u1* class_data = dex_file->GetClassData(class_def);
- if (class_data == nullptr) { // empty class such as a marker interface?
- return;
- }
- ClassDataItemIterator it(*dex_file, class_data);
- it.SkipAllFields();
- while (it.HasNextMethod()) {
- dumpCfg(dex_file,
- it.GetMemberIndex(),
- it.GetMethodCodeItem());
- it.Next();
+ ClassAccessor accessor(*dex_file, dex_file->GetClassDef(idx));
+ for (const ClassAccessor::Method& method : accessor.GetMethods()) {
+ if (method.GetCodeItem() != nullptr) {
+ std::ostringstream oss;
+ DumpMethodCFG(method, oss);
+ fputs(oss.str().c_str(), gOutFile);
+ }
}
}
@@ -1512,65 +1494,50 @@
}
// Fields and methods.
- const u1* pEncodedData = pDexFile->GetClassData(pClassDef);
- if (pEncodedData == nullptr) {
- if (gOptions.outputFormat == OUTPUT_PLAIN) {
- fprintf(gOutFile, " Static fields -\n");
- fprintf(gOutFile, " Instance fields -\n");
- fprintf(gOutFile, " Direct methods -\n");
- fprintf(gOutFile, " Virtual methods -\n");
- }
- } else {
- ClassDataItemIterator pClassData(*pDexFile, pEncodedData);
+ ClassAccessor accessor(*pDexFile, pClassDef);
- // Prepare data for static fields.
- const u1* sData = pDexFile->GetEncodedStaticFieldValuesArray(pClassDef);
- const u4 sSize = sData != nullptr ? DecodeUnsignedLeb128(&sData) : 0;
+ // Prepare data for static fields.
+ const u1* sData = pDexFile->GetEncodedStaticFieldValuesArray(pClassDef);
+ const u4 sSize = sData != nullptr ? DecodeUnsignedLeb128(&sData) : 0;
- // Static fields.
- if (gOptions.outputFormat == OUTPUT_PLAIN) {
- fprintf(gOutFile, " Static fields -\n");
- }
- for (u4 i = 0; pClassData.HasNextStaticField(); i++, pClassData.Next()) {
- dumpSField(pDexFile,
- pClassData.GetMemberIndex(),
- pClassData.GetRawMemberAccessFlags(),
- i,
- i < sSize ? &sData : nullptr);
- } // for
+ // Static fields.
+ if (gOptions.outputFormat == OUTPUT_PLAIN) {
+ fprintf(gOutFile, " Static fields -\n");
+ }
+ uint32_t i = 0u;
+ for (const ClassAccessor::Field& field : accessor.GetStaticFields()) {
+ dumpField(field, i, i < sSize ? &sData : nullptr);
+ ++i;
+ }
- // Instance fields.
- if (gOptions.outputFormat == OUTPUT_PLAIN) {
- fprintf(gOutFile, " Instance fields -\n");
- }
- for (u4 i = 0; pClassData.HasNextInstanceField(); i++, pClassData.Next()) {
- dumpIField(pDexFile,
- pClassData.GetMemberIndex(),
- pClassData.GetRawMemberAccessFlags(),
- i);
- } // for
+ // Instance fields.
+ if (gOptions.outputFormat == OUTPUT_PLAIN) {
+ fprintf(gOutFile, " Instance fields -\n");
+ }
+ i = 0u;
+ for (const ClassAccessor::Field& field : accessor.GetInstanceFields()) {
+ dumpField(field, i);
+ ++i;
+ }
- // Direct methods.
- if (gOptions.outputFormat == OUTPUT_PLAIN) {
- fprintf(gOutFile, " Direct methods -\n");
- }
- for (int i = 0; pClassData.HasNextDirectMethod(); i++, pClassData.Next()) {
- dumpMethod(pDexFile, pClassData.GetMemberIndex(),
- pClassData.GetRawMemberAccessFlags(),
- pClassData.GetMethodCodeItem(),
- pClassData.GetMethodCodeItemOffset(), i);
- } // for
+ // Direct methods.
+ if (gOptions.outputFormat == OUTPUT_PLAIN) {
+ fprintf(gOutFile, " Direct methods -\n");
+ }
+ i = 0u;
+ for (const ClassAccessor::Method& method : accessor.GetDirectMethods()) {
+ dumpMethod(method, i);
+ ++i;
+ }
- // Virtual methods.
- if (gOptions.outputFormat == OUTPUT_PLAIN) {
- fprintf(gOutFile, " Virtual methods -\n");
- }
- for (int i = 0; pClassData.HasNextVirtualMethod(); i++, pClassData.Next()) {
- dumpMethod(pDexFile, pClassData.GetMemberIndex(),
- pClassData.GetRawMemberAccessFlags(),
- pClassData.GetMethodCodeItem(),
- pClassData.GetMethodCodeItemOffset(), i);
- } // for
+ // Virtual methods.
+ if (gOptions.outputFormat == OUTPUT_PLAIN) {
+ fprintf(gOutFile, " Virtual methods -\n");
+ }
+ i = 0u;
+ for (const ClassAccessor::Method& method : accessor.GetVirtualMethods()) {
+ dumpMethod(method, i);
+ ++i;
}
// End of class.
diff --git a/dexdump/dexdump_cfg.cc b/dexdump/dexdump_cfg.cc
index 7e534ed..7a0eb0e 100644
--- a/dexdump/dexdump_cfg.cc
+++ b/dexdump/dexdump_cfg.cc
@@ -25,6 +25,7 @@
#include <set>
#include <sstream>
+#include "dex/class_accessor-inl.h"
#include "dex/code_item_accessors-inl.h"
#include "dex/dex_file-inl.h"
#include "dex/dex_file_exception_helpers.h"
@@ -32,15 +33,12 @@
namespace art {
-static void dumpMethodCFGImpl(const DexFile* dex_file,
- uint32_t dex_method_idx,
- const DexFile::CodeItem* code_item,
- std::ostream& os) {
+void DumpMethodCFG(const ClassAccessor::Method& method, std::ostream& os) {
+ const DexFile* dex_file = &method.GetDexFile();
os << "digraph {\n";
- os << " # /* " << dex_file->PrettyMethod(dex_method_idx, true) << " */\n";
+ os << " # /* " << dex_file->PrettyMethod(method.GetIndex(), true) << " */\n";
- CodeItemDataAccessor accessor(*dex_file, code_item);
-
+ CodeItemDataAccessor accessor(method.GetInstructionsAndData());
std::set<uint32_t> dex_pc_is_branch_target;
{
// Go and populate.
@@ -353,42 +351,5 @@
os << "}\n";
}
-void DumpMethodCFG(const DexFile* dex_file, uint32_t dex_method_idx, std::ostream& os) {
- // This is painful, we need to find the code item. That means finding the class, and then
- // iterating the table.
- if (dex_method_idx >= dex_file->NumMethodIds()) {
- os << "Could not find method-idx.";
- return;
- }
- const DexFile::MethodId& method_id = dex_file->GetMethodId(dex_method_idx);
-
- const DexFile::ClassDef* class_def = dex_file->FindClassDef(method_id.class_idx_);
- if (class_def == nullptr) {
- os << "Could not find class-def.";
- return;
- }
-
- const uint8_t* class_data = dex_file->GetClassData(*class_def);
- if (class_data == nullptr) {
- os << "No class data.";
- return;
- }
-
- ClassDataItemIterator it(*dex_file, class_data);
- it.SkipAllFields();
-
- // Find method, and dump it.
- while (it.HasNextMethod()) {
- uint32_t method_idx = it.GetMemberIndex();
- if (method_idx == dex_method_idx) {
- dumpMethodCFGImpl(dex_file, dex_method_idx, it.GetMethodCodeItem(), os);
- return;
- }
- it.Next();
- }
-
- // Otherwise complain.
- os << "Something went wrong, didn't find the method in the class data.";
-}
} // namespace art
diff --git a/dexdump/dexdump_cfg.h b/dexdump/dexdump_cfg.h
index 64e5f9a..564eef6 100644
--- a/dexdump/dexdump_cfg.h
+++ b/dexdump/dexdump_cfg.h
@@ -20,11 +20,11 @@
#include <inttypes.h>
#include <ostream>
+#include "dex/class_accessor.h"
+
namespace art {
-class DexFile;
-
-void DumpMethodCFG(const DexFile* dex_file, uint32_t dex_method_idx, std::ostream& os);
+void DumpMethodCFG(const ClassAccessor::Method& method, std::ostream& os);
} // namespace art
diff --git a/dexlist/dexlist.cc b/dexlist/dexlist.cc
index 88a74de..e7eaf30 100644
--- a/dexlist/dexlist.cc
+++ b/dexlist/dexlist.cc
@@ -30,6 +30,7 @@
#include <android-base/file.h>
#include <android-base/logging.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"
@@ -142,27 +143,21 @@
* Runs through all direct and virtual methods in the class.
*/
void dumpClass(const DexFile* pDexFile, u4 idx) {
- const DexFile::ClassDef& pClassDef = pDexFile->GetClassDef(idx);
+ const DexFile::ClassDef& class_def = pDexFile->GetClassDef(idx);
- const char* fileName;
- if (!pClassDef.source_file_idx_.IsValid()) {
- fileName = nullptr;
- } else {
- fileName = pDexFile->StringDataByIdx(pClassDef.source_file_idx_);
+ const char* fileName = nullptr;
+ if (class_def.source_file_idx_.IsValid()) {
+ fileName = pDexFile->StringDataByIdx(class_def.source_file_idx_);
}
- const u1* pEncodedData = pDexFile->GetClassData(pClassDef);
- if (pEncodedData != nullptr) {
- ClassDataItemIterator pClassData(*pDexFile, pEncodedData);
- pClassData.SkipAllFields();
- // Direct and virtual methods.
- for (; pClassData.HasNextMethod(); pClassData.Next()) {
- dumpMethod(pDexFile, fileName,
- pClassData.GetMemberIndex(),
- pClassData.GetRawMemberAccessFlags(),
- pClassData.GetMethodCodeItem(),
- pClassData.GetMethodCodeItemOffset());
- }
+ ClassAccessor accessor(*pDexFile, class_def);
+ for (const ClassAccessor::Method& method : accessor.GetMethods()) {
+ dumpMethod(pDexFile,
+ fileName,
+ method.GetIndex(),
+ method.GetRawAccessFlags(),
+ method.GetCodeItem(),
+ method.GetCodeItemOffset());
}
}
diff --git a/libdexfile/dex/class_accessor.h b/libdexfile/dex/class_accessor.h
index 6af907e..5579be2 100644
--- a/libdexfile/dex/class_accessor.h
+++ b/libdexfile/dex/class_accessor.h
@@ -34,7 +34,8 @@
private:
class BaseItem {
public:
- explicit BaseItem(const uint8_t* ptr_pos) : ptr_pos_(ptr_pos) {}
+ explicit BaseItem(const DexFile& dex_file,
+ const uint8_t* ptr_pos) : dex_file_(dex_file), ptr_pos_(ptr_pos) {}
uint32_t GetIndex() const {
return index_;
@@ -56,8 +57,13 @@
return (GetAccessFlags() & kAccFinal) != 0;
}
+ const DexFile& GetDexFile() const {
+ return dex_file_;
+ }
+
protected:
// Internal data pointer for reading.
+ const DexFile& dex_file_;
const uint8_t* ptr_pos_ = nullptr;
uint32_t index_ = 0u;
uint32_t access_flags_ = 0u;
@@ -97,9 +103,7 @@
explicit Method(const DexFile& dex_file,
const uint8_t* ptr_pos,
bool is_static_or_direct = true)
- : BaseItem(ptr_pos),
- dex_file_(dex_file),
- is_static_or_direct_(is_static_or_direct) {}
+ : BaseItem(dex_file, ptr_pos), is_static_or_direct_(is_static_or_direct) {}
void Read();
@@ -125,7 +129,6 @@
index_ = 0u;
}
- const DexFile& dex_file_;
bool is_static_or_direct_ = true;
uint32_t code_off_ = 0u;
@@ -136,11 +139,7 @@
class Field : public BaseItem {
public:
explicit Field(const DexFile& dex_file,
- const uint8_t* ptr_pos) : BaseItem(ptr_pos), dex_file_(dex_file) {}
-
- const DexFile& GetDexFile() const {
- return dex_file_;
- }
+ const uint8_t* ptr_pos) : BaseItem(dex_file, ptr_pos) {}
bool IsStatic() const {
return is_static_;
@@ -158,7 +157,6 @@
is_static_ = false;
}
- const DexFile& dex_file_;
bool is_static_ = true;
friend class ClassAccessor;
};
diff --git a/openjdkjvmti/ti_redefine.cc b/openjdkjvmti/ti_redefine.cc
index 4de42ac..1476880 100644
--- a/openjdkjvmti/ti_redefine.cc
+++ b/openjdkjvmti/ti_redefine.cc
@@ -45,6 +45,7 @@
#include "class_root.h"
#include "debugger.h"
#include "dex/art_dex_file_loader.h"
+#include "dex/class_accessor-inl.h"
#include "dex/dex_file.h"
#include "dex/dex_file_loader.h"
#include "dex/dex_file_types.h"
@@ -620,11 +621,9 @@
art::Handle<art::mirror::Class> h_klass(hs.NewHandle(GetMirrorClass()));
DCHECK_EQ(dex_file_->NumClassDefs(), 1u);
- art::ClassDataItemIterator new_iter(*dex_file_,
- dex_file_->GetClassData(dex_file_->GetClassDef(0)));
-
// Make sure we have the same number of methods.
- uint32_t num_new_method = new_iter.NumVirtualMethods() + new_iter.NumDirectMethods();
+ art::ClassAccessor accessor(*dex_file_, dex_file_->GetClassDef(0));
+ uint32_t num_new_method = accessor.NumMethods();
uint32_t num_old_method = h_klass->GetDeclaredMethodsSlice(art::kRuntimePointerSize).size();
if (num_new_method != num_old_method) {
bool bigger = num_new_method > num_old_method;
@@ -636,13 +635,12 @@
}
// Skip all of the fields. We should have already checked this.
- new_iter.SkipAllFields();
// Check each of the methods. NB we don't need to specifically check for removals since the 2 dex
// files have the same number of methods, which means there must be an equal amount of additions
- // and removals.
- for (; new_iter.HasNextMethod(); new_iter.Next()) {
+ // and removals. We should have already checked the fields.
+ for (const art::ClassAccessor::Method& method : accessor.GetMethods()) {
// Get the data on the method we are searching for
- const art::DexFile::MethodId& new_method_id = dex_file_->GetMethodId(new_iter.GetMemberIndex());
+ const art::DexFile::MethodId& new_method_id = dex_file_->GetMethodId(method.GetIndex());
const char* new_method_name = dex_file_->GetMethodName(new_method_id);
art::Signature new_method_signature = dex_file_->GetMethodSignature(new_method_id);
art::ArtMethod* old_method = FindMethod(h_klass, new_method_name, new_method_signature);
@@ -659,7 +657,7 @@
// Since direct methods have different flags than virtual ones (specifically direct methods must
// have kAccPrivate or kAccStatic or kAccConstructor flags) we can tell if a method changes from
// virtual to direct.
- uint32_t new_flags = new_iter.GetMethodAccessFlags();
+ uint32_t new_flags = method.GetAccessFlags();
if (new_flags != (old_method->GetAccessFlags() & art::kAccValidMethodFlags)) {
RecordFailure(ERR(UNSUPPORTED_REDEFINITION_METHOD_MODIFIERS_CHANGED),
StringPrintf("method '%s' (sig: %s) had different access flags",
@@ -675,20 +673,21 @@
art::StackHandleScope<1> hs(driver_->self_);
art::Handle<art::mirror::Class> h_klass(hs.NewHandle(GetMirrorClass()));
DCHECK_EQ(dex_file_->NumClassDefs(), 1u);
- art::ClassDataItemIterator new_iter(*dex_file_,
- dex_file_->GetClassData(dex_file_->GetClassDef(0)));
+ art::ClassAccessor new_accessor(*dex_file_, dex_file_->GetClassDef(0));
+
const art::DexFile& old_dex_file = h_klass->GetDexFile();
- art::ClassDataItemIterator old_iter(old_dex_file,
- old_dex_file.GetClassData(*h_klass->GetClassDef()));
+ art::ClassAccessor old_accessor(old_dex_file, *h_klass->GetClassDef());
// Instance and static fields can be differentiated by their flags so no need to check them
// separately.
- while (new_iter.HasNextInstanceField() || new_iter.HasNextStaticField()) {
+ auto old_fields = old_accessor.GetFields();
+ auto old_iter = old_fields.begin();
+ for (const art::ClassAccessor::Field& new_field : new_accessor.GetFields()) {
// Get the data on the method we are searching for
- const art::DexFile::FieldId& new_field_id = dex_file_->GetFieldId(new_iter.GetMemberIndex());
+ const art::DexFile::FieldId& new_field_id = dex_file_->GetFieldId(new_field.GetIndex());
const char* new_field_name = dex_file_->GetFieldName(new_field_id);
const char* new_field_type = dex_file_->GetFieldTypeDescriptor(new_field_id);
- if (!(old_iter.HasNextInstanceField() || old_iter.HasNextStaticField())) {
+ if (old_iter == old_fields.end()) {
// We are missing the old version of this method!
RecordFailure(ERR(UNSUPPORTED_REDEFINITION_SCHEMA_CHANGED),
StringPrintf("Unknown field '%s' (type: %s) added!",
@@ -697,7 +696,7 @@
return false;
}
- const art::DexFile::FieldId& old_field_id = old_dex_file.GetFieldId(old_iter.GetMemberIndex());
+ const art::DexFile::FieldId& old_field_id = old_dex_file.GetFieldId(old_iter->GetIndex());
const char* old_field_name = old_dex_file.GetFieldName(old_field_id);
const char* old_field_type = old_dex_file.GetFieldTypeDescriptor(old_field_id);
@@ -715,7 +714,7 @@
// Since static fields have different flags than instance ones (specifically static fields must
// have the kAccStatic flag) we can tell if a field changes from static to instance.
- if (new_iter.GetFieldAccessFlags() != old_iter.GetFieldAccessFlags()) {
+ if (new_field.GetAccessFlags() != old_iter->GetAccessFlags()) {
RecordFailure(ERR(UNSUPPORTED_REDEFINITION_SCHEMA_CHANGED),
StringPrintf("Field '%s' (sig: %s) had different access flags",
new_field_name,
@@ -723,16 +722,15 @@
return false;
}
- new_iter.Next();
- old_iter.Next();
+ ++old_iter;
}
- if (old_iter.HasNextInstanceField() || old_iter.HasNextStaticField()) {
+ if (old_iter != old_fields.end()) {
RecordFailure(ERR(UNSUPPORTED_REDEFINITION_SCHEMA_CHANGED),
StringPrintf("field '%s' (sig: %s) is missing!",
old_dex_file.GetFieldName(old_dex_file.GetFieldId(
- old_iter.GetMemberIndex())),
+ old_iter->GetIndex())),
old_dex_file.GetFieldTypeDescriptor(old_dex_file.GetFieldId(
- old_iter.GetMemberIndex()))));
+ old_iter->GetIndex()))));
return false;
}
return true;
diff --git a/runtime/vdex_file.h b/runtime/vdex_file.h
index b7f28f0..866a57e 100644
--- a/runtime/vdex_file.h
+++ b/runtime/vdex_file.h
@@ -281,8 +281,8 @@
// In-place unquicken the given `dex_files` based on `quickening_info`.
// `decompile_return_instruction` controls if RETURN_VOID_BARRIER instructions are
- // decompiled to RETURN_VOID instructions using the slower ClassDataItemIterator
- // instead of the faster QuickeningInfoIterator.
+ // decompiled to RETURN_VOID instructions using the slower ClassAccessor instead of the faster
+ // QuickeningInfoIterator.
// Always unquickens using the vdex dex files as the source for quicken tables.
void Unquicken(const std::vector<const DexFile*>& target_dex_files,
bool decompile_return_instruction) const;
diff --git a/test/983-source-transform-verify/source_transform_art.cc b/test/983-source-transform-verify/source_transform_art.cc
index 5353370..fbf25b8 100644
--- a/test/983-source-transform-verify/source_transform_art.cc
+++ b/test/983-source-transform-verify/source_transform_art.cc
@@ -24,6 +24,7 @@
#include "dex/code_item_accessors-inl.h"
#include "dex/art_dex_file_loader.h"
+#include "dex/class_accessor-inl.h"
#include "dex/dex_file.h"
#include "dex/dex_file_loader.h"
#include "dex/dex_instruction.h"
@@ -51,23 +52,15 @@
/*verify_checksum*/ true,
&error));
CHECK(dex.get() != nullptr) << "Failed to verify dex: " << error;
- for (uint32_t i = 0; i < dex->NumClassDefs(); i++) {
- const DexFile::ClassDef& def = dex->GetClassDef(i);
- const uint8_t* data_item = dex->GetClassData(def);
- if (data_item == nullptr) {
- continue;
- }
- for (ClassDataItemIterator it(*dex, data_item); it.HasNext(); it.Next()) {
- if (!it.IsAtMethod() || it.GetMethodCodeItem() == nullptr) {
- continue;
- }
- for (const DexInstructionPcPair& pair :
- art::CodeItemInstructionAccessor(*dex, it.GetMethodCodeItem())) {
+
+ for (ClassAccessor accessor : dex->GetClasses()) {
+ for (const ClassAccessor::Method& method : accessor.GetMethods()) {
+ for (const DexInstructionPcPair& pair : method.GetInstructions()) {
const Instruction& inst = pair.Inst();
int forbidden_flags = (Instruction::kVerifyError | Instruction::kVerifyRuntimeOnly);
if (inst.Opcode() == Instruction::RETURN_VOID_NO_BARRIER ||
(inst.GetVerifyExtraFlags() & forbidden_flags) != 0) {
- LOG(FATAL) << "Unexpected instruction found in " << dex->PrettyMethod(it.GetMemberIndex())
+ LOG(FATAL) << "Unexpected instruction found in " << dex->PrettyMethod(method.GetIndex())
<< " [Dex PC: 0x" << std::hex << pair.DexPc() << std::dec << "] : "
<< inst.DumpString(dex.get()) << std::endl;
}