blob: 81e17943ec268e9623699886e50a707280c47a19 [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>
Andreas Gampe5a4b8a22014-09-11 08:30:08 -070029template <template <class T2> class HandleKind2>
Ian Rogersded66a02014-10-28 18:12:55 -070030bool MethodHelperT<HandleKind>::HasSameSignatureWithDifferentClassLoaders(Thread* self,
Andreas Gampe5a4b8a22014-09-11 08:30:08 -070031 MethodHelperT<HandleKind2>* other) {
Ian Rogersded66a02014-10-28 18:12:55 -070032 {
33 StackHandleScope<1> hs(self);
34 Handle<mirror::Class> return_type(hs.NewHandle(GetMethod()->GetReturnType()));
35 if (UNLIKELY(other->GetMethod()->GetReturnType() != return_type.Get())) {
36 return false;
37 }
Ian Rogerse5877a12014-07-16 12:06:35 -070038 }
39 const DexFile::TypeList* types = method_->GetParameterTypeList();
40 const DexFile::TypeList* other_types = other->method_->GetParameterTypeList();
41 if (types == nullptr) {
42 return (other_types == nullptr) || (other_types->Size() == 0);
43 } else if (UNLIKELY(other_types == nullptr)) {
44 return types->Size() == 0;
45 }
46 uint32_t num_types = types->Size();
47 if (UNLIKELY(num_types != other_types->Size())) {
48 return false;
49 }
50 for (uint32_t i = 0; i < num_types; ++i) {
51 mirror::Class* param_type = GetClassFromTypeIdx(types->GetTypeItem(i).type_idx_);
52 mirror::Class* other_param_type =
53 other->GetClassFromTypeIdx(other_types->GetTypeItem(i).type_idx_);
54 if (UNLIKELY(param_type != other_param_type)) {
55 return false;
56 }
57 }
58 return true;
59}
60
Andreas Gampe5a4b8a22014-09-11 08:30:08 -070061template <template <class T> class HandleKind>
62uint32_t MethodHelperT<HandleKind>::FindDexMethodIndexInOtherDexFile(const DexFile& other_dexfile)
Ian Rogers22d5e732014-07-15 22:23:51 -070063 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
64 mirror::ArtMethod* method = GetMethod();
65 const DexFile* dexfile = method->GetDexFile();
66 if (dexfile == &other_dexfile) {
67 return method->GetDexMethodIndex();
68 }
69 const DexFile::MethodId& mid = dexfile->GetMethodId(method->GetDexMethodIndex());
70 const char* mid_declaring_class_descriptor = dexfile->StringByTypeIdx(mid.class_idx_);
71 const DexFile::StringId* other_descriptor =
72 other_dexfile.FindStringId(mid_declaring_class_descriptor);
73 if (other_descriptor != nullptr) {
74 const DexFile::TypeId* other_type_id =
75 other_dexfile.FindTypeId(other_dexfile.GetIndexForStringId(*other_descriptor));
76 if (other_type_id != nullptr) {
77 const char* mid_name = dexfile->GetMethodName(mid);
78 const DexFile::StringId* other_name = other_dexfile.FindStringId(mid_name);
79 if (other_name != nullptr) {
80 uint16_t other_return_type_idx;
81 std::vector<uint16_t> other_param_type_idxs;
82 bool success = other_dexfile.CreateTypeList(
83 dexfile->GetMethodSignature(mid).ToString(), &other_return_type_idx,
84 &other_param_type_idxs);
85 if (success) {
86 const DexFile::ProtoId* other_sig =
87 other_dexfile.FindProtoId(other_return_type_idx, other_param_type_idxs);
88 if (other_sig != nullptr) {
89 const DexFile::MethodId* other_mid = other_dexfile.FindMethodId(
90 *other_type_id, *other_name, *other_sig);
91 if (other_mid != nullptr) {
92 return other_dexfile.GetIndexForMethodId(*other_mid);
93 }
94 }
95 }
96 }
97 }
98 }
99 return DexFile::kDexNoIndex;
100}
101
Andreas Gampe5a4b8a22014-09-11 08:30:08 -0700102template <template <typename> class HandleKind>
103uint32_t MethodHelperT<HandleKind>::FindDexMethodIndexInOtherDexFile(
104 const DexFile& other_dexfile, uint32_t name_and_signature_idx)
Ian Rogers22d5e732014-07-15 22:23:51 -0700105 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
106 mirror::ArtMethod* method = GetMethod();
107 const DexFile* dexfile = method->GetDexFile();
108 const uint32_t dex_method_idx = method->GetDexMethodIndex();
109 const DexFile::MethodId& mid = dexfile->GetMethodId(dex_method_idx);
110 const DexFile::MethodId& name_and_sig_mid = other_dexfile.GetMethodId(name_and_signature_idx);
111 DCHECK_STREQ(dexfile->GetMethodName(mid), other_dexfile.GetMethodName(name_and_sig_mid));
112 DCHECK_EQ(dexfile->GetMethodSignature(mid), other_dexfile.GetMethodSignature(name_and_sig_mid));
113 if (dexfile == &other_dexfile) {
114 return dex_method_idx;
115 }
116 const char* mid_declaring_class_descriptor = dexfile->StringByTypeIdx(mid.class_idx_);
117 const DexFile::StringId* other_descriptor =
118 other_dexfile.FindStringId(mid_declaring_class_descriptor);
119 if (other_descriptor != nullptr) {
120 const DexFile::TypeId* other_type_id =
121 other_dexfile.FindTypeId(other_dexfile.GetIndexForStringId(*other_descriptor));
122 if (other_type_id != nullptr) {
123 const DexFile::MethodId* other_mid = other_dexfile.FindMethodId(
124 *other_type_id, other_dexfile.GetStringId(name_and_sig_mid.name_idx_),
125 other_dexfile.GetProtoId(name_and_sig_mid.proto_idx_));
126 if (other_mid != nullptr) {
127 return other_dexfile.GetIndexForMethodId(*other_mid);
128 }
129 }
130 }
131 return DexFile::kDexNoIndex;
132}
133
Andreas Gampe5a4b8a22014-09-11 08:30:08 -0700134// Instantiate methods.
Andreas Gampe5a4b8a22014-09-11 08:30:08 -0700135template
136uint32_t MethodHelperT<Handle>::FindDexMethodIndexInOtherDexFile(const DexFile& other_dexfile);
137template
138uint32_t MethodHelperT<MutableHandle>::FindDexMethodIndexInOtherDexFile(
139 const DexFile& other_dexfile);
140
141template
142uint32_t MethodHelperT<Handle>::FindDexMethodIndexInOtherDexFile(const DexFile& other_dexfile,
143 uint32_t name_and_signature_idx);
144template
145uint32_t MethodHelperT<MutableHandle>::FindDexMethodIndexInOtherDexFile(
146 const DexFile& other_dexfile, uint32_t name_and_signature_idx);
147
148template
Ian Rogersded66a02014-10-28 18:12:55 -0700149bool MethodHelperT<Handle>::HasSameSignatureWithDifferentClassLoaders<Handle>(Thread* self,
Andreas Gampe5a4b8a22014-09-11 08:30:08 -0700150 MethodHelperT<Handle>* other);
151
152template
Ian Rogersded66a02014-10-28 18:12:55 -0700153bool MethodHelperT<Handle>::HasSameSignatureWithDifferentClassLoaders<MutableHandle>(Thread* self,
Andreas Gampe5a4b8a22014-09-11 08:30:08 -0700154 MethodHelperT<MutableHandle>* other);
155
156template
Ian Rogersded66a02014-10-28 18:12:55 -0700157bool MethodHelperT<MutableHandle>::HasSameSignatureWithDifferentClassLoaders<Handle>(Thread* self,
Andreas Gampe5a4b8a22014-09-11 08:30:08 -0700158 MethodHelperT<Handle>* other);
159
160template
161bool MethodHelperT<MutableHandle>::HasSameSignatureWithDifferentClassLoaders<MutableHandle>(
Ian Rogersded66a02014-10-28 18:12:55 -0700162 Thread* self, MethodHelperT<MutableHandle>* other);
Andreas Gampe5a4b8a22014-09-11 08:30:08 -0700163
Ian Rogers22d5e732014-07-15 22:23:51 -0700164} // namespace art