diff options
| -rw-r--r-- | dexdump/dexdump.cc | 173 | ||||
| -rw-r--r-- | dexdump/dexdump_cfg.cc | 49 | ||||
| -rw-r--r-- | dexdump/dexdump_cfg.h | 6 | ||||
| -rw-r--r-- | dexlist/dexlist.cc | 31 | ||||
| -rw-r--r-- | libdexfile/dex/class_accessor.h | 20 | ||||
| -rw-r--r-- | openjdkjvmti/ti_redefine.cc | 44 | ||||
| -rw-r--r-- | runtime/vdex_file.h | 4 | ||||
| -rw-r--r-- | test/983-source-transform-verify/source_transform_art.cc | 19 |
8 files changed, 129 insertions, 217 deletions
diff --git a/dexdump/dexdump.cc b/dexdump/dexdump.cc index 060d079270..f8274e2f9a 100644 --- a/dexdump/dexdump.cc +++ b/dexdump/dexdump.cc @@ -1212,18 +1212,19 @@ static void dumpCode(const DexFile* pDexFile, u4 idx, u4 flags, /* * 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 @@ static void dumpMethod(const DexFile* pDexFile, u4 idx, u4 flags, 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 @@ static void dumpMethod(const DexFile* pDexFile, u4 idx, u4 flags, } /* - * 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 @@ static void dumpSField(const DexFile* pDexFile, u4 idx, u4 flags, int i, const u 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 @@ static void dumpSField(const DexFile* pDexFile, u4 idx, u4 flags, int i, const u 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 @@ static void dumpSField(const DexFile* pDexFile, u4 idx, u4 flags, int i, const u } /* - * 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 @@ static void dumpClass(const DexFile* pDexFile, int idx, char** pLastPackage) { } // 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 7e534ed359..7a0eb0e088 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"; - - CodeItemDataAccessor accessor(*dex_file, code_item); + os << " # /* " << dex_file->PrettyMethod(method.GetIndex(), true) << " */\n"; + CodeItemDataAccessor accessor(method.GetInstructionsAndData()); std::set<uint32_t> dex_pc_is_branch_target; { // Go and populate. @@ -353,42 +351,5 @@ static void dumpMethodCFGImpl(const DexFile* dex_file, 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 64e5f9af60..564eef6e68 100644 --- a/dexdump/dexdump_cfg.h +++ b/dexdump/dexdump_cfg.h @@ -20,11 +20,11 @@ #include <inttypes.h> #include <ostream> -namespace art { +#include "dex/class_accessor.h" -class DexFile; +namespace art { -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 88a74de37e..e7eaf30b7c 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 @@ static void dumpMethod(const DexFile* pDexFile, * 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 6af907eb99..5579be21e5 100644 --- a/libdexfile/dex/class_accessor.h +++ b/libdexfile/dex/class_accessor.h @@ -34,7 +34,8 @@ class ClassAccessor { 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 @@ class ClassAccessor { 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 @@ class ClassAccessor { 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 @@ class ClassAccessor { index_ = 0u; } - const DexFile& dex_file_; bool is_static_or_direct_ = true; uint32_t code_off_ = 0u; @@ -136,11 +139,7 @@ class ClassAccessor { 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 @@ class ClassAccessor { 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 4de42ac669..1476880f45 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 @@ bool Redefiner::ClassRedefinition::CheckSameMethods() { 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 @@ bool Redefiner::ClassRedefinition::CheckSameMethods() { } // 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 @@ bool Redefiner::ClassRedefinition::CheckSameMethods() { // 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 @@ bool Redefiner::ClassRedefinition::CheckSameFields() { 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 @@ bool Redefiner::ClassRedefinition::CheckSameFields() { 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 @@ bool Redefiner::ClassRedefinition::CheckSameFields() { // 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 @@ bool Redefiner::ClassRedefinition::CheckSameFields() { 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 b7f28f0d03..866a57e7d2 100644 --- a/runtime/vdex_file.h +++ b/runtime/vdex_file.h @@ -281,8 +281,8 @@ class VdexFile { // 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 5353370ac6..fbf25b849e 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 @@ void VerifyClassData(jint class_data_len, const unsigned char* class_data) { /*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; } |