Refactor ClassAccessor to use an index instead of ClassDef pointer
Removes a separate class_def_idx being required for getting the index
of a ClassAccessor foreach loop.
Bug: 79758018
Test: test-art-host-gtest
Change-Id: Ie3010a17669f24cf492c678b55bdddba7ec62ea8
diff --git a/compiler/dex/dex_to_dex_decompiler_test.cc b/compiler/dex/dex_to_dex_decompiler_test.cc
index 1fe42ad..d4a9ba5 100644
--- a/compiler/dex/dex_to_dex_decompiler_test.cc
+++ b/compiler/dex/dex_to_dex_decompiler_test.cc
@@ -82,9 +82,8 @@
ASSERT_NE(0, cmp);
// Unquicken the dex file.
- for (uint32_t i = 0; i < updated_dex_file->NumClassDefs(); ++i) {
+ for (ClassAccessor accessor : updated_dex_file->GetClasses()) {
// Unquicken each method.
- ClassAccessor accessor(*updated_dex_file, updated_dex_file->GetClassDef(i));
for (const ClassAccessor::Method& method : accessor.GetMethods()) {
CompiledMethod* compiled_method = compiler_driver_->GetCompiledMethod(
method.GetReference());
diff --git a/compiler/driver/compiler_driver.cc b/compiler/driver/compiler_driver.cc
index 653e9ed..6cb3936 100644
--- a/compiler/driver/compiler_driver.cc
+++ b/compiler/driver/compiler_driver.cc
@@ -1685,16 +1685,14 @@
bool CompilerDriver::RequiresConstructorBarrier(const DexFile& dex_file,
uint16_t class_def_idx) const {
- ClassAccessor accessor(dex_file, dex_file.GetClassDef(class_def_idx));
- bool has_is_final = false;
+ ClassAccessor accessor(dex_file, class_def_idx);
// We require a constructor barrier if there are final instance fields.
- accessor.VisitFields(/*static*/ VoidFunctor(),
- [&](const ClassAccessor::Field& field) {
+ for (const ClassAccessor::Field& field : accessor.GetInstanceFields()) {
if (field.IsFinal()) {
- has_is_final = true;
+ return true;
}
- });
- return has_is_final;
+ }
+ return false;
}
class ResolveClassFieldsAndMethodsVisitor : public CompilationVisitor {
@@ -1744,7 +1742,7 @@
// fields are assigned within the lock held for class initialization.
bool requires_constructor_barrier = false;
- ClassAccessor accessor(dex_file, class_def);
+ ClassAccessor accessor(dex_file, class_def_index);
// Optionally resolve fields and methods and figure out if we need a constructor barrier.
auto method_visitor = [&](const ClassAccessor::Method& method)
REQUIRES_SHARED(Locks::mutator_lock_) {
@@ -1926,13 +1924,12 @@
// Fetch the list of unverified classes.
const std::set<dex::TypeIndex>& unverified_classes =
verifier_deps->GetUnverifiedClasses(*dex_file);
- uint32_t class_def_idx = 0u;
for (ClassAccessor accessor : dex_file->GetClasses()) {
if (unverified_classes.find(accessor.GetClassIdx()) == unverified_classes.end()) {
if (compiler_only_verifies) {
// Just update the compiled_classes_ map. The compiler doesn't need to resolve
// the type.
- ClassReference ref(dex_file, class_def_idx);
+ ClassReference ref(dex_file, accessor.GetClassDefIndex());
const ClassStatus existing = ClassStatus::kNotReady;
ClassStateTable::InsertResult result =
compiled_classes_.Insert(ref, existing, ClassStatus::kVerified);
@@ -1959,7 +1956,6 @@
class_loader,
soa.Self());
}
- ++class_def_idx;
}
}
return true;
@@ -2700,7 +2696,7 @@
jobject jclass_loader = context.GetClassLoader();
ClassReference ref(&dex_file, class_def_index);
const DexFile::ClassDef& class_def = dex_file.GetClassDef(class_def_index);
- ClassAccessor accessor(dex_file, class_def);
+ ClassAccessor accessor(dex_file, class_def_index);
// Skip compiling classes with generic verifier failures since they will still fail at runtime
if (context.GetCompiler()->GetVerificationResults()->IsClassRejected(ref)) {
return;
diff --git a/dexdump/dexdump.cc b/dexdump/dexdump.cc
index 85778b6..8261035 100644
--- a/dexdump/dexdump.cc
+++ b/dexdump/dexdump.cc
@@ -612,7 +612,7 @@
pClassDef.class_data_off_, pClassDef.class_data_off_);
// Fields and methods.
- ClassAccessor accessor(*pDexFile, pClassDef);
+ ClassAccessor accessor(*pDexFile, idx);
fprintf(gOutFile, "static_fields_size : %d\n", accessor.NumStaticFields());
fprintf(gOutFile, "instance_fields_size: %d\n", accessor.NumInstanceFields());
fprintf(gOutFile, "direct_methods_size : %d\n", accessor.NumDirectMethods());
diff --git a/libdexfile/dex/class_accessor-inl.h b/libdexfile/dex/class_accessor-inl.h
index 3bb9e93..a335f08 100644
--- a/libdexfile/dex/class_accessor-inl.h
+++ b/libdexfile/dex/class_accessor-inl.h
@@ -26,12 +26,15 @@
namespace art {
inline ClassAccessor::ClassAccessor(const ClassIteratorData& data)
- : ClassAccessor(data.dex_file_, data.dex_file_.GetClassDef(data.class_def_idx_)) {}
+ : ClassAccessor(data.dex_file_, data.class_def_idx_) {}
inline ClassAccessor::ClassAccessor(const DexFile& dex_file, const DexFile::ClassDef& class_def)
+ : ClassAccessor(dex_file, dex_file.GetIndexForClassDef(class_def)) {}
+
+inline ClassAccessor::ClassAccessor(const DexFile& dex_file, uint32_t class_def_index)
: dex_file_(dex_file),
- descriptor_index_(class_def.class_idx_),
- ptr_pos_(dex_file.GetClassData(class_def)),
+ class_def_index_(class_def_index),
+ ptr_pos_(dex_file.GetClassData(dex_file.GetClassDef(class_def_index))),
num_static_fields_(ptr_pos_ != nullptr ? DecodeUnsignedLeb128(&ptr_pos_) : 0u),
num_instance_fields_(ptr_pos_ != nullptr ? DecodeUnsignedLeb128(&ptr_pos_) : 0u),
num_direct_methods_(ptr_pos_ != nullptr ? DecodeUnsignedLeb128(&ptr_pos_) : 0u),
@@ -108,7 +111,7 @@
}
inline const char* ClassAccessor::GetDescriptor() const {
- return dex_file_.StringByTypeIdx(descriptor_index_);
+ return dex_file_.StringByTypeIdx(GetClassIdx());
}
inline const DexFile::CodeItem* ClassAccessor::Method::GetCodeItem() const {
@@ -175,6 +178,10 @@
DexFile::UnHideAccessFlags(const_cast<uint8_t*>(ptr_pos_), GetAccessFlags(), /*is_method*/ true);
}
+inline dex::TypeIndex ClassAccessor::GetClassIdx() const {
+ return dex_file_.GetClassDef(class_def_index_).class_idx_;
+}
+
} // namespace art
#endif // ART_LIBDEXFILE_DEX_CLASS_ACCESSOR_INL_H_
diff --git a/libdexfile/dex/class_accessor.h b/libdexfile/dex/class_accessor.h
index 4f0fd32..34c7e07 100644
--- a/libdexfile/dex/class_accessor.h
+++ b/libdexfile/dex/class_accessor.h
@@ -248,6 +248,8 @@
ClassAccessor(const DexFile& dex_file, const DexFile::ClassDef& class_def);
+ ClassAccessor(const DexFile& dex_file, uint32_t class_def_index);
+
// Return the code item for a method.
const DexFile::CodeItem* GetCodeItem(const Method& method) const;
@@ -315,9 +317,7 @@
const char* GetDescriptor() const;
- dex::TypeIndex GetClassIdx() const {
- return descriptor_index_;
- }
+ dex::TypeIndex GetClassIdx() const;
const DexFile& GetDexFile() const {
return dex_file_;
@@ -327,6 +327,10 @@
return ptr_pos_ != nullptr;
}
+ uint32_t GetClassDefIndex() const {
+ return class_def_index_;
+ }
+
protected:
// Template visitor to reduce copy paste for visiting elements.
// No thread safety analysis since the visitor may require capabilities.
@@ -341,7 +345,7 @@
IterationRange<DataIterator<Method>> GetMethodsInternal(size_t count) const;
const DexFile& dex_file_;
- const dex::TypeIndex descriptor_index_ = {};
+ const uint32_t class_def_index_;
const uint8_t* ptr_pos_ = nullptr; // Pointer into stream of class_data_item.
const uint32_t num_static_fields_ = 0u;
const uint32_t num_instance_fields_ = 0u;
diff --git a/libdexfile/dex/class_accessor_test.cc b/libdexfile/dex/class_accessor_test.cc
index d0533c1..1f30ae5 100644
--- a/libdexfile/dex/class_accessor_test.cc
+++ b/libdexfile/dex/class_accessor_test.cc
@@ -30,8 +30,9 @@
uint32_t class_def_idx = 0u;
ASSERT_GT(dex_file->NumClassDefs(), 0u);
for (ClassAccessor accessor : dex_file->GetClasses()) {
- const DexFile::ClassDef& class_def = dex_file->GetClassDef(class_def_idx);
+ const DexFile::ClassDef& class_def = dex_file->GetClassDef(accessor.GetClassDefIndex());
EXPECT_EQ(accessor.GetDescriptor(), dex_file->StringByTypeIdx(class_def.class_idx_));
+ EXPECT_EQ(class_def_idx, accessor.GetClassDefIndex());
++class_def_idx;
// Check iterators against visitors.
auto methods = accessor.GetMethods();
diff --git a/oatdump/oatdump.cc b/oatdump/oatdump.cc
index 25676f7..5c339b8 100644
--- a/oatdump/oatdump.cc
+++ b/oatdump/oatdump.cc
@@ -274,7 +274,7 @@
void WalkOatClass(const OatFile::OatClass& oat_class,
const DexFile& dex_file,
uint32_t class_def_index) {
- ClassAccessor accessor(dex_file, dex_file.GetClassDef(class_def_index));
+ ClassAccessor accessor(dex_file, class_def_index);
// Note: even if this is an interface or a native class, we still have to walk it, as there
// might be a static initializer.
uint32_t class_method_idx = 0;
@@ -905,15 +905,13 @@
continue;
}
offsets_.insert(reinterpret_cast<uintptr_t>(&dex_file->GetHeader()));
- uint32_t class_def_index = 0u;
for (ClassAccessor accessor : dex_file->GetClasses()) {
- const OatFile::OatClass oat_class = oat_dex_file->GetOatClass(class_def_index);
+ const OatFile::OatClass oat_class = oat_dex_file->GetOatClass(accessor.GetClassDefIndex());
for (uint32_t class_method_index = 0;
class_method_index < accessor.NumMethods();
++class_method_index) {
AddOffsets(oat_class.GetOatMethod(class_method_index));
}
- ++class_def_index;
}
}
diff --git a/profman/profman.cc b/profman/profman.cc
index 096e5dc..5fbce66 100644
--- a/profman/profman.cc
+++ b/profman/profman.cc
@@ -930,7 +930,9 @@
dex_resolved_classes.first->AddClass(class_ref.TypeIndex());
std::vector<ProfileMethodInfo> methods;
if (method_str == kClassAllMethods) {
- ClassAccessor accessor(*dex_file, *dex_file->FindClassDef(class_ref.TypeIndex()));
+ ClassAccessor accessor(
+ *dex_file,
+ dex_file->GetIndexForClassDef(*dex_file->FindClassDef(class_ref.TypeIndex())));
for (const ClassAccessor::Method& method : accessor.GetMethods()) {
if (method.GetCodeItemOffset() != 0) {
// Add all of the methods that have code to the profile.
diff --git a/runtime/art_method.cc b/runtime/art_method.cc
index 45bf664..5b4dcb7 100644
--- a/runtime/art_method.cc
+++ b/runtime/art_method.cc
@@ -425,7 +425,7 @@
static uint32_t GetOatMethodIndexFromMethodIndex(const DexFile& dex_file,
uint16_t class_def_idx,
uint32_t method_idx) {
- ClassAccessor accessor(dex_file, dex_file.GetClassDef(class_def_idx));
+ ClassAccessor accessor(dex_file, class_def_idx);
uint32_t class_def_method_index = 0u;
for (const ClassAccessor::Method& method : accessor.GetMethods()) {
if (method.GetIndex() == method_idx) {
diff --git a/runtime/class_linker.cc b/runtime/class_linker.cc
index be636d8..b1fd5f4 100644
--- a/runtime/class_linker.cc
+++ b/runtime/class_linker.cc
@@ -2863,9 +2863,9 @@
}
const DexFile& dex_file = klass->GetDexFile();
- const DexFile::ClassDef* dex_class_def = klass->GetClassDef();
- CHECK(dex_class_def != nullptr);
- ClassAccessor accessor(dex_file, *dex_class_def);
+ const uint16_t class_def_idx = klass->GetDexClassDefIndex();
+ CHECK_NE(class_def_idx, DexFile::kDexNoIndex16);
+ ClassAccessor accessor(dex_file, class_def_idx);
// There should always be class data if there were direct methods.
CHECK(accessor.HasClassData()) << klass->PrettyDescriptor();
bool has_oat_class;
diff --git a/runtime/verifier/method_verifier.cc b/runtime/verifier/method_verifier.cc
index 5961748..a62271d 100644
--- a/runtime/verifier/method_verifier.cc
+++ b/runtime/verifier/method_verifier.cc
@@ -212,8 +212,6 @@
bool allow_soft_failures,
HardFailLogMode log_level,
std::string* error) {
- SCOPED_TRACE << "VerifyClass " << PrettyDescriptor(dex_file->GetClassDescriptor(class_def));
-
// A class must not be abstract and final.
if ((class_def.access_flags_ & (kAccAbstract | kAccFinal)) == (kAccAbstract | kAccFinal)) {
*error = "Verifier rejected class ";
@@ -223,6 +221,7 @@
}
ClassAccessor accessor(*dex_file, class_def);
+ SCOPED_TRACE << "VerifyClass " << PrettyDescriptor(accessor.GetDescriptor());
int64_t previous_method_idx[2] = { -1, -1 };
MethodVerifier::FailureData failure_data;