blob: 0799bb0acaeb0cb3bdeca26125f6cfc2c9802594 [file] [log] [blame]
Ian Rogers22d5e732014-07-15 22:23:51 -07001/*
2 * Copyright (C) 2011 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
Ian Rogerse5877a12014-07-16 12:06:35 -070017#include "method_helper-inl.h"
Ian Rogers22d5e732014-07-15 22:23:51 -070018
19#include "class_linker.h"
20#include "dex_file-inl.h"
21#include "handle_scope-inl.h"
22#include "mirror/art_method-inl.h"
23#include "mirror/dex_cache.h"
24#include "runtime.h"
25
26namespace art {
27
Andreas Gampe5a4b8a22014-09-11 08:30:08 -070028template <template <class T> class HandleKind>
29mirror::String* MethodHelperT<HandleKind>::GetNameAsString(Thread* self) {
Ian Rogers22d5e732014-07-15 22:23:51 -070030 const DexFile* dex_file = method_->GetDexFile();
31 mirror::ArtMethod* method = method_->GetInterfaceMethodIfProxy();
32 uint32_t dex_method_idx = method->GetDexMethodIndex();
33 const DexFile::MethodId& method_id = dex_file->GetMethodId(dex_method_idx);
34 StackHandleScope<1> hs(self);
35 Handle<mirror::DexCache> dex_cache(hs.NewHandle(method->GetDexCache()));
36 return Runtime::Current()->GetClassLinker()->ResolveString(*dex_file, method_id.name_idx_,
37 dex_cache);
38}
39
Andreas Gampe5a4b8a22014-09-11 08:30:08 -070040template <template <class T> class HandleKind>
41template <template <class T2> class HandleKind2>
Ian Rogersded66a02014-10-28 18:12:55 -070042bool MethodHelperT<HandleKind>::HasSameSignatureWithDifferentClassLoaders(Thread* self,
Andreas Gampe5a4b8a22014-09-11 08:30:08 -070043 MethodHelperT<HandleKind2>* other) {
Ian Rogersded66a02014-10-28 18:12:55 -070044 {
45 StackHandleScope<1> hs(self);
46 Handle<mirror::Class> return_type(hs.NewHandle(GetMethod()->GetReturnType()));
47 if (UNLIKELY(other->GetMethod()->GetReturnType() != return_type.Get())) {
48 return false;
49 }
Ian Rogerse5877a12014-07-16 12:06:35 -070050 }
51 const DexFile::TypeList* types = method_->GetParameterTypeList();
52 const DexFile::TypeList* other_types = other->method_->GetParameterTypeList();
53 if (types == nullptr) {
54 return (other_types == nullptr) || (other_types->Size() == 0);
55 } else if (UNLIKELY(other_types == nullptr)) {
56 return types->Size() == 0;
57 }
58 uint32_t num_types = types->Size();
59 if (UNLIKELY(num_types != other_types->Size())) {
60 return false;
61 }
62 for (uint32_t i = 0; i < num_types; ++i) {
63 mirror::Class* param_type = GetClassFromTypeIdx(types->GetTypeItem(i).type_idx_);
64 mirror::Class* other_param_type =
65 other->GetClassFromTypeIdx(other_types->GetTypeItem(i).type_idx_);
66 if (UNLIKELY(param_type != other_param_type)) {
67 return false;
68 }
69 }
70 return true;
71}
72
Andreas Gampe5a4b8a22014-09-11 08:30:08 -070073template <template <class T> class HandleKind>
74uint32_t MethodHelperT<HandleKind>::FindDexMethodIndexInOtherDexFile(const DexFile& other_dexfile)
Ian Rogers22d5e732014-07-15 22:23:51 -070075 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
76 mirror::ArtMethod* method = GetMethod();
77 const DexFile* dexfile = method->GetDexFile();
78 if (dexfile == &other_dexfile) {
79 return method->GetDexMethodIndex();
80 }
81 const DexFile::MethodId& mid = dexfile->GetMethodId(method->GetDexMethodIndex());
82 const char* mid_declaring_class_descriptor = dexfile->StringByTypeIdx(mid.class_idx_);
83 const DexFile::StringId* other_descriptor =
84 other_dexfile.FindStringId(mid_declaring_class_descriptor);
85 if (other_descriptor != nullptr) {
86 const DexFile::TypeId* other_type_id =
87 other_dexfile.FindTypeId(other_dexfile.GetIndexForStringId(*other_descriptor));
88 if (other_type_id != nullptr) {
89 const char* mid_name = dexfile->GetMethodName(mid);
90 const DexFile::StringId* other_name = other_dexfile.FindStringId(mid_name);
91 if (other_name != nullptr) {
92 uint16_t other_return_type_idx;
93 std::vector<uint16_t> other_param_type_idxs;
94 bool success = other_dexfile.CreateTypeList(
95 dexfile->GetMethodSignature(mid).ToString(), &other_return_type_idx,
96 &other_param_type_idxs);
97 if (success) {
98 const DexFile::ProtoId* other_sig =
99 other_dexfile.FindProtoId(other_return_type_idx, other_param_type_idxs);
100 if (other_sig != nullptr) {
101 const DexFile::MethodId* other_mid = other_dexfile.FindMethodId(
102 *other_type_id, *other_name, *other_sig);
103 if (other_mid != nullptr) {
104 return other_dexfile.GetIndexForMethodId(*other_mid);
105 }
106 }
107 }
108 }
109 }
110 }
111 return DexFile::kDexNoIndex;
112}
113
Andreas Gampe5a4b8a22014-09-11 08:30:08 -0700114template <template <typename> class HandleKind>
115uint32_t MethodHelperT<HandleKind>::FindDexMethodIndexInOtherDexFile(
116 const DexFile& other_dexfile, uint32_t name_and_signature_idx)
Ian Rogers22d5e732014-07-15 22:23:51 -0700117 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
118 mirror::ArtMethod* method = GetMethod();
119 const DexFile* dexfile = method->GetDexFile();
120 const uint32_t dex_method_idx = method->GetDexMethodIndex();
121 const DexFile::MethodId& mid = dexfile->GetMethodId(dex_method_idx);
122 const DexFile::MethodId& name_and_sig_mid = other_dexfile.GetMethodId(name_and_signature_idx);
123 DCHECK_STREQ(dexfile->GetMethodName(mid), other_dexfile.GetMethodName(name_and_sig_mid));
124 DCHECK_EQ(dexfile->GetMethodSignature(mid), other_dexfile.GetMethodSignature(name_and_sig_mid));
125 if (dexfile == &other_dexfile) {
126 return dex_method_idx;
127 }
128 const char* mid_declaring_class_descriptor = dexfile->StringByTypeIdx(mid.class_idx_);
129 const DexFile::StringId* other_descriptor =
130 other_dexfile.FindStringId(mid_declaring_class_descriptor);
131 if (other_descriptor != nullptr) {
132 const DexFile::TypeId* other_type_id =
133 other_dexfile.FindTypeId(other_dexfile.GetIndexForStringId(*other_descriptor));
134 if (other_type_id != nullptr) {
135 const DexFile::MethodId* other_mid = other_dexfile.FindMethodId(
136 *other_type_id, other_dexfile.GetStringId(name_and_sig_mid.name_idx_),
137 other_dexfile.GetProtoId(name_and_sig_mid.proto_idx_));
138 if (other_mid != nullptr) {
139 return other_dexfile.GetIndexForMethodId(*other_mid);
140 }
141 }
142 }
143 return DexFile::kDexNoIndex;
144}
145
Andreas Gampe5a4b8a22014-09-11 08:30:08 -0700146// Instantiate methods.
147template mirror::String* MethodHelperT<Handle>::GetNameAsString(Thread* self);
148
149template mirror::String* MethodHelperT<MutableHandle>::GetNameAsString(Thread* self);
150
151template
152uint32_t MethodHelperT<Handle>::FindDexMethodIndexInOtherDexFile(const DexFile& other_dexfile);
153template
154uint32_t MethodHelperT<MutableHandle>::FindDexMethodIndexInOtherDexFile(
155 const DexFile& other_dexfile);
156
157template
158uint32_t MethodHelperT<Handle>::FindDexMethodIndexInOtherDexFile(const DexFile& other_dexfile,
159 uint32_t name_and_signature_idx);
160template
161uint32_t MethodHelperT<MutableHandle>::FindDexMethodIndexInOtherDexFile(
162 const DexFile& other_dexfile, uint32_t name_and_signature_idx);
163
164template
Ian Rogersded66a02014-10-28 18:12:55 -0700165bool MethodHelperT<Handle>::HasSameSignatureWithDifferentClassLoaders<Handle>(Thread* self,
Andreas Gampe5a4b8a22014-09-11 08:30:08 -0700166 MethodHelperT<Handle>* other);
167
168template
Ian Rogersded66a02014-10-28 18:12:55 -0700169bool MethodHelperT<Handle>::HasSameSignatureWithDifferentClassLoaders<MutableHandle>(Thread* self,
Andreas Gampe5a4b8a22014-09-11 08:30:08 -0700170 MethodHelperT<MutableHandle>* other);
171
172template
Ian Rogersded66a02014-10-28 18:12:55 -0700173bool MethodHelperT<MutableHandle>::HasSameSignatureWithDifferentClassLoaders<Handle>(Thread* self,
Andreas Gampe5a4b8a22014-09-11 08:30:08 -0700174 MethodHelperT<Handle>* other);
175
176template
177bool MethodHelperT<MutableHandle>::HasSameSignatureWithDifferentClassLoaders<MutableHandle>(
Ian Rogersded66a02014-10-28 18:12:55 -0700178 Thread* self, MethodHelperT<MutableHandle>* other);
Andreas Gampe5a4b8a22014-09-11 08:30:08 -0700179
Ian Rogers22d5e732014-07-15 22:23:51 -0700180} // namespace art