summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--compiler/dex/quick/codegen_util.cc12
-rw-r--r--compiler/dex/quick/mir_to_lir.h4
-rw-r--r--compiler/driver/compiler_driver.cc5
-rw-r--r--runtime/class_linker.cc22
-rw-r--r--runtime/class_linker_test.cc21
-rw-r--r--runtime/common_throws.cc2
-rw-r--r--runtime/common_throws.h3
-rw-r--r--runtime/debugger.cc2
-rw-r--r--runtime/dex_file-inl.h4
-rw-r--r--runtime/dex_file.cc66
-rw-r--r--runtime/dex_file.h95
-rw-r--r--runtime/dex_file_test.cc27
-rw-r--r--runtime/jni_internal.cc1
-rw-r--r--runtime/mirror/class.cc64
-rw-r--r--runtime/mirror/class.h35
-rw-r--r--runtime/object_utils.h41
-rw-r--r--runtime/trace.cc2
-rw-r--r--runtime/utils.cc22
-rw-r--r--runtime/verifier/method_verifier.cc4
-rw-r--r--test/Android.mk2
-rw-r--r--test/GetMethodSignature/GetMethodSignature.java (renamed from test/CreateMethodSignature/CreateMethodSignature.java)4
21 files changed, 283 insertions, 155 deletions
diff --git a/compiler/dex/quick/codegen_util.cc b/compiler/dex/quick/codegen_util.cc
index 4ce752fb39..6e49f0bc54 100644
--- a/compiler/dex/quick/codegen_util.cc
+++ b/compiler/dex/quick/codegen_util.cc
@@ -248,12 +248,12 @@ void Mir2Lir::DumpPromotionMap() {
}
/* Dump a mapping table */
-void Mir2Lir::DumpMappingTable(const char* table_name, const std::string& descriptor,
- const std::string& name, const std::string& signature,
+void Mir2Lir::DumpMappingTable(const char* table_name, const char* descriptor,
+ const char* name, const Signature& signature,
const std::vector<uint32_t>& v) {
if (v.size() > 0) {
std::string line(StringPrintf("\n %s %s%s_%s_table[%zu] = {", table_name,
- descriptor.c_str(), name.c_str(), signature.c_str(), v.size()));
+ descriptor, name, signature.ToString().c_str(), v.size()));
std::replace(line.begin(), line.end(), ';', '_');
LOG(INFO) << line;
for (uint32_t i = 0; i < v.size(); i+=2) {
@@ -293,9 +293,9 @@ void Mir2Lir::CodegenDump() {
const DexFile::MethodId& method_id =
cu_->dex_file->GetMethodId(cu_->method_idx);
- std::string signature(cu_->dex_file->GetMethodSignature(method_id));
- std::string name(cu_->dex_file->GetMethodName(method_id));
- std::string descriptor(cu_->dex_file->GetMethodDeclaringClassDescriptor(method_id));
+ const Signature signature = cu_->dex_file->GetMethodSignature(method_id);
+ const char* name = cu_->dex_file->GetMethodName(method_id);
+ const char* descriptor(cu_->dex_file->GetMethodDeclaringClassDescriptor(method_id));
// Dump mapping tables
DumpMappingTable("PC2Dex_MappingTable", descriptor, name, signature, pc2dex_mapping_table_);
diff --git a/compiler/dex/quick/mir_to_lir.h b/compiler/dex/quick/mir_to_lir.h
index 401e3d5f93..7d6f968da5 100644
--- a/compiler/dex/quick/mir_to_lir.h
+++ b/compiler/dex/quick/mir_to_lir.h
@@ -283,8 +283,8 @@ class Mir2Lir : public Backend {
bool EvaluateBranch(Instruction::Code opcode, int src1, int src2);
bool IsInexpensiveConstant(RegLocation rl_src);
ConditionCode FlipComparisonOrder(ConditionCode before);
- void DumpMappingTable(const char* table_name, const std::string& descriptor,
- const std::string& name, const std::string& signature,
+ void DumpMappingTable(const char* table_name, const char* descriptor,
+ const char* name, const Signature& signature,
const std::vector<uint32_t>& v);
void InstallLiteralPools();
void InstallSwitchTables();
diff --git a/compiler/driver/compiler_driver.cc b/compiler/driver/compiler_driver.cc
index e227715605..056be1fb04 100644
--- a/compiler/driver/compiler_driver.cc
+++ b/compiler/driver/compiler_driver.cc
@@ -1227,8 +1227,9 @@ bool CompilerDriver::ComputeInvokeInfo(const DexCompilationUnit* mUnit, const ui
if (name != NULL) {
uint16_t return_type_idx;
std::vector<uint16_t> param_type_idxs;
- bool success = dexfile->CreateTypeList(&return_type_idx, &param_type_idxs,
- cm_dexfile->GetMethodSignature(cm_method_id));
+ bool success =
+ dexfile->CreateTypeList(cm_dexfile->GetMethodSignature(cm_method_id).ToString(),
+ &return_type_idx, &param_type_idxs);
if (success) {
const DexFile::ProtoId* sig =
dexfile->FindProtoId(return_type_idx, param_type_idxs);
diff --git a/runtime/class_linker.cc b/runtime/class_linker.cc
index 6aae63ee2c..17a179f2d9 100644
--- a/runtime/class_linker.cc
+++ b/runtime/class_linker.cc
@@ -2823,12 +2823,12 @@ static void CheckProxyConstructor(mirror::ArtMethod* constructor)
CHECK(constructor->IsConstructor());
MethodHelper mh(constructor);
CHECK_STREQ(mh.GetName(), "<init>");
- CHECK_EQ(mh.GetSignature(), std::string("(Ljava/lang/reflect/InvocationHandler;)V"));
+ CHECK_STREQ(mh.GetSignature().ToString().c_str(), "(Ljava/lang/reflect/InvocationHandler;)V");
DCHECK(constructor->IsPublic());
}
mirror::ArtMethod* ClassLinker::CreateProxyMethod(Thread* self, SirtRef<mirror::Class>& klass,
- SirtRef<mirror::ArtMethod>& prototype) {
+ SirtRef<mirror::ArtMethod>& prototype) {
// Ensure prototype is in dex cache so that we can use the dex cache to look up the overridden
// prototype method
prototype->GetDeclaringClass()->GetDexCache()->SetResolvedMethod(prototype->GetDexMethodIndex(),
@@ -2892,7 +2892,7 @@ static bool CanWeInitializeClass(mirror::Class* klass, bool can_init_statics,
}
if (!can_init_statics) {
// Check if there's a class initializer.
- mirror::ArtMethod* clinit = klass->FindDeclaredDirectMethod("<clinit>", "()V");
+ mirror::ArtMethod* clinit = klass->FindClassInitializer();
if (clinit != NULL) {
return false;
}
@@ -3039,7 +3039,7 @@ bool ClassLinker::InitializeClass(mirror::Class* klass, bool can_init_statics,
}
}
- mirror::ArtMethod* clinit = klass->FindDeclaredDirectMethod("<clinit>", "()V");
+ mirror::ArtMethod* clinit = klass->FindClassInitializer();
if (clinit != NULL) {
CHECK(can_init_statics);
if (LIKELY(Runtime::Current()->IsStarted())) {
@@ -3992,11 +3992,11 @@ mirror::Class* ClassLinker::ResolveType(const DexFile& dex_file,
}
mirror::ArtMethod* ClassLinker::ResolveMethod(const DexFile& dex_file,
- uint32_t method_idx,
- mirror::DexCache* dex_cache,
- mirror::ClassLoader* class_loader,
- const mirror::ArtMethod* referrer,
- InvokeType type) {
+ uint32_t method_idx,
+ mirror::DexCache* dex_cache,
+ mirror::ClassLoader* class_loader,
+ const mirror::ArtMethod* referrer,
+ InvokeType type) {
DCHECK(dex_cache != NULL);
// Check for hit in the dex cache.
mirror::ArtMethod* resolved = dex_cache->GetResolvedMethod(method_idx);
@@ -4031,7 +4031,7 @@ mirror::ArtMethod* ClassLinker::ResolveMethod(const DexFile& dex_file,
if (resolved == NULL) {
// Search by name, which works across dex files.
const char* name = dex_file.StringDataByIdx(method_id.name_idx_);
- std::string signature(dex_file.CreateMethodSignature(method_id.proto_idx_, NULL));
+ const Signature signature = dex_file.GetMethodSignature(method_id);
switch (type) {
case kDirect: // Fall-through.
case kStatic:
@@ -4061,7 +4061,7 @@ mirror::ArtMethod* ClassLinker::ResolveMethod(const DexFile& dex_file,
// We failed to find the method which means either an access error, an incompatible class
// change, or no such method. First try to find the method among direct and virtual methods.
const char* name = dex_file.StringDataByIdx(method_id.name_idx_);
- std::string signature(dex_file.CreateMethodSignature(method_id.proto_idx_, NULL));
+ const Signature signature = dex_file.GetMethodSignature(method_id);
switch (type) {
case kDirect:
case kStatic:
diff --git a/runtime/class_linker_test.cc b/runtime/class_linker_test.cc
index bea1139679..ad9347fee1 100644
--- a/runtime/class_linker_test.cc
+++ b/runtime/class_linker_test.cc
@@ -152,7 +152,7 @@ class ClassLinkerTest : public CommonTest {
EXPECT_TRUE(method != NULL);
EXPECT_TRUE(method->GetClass() != NULL);
EXPECT_TRUE(mh.GetName() != NULL);
- EXPECT_TRUE(mh.GetSignature() != NULL);
+ EXPECT_TRUE(mh.GetSignature() != Signature::NoSignature());
EXPECT_TRUE(method->GetDexCacheStrings() != NULL);
EXPECT_TRUE(method->GetDexCacheResolvedMethods() != NULL);
@@ -942,15 +942,16 @@ TEST_F(ClassLinkerTest, Interfaces) {
EXPECT_TRUE(K->IsAssignableFrom(B));
EXPECT_TRUE(J->IsAssignableFrom(B));
- mirror::ArtMethod* Ii = I->FindVirtualMethod("i", "()V");
- mirror::ArtMethod* Jj1 = J->FindVirtualMethod("j1", "()V");
- mirror::ArtMethod* Jj2 = J->FindVirtualMethod("j2", "()V");
- mirror::ArtMethod* Kj1 = K->FindInterfaceMethod("j1", "()V");
- mirror::ArtMethod* Kj2 = K->FindInterfaceMethod("j2", "()V");
- mirror::ArtMethod* Kk = K->FindInterfaceMethod("k", "()V");
- mirror::ArtMethod* Ai = A->FindVirtualMethod("i", "()V");
- mirror::ArtMethod* Aj1 = A->FindVirtualMethod("j1", "()V");
- mirror::ArtMethod* Aj2 = A->FindVirtualMethod("j2", "()V");
+ const Signature void_sig = I->GetDexCache()->GetDexFile()->CreateSignature("()V");
+ mirror::ArtMethod* Ii = I->FindVirtualMethod("i", void_sig);
+ mirror::ArtMethod* Jj1 = J->FindVirtualMethod("j1", void_sig);
+ mirror::ArtMethod* Jj2 = J->FindVirtualMethod("j2", void_sig);
+ mirror::ArtMethod* Kj1 = K->FindInterfaceMethod("j1", void_sig);
+ mirror::ArtMethod* Kj2 = K->FindInterfaceMethod("j2", void_sig);
+ mirror::ArtMethod* Kk = K->FindInterfaceMethod("k", void_sig);
+ mirror::ArtMethod* Ai = A->FindVirtualMethod("i", void_sig);
+ mirror::ArtMethod* Aj1 = A->FindVirtualMethod("j1", void_sig);
+ mirror::ArtMethod* Aj2 = A->FindVirtualMethod("j2", void_sig);
ASSERT_TRUE(Ii != NULL);
ASSERT_TRUE(Jj1 != NULL);
ASSERT_TRUE(Jj2 != NULL);
diff --git a/runtime/common_throws.cc b/runtime/common_throws.cc
index 26ce5be1ec..189e3edc0f 100644
--- a/runtime/common_throws.cc
+++ b/runtime/common_throws.cc
@@ -265,7 +265,7 @@ void ThrowNoSuchFieldError(const StringPiece& scope, mirror::Class* c,
// NoSuchMethodError
void ThrowNoSuchMethodError(InvokeType type, mirror::Class* c, const StringPiece& name,
- const StringPiece& signature) {
+ const Signature& signature) {
std::ostringstream msg;
ClassHelper kh(c);
msg << "No " << type << " method " << name << signature
diff --git a/runtime/common_throws.h b/runtime/common_throws.h
index 99c6343cdd..1d77e2d625 100644
--- a/runtime/common_throws.h
+++ b/runtime/common_throws.h
@@ -27,6 +27,7 @@ class ArtMethod;
class Class;
class Object;
} // namespace mirror
+class Signature;
class StringPiece;
class ThrowLocation;
@@ -140,7 +141,7 @@ void ThrowNoSuchFieldError(const StringPiece& scope, mirror::Class* c,
// NoSuchMethodError
void ThrowNoSuchMethodError(InvokeType type, mirror::Class* c, const StringPiece& name,
- const StringPiece& signature)
+ const Signature& signature)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
void ThrowNoSuchMethodError(uint32_t method_idx)
diff --git a/runtime/debugger.cc b/runtime/debugger.cc
index e57137fb96..ae57aa34ec 100644
--- a/runtime/debugger.cc
+++ b/runtime/debugger.cc
@@ -1287,7 +1287,7 @@ JDWP::JdwpError Dbg::OutputDeclaredMethods(JDWP::RefTypeId class_id, bool with_g
MethodHelper mh(m);
expandBufAddMethodId(pReply, ToMethodId(m));
expandBufAddUtf8String(pReply, mh.GetName());
- expandBufAddUtf8String(pReply, mh.GetSignature());
+ expandBufAddUtf8String(pReply, mh.GetSignature().ToString());
if (with_generic) {
static const char genericSignature[1] = "";
expandBufAddUtf8String(pReply, genericSignature);
diff --git a/runtime/dex_file-inl.h b/runtime/dex_file-inl.h
index 2ee9244bf2..c57a1e7582 100644
--- a/runtime/dex_file-inl.h
+++ b/runtime/dex_file-inl.h
@@ -47,6 +47,10 @@ inline StringPiece DexFile::StringDataAsStringPieceByIdx(uint32_t idx) const {
return StringPiece(data, static_cast<int>(length));
}
+inline const Signature DexFile::GetMethodSignature(const MethodId& method_id) const {
+ return Signature(this, GetProtoId(method_id.proto_idx_));
+}
+
inline const DexFile::TryItem* DexFile::GetTryItems(const CodeItem& code_item, uint32_t offset) {
const uint16_t* insns_end_ = &code_item.insns_[code_item.insns_size_in_code_units_];
return reinterpret_cast<const TryItem*>
diff --git a/runtime/dex_file.cc b/runtime/dex_file.cc
index 098ab674f4..275dcc5a03 100644
--- a/runtime/dex_file.cc
+++ b/runtime/dex_file.cc
@@ -503,8 +503,8 @@ const DexFile::ProtoId* DexFile::FindProtoId(uint16_t return_type_idx,
}
// Given a signature place the type ids into the given vector
-bool DexFile::CreateTypeList(uint16_t* return_type_idx, std::vector<uint16_t>* param_type_idxs,
- const std::string& signature) const {
+bool DexFile::CreateTypeList(const StringPiece& signature, uint16_t* return_type_idx,
+ std::vector<uint16_t>* param_type_idxs) const {
if (signature[0] != '(') {
return false;
}
@@ -518,6 +518,7 @@ bool DexFile::CreateTypeList(uint16_t* return_type_idx, std::vector<uint16_t>* p
process_return = true;
continue;
}
+ // TODO: avoid building a string.
std::string descriptor;
descriptor += c;
while (c == '[') { // process array prefix
@@ -557,35 +558,18 @@ bool DexFile::CreateTypeList(uint16_t* return_type_idx, std::vector<uint16_t>* p
return false; // failed to correctly parse return type
}
-// Materializes the method descriptor for a method prototype. Method
-// descriptors are not stored directly in the dex file. Instead, one
-// must assemble the descriptor from references in the prototype.
-std::string DexFile::CreateMethodSignature(uint32_t proto_idx, int32_t* unicode_length) const {
- const ProtoId& proto_id = GetProtoId(proto_idx);
- std::string descriptor;
- descriptor.push_back('(');
- const TypeList* type_list = GetProtoParameters(proto_id);
- size_t parameter_length = 0;
- if (type_list != NULL) {
- // A non-zero number of arguments. Append the type names.
- for (size_t i = 0; i < type_list->Size(); ++i) {
- const TypeItem& type_item = type_list->GetTypeItem(i);
- uint32_t type_idx = type_item.type_idx_;
- uint32_t type_length;
- const char* name = StringByTypeIdx(type_idx, &type_length);
- parameter_length += type_length;
- descriptor.append(name);
- }
+const Signature DexFile::CreateSignature(const StringPiece& signature) const {
+ uint16_t return_type_idx;
+ std::vector<uint16_t> param_type_indices;
+ bool success = CreateTypeList(signature, &return_type_idx, &param_type_indices);
+ if (!success) {
+ return Signature::NoSignature();
}
- descriptor.push_back(')');
- uint32_t return_type_idx = proto_id.return_type_idx_;
- uint32_t return_type_length;
- const char* name = StringByTypeIdx(return_type_idx, &return_type_length);
- descriptor.append(name);
- if (unicode_length != NULL) {
- *unicode_length = parameter_length + return_type_length + 2; // 2 for ( and )
+ const ProtoId* proto_id = FindProtoId(return_type_idx, param_type_indices);
+ if (proto_id == NULL) {
+ return Signature::NoSignature();
}
- return descriptor;
+ return Signature(this, *proto_id);
}
int32_t DexFile::GetLineNumFromPC(const mirror::ArtMethod* method, uint32_t rel_pc) const {
@@ -831,6 +815,30 @@ bool DexFile::LineNumForPcCb(void* raw_context, uint32_t address, uint32_t line_
}
}
+std::string Signature::ToString() const {
+ if (dex_file_ == nullptr) {
+ CHECK(proto_id_ == nullptr);
+ return "<no signature>";
+ }
+ const DexFile::TypeList* params = dex_file_->GetProtoParameters(*proto_id_);
+ std::string result;
+ if (params == nullptr) {
+ result += "()";
+ } else {
+ result += "(";
+ for (uint32_t i = 0; i < params->Size(); ++i) {
+ result += dex_file_->StringByTypeIdx(params->GetTypeItem(i).type_idx_);
+ }
+ result += ")";
+ }
+ result += dex_file_->StringByTypeIdx(proto_id_->return_type_idx_);
+ return result;
+}
+
+std::ostream& operator<<(std::ostream& os, const Signature& sig) {
+ return os << sig.ToString();
+}
+
// Decodes the header section from the class data bytes.
void ClassDataItemIterator::ReadClassDataHeader() {
CHECK(ptr_pos_ != NULL);
diff --git a/runtime/dex_file.h b/runtime/dex_file.h
index 4534b41e92..40e4c72772 100644
--- a/runtime/dex_file.h
+++ b/runtime/dex_file.h
@@ -40,6 +40,7 @@ namespace mirror {
class DexCache;
} // namespace mirror
class ClassLinker;
+class Signature;
class StringPiece;
class ZipArchive;
@@ -559,10 +560,8 @@ class DexFile {
return GetProtoId(method_id.proto_idx_);
}
- // Returns the signature of a method id.
- const std::string GetMethodSignature(const MethodId& method_id) const {
- return CreateMethodSignature(method_id.proto_idx_, NULL);
- }
+ // Returns a representation of the signature of a method id.
+ const Signature GetMethodSignature(const MethodId& method_id) const;
// Returns the name of a method id.
const char* GetMethodName(const MethodId& method_id) const {
@@ -656,15 +655,16 @@ class DexFile {
}
// Looks up a proto id for a given return type and signature type list
- const ProtoId* FindProtoId(uint16_t return_type_id,
+ const ProtoId* FindProtoId(uint16_t return_type_idx,
const std::vector<uint16_t>& signature_type_idxs_) const;
// Given a signature place the type ids into the given vector, returns true on success
- bool CreateTypeList(uint16_t* return_type_idx, std::vector<uint16_t>* param_type_idxs,
- const std::string& signature) const;
+ bool CreateTypeList(const StringPiece& signature, uint16_t* return_type_idx,
+ std::vector<uint16_t>* param_type_idxs) const;
- // Given a proto_idx decode the type list and return type into a method signature
- std::string CreateMethodSignature(uint32_t proto_idx, int32_t* unicode_length) const;
+ // Create a Signature from the given string signature or return Signature::NoSignature if not
+ // possible.
+ const Signature CreateSignature(const StringPiece& signature) const;
// Returns the short form method descriptor for the given prototype.
const char* GetShorty(uint32_t proto_idx) const {
@@ -942,6 +942,83 @@ class DexFileParameterIterator {
DISALLOW_IMPLICIT_CONSTRUCTORS(DexFileParameterIterator);
};
+// Abstract the signature of a method.
+class Signature {
+ public:
+ std::string ToString() const;
+
+ static Signature NoSignature() {
+ return Signature();
+ }
+
+ bool operator==(const Signature& rhs) const {
+ if (dex_file_ == nullptr) {
+ return rhs.dex_file_ == nullptr;
+ }
+ if (rhs.dex_file_ == nullptr) {
+ return false;
+ }
+ if (dex_file_ == rhs.dex_file_) {
+ return proto_id_ == rhs.proto_id_;
+ }
+ StringPiece shorty(dex_file_->StringDataAsStringPieceByIdx(proto_id_->shorty_idx_));
+ if (shorty != rhs.dex_file_->StringDataAsStringPieceByIdx(rhs.proto_id_->shorty_idx_)) {
+ return false; // Shorty mismatch.
+ }
+ if (shorty[0] == 'L') {
+ const DexFile::TypeId& return_type_id = dex_file_->GetTypeId(proto_id_->return_type_idx_);
+ const DexFile::TypeId& rhs_return_type_id =
+ rhs.dex_file_->GetTypeId(rhs.proto_id_->return_type_idx_);
+ if (dex_file_->StringDataAsStringPieceByIdx(return_type_id.descriptor_idx_) !=
+ rhs.dex_file_->StringDataAsStringPieceByIdx(rhs_return_type_id.descriptor_idx_)) {
+ return false; // Return type mismatch.
+ }
+ }
+ if (shorty.find('L', 1) != StringPiece::npos) {
+ const DexFile::TypeList* params = dex_file_->GetProtoParameters(*proto_id_);
+ const DexFile::TypeList* rhs_params = rhs.dex_file_->GetProtoParameters(*rhs.proto_id_);
+ // Both lists are empty or have contents, or else shorty is broken.
+ DCHECK_EQ(params == nullptr, rhs_params == nullptr);
+ if (params != nullptr) {
+ uint32_t params_size = params->Size();
+ DCHECK_EQ(params_size, rhs_params->Size()); // Parameter list size must match.
+ for (uint32_t i = 0; i < params_size; ++i) {
+ const DexFile::TypeId& param_id = dex_file_->GetTypeId(params->GetTypeItem(i).type_idx_);
+ const DexFile::TypeId& rhs_param_id =
+ rhs.dex_file_->GetTypeId(rhs_params->GetTypeItem(i).type_idx_);
+ if (dex_file_->StringDataAsStringPieceByIdx(param_id.descriptor_idx_) !=
+ rhs.dex_file_->StringDataAsStringPieceByIdx(rhs_param_id.descriptor_idx_)) {
+ return false; // Parameter type mismatch.
+ }
+ }
+ }
+ }
+ return true;
+ }
+
+ bool operator!=(const Signature& rhs) const {
+ return !(*this == rhs);
+ }
+
+ bool operator==(const StringPiece& rhs) const {
+ // TODO: Avoid temporary string allocation.
+ return ToString() == rhs;
+ }
+
+ private:
+ Signature(const DexFile* dex, const DexFile::ProtoId& proto) : dex_file_(dex), proto_id_(&proto) {
+ }
+
+ Signature() : dex_file_(nullptr), proto_id_(nullptr) {
+ }
+
+ friend class DexFile;
+
+ const DexFile* const dex_file_;
+ const DexFile::ProtoId* const proto_id_;
+};
+std::ostream& operator<<(std::ostream& os, const Signature& sig);
+
// Iterate and decode class_data_item
class ClassDataItemIterator {
public:
diff --git a/runtime/dex_file_test.cc b/runtime/dex_file_test.cc
index 32a8354d01..1b40529a08 100644
--- a/runtime/dex_file_test.cc
+++ b/runtime/dex_file_test.cc
@@ -137,14 +137,14 @@ TEST_F(DexFileTest, ClassDefs) {
EXPECT_STREQ("LNested;", raw->GetClassDescriptor(c1));
}
-TEST_F(DexFileTest, CreateMethodSignature) {
+TEST_F(DexFileTest, GetMethodSignature) {
ScopedObjectAccess soa(Thread::Current());
- const DexFile* raw(OpenTestDexFile("CreateMethodSignature"));
+ const DexFile* raw(OpenTestDexFile("GetMethodSignature"));
ASSERT_TRUE(raw != NULL);
EXPECT_EQ(1U, raw->NumClassDefs());
const DexFile::ClassDef& class_def = raw->GetClassDef(0);
- ASSERT_STREQ("LCreateMethodSignature;", raw->GetClassDescriptor(class_def));
+ ASSERT_STREQ("LGetMethodSignature;", raw->GetClassDescriptor(class_def));
const byte* class_data = raw->GetClassData(class_def);
ASSERT_TRUE(class_data != NULL);
@@ -156,11 +156,9 @@ TEST_F(DexFileTest, CreateMethodSignature) {
{
ASSERT_EQ(1U, it.NumDirectMethods());
const DexFile::MethodId& method_id = raw->GetMethodId(it.GetMemberIndex());
- uint32_t proto_idx = method_id.proto_idx_;
const char* name = raw->StringDataByIdx(method_id.name_idx_);
ASSERT_STREQ("<init>", name);
- int32_t length;
- std::string signature(raw->CreateMethodSignature(proto_idx, &length));
+ std::string signature(raw->GetMethodSignature(method_id).ToString());
ASSERT_EQ("()V", signature);
}
@@ -173,9 +171,7 @@ TEST_F(DexFileTest, CreateMethodSignature) {
const char* name = raw->StringDataByIdx(method_id.name_idx_);
ASSERT_STREQ("m1", name);
- uint32_t proto_idx = method_id.proto_idx_;
- int32_t length;
- std::string signature(raw->CreateMethodSignature(proto_idx, &length));
+ std::string signature(raw->GetMethodSignature(method_id).ToString());
ASSERT_EQ("(IDJLjava/lang/Object;)Ljava/lang/Float;", signature);
}
@@ -186,20 +182,18 @@ TEST_F(DexFileTest, CreateMethodSignature) {
const char* name = raw->StringDataByIdx(method_id.name_idx_);
ASSERT_STREQ("m2", name);
- uint32_t proto_idx = method_id.proto_idx_;
- int32_t length;
- std::string signature(raw->CreateMethodSignature(proto_idx, &length));
- ASSERT_EQ("(ZSC)LCreateMethodSignature;", signature);
+ std::string signature(raw->GetMethodSignature(method_id).ToString());
+ ASSERT_EQ("(ZSC)LGetMethodSignature;", signature);
}
}
TEST_F(DexFileTest, FindStringId) {
ScopedObjectAccess soa(Thread::Current());
- const DexFile* raw(OpenTestDexFile("CreateMethodSignature"));
+ const DexFile* raw(OpenTestDexFile("GetMethodSignature"));
ASSERT_TRUE(raw != NULL);
EXPECT_EQ(1U, raw->NumClassDefs());
- const char* strings[] = { "LCreateMethodSignature;", "Ljava/lang/Float;", "Ljava/lang/Object;",
+ const char* strings[] = { "LGetMethodSignature;", "Ljava/lang/Float;", "Ljava/lang/Object;",
"D", "I", "J", NULL };
for (size_t i = 0; strings[i] != NULL; i++) {
const char* str = strings[i];
@@ -245,11 +239,10 @@ TEST_F(DexFileTest, FindMethodId) {
const DexFile::StringId& name = java_lang_dex_file_->GetStringId(to_find.name_idx_);
const DexFile::ProtoId& signature = java_lang_dex_file_->GetProtoId(to_find.proto_idx_);
const DexFile::MethodId* found = java_lang_dex_file_->FindMethodId(klass, name, signature);
- int32_t length;
ASSERT_TRUE(found != NULL) << "Didn't find method " << i << ": "
<< java_lang_dex_file_->StringByTypeIdx(to_find.class_idx_) << "."
<< java_lang_dex_file_->GetStringData(name)
- << java_lang_dex_file_->CreateMethodSignature(to_find.proto_idx_, &length);
+ << java_lang_dex_file_->GetMethodSignature(to_find);
EXPECT_EQ(java_lang_dex_file_->GetIndexForMethodId(*found), i);
}
}
diff --git a/runtime/jni_internal.cc b/runtime/jni_internal.cc
index 60fad6ee48..8be9b21cdf 100644
--- a/runtime/jni_internal.cc
+++ b/runtime/jni_internal.cc
@@ -228,6 +228,7 @@ static jmethodID FindMethodID(ScopedObjectAccess& soa, jclass jni_class,
const char* name, const char* sig, bool is_static)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Class* c = soa.Decode<Class*>(jni_class);
+ DCHECK(c != nullptr);
if (!Runtime::Current()->GetClassLinker()->EnsureInitialized(c, true, true)) {
return NULL;
}
diff --git a/runtime/mirror/class.cc b/runtime/mirror/class.cc
index 287e8b0959..c6db5b9a61 100644
--- a/runtime/mirror/class.cc
+++ b/runtime/mirror/class.cc
@@ -325,7 +325,7 @@ void Class::SetClassLoader(ClassLoader* new_class_loader) {
SetFieldObject(OFFSET_OF_OBJECT_MEMBER(Class, class_loader_), new_class_loader, false);
}
-ArtMethod* Class::FindInterfaceMethod(const StringPiece& name, const StringPiece& signature) const {
+ArtMethod* Class::FindInterfaceMethod(const StringPiece& name, const Signature& signature) const {
// Check the current class before checking the interfaces.
ArtMethod* method = FindDeclaredVirtualMethod(name, signature);
if (method != NULL) {
@@ -361,12 +361,23 @@ ArtMethod* Class::FindInterfaceMethod(const DexCache* dex_cache, uint32_t dex_me
return NULL;
}
-
ArtMethod* Class::FindDeclaredDirectMethod(const StringPiece& name, const StringPiece& signature) const {
MethodHelper mh;
for (size_t i = 0; i < NumDirectMethods(); ++i) {
ArtMethod* method = GetDirectMethod(i);
mh.ChangeMethod(method);
+ if (name == mh.GetNameAsStringPiece() && mh.GetSignature() == signature) {
+ return method;
+ }
+ }
+ return NULL;
+}
+
+ArtMethod* Class::FindDeclaredDirectMethod(const StringPiece& name, const Signature& signature) const {
+ MethodHelper mh;
+ for (size_t i = 0; i < NumDirectMethods(); ++i) {
+ ArtMethod* method = GetDirectMethod(i);
+ mh.ChangeMethod(method);
if (name == mh.GetNameAsStringPiece() && signature == mh.GetSignature()) {
return method;
}
@@ -396,6 +407,16 @@ ArtMethod* Class::FindDirectMethod(const StringPiece& name, const StringPiece& s
return NULL;
}
+ArtMethod* Class::FindDirectMethod(const StringPiece& name, const Signature& signature) const {
+ for (const Class* klass = this; klass != NULL; klass = klass->GetSuperClass()) {
+ ArtMethod* method = klass->FindDeclaredDirectMethod(name, signature);
+ if (method != NULL) {
+ return method;
+ }
+ }
+ return NULL;
+}
+
ArtMethod* Class::FindDirectMethod(const DexCache* dex_cache, uint32_t dex_method_idx) const {
for (const Class* klass = this; klass != NULL; klass = klass->GetSuperClass()) {
ArtMethod* method = klass->FindDeclaredDirectMethod(dex_cache, dex_method_idx);
@@ -406,8 +427,20 @@ ArtMethod* Class::FindDirectMethod(const DexCache* dex_cache, uint32_t dex_metho
return NULL;
}
+ArtMethod* Class::FindDeclaredVirtualMethod(const StringPiece& name, const StringPiece& signature) const {
+ MethodHelper mh;
+ for (size_t i = 0; i < NumVirtualMethods(); ++i) {
+ ArtMethod* method = GetVirtualMethod(i);
+ mh.ChangeMethod(method);
+ if (name == mh.GetNameAsStringPiece() && mh.GetSignature() == signature) {
+ return method;
+ }
+ }
+ return NULL;
+}
+
ArtMethod* Class::FindDeclaredVirtualMethod(const StringPiece& name,
- const StringPiece& signature) const {
+ const Signature& signature) const {
MethodHelper mh;
for (size_t i = 0; i < NumVirtualMethods(); ++i) {
ArtMethod* method = GetVirtualMethod(i);
@@ -441,6 +474,16 @@ ArtMethod* Class::FindVirtualMethod(const StringPiece& name, const StringPiece&
return NULL;
}
+ArtMethod* Class::FindVirtualMethod(const StringPiece& name, const Signature& signature) const {
+ for (const Class* klass = this; klass != NULL; klass = klass->GetSuperClass()) {
+ ArtMethod* method = klass->FindDeclaredVirtualMethod(name, signature);
+ if (method != NULL) {
+ return method;
+ }
+ }
+ return NULL;
+}
+
ArtMethod* Class::FindVirtualMethod(const DexCache* dex_cache, uint32_t dex_method_idx) const {
for (const Class* klass = this; klass != NULL; klass = klass->GetSuperClass()) {
ArtMethod* method = klass->FindDeclaredVirtualMethod(dex_cache, dex_method_idx);
@@ -451,6 +494,21 @@ ArtMethod* Class::FindVirtualMethod(const DexCache* dex_cache, uint32_t dex_meth
return NULL;
}
+ArtMethod* Class::FindClassInitializer() const {
+ for (size_t i = 0; i < NumDirectMethods(); ++i) {
+ ArtMethod* method = GetDirectMethod(i);
+ if (method->IsConstructor() && method->IsStatic()) {
+ if (kIsDebugBuild) {
+ MethodHelper mh(method);
+ CHECK_STREQ(mh.GetName(), "<clinit>");
+ CHECK_STREQ(mh.GetSignature().ToString().c_str(), "()V");
+ }
+ return method;
+ }
+ }
+ return NULL;
+}
+
ArtField* Class::FindDeclaredInstanceField(const StringPiece& name, const StringPiece& type) {
// Is the field in this class?
// Interfaces are not relevant because they can't contain instance fields.
diff --git a/runtime/mirror/class.h b/runtime/mirror/class.h
index 4f8ab7d90a..586151de45 100644
--- a/runtime/mirror/class.h
+++ b/runtime/mirror/class.h
@@ -59,6 +59,7 @@ namespace art {
struct ClassClassOffsets;
struct ClassOffsets;
+class Signature;
class StringPiece;
namespace mirror {
@@ -565,39 +566,53 @@ class MANAGED Class : public StaticStorageBase {
ArtMethod* FindVirtualMethodForInterface(ArtMethod* method) const
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) ALWAYS_INLINE;
- ArtMethod* FindInterfaceMethod(const StringPiece& name, const StringPiece& descriptor) const
+ ArtMethod* FindVirtualMethodForVirtualOrInterface(ArtMethod* method) const
+ SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+
+ ArtMethod* FindInterfaceMethod(const StringPiece& name, const Signature& signature) const
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
ArtMethod* FindInterfaceMethod(const DexCache* dex_cache, uint32_t dex_method_idx) const
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
- ArtMethod* FindVirtualMethodForVirtualOrInterface(ArtMethod* method) const
+ ArtMethod* FindDeclaredDirectMethod(const StringPiece& name, const StringPiece& signature) const
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
- ArtMethod* FindDeclaredVirtualMethod(const StringPiece& name, const StringPiece& signature) const
+ ArtMethod* FindDeclaredDirectMethod(const StringPiece& name, const Signature& signature) const
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
- ArtMethod* FindDeclaredVirtualMethod(const DexCache* dex_cache, uint32_t dex_method_idx) const
+ ArtMethod* FindDeclaredDirectMethod(const DexCache* dex_cache, uint32_t dex_method_idx) const
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
- ArtMethod* FindVirtualMethod(const StringPiece& name, const StringPiece& descriptor) const
+ ArtMethod* FindDirectMethod(const StringPiece& name, const StringPiece& signature) const
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
- ArtMethod* FindVirtualMethod(const DexCache* dex_cache, uint32_t dex_method_idx) const
+ ArtMethod* FindDirectMethod(const StringPiece& name, const Signature& signature) const
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
- ArtMethod* FindDeclaredDirectMethod(const StringPiece& name, const StringPiece& signature) const
+ ArtMethod* FindDirectMethod(const DexCache* dex_cache, uint32_t dex_method_idx) const
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
- ArtMethod* FindDeclaredDirectMethod(const DexCache* dex_cache, uint32_t dex_method_idx) const
+ ArtMethod* FindDeclaredVirtualMethod(const StringPiece& name, const StringPiece& signature) const
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
- ArtMethod* FindDirectMethod(const StringPiece& name, const StringPiece& signature) const
+ ArtMethod* FindDeclaredVirtualMethod(const StringPiece& name, const Signature& signature) const
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
- ArtMethod* FindDirectMethod(const DexCache* dex_cache, uint32_t dex_method_idx) const
+ ArtMethod* FindDeclaredVirtualMethod(const DexCache* dex_cache, uint32_t dex_method_idx) const
+ SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+
+ ArtMethod* FindVirtualMethod(const StringPiece& name, const StringPiece& signature) const
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+ ArtMethod* FindVirtualMethod(const StringPiece& name, const Signature& signature) const
+ SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+
+ ArtMethod* FindVirtualMethod(const DexCache* dex_cache, uint32_t dex_method_idx) const
+ SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+
+ ArtMethod* FindClassInitializer() const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+
int32_t GetIfTableCount() const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
IfTable* GetIfTable() const;
diff --git a/runtime/object_utils.h b/runtime/object_utils.h
index 9e107a46d5..f83db903ff 100644
--- a/runtime/object_utils.h
+++ b/runtime/object_utils.h
@@ -504,13 +504,13 @@ class MethodHelper {
return shorty_len_;
}
- const std::string GetSignature() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
+ const Signature GetSignature() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
const DexFile& dex_file = GetDexFile();
uint32_t dex_method_idx = method_->GetDexMethodIndex();
if (dex_method_idx != DexFile::kDexNoIndex) {
return dex_file.GetMethodSignature(dex_file.GetMethodId(dex_method_idx));
} else {
- return "<no signature>";
+ return Signature::NoSignature();
}
}
@@ -638,42 +638,7 @@ class MethodHelper {
other_dex_file.StringDataAsStringPieceByIdx(other_mid.name_idx_)) {
return false; // Name mismatch.
}
- const DexFile::ProtoId& proto_id = dex_file.GetMethodPrototype(mid);
- const DexFile::ProtoId& other_proto_id = other_dex_file.GetMethodPrototype(other_mid);
- if (dex_file.StringDataAsStringPieceByIdx(proto_id.shorty_idx_) !=
- other_dex_file.StringDataAsStringPieceByIdx(other_proto_id.shorty_idx_)) {
- return false; // Shorty mismatch.
- }
- const DexFile::TypeId& return_type_id = dex_file.GetTypeId(proto_id.return_type_idx_);
- const DexFile::TypeId& other_return_type_id =
- other_dex_file.GetTypeId(other_proto_id.return_type_idx_);
- if (dex_file.StringDataAsStringPieceByIdx(return_type_id.descriptor_idx_) !=
- other_dex_file.StringDataAsStringPieceByIdx(other_return_type_id.descriptor_idx_)) {
- return false; // Return type mismatch.
- }
- const DexFile::TypeList* params = dex_file.GetProtoParameters(proto_id);
- const DexFile::TypeList* other_params = other_dex_file.GetProtoParameters(other_proto_id);
- if (params == nullptr) {
- return other_params == nullptr; // Check both lists are empty.
- }
- if (other_params == nullptr) {
- return false; // Parameter list size mismatch.
- }
- uint32_t params_size = params->Size();
- uint32_t other_params_size = other_params->Size();
- if (params_size != other_params_size) {
- return false; // Parameter list size mismatch.
- }
- for (uint32_t i = 0; i < params_size; ++i) {
- const DexFile::TypeId& param_id = dex_file.GetTypeId(params->GetTypeItem(i).type_idx_);
- const DexFile::TypeId& other_param_id =
- other_dex_file.GetTypeId(other_params->GetTypeItem(i).type_idx_);
- if (dex_file.StringDataAsStringPieceByIdx(param_id.descriptor_idx_) !=
- other_dex_file.StringDataAsStringPieceByIdx(other_param_id.descriptor_idx_)) {
- return false; // Parameter type mismatch.
- }
- }
- return true;
+ return dex_file.GetMethodSignature(mid) == other_dex_file.GetMethodSignature(other_mid);
}
const DexFile::CodeItem* GetCodeItem()
diff --git a/runtime/trace.cc b/runtime/trace.cc
index 7b25306177..ec95a87146 100644
--- a/runtime/trace.cc
+++ b/runtime/trace.cc
@@ -667,7 +667,7 @@ void Trace::DumpMethodList(std::ostream& os, const std::set<mirror::ArtMethod*>&
mh.ChangeMethod(method);
os << StringPrintf("%p\t%s\t%s\t%s\t%s\n", method,
PrettyDescriptor(mh.GetDeclaringClassDescriptor()).c_str(), mh.GetName(),
- mh.GetSignature().c_str(), mh.GetDeclaringClassSourceFile());
+ mh.GetSignature().ToString().c_str(), mh.GetDeclaringClassSourceFile());
}
}
diff --git a/runtime/utils.cc b/runtime/utils.cc
index 23dcde3065..b97239fd18 100644
--- a/runtime/utils.cc
+++ b/runtime/utils.cc
@@ -367,11 +367,13 @@ std::string PrettyMethod(const mirror::ArtMethod* m, bool with_signature) {
result += '.';
result += mh.GetName();
if (with_signature) {
- std::string signature(mh.GetSignature());
- if (signature == "<no signature>") {
- return result + signature;
+ const Signature signature = mh.GetSignature();
+ std::string sig_as_string(signature.ToString());
+ if (signature == Signature::NoSignature()) {
+ return result + sig_as_string;
}
- result = PrettyReturnType(signature.c_str()) + " " + result + PrettyArguments(signature.c_str());
+ result = PrettyReturnType(sig_as_string.c_str()) + " " + result +
+ PrettyArguments(sig_as_string.c_str());
}
return result;
}
@@ -385,11 +387,13 @@ std::string PrettyMethod(uint32_t method_idx, const DexFile& dex_file, bool with
result += '.';
result += dex_file.GetMethodName(method_id);
if (with_signature) {
- std::string signature(dex_file.GetMethodSignature(method_id));
- if (signature == "<no signature>") {
- return result + signature;
+ const Signature signature = dex_file.GetMethodSignature(method_id);
+ std::string sig_as_string(signature.ToString());
+ if (signature == Signature::NoSignature()) {
+ return result + sig_as_string;
}
- result = PrettyReturnType(signature.c_str()) + " " + result + PrettyArguments(signature.c_str());
+ result = PrettyReturnType(sig_as_string.c_str()) + " " + result +
+ PrettyArguments(sig_as_string.c_str());
}
return result;
}
@@ -641,7 +645,7 @@ std::string JniLongName(const mirror::ArtMethod* m) {
long_name += JniShortName(m);
long_name += "__";
- std::string signature(MethodHelper(m).GetSignature());
+ std::string signature(MethodHelper(m).GetSignature().ToString());
signature.erase(0, 1);
signature.erase(signature.begin() + signature.find(')'), signature.end());
diff --git a/runtime/verifier/method_verifier.cc b/runtime/verifier/method_verifier.cc
index 6b13517fdc..36b409d142 100644
--- a/runtime/verifier/method_verifier.cc
+++ b/runtime/verifier/method_verifier.cc
@@ -2910,7 +2910,7 @@ const RegType& MethodVerifier::GetCaughtExceptionType() {
}
mirror::ArtMethod* MethodVerifier::ResolveMethodAndCheckAccess(uint32_t dex_method_idx,
- MethodType method_type) {
+ MethodType method_type) {
const DexFile::MethodId& method_id = dex_file_->GetMethodId(dex_method_idx);
const RegType& klass_type = ResolveClassAndCheckAccess(method_id.class_idx_);
if (klass_type.IsConflict()) {
@@ -2927,7 +2927,7 @@ mirror::ArtMethod* MethodVerifier::ResolveMethodAndCheckAccess(uint32_t dex_meth
mirror::ArtMethod* res_method = dex_cache_->GetResolvedMethod(dex_method_idx);
if (res_method == NULL) {
const char* name = dex_file_->GetMethodName(method_id);
- std::string signature(dex_file_->CreateMethodSignature(method_id.proto_idx_, NULL));
+ const Signature signature = dex_file_->GetMethodSignature(method_id);
if (method_type == METHOD_DIRECT || method_type == METHOD_STATIC) {
res_method = klass->FindDirectMethod(name, signature);
diff --git a/test/Android.mk b/test/Android.mk
index 6f498e8c02..08ec03a01a 100644
--- a/test/Android.mk
+++ b/test/Android.mk
@@ -23,8 +23,8 @@ include art/build/Android.common.mk
TEST_DEX_DIRECTORIES := \
AbstractMethod \
AllFields \
- CreateMethodSignature \
ExceptionHandle \
+ GetMethodSignature \
Interfaces \
Main \
MyClass \
diff --git a/test/CreateMethodSignature/CreateMethodSignature.java b/test/GetMethodSignature/GetMethodSignature.java
index f6cd6ae6fd..c2ba948d60 100644
--- a/test/CreateMethodSignature/CreateMethodSignature.java
+++ b/test/GetMethodSignature/GetMethodSignature.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-class CreateMethodSignature {
+class GetMethodSignature {
Float m1(int a, double b, long c, Object d) { return null; }
- CreateMethodSignature m2(boolean x, short y, char z) { return null; }
+ GetMethodSignature m2(boolean x, short y, char z) { return null; }
}