summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/class_linker_test.cc7
-rw-r--r--src/common_test.h25
-rw-r--r--src/dex_file.cc39
-rw-r--r--src/dex_file.h16
-rw-r--r--src/dex_file_test.cc15
-rw-r--r--src/object_test.cc28
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);