diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/class_linker_test.cc | 7 | ||||
-rw-r--r-- | src/common_test.h | 25 | ||||
-rw-r--r-- | src/dex_file.cc | 39 | ||||
-rw-r--r-- | src/dex_file.h | 16 | ||||
-rw-r--r-- | src/dex_file_test.cc | 15 | ||||
-rw-r--r-- | src/object_test.cc | 28 |
6 files changed, 97 insertions, 33 deletions
diff --git a/src/class_linker_test.cc b/src/class_linker_test.cc index 5448a51..e64131f 100644 --- a/src/class_linker_test.cc +++ b/src/class_linker_test.cc @@ -947,8 +947,11 @@ TEST_F(ClassLinkerTest, InitializeStaticStorageFromCode) { Class* klass = class_linker_->FindClass("LStaticsFromCode;", class_loader.get()); Method* clinit = klass->FindDirectMethod("<clinit>", "()V"); Method* getS0 = klass->FindDirectMethod("getS0", "()Ljava/lang/Object;"); - uint32_t type_idx = FindTypeIdxByDescriptor(*dex_file, "LStaticsFromCode;"); - + const DexFile::StringId* string_id = dex_file->FindStringId("LStaticsFromCode;"); + ASSERT_TRUE(string_id != NULL); + const DexFile::TypeId* type_id = dex_file->FindTypeId(dex_file->GetIndexForStringId(*string_id)); + ASSERT_TRUE(type_id != NULL); + uint32_t type_idx = dex_file->GetIndexForTypeId(*type_id); EXPECT_TRUE(clinit->GetDexCacheInitializedStaticStorage()->Get(type_idx) == NULL); StaticStorageBase* uninit = InitializeStaticStorage(type_idx, clinit, Thread::Current()); EXPECT_TRUE(uninit != NULL); diff --git a/src/common_test.h b/src/common_test.h index c55ef7f..f2a18e5 100644 --- a/src/common_test.h +++ b/src/common_test.h @@ -282,31 +282,6 @@ class CommonTest : public testing::Test { return DexFile::Open(libcore_dex_file_name, ""); } - uint32_t FindTypeIdxByDescriptor(const DexFile& dex_file, const StringPiece& descriptor) { - for (size_t i = 0; i < dex_file.NumTypeIds(); i++) { - const DexFile::TypeId& type_id = dex_file.GetTypeId(i); - if (descriptor == dex_file.GetTypeDescriptor(type_id)) { - return i; - } - } - CHECK(false) << "Failed to find type index for " << descriptor; - return 0; - } - - uint32_t FindFieldIdxByDescriptorAndName(const DexFile& dex_file, - const StringPiece& class_descriptor, - const StringPiece& field_name) { - for (size_t i = 0; i < dex_file.NumFieldIds(); i++) { - const DexFile::FieldId& field_id = dex_file.GetFieldId(i); - if (class_descriptor == dex_file.GetFieldDeclaringClassDescriptor(field_id) - && field_name == dex_file.GetFieldName(field_id)) { - return i; - } - } - CHECK(false) << "Failed to find field index for " << class_descriptor << " " << field_name; - return 0; - } - const DexFile* OpenTestDexFile(const char* name) { CHECK(name != NULL); std::string filename; diff --git a/src/dex_file.cc b/src/dex_file.cc index e9a883c..208479e 100644 --- a/src/dex_file.cc +++ b/src/dex_file.cc @@ -463,11 +463,46 @@ const DexFile::ClassDef* DexFile::FindClassDef(const StringPiece& descriptor) co return NULL; } -const DexFile::MethodId* DexFile::FindMethodId(const DexFile::TypeId& klass, +const DexFile::FieldId* DexFile::FindFieldId(const DexFile::TypeId& declaring_klass, + const DexFile::StringId& name, + const DexFile::TypeId& type) const { + // Binary search MethodIds knowing that they are sorted by class_idx, name_idx then proto_idx + const uint16_t class_idx = GetIndexForTypeId(declaring_klass); + const uint32_t name_idx = GetIndexForStringId(name); + const uint16_t type_idx = GetIndexForTypeId(type); + uint32_t lo = 0; + uint32_t hi = NumFieldIds() - 1; + while (hi >= lo) { + uint32_t mid = (hi + lo) / 2; + const DexFile::FieldId& field = GetFieldId(mid); + if (class_idx > field.class_idx_) { + lo = mid + 1; + } else if (class_idx < field.class_idx_) { + hi = mid - 1; + } else { + if (name_idx > field.name_idx_) { + lo = mid + 1; + } else if (name_idx < field.name_idx_) { + hi = mid - 1; + } else { + if (type_idx > field.type_idx_) { + lo = mid + 1; + } else if (type_idx < field.type_idx_) { + hi = mid - 1; + } else { + return &field; + } + } + } + } + return NULL; +} + +const DexFile::MethodId* DexFile::FindMethodId(const DexFile::TypeId& declaring_klass, const DexFile::StringId& name, const DexFile::ProtoId& signature) const { // Binary search MethodIds knowing that they are sorted by class_idx, name_idx then proto_idx - const uint16_t class_idx = GetIndexForTypeId(klass); + const uint16_t class_idx = GetIndexForTypeId(declaring_klass); const uint32_t name_idx = GetIndexForStringId(name); const uint16_t proto_idx = GetIndexForProtoId(signature); uint32_t lo = 0; diff --git a/src/dex_file.h b/src/dex_file.h index 62b99ab..d48067b 100644 --- a/src/dex_file.h +++ b/src/dex_file.h @@ -300,6 +300,17 @@ class DexFile { return field_ids_[idx]; } + uint32_t GetIndexForFieldId(const FieldId& field_id) const { + CHECK_GE(&field_id, field_ids_); + CHECK_LT(&field_id, field_ids_ + header_->field_ids_size_); + return &field_id - field_ids_; + } + + // Looks up a field by its declaring class, name and type + const FieldId* FindFieldId(const DexFile::TypeId& declaring_klass, + const DexFile::StringId& name, + const DexFile::TypeId& type) const; + // Returns the declaring class descriptor string of a field id. const char* GetFieldDeclaringClassDescriptor(const FieldId& field_id) const { const DexFile::TypeId& type_id = GetTypeId(field_id.class_idx_); @@ -335,8 +346,9 @@ class DexFile { return &method_id - method_ids_; } - // Looks up a method by its class_dex, name and proto_id - const MethodId* FindMethodId(const DexFile::TypeId& klass, const DexFile::StringId& name, + // Looks up a method by its declaring class, name and proto_id + const MethodId* FindMethodId(const DexFile::TypeId& declaring_klass, + const DexFile::StringId& name, const DexFile::ProtoId& signature) const; // Returns the declaring class descriptor string of a method id. diff --git a/src/dex_file_test.cc b/src/dex_file_test.cc index 6f99551..4b311dc 100644 --- a/src/dex_file_test.cc +++ b/src/dex_file_test.cc @@ -196,4 +196,19 @@ TEST_F(DexFileTest, FindMethodId) { } } +TEST_F(DexFileTest, FindFieldId) { + for (size_t i = 0; i < java_lang_dex_file_->NumFieldIds(); i++) { + const DexFile::FieldId& to_find = java_lang_dex_file_->GetFieldId(i); + const DexFile::TypeId& klass = java_lang_dex_file_->GetTypeId(to_find.class_idx_); + const DexFile::StringId& name = java_lang_dex_file_->GetStringId(to_find.name_idx_); + const DexFile::TypeId& type = java_lang_dex_file_->GetTypeId(to_find.type_idx_); + const DexFile::FieldId* found = java_lang_dex_file_->FindFieldId(klass, name, type); + ASSERT_TRUE(found != NULL) << "Didn't find field " << i << ": " + << java_lang_dex_file_->StringByTypeIdx(to_find.type_idx_) << " " + << java_lang_dex_file_->StringByTypeIdx(to_find.class_idx_) << "." + << java_lang_dex_file_->GetStringData(name); + EXPECT_EQ(java_lang_dex_file_->GetIndexForFieldId(*found), i); + } +} + } // namespace art diff --git a/src/object_test.cc b/src/object_test.cc index b09cff1..08abb6f 100644 --- a/src/object_test.cc +++ b/src/object_test.cc @@ -169,7 +169,12 @@ TEST_F(ObjectTest, CheckAndAllocArrayFromCode) { // pretend we are trying to call 'new char[3]' from String.toCharArray Class* java_util_Arrays = class_linker_->FindSystemClass("Ljava/util/Arrays;"); Method* sort = java_util_Arrays->FindDirectMethod("sort", "([I)V"); - uint32_t type_idx = FindTypeIdxByDescriptor(*java_lang_dex_file_.get(), "[I"); + const DexFile::StringId* string_id = java_lang_dex_file_->FindStringId("[I"); + ASSERT_TRUE(string_id != NULL); + const DexFile::TypeId* type_id = java_lang_dex_file_->FindTypeId( + java_lang_dex_file_->GetIndexForStringId(*string_id)); + ASSERT_TRUE(type_id != NULL); + uint32_t type_idx = java_lang_dex_file_->GetIndexForTypeId(*type_id); Object* array = CheckAndAllocArrayFromCode(type_idx, sort, 3, Thread::Current()); EXPECT_TRUE(array->IsArrayInstance()); EXPECT_EQ(3, array->AsArray()->GetLength()); @@ -185,7 +190,26 @@ TEST_F(ObjectTest, StaticFieldFromCode) { Class* klass = class_linker_->FindClass("LStaticsFromCode;", class_loader.get()); Method* clinit = klass->FindDirectMethod("<clinit>", "()V"); - uint32_t field_idx = FindFieldIdxByDescriptorAndName(*dex_file, "LStaticsFromCode;", "s0"); + const DexFile::StringId* klass_string_id = dex_file->FindStringId("LStaticsFromCode;"); + ASSERT_TRUE(klass_string_id != NULL); + const DexFile::TypeId* klass_type_id = dex_file->FindTypeId( + dex_file->GetIndexForStringId(*klass_string_id)); + ASSERT_TRUE(klass_type_id != NULL); + + const DexFile::StringId* type_string_id = dex_file->FindStringId("Ljava/lang/Object;"); + ASSERT_TRUE(type_string_id != NULL); + const DexFile::TypeId* type_type_id = dex_file->FindTypeId( + dex_file->GetIndexForStringId(*type_string_id)); + ASSERT_TRUE(type_type_id != NULL); + + const DexFile::StringId* name_str_id = dex_file->FindStringId("s0"); + ASSERT_TRUE(name_str_id != NULL); + + const DexFile::FieldId* field_id = dex_file->FindFieldId( + *klass_type_id, *name_str_id, *type_type_id); + ASSERT_TRUE(field_id != NULL); + uint32_t field_idx = dex_file->GetIndexForFieldId(*field_id); + Field* field = FindFieldFromCode(field_idx, clinit, true); Object* s0 = field->GetObj(NULL); EXPECT_EQ(NULL, s0); |