blob: 692ceccc6cedeab53080fd7d704b58f4d368250d [file] [log] [blame]
Ian Rogers6d4d9fc2011-11-30 16:24:48 -08001/*
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
Brian Carlstromfc0e3212013-07-17 14:40:12 -070017#ifndef ART_RUNTIME_OBJECT_UTILS_H_
18#define ART_RUNTIME_OBJECT_UTILS_H_
Ian Rogers6d4d9fc2011-11-30 16:24:48 -080019
Ian Rogersd8274bc2013-05-15 15:54:45 -070020#include "class_linker-inl.h"
Ian Rogers6d4d9fc2011-11-30 16:24:48 -080021#include "dex_file.h"
Ian Rogers672f5202012-01-12 18:06:40 -080022#include "monitor.h"
Brian Carlstromea46f952013-07-30 01:26:50 -070023#include "mirror/art_field.h"
24#include "mirror/art_method.h"
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080025#include "mirror/class.h"
26#include "mirror/dex_cache.h"
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080027#include "mirror/iftable.h"
28#include "mirror/string.h"
29
Ian Rogers6d4d9fc2011-11-30 16:24:48 -080030#include "runtime.h"
Ian Rogers50b35e22012-10-04 10:09:15 -070031#include "sirt_ref.h"
Ian Rogers6d4d9fc2011-11-30 16:24:48 -080032
33#include <string>
34
35namespace art {
36
Ian Rogers672f5202012-01-12 18:06:40 -080037class ObjectLock {
38 public:
Ian Rogersd9c4fc92013-10-01 19:45:43 -070039 explicit ObjectLock(Thread* self, mirror::Object* object)
40 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_)
Ian Rogers1f539342012-10-03 21:09:42 -070041 : self_(self), obj_(object) {
Ian Rogers672f5202012-01-12 18:06:40 -080042 CHECK(object != NULL);
43 obj_->MonitorEnter(self_);
44 }
45
Ian Rogersb726dcb2012-09-05 08:57:23 -070046 ~ObjectLock() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Ian Rogers672f5202012-01-12 18:06:40 -080047 obj_->MonitorExit(self_);
48 }
49
Ian Rogers05f30572013-02-20 12:13:11 -080050 void WaitIgnoringInterrupts() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
51 Monitor::Wait(self_, obj_, 0, 0, false, kWaiting);
Ian Rogers672f5202012-01-12 18:06:40 -080052 }
53
Ian Rogersb726dcb2012-09-05 08:57:23 -070054 void Notify() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Ian Rogers05f30572013-02-20 12:13:11 -080055 obj_->Notify(self_);
Ian Rogers672f5202012-01-12 18:06:40 -080056 }
57
Ian Rogersb726dcb2012-09-05 08:57:23 -070058 void NotifyAll() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Ian Rogers05f30572013-02-20 12:13:11 -080059 obj_->NotifyAll(self_);
Ian Rogers672f5202012-01-12 18:06:40 -080060 }
61
62 private:
Ian Rogers00f7d0e2012-07-19 15:28:27 -070063 Thread* const self_;
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080064 mirror::Object* obj_;
Ian Rogers672f5202012-01-12 18:06:40 -080065 DISALLOW_COPY_AND_ASSIGN(ObjectLock);
66};
67
Ian Rogers6d4d9fc2011-11-30 16:24:48 -080068class ClassHelper {
69 public:
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080070 ClassHelper(const mirror::Class* c = NULL, ClassLinker* l = NULL)
Ian Rogersb726dcb2012-09-05 08:57:23 -070071 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_)
Ian Rogers8b2c0b92013-09-19 02:56:49 -070072 : class_linker_(l),
Elliott Hughes91250e02011-12-13 22:30:35 -080073 dex_cache_(NULL),
74 dex_file_(NULL),
75 interface_type_list_(NULL),
Brian Carlstrome77be402012-03-30 01:08:38 -070076 klass_(NULL) {
77 if (c != NULL) {
78 ChangeClass(c);
79 }
Elliott Hughes91250e02011-12-13 22:30:35 -080080 }
Ian Rogers6d4d9fc2011-11-30 16:24:48 -080081
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080082 void ChangeClass(const mirror::Class* new_c)
Ian Rogersb726dcb2012-09-05 08:57:23 -070083 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Brian Carlstrom01e076e2012-03-30 11:54:16 -070084 CHECK(new_c != NULL) << "klass_=" << klass_; // Log what we were changing from if any
85 CHECK(new_c->IsClass()) << "new_c=" << new_c;
Ian Rogers6d4d9fc2011-11-30 16:24:48 -080086 if (dex_cache_ != NULL) {
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080087 mirror::DexCache* new_c_dex_cache = new_c->GetDexCache();
Ian Rogers6d4d9fc2011-11-30 16:24:48 -080088 if (new_c_dex_cache != dex_cache_) {
89 dex_cache_ = new_c_dex_cache;
90 dex_file_ = NULL;
91 }
92 }
93 klass_ = new_c;
94 interface_type_list_ = NULL;
Ian Rogers6d4d9fc2011-11-30 16:24:48 -080095 }
96
Elliott Hughes91250e02011-12-13 22:30:35 -080097 // The returned const char* is only guaranteed to be valid for the lifetime of the ClassHelper.
98 // If you need it longer, copy it into a std::string.
Ian Rogersb726dcb2012-09-05 08:57:23 -070099 const char* GetDescriptor() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Brian Carlstrom93235f72012-03-29 22:48:15 -0700100 CHECK(klass_ != NULL);
Ian Rogersa68a1cb2012-01-10 10:34:36 -0800101 if (UNLIKELY(klass_->IsArrayClass())) {
102 return GetArrayDescriptor();
103 } else if (UNLIKELY(klass_->IsPrimitive())) {
Elliott Hughes91250e02011-12-13 22:30:35 -0800104 return Primitive::Descriptor(klass_->GetPrimitiveType());
Ian Rogersa68a1cb2012-01-10 10:34:36 -0800105 } else if (UNLIKELY(klass_->IsProxyClass())) {
Elliott Hughes91250e02011-12-13 22:30:35 -0800106 descriptor_ = GetClassLinker()->GetDescriptorForProxy(klass_);
107 return descriptor_.c_str();
Ian Rogers6d4d9fc2011-11-30 16:24:48 -0800108 } else {
109 const DexFile& dex_file = GetDexFile();
Ian Rogers8b2c0b92013-09-19 02:56:49 -0700110 const DexFile::TypeId& type_id = dex_file.GetTypeId(GetClassDef()->class_idx_);
Ian Rogers6d4d9fc2011-11-30 16:24:48 -0800111 return dex_file.GetTypeDescriptor(type_id);
112 }
113 }
Elliott Hughes91250e02011-12-13 22:30:35 -0800114
Ian Rogersfc0e94b2013-09-23 23:51:32 -0700115 StringPiece GetDescriptorAsStringPiece() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
116 CHECK(klass_ != NULL);
117 if (UNLIKELY(klass_->IsArrayClass() || klass_->IsPrimitive() || klass_->IsProxyClass())) {
118 return StringPiece(GetDescriptor());
119 } else {
120 const DexFile& dex_file = GetDexFile();
121 const DexFile::TypeId& type_id = dex_file.GetTypeId(GetClassDef()->class_idx_);
122 return dex_file.StringDataAsStringPieceByIdx(type_id.descriptor_idx_);
123 }
124 }
125
Ian Rogersb726dcb2012-09-05 08:57:23 -0700126 const char* GetArrayDescriptor() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Ian Rogersa68a1cb2012-01-10 10:34:36 -0800127 std::string result("[");
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800128 const mirror::Class* saved_klass = klass_;
Brian Carlstrom93235f72012-03-29 22:48:15 -0700129 CHECK(saved_klass != NULL);
Ian Rogersa68a1cb2012-01-10 10:34:36 -0800130 ChangeClass(klass_->GetComponentType());
131 result += GetDescriptor();
132 ChangeClass(saved_klass);
133 descriptor_ = result;
134 return descriptor_.c_str();
135 }
136
Ian Rogers8b2c0b92013-09-19 02:56:49 -0700137 const DexFile::ClassDef* GetClassDef() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
138 DCHECK(klass_ != nullptr);
139 uint16_t class_def_idx = klass_->GetDexClassDefIndex();
140 if (class_def_idx == DexFile::kDexNoIndex16) {
141 return nullptr;
Ian Rogers6d4d9fc2011-11-30 16:24:48 -0800142 }
Ian Rogers8b2c0b92013-09-19 02:56:49 -0700143 return &GetDexFile().GetClassDef(class_def_idx);
Ian Rogers6d4d9fc2011-11-30 16:24:48 -0800144 }
Elliott Hughes91250e02011-12-13 22:30:35 -0800145
Ian Rogersb726dcb2012-09-05 08:57:23 -0700146 uint32_t NumDirectInterfaces() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Brian Carlstrom93235f72012-03-29 22:48:15 -0700147 DCHECK(klass_ != NULL);
Ian Rogers6d4d9fc2011-11-30 16:24:48 -0800148 if (klass_->IsPrimitive()) {
149 return 0;
150 } else if (klass_->IsArrayClass()) {
151 return 2;
Ian Rogersc2b44472011-12-14 21:17:17 -0800152 } else if (klass_->IsProxyClass()) {
153 return klass_->GetIfTable()->GetLength();
Ian Rogers6d4d9fc2011-11-30 16:24:48 -0800154 } else {
Ian Rogers6d4d9fc2011-11-30 16:24:48 -0800155 const DexFile::TypeList* interfaces = GetInterfaceTypeList();
156 if (interfaces == NULL) {
157 return 0;
158 } else {
159 return interfaces->Size();
160 }
161 }
162 }
Elliott Hughes91250e02011-12-13 22:30:35 -0800163
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700164 uint16_t GetDirectInterfaceTypeIdx(uint32_t idx)
Ian Rogersb726dcb2012-09-05 08:57:23 -0700165 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Brian Carlstrom93235f72012-03-29 22:48:15 -0700166 DCHECK(klass_ != NULL);
Ian Rogers6d4d9fc2011-11-30 16:24:48 -0800167 DCHECK(!klass_->IsPrimitive());
168 DCHECK(!klass_->IsArrayClass());
169 return GetInterfaceTypeList()->GetTypeItem(idx).type_idx_;
170 }
Elliott Hughes91250e02011-12-13 22:30:35 -0800171
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800172 mirror::Class* GetDirectInterface(uint32_t idx)
Ian Rogersb726dcb2012-09-05 08:57:23 -0700173 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Brian Carlstrom93235f72012-03-29 22:48:15 -0700174 DCHECK(klass_ != NULL);
Ian Rogers6d4d9fc2011-11-30 16:24:48 -0800175 DCHECK(!klass_->IsPrimitive());
176 if (klass_->IsArrayClass()) {
177 if (idx == 0) {
178 return GetClassLinker()->FindSystemClass("Ljava/lang/Cloneable;");
179 } else {
180 DCHECK_EQ(1U, idx);
181 return GetClassLinker()->FindSystemClass("Ljava/io/Serializable;");
182 }
Ian Rogersc2b44472011-12-14 21:17:17 -0800183 } else if (klass_->IsProxyClass()) {
Ian Rogers9bc81912012-10-11 21:43:36 -0700184 return klass_->GetIfTable()->GetInterface(idx);
Ian Rogers6d4d9fc2011-11-30 16:24:48 -0800185 } else {
Ian Rogersd24e2642012-06-06 21:21:43 -0700186 uint16_t type_idx = GetDirectInterfaceTypeIdx(idx);
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800187 mirror::Class* interface = GetDexCache()->GetResolvedType(type_idx);
Ian Rogers6d4d9fc2011-11-30 16:24:48 -0800188 if (interface == NULL) {
189 interface = GetClassLinker()->ResolveType(GetDexFile(), type_idx, klass_);
190 CHECK(interface != NULL || Thread::Current()->IsExceptionPending());
191 }
192 return interface;
193 }
194 }
Elliott Hughes91250e02011-12-13 22:30:35 -0800195
Ian Rogersb726dcb2012-09-05 08:57:23 -0700196 const char* GetSourceFile() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Ian Rogersfc0e94b2013-09-23 23:51:32 -0700197 std::string descriptor(GetDescriptorAsStringPiece().as_string());
Ian Rogers6d4d9fc2011-11-30 16:24:48 -0800198 const DexFile& dex_file = GetDexFile();
Ian Rogers8b2c0b92013-09-19 02:56:49 -0700199 const DexFile::ClassDef* dex_class_def = GetClassDef();
Elliott Hughes12c51e32012-01-17 20:25:05 -0800200 CHECK(dex_class_def != NULL);
201 return dex_file.GetSourceFile(*dex_class_def);
Ian Rogers6d4d9fc2011-11-30 16:24:48 -0800202 }
Elliott Hughes91250e02011-12-13 22:30:35 -0800203
Ian Rogersb726dcb2012-09-05 08:57:23 -0700204 std::string GetLocation() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800205 mirror::DexCache* dex_cache = GetDexCache();
Ian Rogersad0b3a32012-04-16 14:50:24 -0700206 if (dex_cache != NULL && !klass_->IsProxyClass()) {
207 return dex_cache->GetLocation()->ToModifiedUtf8();
208 } else {
209 // Arrays and proxies are generated and have no corresponding dex file location.
210 return "generated class";
211 }
Ian Rogers6d4d9fc2011-11-30 16:24:48 -0800212 }
213
Ian Rogersb726dcb2012-09-05 08:57:23 -0700214 const DexFile& GetDexFile() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Mathieu Chartier66f19252012-09-18 08:57:04 -0700215 if (dex_file_ == NULL) {
216 dex_file_ = GetDexCache()->GetDexFile();
Ian Rogers6d4d9fc2011-11-30 16:24:48 -0800217 }
Mathieu Chartier66f19252012-09-18 08:57:04 -0700218 return *dex_file_;
Ian Rogers6d4d9fc2011-11-30 16:24:48 -0800219 }
220
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800221 mirror::DexCache* GetDexCache() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
222 mirror::DexCache* result = dex_cache_;
Ian Rogersad0b3a32012-04-16 14:50:24 -0700223 if (result == NULL) {
224 DCHECK(klass_ != NULL);
225 result = klass_->GetDexCache();
226 dex_cache_ = result;
227 }
228 return result;
229 }
230
Ian Rogers6d4d9fc2011-11-30 16:24:48 -0800231 private:
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700232 const DexFile::TypeList* GetInterfaceTypeList()
Ian Rogersb726dcb2012-09-05 08:57:23 -0700233 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Ian Rogers6d4d9fc2011-11-30 16:24:48 -0800234 const DexFile::TypeList* result = interface_type_list_;
235 if (result == NULL) {
236 const DexFile::ClassDef* class_def = GetClassDef();
237 if (class_def != NULL) {
238 result = GetDexFile().GetInterfacesList(*class_def);
239 interface_type_list_ = result;
240 }
241 }
242 return result;
243 }
Elliott Hughes91250e02011-12-13 22:30:35 -0800244
Ian Rogers6d4d9fc2011-11-30 16:24:48 -0800245 ClassLinker* GetClassLinker() {
246 ClassLinker* result = class_linker_;
247 if (result == NULL) {
248 result = Runtime::Current()->GetClassLinker();
249 class_linker_ = result;
250 }
251 return result;
252 }
253
Ian Rogers6d4d9fc2011-11-30 16:24:48 -0800254 ClassLinker* class_linker_;
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800255 mirror::DexCache* dex_cache_;
Ian Rogers6d4d9fc2011-11-30 16:24:48 -0800256 const DexFile* dex_file_;
257 const DexFile::TypeList* interface_type_list_;
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800258 const mirror::Class* klass_;
Elliott Hughes91250e02011-12-13 22:30:35 -0800259 std::string descriptor_;
Ian Rogers6d4d9fc2011-11-30 16:24:48 -0800260
261 DISALLOW_COPY_AND_ASSIGN(ClassHelper);
262};
263
264class FieldHelper {
265 public:
266 FieldHelper() : class_linker_(NULL), dex_cache_(NULL), dex_file_(NULL), field_(NULL) {}
Brian Carlstromea46f952013-07-30 01:26:50 -0700267 explicit FieldHelper(const mirror::ArtField* f) : class_linker_(NULL), dex_cache_(NULL), dex_file_(NULL), field_(f) {}
268 FieldHelper(const mirror::ArtField* f, ClassLinker* l)
Ian Rogersca190662012-06-26 15:45:57 -0700269 : class_linker_(l), dex_cache_(NULL), dex_file_(NULL), field_(f) {}
Ian Rogers6d4d9fc2011-11-30 16:24:48 -0800270
Brian Carlstromea46f952013-07-30 01:26:50 -0700271 void ChangeField(const mirror::ArtField* new_f) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Ian Rogers6d4d9fc2011-11-30 16:24:48 -0800272 DCHECK(new_f != NULL);
273 if (dex_cache_ != NULL) {
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800274 mirror::DexCache* new_f_dex_cache = new_f->GetDeclaringClass()->GetDexCache();
Ian Rogers6d4d9fc2011-11-30 16:24:48 -0800275 if (new_f_dex_cache != dex_cache_) {
276 dex_cache_ = new_f_dex_cache;
277 dex_file_ = NULL;
278 }
279 }
280 field_ = new_f;
281 }
Ian Rogersfc0e94b2013-09-23 23:51:32 -0700282
Ian Rogersb726dcb2012-09-05 08:57:23 -0700283 const char* GetName() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Ian Rogersc2b44472011-12-14 21:17:17 -0800284 uint32_t field_index = field_->GetDexFieldIndex();
Ian Rogersfc0e94b2013-09-23 23:51:32 -0700285 if (UNLIKELY(field_->GetDeclaringClass()->IsProxyClass())) {
Ian Rogersc2b44472011-12-14 21:17:17 -0800286 DCHECK(field_->IsStatic());
Elliott Hughes2ed52c42012-03-21 16:56:56 -0700287 DCHECK_LT(field_index, 2U);
288 return field_index == 0 ? "interfaces" : "throws";
Ian Rogersc2b44472011-12-14 21:17:17 -0800289 }
Ian Rogersfc0e94b2013-09-23 23:51:32 -0700290 const DexFile& dex_file = GetDexFile();
291 return dex_file.GetFieldName(dex_file.GetFieldId(field_index));
Ian Rogers6d4d9fc2011-11-30 16:24:48 -0800292 }
Ian Rogersfc0e94b2013-09-23 23:51:32 -0700293
294 StringPiece GetNameAsStringPiece() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
295 uint32_t field_index = field_->GetDexFieldIndex();
296 if (UNLIKELY(field_->GetDeclaringClass()->IsProxyClass())) {
297 return StringPiece(GetName());
298 }
299 const DexFile& dex_file = GetDexFile();
300 const DexFile::FieldId& field_id = dex_file.GetFieldId(field_index);
301 return dex_file.StringDataAsStringPieceByIdx(field_id.name_idx_);
302 }
303
Ian Rogers50239c72013-06-17 14:53:22 -0700304 mirror::Class* GetType(bool resolve = true) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Ian Rogersc2b44472011-12-14 21:17:17 -0800305 uint32_t field_index = field_->GetDexFieldIndex();
Ian Rogersfc0e94b2013-09-23 23:51:32 -0700306 if (UNLIKELY(field_->GetDeclaringClass()->IsProxyClass())) {
Elliott Hughes2ed52c42012-03-21 16:56:56 -0700307 return GetClassLinker()->FindSystemClass(GetTypeDescriptor());
Ian Rogers6d4d9fc2011-11-30 16:24:48 -0800308 }
Ian Rogersfc0e94b2013-09-23 23:51:32 -0700309 const DexFile& dex_file = GetDexFile();
310 const DexFile::FieldId& field_id = dex_file.GetFieldId(field_index);
311 mirror::Class* type = GetDexCache()->GetResolvedType(field_id.type_idx_);
312 if (resolve && (type == NULL)) {
313 type = GetClassLinker()->ResolveType(field_id.type_idx_, field_);
314 CHECK(type != NULL || Thread::Current()->IsExceptionPending());
315 }
316 return type;
Ian Rogers6d4d9fc2011-11-30 16:24:48 -0800317 }
Ian Rogersfc0e94b2013-09-23 23:51:32 -0700318
Ian Rogersb726dcb2012-09-05 08:57:23 -0700319 const char* GetTypeDescriptor() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Ian Rogersc2b44472011-12-14 21:17:17 -0800320 uint32_t field_index = field_->GetDexFieldIndex();
Ian Rogersfc0e94b2013-09-23 23:51:32 -0700321 if (UNLIKELY(field_->GetDeclaringClass()->IsProxyClass())) {
Ian Rogersc2b44472011-12-14 21:17:17 -0800322 DCHECK(field_->IsStatic());
Elliott Hughes2ed52c42012-03-21 16:56:56 -0700323 DCHECK_LT(field_index, 2U);
324 // 0 == Class[] interfaces; 1 == Class[][] throws;
325 return field_index == 0 ? "[Ljava/lang/Class;" : "[[Ljava/lang/Class;";
Ian Rogersc2b44472011-12-14 21:17:17 -0800326 }
Ian Rogersfc0e94b2013-09-23 23:51:32 -0700327 const DexFile& dex_file = GetDexFile();
328 const DexFile::FieldId& field_id = dex_file.GetFieldId(field_index);
329 return dex_file.GetFieldTypeDescriptor(field_id);
Ian Rogers6d4d9fc2011-11-30 16:24:48 -0800330 }
Ian Rogersfc0e94b2013-09-23 23:51:32 -0700331
332 StringPiece GetTypeDescriptorAsStringPiece() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
333 uint32_t field_index = field_->GetDexFieldIndex();
334 if (UNLIKELY(field_->GetDeclaringClass()->IsProxyClass())) {
335 return StringPiece(GetTypeDescriptor());
336 }
337 const DexFile& dex_file = GetDexFile();
338 const DexFile::FieldId& field_id = dex_file.GetFieldId(field_index);
339 const DexFile::TypeId& type_id = dex_file.GetTypeId(field_id.type_idx_);
340 return dex_file.StringDataAsStringPieceByIdx(type_id.descriptor_idx_);
341 }
342
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700343 Primitive::Type GetTypeAsPrimitiveType()
Ian Rogersb726dcb2012-09-05 08:57:23 -0700344 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Ian Rogers6d4d9fc2011-11-30 16:24:48 -0800345 return Primitive::GetType(GetTypeDescriptor()[0]);
346 }
Ian Rogersfc0e94b2013-09-23 23:51:32 -0700347
Ian Rogersb726dcb2012-09-05 08:57:23 -0700348 bool IsPrimitiveType() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Ian Rogers6d4d9fc2011-11-30 16:24:48 -0800349 Primitive::Type type = GetTypeAsPrimitiveType();
350 return type != Primitive::kPrimNot;
351 }
Ian Rogersfc0e94b2013-09-23 23:51:32 -0700352
Ian Rogersb726dcb2012-09-05 08:57:23 -0700353 size_t FieldSize() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Ian Rogers6d4d9fc2011-11-30 16:24:48 -0800354 Primitive::Type type = GetTypeAsPrimitiveType();
355 return Primitive::FieldSize(type);
356 }
Ian Rogersc2b44472011-12-14 21:17:17 -0800357
358 // The returned const char* is only guaranteed to be valid for the lifetime of the FieldHelper.
359 // If you need it longer, copy it into a std::string.
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700360 const char* GetDeclaringClassDescriptor()
Ian Rogersb726dcb2012-09-05 08:57:23 -0700361 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Ian Rogers8b2c0b92013-09-19 02:56:49 -0700362 uint32_t field_index = field_->GetDexFieldIndex();
Ian Rogersfc0e94b2013-09-23 23:51:32 -0700363 if (UNLIKELY(field_->GetDeclaringClass()->IsProxyClass())) {
Ian Rogers8b2c0b92013-09-19 02:56:49 -0700364 DCHECK(field_->IsStatic());
365 DCHECK_LT(field_index, 2U);
366 // 0 == Class[] interfaces; 1 == Class[][] throws;
Ian Rogersc2b44472011-12-14 21:17:17 -0800367 ClassHelper kh(field_->GetDeclaringClass());
Ian Rogersfc0e94b2013-09-23 23:51:32 -0700368 declaring_class_descriptor_ = kh.GetDescriptorAsStringPiece().as_string();
Ian Rogersc2b44472011-12-14 21:17:17 -0800369 return declaring_class_descriptor_.c_str();
370 }
Ian Rogersfc0e94b2013-09-23 23:51:32 -0700371 const DexFile& dex_file = GetDexFile();
372 const DexFile::FieldId& field_id = dex_file.GetFieldId(field_index);
373 return dex_file.GetFieldDeclaringClassDescriptor(field_id);
Ian Rogers6d4d9fc2011-11-30 16:24:48 -0800374 }
375
376 private:
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800377 mirror::DexCache* GetDexCache() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
378 mirror::DexCache* result = dex_cache_;
Ian Rogers6d4d9fc2011-11-30 16:24:48 -0800379 if (result == NULL) {
380 result = field_->GetDeclaringClass()->GetDexCache();
381 dex_cache_ = result;
382 }
383 return result;
384 }
385 ClassLinker* GetClassLinker() {
386 ClassLinker* result = class_linker_;
387 if (result == NULL) {
388 result = Runtime::Current()->GetClassLinker();
389 class_linker_ = result;
390 }
391 return result;
392 }
Ian Rogersb726dcb2012-09-05 08:57:23 -0700393 const DexFile& GetDexFile() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Mathieu Chartier66f19252012-09-18 08:57:04 -0700394 if (dex_file_ == NULL) {
395 dex_file_ = GetDexCache()->GetDexFile();
Ian Rogers6d4d9fc2011-11-30 16:24:48 -0800396 }
Mathieu Chartier66f19252012-09-18 08:57:04 -0700397 return *dex_file_;
Ian Rogers6d4d9fc2011-11-30 16:24:48 -0800398 }
399
400 ClassLinker* class_linker_;
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800401 mirror::DexCache* dex_cache_;
Ian Rogers6d4d9fc2011-11-30 16:24:48 -0800402 const DexFile* dex_file_;
Brian Carlstromea46f952013-07-30 01:26:50 -0700403 const mirror::ArtField* field_;
Ian Rogersc2b44472011-12-14 21:17:17 -0800404 std::string declaring_class_descriptor_;
Ian Rogers6d4d9fc2011-11-30 16:24:48 -0800405
406 DISALLOW_COPY_AND_ASSIGN(FieldHelper);
407};
408
409class MethodHelper {
410 public:
Ian Rogersca190662012-06-26 15:45:57 -0700411 MethodHelper()
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700412 : class_linker_(NULL), dex_cache_(NULL), dex_file_(NULL), method_(NULL), shorty_(NULL),
413 shorty_len_(0) {}
Ian Rogersca190662012-06-26 15:45:57 -0700414
Brian Carlstromea46f952013-07-30 01:26:50 -0700415 explicit MethodHelper(const mirror::ArtMethod* m)
Ian Rogersb726dcb2012-09-05 08:57:23 -0700416 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_)
Ian Rogersca190662012-06-26 15:45:57 -0700417 : class_linker_(NULL), dex_cache_(NULL), dex_file_(NULL), method_(NULL), shorty_(NULL),
418 shorty_len_(0) {
Ian Rogers6d4d9fc2011-11-30 16:24:48 -0800419 SetMethod(m);
420 }
Ian Rogersca190662012-06-26 15:45:57 -0700421
Brian Carlstromea46f952013-07-30 01:26:50 -0700422 MethodHelper(const mirror::ArtMethod* m, ClassLinker* l)
Ian Rogersb726dcb2012-09-05 08:57:23 -0700423 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_)
Ian Rogersca190662012-06-26 15:45:57 -0700424 : class_linker_(l), dex_cache_(NULL), dex_file_(NULL), method_(NULL), shorty_(NULL),
425 shorty_len_(0) {
Ian Rogers6d4d9fc2011-11-30 16:24:48 -0800426 SetMethod(m);
427 }
428
Brian Carlstromea46f952013-07-30 01:26:50 -0700429 void ChangeMethod(mirror::ArtMethod* new_m) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Ian Rogers6d4d9fc2011-11-30 16:24:48 -0800430 DCHECK(new_m != NULL);
431 if (dex_cache_ != NULL) {
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800432 mirror::Class* klass = new_m->GetDeclaringClass();
Ian Rogers6d4d9fc2011-11-30 16:24:48 -0800433 if (klass->IsProxyClass()) {
434 dex_cache_ = NULL;
435 dex_file_ = NULL;
436 } else {
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800437 mirror::DexCache* new_m_dex_cache = klass->GetDexCache();
Ian Rogers6d4d9fc2011-11-30 16:24:48 -0800438 if (new_m_dex_cache != dex_cache_) {
439 dex_cache_ = new_m_dex_cache;
440 dex_file_ = NULL;
441 }
442 }
443 }
444 SetMethod(new_m);
445 shorty_ = NULL;
446 }
Ian Rogersad0b3a32012-04-16 14:50:24 -0700447
Brian Carlstromea46f952013-07-30 01:26:50 -0700448 const mirror::ArtMethod* GetMethod() const {
Ian Rogers848871b2013-08-05 10:56:33 -0700449 return method_;
450 }
451
Ian Rogersb726dcb2012-09-05 08:57:23 -0700452 const char* GetName() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Ian Rogers6d4d9fc2011-11-30 16:24:48 -0800453 const DexFile& dex_file = GetDexFile();
Ian Rogers19846512012-02-24 11:42:47 -0800454 uint32_t dex_method_idx = method_->GetDexMethodIndex();
Ian Rogersfc0e94b2013-09-23 23:51:32 -0700455 if (LIKELY(dex_method_idx != DexFile::kDexNoIndex)) {
Ian Rogers19846512012-02-24 11:42:47 -0800456 return dex_file.GetMethodName(dex_file.GetMethodId(dex_method_idx));
457 } else {
458 Runtime* runtime = Runtime::Current();
459 if (method_ == runtime->GetResolutionMethod()) {
Elliott Hughes81ff3182012-03-23 20:35:56 -0700460 return "<runtime internal resolution method>";
Ian Rogers19846512012-02-24 11:42:47 -0800461 } else if (method_ == runtime->GetCalleeSaveMethod(Runtime::kSaveAll)) {
Elliott Hughes81ff3182012-03-23 20:35:56 -0700462 return "<runtime internal callee-save all registers method>";
Ian Rogers19846512012-02-24 11:42:47 -0800463 } else if (method_ == runtime->GetCalleeSaveMethod(Runtime::kRefsOnly)) {
Elliott Hughes81ff3182012-03-23 20:35:56 -0700464 return "<runtime internal callee-save reference registers method>";
Ian Rogers19846512012-02-24 11:42:47 -0800465 } else if (method_ == runtime->GetCalleeSaveMethod(Runtime::kRefsAndArgs)) {
Elliott Hughes81ff3182012-03-23 20:35:56 -0700466 return "<runtime internal callee-save reference and argument registers method>";
Ian Rogers19846512012-02-24 11:42:47 -0800467 } else {
Elliott Hughes81ff3182012-03-23 20:35:56 -0700468 return "<unknown runtime internal method>";
Ian Rogers19846512012-02-24 11:42:47 -0800469 }
470 }
Ian Rogers6d4d9fc2011-11-30 16:24:48 -0800471 }
Ian Rogersad0b3a32012-04-16 14:50:24 -0700472
Ian Rogersfc0e94b2013-09-23 23:51:32 -0700473 StringPiece GetNameAsStringPiece() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
474 const DexFile& dex_file = GetDexFile();
475 uint32_t dex_method_idx = method_->GetDexMethodIndex();
476 if (UNLIKELY(dex_method_idx == DexFile::kDexNoIndex)) {
477 return StringPiece(GetName());
478 }
479 const DexFile::MethodId& method_id = dex_file.GetMethodId(dex_method_idx);
480 return dex_file.StringDataAsStringPieceByIdx(method_id.name_idx_);
481 }
482
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800483 mirror::String* GetNameAsString() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Ian Rogers6d4d9fc2011-11-30 16:24:48 -0800484 const DexFile& dex_file = GetDexFile();
Ian Rogers19846512012-02-24 11:42:47 -0800485 uint32_t dex_method_idx = method_->GetDexMethodIndex();
486 const DexFile::MethodId& method_id = dex_file.GetMethodId(dex_method_idx);
Ian Rogers6d4d9fc2011-11-30 16:24:48 -0800487 return GetClassLinker()->ResolveString(dex_file, method_id.name_idx_, GetDexCache());
488 }
Ian Rogersad0b3a32012-04-16 14:50:24 -0700489
Jeff Hao9a916d32013-06-27 18:45:37 -0700490 const char* GetShorty() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Ian Rogers6d4d9fc2011-11-30 16:24:48 -0800491 const char* result = shorty_;
492 if (result == NULL) {
493 const DexFile& dex_file = GetDexFile();
494 result = dex_file.GetMethodShorty(dex_file.GetMethodId(method_->GetDexMethodIndex()),
495 &shorty_len_);
496 shorty_ = result;
497 }
498 return result;
499 }
Ian Rogersad0b3a32012-04-16 14:50:24 -0700500
Ian Rogersb726dcb2012-09-05 08:57:23 -0700501 uint32_t GetShortyLength() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Ian Rogers6d4d9fc2011-11-30 16:24:48 -0800502 if (shorty_ == NULL) {
503 GetShorty();
504 }
505 return shorty_len_;
506 }
Ian Rogersad0b3a32012-04-16 14:50:24 -0700507
Ian Rogersd91d6d62013-09-25 20:26:14 -0700508 const Signature GetSignature() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Ian Rogers6d4d9fc2011-11-30 16:24:48 -0800509 const DexFile& dex_file = GetDexFile();
Ian Rogers19846512012-02-24 11:42:47 -0800510 uint32_t dex_method_idx = method_->GetDexMethodIndex();
Ian Rogers8b2c0b92013-09-19 02:56:49 -0700511 if (dex_method_idx != DexFile::kDexNoIndex) {
Ian Rogers19846512012-02-24 11:42:47 -0800512 return dex_file.GetMethodSignature(dex_file.GetMethodId(dex_method_idx));
513 } else {
Ian Rogersd91d6d62013-09-25 20:26:14 -0700514 return Signature::NoSignature();
Ian Rogers19846512012-02-24 11:42:47 -0800515 }
Ian Rogers6d4d9fc2011-11-30 16:24:48 -0800516 }
Ian Rogersad0b3a32012-04-16 14:50:24 -0700517
Ian Rogers8b2c0b92013-09-19 02:56:49 -0700518 const DexFile::ProtoId& GetPrototype() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Ian Rogers6d4d9fc2011-11-30 16:24:48 -0800519 const DexFile& dex_file = GetDexFile();
520 return dex_file.GetMethodPrototype(dex_file.GetMethodId(method_->GetDexMethodIndex()));
521 }
Ian Rogersad0b3a32012-04-16 14:50:24 -0700522
Ian Rogers8b2c0b92013-09-19 02:56:49 -0700523 const DexFile::TypeList* GetParameterTypeList() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Ian Rogers6d4d9fc2011-11-30 16:24:48 -0800524 const DexFile::ProtoId& proto = GetPrototype();
525 return GetDexFile().GetProtoParameters(proto);
526 }
Ian Rogersad0b3a32012-04-16 14:50:24 -0700527
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800528 mirror::Class* GetReturnType() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Ian Rogers6d4d9fc2011-11-30 16:24:48 -0800529 const DexFile& dex_file = GetDexFile();
530 const DexFile::MethodId& method_id = dex_file.GetMethodId(method_->GetDexMethodIndex());
531 const DexFile::ProtoId& proto_id = dex_file.GetMethodPrototype(method_id);
532 uint16_t return_type_idx = proto_id.return_type_idx_;
533 return GetClassFromTypeIdx(return_type_idx);
534 }
Ian Rogersad0b3a32012-04-16 14:50:24 -0700535
Ian Rogers8b2c0b92013-09-19 02:56:49 -0700536 const char* GetReturnTypeDescriptor() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Ian Rogers6d4d9fc2011-11-30 16:24:48 -0800537 const DexFile& dex_file = GetDexFile();
538 const DexFile::MethodId& method_id = dex_file.GetMethodId(method_->GetDexMethodIndex());
539 const DexFile::ProtoId& proto_id = dex_file.GetMethodPrototype(method_id);
540 uint16_t return_type_idx = proto_id.return_type_idx_;
541 return dex_file.GetTypeDescriptor(dex_file.GetTypeId(return_type_idx));
542 }
Ian Rogersad0b3a32012-04-16 14:50:24 -0700543
Ian Rogers8b2c0b92013-09-19 02:56:49 -0700544 int32_t GetLineNumFromDexPC(uint32_t dex_pc) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Ian Rogers0399dde2012-06-06 17:09:28 -0700545 if (dex_pc == DexFile::kDexNoIndex) {
546 return method_->IsNative() ? -2 : -1;
547 } else {
548 const DexFile& dex_file = GetDexFile();
549 return dex_file.GetLineNumFromPC(method_, dex_pc);
550 }
Ian Rogers6d4d9fc2011-11-30 16:24:48 -0800551 }
Ian Rogersad0b3a32012-04-16 14:50:24 -0700552
Ian Rogers8b2c0b92013-09-19 02:56:49 -0700553 const char* GetDeclaringClassDescriptor() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Ian Rogers6d4d9fc2011-11-30 16:24:48 -0800554 const DexFile& dex_file = GetDexFile();
Ian Rogers8b2c0b92013-09-19 02:56:49 -0700555 uint32_t dex_method_idx = method_->GetDexMethodIndex();
Ian Rogersfc0e94b2013-09-23 23:51:32 -0700556 if (UNLIKELY(dex_method_idx == DexFile::kDexNoIndex)) {
Ian Rogers8b2c0b92013-09-19 02:56:49 -0700557 return "<runtime method>";
558 }
Ian Rogersfc0e94b2013-09-23 23:51:32 -0700559 return dex_file.GetMethodDeclaringClassDescriptor(dex_file.GetMethodId(dex_method_idx));
560 }
561
562 StringPiece GetDeclaringClassDescriptorAsStringPiece()
563 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
564 const DexFile& dex_file = GetDexFile();
565 uint32_t dex_method_idx = method_->GetDexMethodIndex();
566 if (UNLIKELY(dex_method_idx == DexFile::kDexNoIndex)) {
567 return StringPiece("<runtime method>");
568 }
569 const DexFile::MethodId& mid = dex_file.GetMethodId(dex_method_idx);
570 const DexFile::TypeId& type_id = dex_file.GetTypeId(mid.class_idx_);
571 return dex_file.StringDataAsStringPieceByIdx(type_id.descriptor_idx_);
Ian Rogers6d4d9fc2011-11-30 16:24:48 -0800572 }
Ian Rogersad0b3a32012-04-16 14:50:24 -0700573
Ian Rogers8b2c0b92013-09-19 02:56:49 -0700574 const char* GetDeclaringClassSourceFile() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
575 return ClassHelper(method_->GetDeclaringClass()).GetSourceFile();
Ian Rogers6d4d9fc2011-11-30 16:24:48 -0800576 }
Ian Rogersad0b3a32012-04-16 14:50:24 -0700577
Ian Rogers8b2c0b92013-09-19 02:56:49 -0700578 uint16_t GetClassDefIndex() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
579 return method_->GetDeclaringClass()->GetDexClassDefIndex();
Ian Rogersad0b3a32012-04-16 14:50:24 -0700580 }
581
Ian Rogers8b2c0b92013-09-19 02:56:49 -0700582 const DexFile::ClassDef& GetClassDef() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
583 return GetDexFile().GetClassDef(GetClassDefIndex());
584 }
585
586 mirror::ClassLoader* GetClassLoader() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Ian Rogersad0b3a32012-04-16 14:50:24 -0700587 return method_->GetDeclaringClass()->GetClassLoader();
588 }
589
Ian Rogersaf6e67a2013-01-16 08:38:37 -0800590 bool IsStatic() const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Ian Rogers6d4d9fc2011-11-30 16:24:48 -0800591 return method_->IsStatic();
592 }
Ian Rogersad0b3a32012-04-16 14:50:24 -0700593
Ian Rogersb726dcb2012-09-05 08:57:23 -0700594 bool IsClassInitializer() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Ian Rogersfc0e94b2013-09-23 23:51:32 -0700595 return IsStatic() && GetNameAsStringPiece() == "<clinit>";
Ian Rogers6d4d9fc2011-11-30 16:24:48 -0800596 }
Ian Rogersad0b3a32012-04-16 14:50:24 -0700597
Ian Rogersb726dcb2012-09-05 08:57:23 -0700598 size_t NumArgs() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Ian Rogers6d4d9fc2011-11-30 16:24:48 -0800599 // "1 +" because the first in Args is the receiver.
600 // "- 1" because we don't count the return type.
601 return (IsStatic() ? 0 : 1) + GetShortyLength() - 1;
602 }
Ian Rogersad0b3a32012-04-16 14:50:24 -0700603
Ian Rogersaf6e67a2013-01-16 08:38:37 -0800604 // Get the primitive type associated with the given parameter.
605 Primitive::Type GetParamPrimitiveType(size_t param) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Ian Rogers6d4d9fc2011-11-30 16:24:48 -0800606 CHECK_LT(param, NumArgs());
607 if (IsStatic()) {
608 param++; // 0th argument must skip return value at start of the shorty
609 } else if (param == 0) {
Ian Rogersaf6e67a2013-01-16 08:38:37 -0800610 return Primitive::kPrimNot;
Ian Rogers6d4d9fc2011-11-30 16:24:48 -0800611 }
Ian Rogersaf6e67a2013-01-16 08:38:37 -0800612 return Primitive::GetType(GetShorty()[param]);
Ian Rogers6d4d9fc2011-11-30 16:24:48 -0800613 }
Ian Rogersad0b3a32012-04-16 14:50:24 -0700614
Ian Rogersaf6e67a2013-01-16 08:38:37 -0800615 // Is the specified parameter a long or double, where parameter 0 is 'this' for instance methods.
616 bool IsParamALongOrDouble(size_t param) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
617 Primitive::Type type = GetParamPrimitiveType(param);
618 return type == Primitive::kPrimLong || type == Primitive::kPrimDouble;
619 }
620
621 // Is the specified parameter a reference, where parameter 0 is 'this' for instance methods.
Ian Rogersb726dcb2012-09-05 08:57:23 -0700622 bool IsParamAReference(size_t param) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Ian Rogersaf6e67a2013-01-16 08:38:37 -0800623 return GetParamPrimitiveType(param) == Primitive::kPrimNot;
Ian Rogers6d4d9fc2011-11-30 16:24:48 -0800624 }
Ian Rogersad0b3a32012-04-16 14:50:24 -0700625
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700626 bool HasSameNameAndSignature(MethodHelper* other)
Ian Rogersb726dcb2012-09-05 08:57:23 -0700627 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Ian Rogersfc0e94b2013-09-23 23:51:32 -0700628 const DexFile& dex_file = GetDexFile();
629 const DexFile::MethodId& mid = dex_file.GetMethodId(method_->GetDexMethodIndex());
Ian Rogers6d4d9fc2011-11-30 16:24:48 -0800630 if (GetDexCache() == other->GetDexCache()) {
Ian Rogers6d4d9fc2011-11-30 16:24:48 -0800631 const DexFile::MethodId& other_mid =
632 dex_file.GetMethodId(other->method_->GetDexMethodIndex());
Ian Rogers7b0c5b42012-02-16 15:29:07 -0800633 return mid.name_idx_ == other_mid.name_idx_ && mid.proto_idx_ == other_mid.proto_idx_;
Ian Rogers6d4d9fc2011-11-30 16:24:48 -0800634 }
Ian Rogersfc0e94b2013-09-23 23:51:32 -0700635 const DexFile& other_dex_file = other->GetDexFile();
636 const DexFile::MethodId& other_mid =
637 other_dex_file.GetMethodId(other->method_->GetDexMethodIndex());
638 if (dex_file.StringDataAsStringPieceByIdx(mid.name_idx_) !=
639 other_dex_file.StringDataAsStringPieceByIdx(other_mid.name_idx_)) {
640 return false; // Name mismatch.
641 }
Ian Rogersd91d6d62013-09-25 20:26:14 -0700642 return dex_file.GetMethodSignature(mid) == other_dex_file.GetMethodSignature(other_mid);
Ian Rogers6d4d9fc2011-11-30 16:24:48 -0800643 }
Ian Rogersad0b3a32012-04-16 14:50:24 -0700644
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700645 const DexFile::CodeItem* GetCodeItem()
Ian Rogersb726dcb2012-09-05 08:57:23 -0700646 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Ian Rogers6d4d9fc2011-11-30 16:24:48 -0800647 return GetDexFile().GetCodeItem(method_->GetCodeItemOffset());
648 }
Ian Rogersad0b3a32012-04-16 14:50:24 -0700649
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700650 bool IsResolvedTypeIdx(uint16_t type_idx) const
Ian Rogersb726dcb2012-09-05 08:57:23 -0700651 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Ian Rogers6f1dfe42011-12-08 17:28:34 -0800652 return method_->GetDexCacheResolvedTypes()->Get(type_idx) != NULL;
653 }
Ian Rogersad0b3a32012-04-16 14:50:24 -0700654
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800655 mirror::Class* GetClassFromTypeIdx(uint16_t type_idx)
Ian Rogersb726dcb2012-09-05 08:57:23 -0700656 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800657 mirror::Class* type = method_->GetDexCacheResolvedTypes()->Get(type_idx);
Ian Rogers6d4d9fc2011-11-30 16:24:48 -0800658 if (type == NULL) {
659 type = GetClassLinker()->ResolveType(type_idx, method_);
660 CHECK(type != NULL || Thread::Current()->IsExceptionPending());
661 }
662 return type;
663 }
Ian Rogersad0b3a32012-04-16 14:50:24 -0700664
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700665 const char* GetTypeDescriptorFromTypeIdx(uint16_t type_idx)
Ian Rogersb726dcb2012-09-05 08:57:23 -0700666 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Ian Rogers6d4d9fc2011-11-30 16:24:48 -0800667 const DexFile& dex_file = GetDexFile();
668 return dex_file.GetTypeDescriptor(dex_file.GetTypeId(type_idx));
669 }
Ian Rogersad0b3a32012-04-16 14:50:24 -0700670
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800671 mirror::Class* GetDexCacheResolvedType(uint16_t type_idx)
Ian Rogersb726dcb2012-09-05 08:57:23 -0700672 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Ian Rogers2fa6b2e2012-10-17 00:10:17 -0700673 return method_->GetDexCacheResolvedTypes()->Get(type_idx);
Ian Rogers6d4d9fc2011-11-30 16:24:48 -0800674 }
Ian Rogersad0b3a32012-04-16 14:50:24 -0700675
Ian Rogersb726dcb2012-09-05 08:57:23 -0700676 const DexFile& GetDexFile() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Ian Rogers6d4d9fc2011-11-30 16:24:48 -0800677 const DexFile* result = dex_file_;
678 if (result == NULL) {
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800679 const mirror::DexCache* dex_cache = GetDexCache();
Ian Rogers4445a7e2012-10-05 17:19:13 -0700680 result = dex_file_ = dex_cache->GetDexFile();
Ian Rogers6d4d9fc2011-11-30 16:24:48 -0800681 }
682 return *result;
683 }
Ian Rogersad0b3a32012-04-16 14:50:24 -0700684
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800685 mirror::DexCache* GetDexCache() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
686 mirror::DexCache* result = dex_cache_;
Ian Rogersad0b3a32012-04-16 14:50:24 -0700687 if (result == NULL) {
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800688 mirror::Class* klass = method_->GetDeclaringClass();
Ian Rogersad0b3a32012-04-16 14:50:24 -0700689 result = klass->GetDexCache();
690 dex_cache_ = result;
691 }
692 return result;
693 }
Elliott Hughesa21039c2012-06-21 12:09:25 -0700694
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800695 mirror::String* ResolveString(uint32_t string_idx) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
696 mirror::String* s = method_->GetDexCacheStrings()->Get(string_idx);
Ian Rogers2fa6b2e2012-10-17 00:10:17 -0700697 if (UNLIKELY(s == NULL)) {
698 s = GetClassLinker()->ResolveString(GetDexFile(), string_idx, GetDexCache());
699 }
700 return s;
701 }
702
Ian Rogers6d4d9fc2011-11-30 16:24:48 -0800703 private:
704 // Set the method_ field, for proxy methods looking up the interface method via the resolved
705 // methods table.
Brian Carlstromea46f952013-07-30 01:26:50 -0700706 void SetMethod(const mirror::ArtMethod* method) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Ian Rogers6d4d9fc2011-11-30 16:24:48 -0800707 if (method != NULL) {
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800708 mirror::Class* klass = method->GetDeclaringClass();
Ian Rogers4f6ad8a2013-03-18 15:27:28 -0700709 if (UNLIKELY(klass->IsProxyClass())) {
Brian Carlstromea46f952013-07-30 01:26:50 -0700710 mirror::ArtMethod* interface_method =
Ian Rogers19846512012-02-24 11:42:47 -0800711 method->GetDexCacheResolvedMethods()->Get(method->GetDexMethodIndex());
Ian Rogers4f6ad8a2013-03-18 15:27:28 -0700712 DCHECK(interface_method != NULL);
713 DCHECK(interface_method == GetClassLinker()->FindMethodForProxy(klass, method));
Ian Rogers19846512012-02-24 11:42:47 -0800714 method = interface_method;
Ian Rogers6d4d9fc2011-11-30 16:24:48 -0800715 }
716 }
717 method_ = method;
718 }
Ian Rogersad0b3a32012-04-16 14:50:24 -0700719
Ian Rogers6d4d9fc2011-11-30 16:24:48 -0800720 ClassLinker* GetClassLinker() {
721 ClassLinker* result = class_linker_;
722 if (result == NULL) {
723 result = Runtime::Current()->GetClassLinker();
724 class_linker_ = result;
725 }
726 return result;
727 }
728
729 ClassLinker* class_linker_;
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800730 mirror::DexCache* dex_cache_;
Ian Rogers6d4d9fc2011-11-30 16:24:48 -0800731 const DexFile* dex_file_;
Brian Carlstromea46f952013-07-30 01:26:50 -0700732 const mirror::ArtMethod* method_;
Ian Rogers6d4d9fc2011-11-30 16:24:48 -0800733 const char* shorty_;
Elliott Hughes45651fd2012-02-21 15:48:20 -0800734 uint32_t shorty_len_;
Ian Rogers6d4d9fc2011-11-30 16:24:48 -0800735
736 DISALLOW_COPY_AND_ASSIGN(MethodHelper);
737};
738
739} // namespace art
740
Brian Carlstromfc0e3212013-07-17 14:40:12 -0700741#endif // ART_RUNTIME_OBJECT_UTILS_H_