blob: ea4de903b14f598e0d95c35ec349a978f9412d6c [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
17#ifndef ART_SRC_OBJECT_UTILS_H_
18#define ART_SRC_OBJECT_UTILS_H_
19
20#include "class_linker.h"
Ian Rogers6d4d9fc2011-11-30 16:24:48 -080021#include "dex_file.h"
Ian Rogers672f5202012-01-12 18:06:40 -080022#include "monitor.h"
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080023#include "mirror/abstract_method.h"
24#include "mirror/class.h"
25#include "mirror/dex_cache.h"
26#include "mirror/field.h"
27#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 Rogers2dd0e2c2013-01-24 12:42:14 -080039 explicit ObjectLock(Thread* self, mirror::Object* object) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_)
Ian Rogers1f539342012-10-03 21:09:42 -070040 : self_(self), obj_(object) {
Ian Rogers672f5202012-01-12 18:06:40 -080041 CHECK(object != NULL);
42 obj_->MonitorEnter(self_);
43 }
44
Ian Rogersb726dcb2012-09-05 08:57:23 -070045 ~ObjectLock() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Ian Rogers672f5202012-01-12 18:06:40 -080046 obj_->MonitorExit(self_);
47 }
48
Ian Rogersb726dcb2012-09-05 08:57:23 -070049 void Wait() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Elliott Hughes4cd121e2013-01-07 17:35:41 -080050 return Monitor::Wait(self_, obj_, 0, 0, false, kWaiting);
Ian Rogers672f5202012-01-12 18:06:40 -080051 }
52
Ian Rogersb726dcb2012-09-05 08:57:23 -070053 void Notify() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Ian Rogers672f5202012-01-12 18:06:40 -080054 obj_->Notify();
55 }
56
Ian Rogersb726dcb2012-09-05 08:57:23 -070057 void NotifyAll() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Ian Rogers672f5202012-01-12 18:06:40 -080058 obj_->NotifyAll();
59 }
60
61 private:
Ian Rogers00f7d0e2012-07-19 15:28:27 -070062 Thread* const self_;
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080063 mirror::Object* obj_;
Ian Rogers672f5202012-01-12 18:06:40 -080064 DISALLOW_COPY_AND_ASSIGN(ObjectLock);
65};
66
Ian Rogers6d4d9fc2011-11-30 16:24:48 -080067class ClassHelper {
68 public:
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080069 ClassHelper(const mirror::Class* c = NULL, ClassLinker* l = NULL)
Ian Rogersb726dcb2012-09-05 08:57:23 -070070 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_)
Elliott Hughes91250e02011-12-13 22:30:35 -080071 : class_def_(NULL),
72 class_linker_(l),
73 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;
95 class_def_ = NULL;
96 }
97
Elliott Hughes91250e02011-12-13 22:30:35 -080098 // The returned const char* is only guaranteed to be valid for the lifetime of the ClassHelper.
99 // If you need it longer, copy it into a std::string.
Ian Rogersb726dcb2012-09-05 08:57:23 -0700100 const char* GetDescriptor() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Brian Carlstrom93235f72012-03-29 22:48:15 -0700101 CHECK(klass_ != NULL);
Ian Rogersa68a1cb2012-01-10 10:34:36 -0800102 if (UNLIKELY(klass_->IsArrayClass())) {
103 return GetArrayDescriptor();
104 } else if (UNLIKELY(klass_->IsPrimitive())) {
Elliott Hughes91250e02011-12-13 22:30:35 -0800105 return Primitive::Descriptor(klass_->GetPrimitiveType());
Ian Rogersa68a1cb2012-01-10 10:34:36 -0800106 } else if (UNLIKELY(klass_->IsProxyClass())) {
Elliott Hughes91250e02011-12-13 22:30:35 -0800107 descriptor_ = GetClassLinker()->GetDescriptorForProxy(klass_);
108 return descriptor_.c_str();
Ian Rogers6d4d9fc2011-11-30 16:24:48 -0800109 } else {
110 const DexFile& dex_file = GetDexFile();
111 const DexFile::TypeId& type_id = dex_file.GetTypeId(klass_->GetDexTypeIndex());
112 return dex_file.GetTypeDescriptor(type_id);
113 }
114 }
Elliott Hughes91250e02011-12-13 22:30:35 -0800115
Ian Rogersb726dcb2012-09-05 08:57:23 -0700116 const char* GetArrayDescriptor() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Ian Rogersa68a1cb2012-01-10 10:34:36 -0800117 std::string result("[");
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800118 const mirror::Class* saved_klass = klass_;
Brian Carlstrom93235f72012-03-29 22:48:15 -0700119 CHECK(saved_klass != NULL);
Ian Rogersa68a1cb2012-01-10 10:34:36 -0800120 ChangeClass(klass_->GetComponentType());
121 result += GetDescriptor();
122 ChangeClass(saved_klass);
123 descriptor_ = result;
124 return descriptor_.c_str();
125 }
126
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700127 const DexFile::ClassDef* GetClassDef()
Ian Rogersb726dcb2012-09-05 08:57:23 -0700128 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Ian Rogers6d4d9fc2011-11-30 16:24:48 -0800129 const DexFile::ClassDef* result = class_def_;
130 if (result == NULL) {
131 result = GetDexFile().FindClassDef(GetDescriptor());
132 class_def_ = result;
133 }
134 return result;
135 }
Elliott Hughes91250e02011-12-13 22:30:35 -0800136
Ian Rogersb726dcb2012-09-05 08:57:23 -0700137 uint32_t NumDirectInterfaces() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Brian Carlstrom93235f72012-03-29 22:48:15 -0700138 DCHECK(klass_ != NULL);
Ian Rogers6d4d9fc2011-11-30 16:24:48 -0800139 if (klass_->IsPrimitive()) {
140 return 0;
141 } else if (klass_->IsArrayClass()) {
142 return 2;
Ian Rogersc2b44472011-12-14 21:17:17 -0800143 } else if (klass_->IsProxyClass()) {
144 return klass_->GetIfTable()->GetLength();
Ian Rogers6d4d9fc2011-11-30 16:24:48 -0800145 } else {
Ian Rogers6d4d9fc2011-11-30 16:24:48 -0800146 const DexFile::TypeList* interfaces = GetInterfaceTypeList();
147 if (interfaces == NULL) {
148 return 0;
149 } else {
150 return interfaces->Size();
151 }
152 }
153 }
Elliott Hughes91250e02011-12-13 22:30:35 -0800154
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700155 uint16_t GetDirectInterfaceTypeIdx(uint32_t idx)
Ian Rogersb726dcb2012-09-05 08:57:23 -0700156 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Brian Carlstrom93235f72012-03-29 22:48:15 -0700157 DCHECK(klass_ != NULL);
Ian Rogers6d4d9fc2011-11-30 16:24:48 -0800158 DCHECK(!klass_->IsPrimitive());
159 DCHECK(!klass_->IsArrayClass());
160 return GetInterfaceTypeList()->GetTypeItem(idx).type_idx_;
161 }
Elliott Hughes91250e02011-12-13 22:30:35 -0800162
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800163 mirror::Class* GetDirectInterface(uint32_t idx)
Ian Rogersb726dcb2012-09-05 08:57:23 -0700164 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Brian Carlstrom93235f72012-03-29 22:48:15 -0700165 DCHECK(klass_ != NULL);
Ian Rogers6d4d9fc2011-11-30 16:24:48 -0800166 DCHECK(!klass_->IsPrimitive());
167 if (klass_->IsArrayClass()) {
168 if (idx == 0) {
169 return GetClassLinker()->FindSystemClass("Ljava/lang/Cloneable;");
170 } else {
171 DCHECK_EQ(1U, idx);
172 return GetClassLinker()->FindSystemClass("Ljava/io/Serializable;");
173 }
Ian Rogersc2b44472011-12-14 21:17:17 -0800174 } else if (klass_->IsProxyClass()) {
Ian Rogers9bc81912012-10-11 21:43:36 -0700175 return klass_->GetIfTable()->GetInterface(idx);
Ian Rogers6d4d9fc2011-11-30 16:24:48 -0800176 } else {
Ian Rogersd24e2642012-06-06 21:21:43 -0700177 uint16_t type_idx = GetDirectInterfaceTypeIdx(idx);
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800178 mirror::Class* interface = GetDexCache()->GetResolvedType(type_idx);
Ian Rogers6d4d9fc2011-11-30 16:24:48 -0800179 if (interface == NULL) {
180 interface = GetClassLinker()->ResolveType(GetDexFile(), type_idx, klass_);
181 CHECK(interface != NULL || Thread::Current()->IsExceptionPending());
182 }
183 return interface;
184 }
185 }
Elliott Hughes91250e02011-12-13 22:30:35 -0800186
Ian Rogersb726dcb2012-09-05 08:57:23 -0700187 const char* GetSourceFile() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Elliott Hughes95572412011-12-13 18:14:20 -0800188 std::string descriptor(GetDescriptor());
Ian Rogers6d4d9fc2011-11-30 16:24:48 -0800189 const DexFile& dex_file = GetDexFile();
190 const DexFile::ClassDef* dex_class_def = dex_file.FindClassDef(descriptor);
Elliott Hughes12c51e32012-01-17 20:25:05 -0800191 CHECK(dex_class_def != NULL);
192 return dex_file.GetSourceFile(*dex_class_def);
Ian Rogers6d4d9fc2011-11-30 16:24:48 -0800193 }
Elliott Hughes91250e02011-12-13 22:30:35 -0800194
Ian Rogersb726dcb2012-09-05 08:57:23 -0700195 std::string GetLocation() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800196 mirror::DexCache* dex_cache = GetDexCache();
Ian Rogersad0b3a32012-04-16 14:50:24 -0700197 if (dex_cache != NULL && !klass_->IsProxyClass()) {
198 return dex_cache->GetLocation()->ToModifiedUtf8();
199 } else {
200 // Arrays and proxies are generated and have no corresponding dex file location.
201 return "generated class";
202 }
Ian Rogers6d4d9fc2011-11-30 16:24:48 -0800203 }
204
Ian Rogersb726dcb2012-09-05 08:57:23 -0700205 const DexFile& GetDexFile() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Mathieu Chartier66f19252012-09-18 08:57:04 -0700206 if (dex_file_ == NULL) {
207 dex_file_ = GetDexCache()->GetDexFile();
Ian Rogers6d4d9fc2011-11-30 16:24:48 -0800208 }
Mathieu Chartier66f19252012-09-18 08:57:04 -0700209 return *dex_file_;
Ian Rogers6d4d9fc2011-11-30 16:24:48 -0800210 }
211
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800212 mirror::DexCache* GetDexCache() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
213 mirror::DexCache* result = dex_cache_;
Ian Rogersad0b3a32012-04-16 14:50:24 -0700214 if (result == NULL) {
215 DCHECK(klass_ != NULL);
216 result = klass_->GetDexCache();
217 dex_cache_ = result;
218 }
219 return result;
220 }
221
Ian Rogers6d4d9fc2011-11-30 16:24:48 -0800222 private:
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700223 const DexFile::TypeList* GetInterfaceTypeList()
Ian Rogersb726dcb2012-09-05 08:57:23 -0700224 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Ian Rogers6d4d9fc2011-11-30 16:24:48 -0800225 const DexFile::TypeList* result = interface_type_list_;
226 if (result == NULL) {
227 const DexFile::ClassDef* class_def = GetClassDef();
228 if (class_def != NULL) {
229 result = GetDexFile().GetInterfacesList(*class_def);
230 interface_type_list_ = result;
231 }
232 }
233 return result;
234 }
Elliott Hughes91250e02011-12-13 22:30:35 -0800235
Ian Rogers6d4d9fc2011-11-30 16:24:48 -0800236 ClassLinker* GetClassLinker() {
237 ClassLinker* result = class_linker_;
238 if (result == NULL) {
239 result = Runtime::Current()->GetClassLinker();
240 class_linker_ = result;
241 }
242 return result;
243 }
244
245 const DexFile::ClassDef* class_def_;
246 ClassLinker* class_linker_;
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800247 mirror::DexCache* dex_cache_;
Ian Rogers6d4d9fc2011-11-30 16:24:48 -0800248 const DexFile* dex_file_;
249 const DexFile::TypeList* interface_type_list_;
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800250 const mirror::Class* klass_;
Elliott Hughes91250e02011-12-13 22:30:35 -0800251 std::string descriptor_;
Ian Rogers6d4d9fc2011-11-30 16:24:48 -0800252
253 DISALLOW_COPY_AND_ASSIGN(ClassHelper);
254};
255
256class FieldHelper {
257 public:
258 FieldHelper() : class_linker_(NULL), dex_cache_(NULL), dex_file_(NULL), field_(NULL) {}
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800259 explicit FieldHelper(const mirror::Field* f) : class_linker_(NULL), dex_cache_(NULL), dex_file_(NULL), field_(f) {}
260 FieldHelper(const mirror::Field* f, ClassLinker* l)
Ian Rogersca190662012-06-26 15:45:57 -0700261 : class_linker_(l), dex_cache_(NULL), dex_file_(NULL), field_(f) {}
Ian Rogers6d4d9fc2011-11-30 16:24:48 -0800262
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800263 void ChangeField(const mirror::Field* new_f) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Ian Rogers6d4d9fc2011-11-30 16:24:48 -0800264 DCHECK(new_f != NULL);
265 if (dex_cache_ != NULL) {
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800266 mirror::DexCache* new_f_dex_cache = new_f->GetDeclaringClass()->GetDexCache();
Ian Rogers6d4d9fc2011-11-30 16:24:48 -0800267 if (new_f_dex_cache != dex_cache_) {
268 dex_cache_ = new_f_dex_cache;
269 dex_file_ = NULL;
270 }
271 }
272 field_ = new_f;
273 }
Ian Rogersb726dcb2012-09-05 08:57:23 -0700274 const char* GetName() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Ian Rogersc2b44472011-12-14 21:17:17 -0800275 uint32_t field_index = field_->GetDexFieldIndex();
Elliott Hughes2ed52c42012-03-21 16:56:56 -0700276 if (!field_->GetDeclaringClass()->IsProxyClass()) {
Ian Rogersc2b44472011-12-14 21:17:17 -0800277 const DexFile& dex_file = GetDexFile();
278 return dex_file.GetFieldName(dex_file.GetFieldId(field_index));
279 } else {
Ian Rogersc2b44472011-12-14 21:17:17 -0800280 DCHECK(field_->IsStatic());
Elliott Hughes2ed52c42012-03-21 16:56:56 -0700281 DCHECK_LT(field_index, 2U);
282 return field_index == 0 ? "interfaces" : "throws";
Ian Rogersc2b44472011-12-14 21:17:17 -0800283 }
Ian Rogers6d4d9fc2011-11-30 16:24:48 -0800284 }
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800285 mirror::Class* GetType() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Ian Rogersc2b44472011-12-14 21:17:17 -0800286 uint32_t field_index = field_->GetDexFieldIndex();
Elliott Hughes2ed52c42012-03-21 16:56:56 -0700287 if (!field_->GetDeclaringClass()->IsProxyClass()) {
Ian Rogersc2b44472011-12-14 21:17:17 -0800288 const DexFile& dex_file = GetDexFile();
289 const DexFile::FieldId& field_id = dex_file.GetFieldId(field_index);
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800290 mirror::Class* type = GetDexCache()->GetResolvedType(field_id.type_idx_);
Ian Rogersc2b44472011-12-14 21:17:17 -0800291 if (type == NULL) {
292 type = GetClassLinker()->ResolveType(field_id.type_idx_, field_);
293 CHECK(type != NULL || Thread::Current()->IsExceptionPending());
294 }
295 return type;
296 } else {
Elliott Hughes2ed52c42012-03-21 16:56:56 -0700297 return GetClassLinker()->FindSystemClass(GetTypeDescriptor());
Ian Rogers6d4d9fc2011-11-30 16:24:48 -0800298 }
Ian Rogers6d4d9fc2011-11-30 16:24:48 -0800299 }
Ian Rogersb726dcb2012-09-05 08:57:23 -0700300 const char* GetTypeDescriptor() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Ian Rogersc2b44472011-12-14 21:17:17 -0800301 uint32_t field_index = field_->GetDexFieldIndex();
Elliott Hughes2ed52c42012-03-21 16:56:56 -0700302 if (!field_->GetDeclaringClass()->IsProxyClass()) {
Ian Rogersc2b44472011-12-14 21:17:17 -0800303 const DexFile& dex_file = GetDexFile();
304 const DexFile::FieldId& field_id = dex_file.GetFieldId(field_index);
305 return dex_file.GetFieldTypeDescriptor(field_id);
306 } else {
Ian Rogersc2b44472011-12-14 21:17:17 -0800307 DCHECK(field_->IsStatic());
Elliott Hughes2ed52c42012-03-21 16:56:56 -0700308 DCHECK_LT(field_index, 2U);
309 // 0 == Class[] interfaces; 1 == Class[][] throws;
310 return field_index == 0 ? "[Ljava/lang/Class;" : "[[Ljava/lang/Class;";
Ian Rogersc2b44472011-12-14 21:17:17 -0800311 }
Ian Rogers6d4d9fc2011-11-30 16:24:48 -0800312 }
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700313 Primitive::Type GetTypeAsPrimitiveType()
Ian Rogersb726dcb2012-09-05 08:57:23 -0700314 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Ian Rogers6d4d9fc2011-11-30 16:24:48 -0800315 return Primitive::GetType(GetTypeDescriptor()[0]);
316 }
Ian Rogersb726dcb2012-09-05 08:57:23 -0700317 bool IsPrimitiveType() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Ian Rogers6d4d9fc2011-11-30 16:24:48 -0800318 Primitive::Type type = GetTypeAsPrimitiveType();
319 return type != Primitive::kPrimNot;
320 }
Ian Rogersb726dcb2012-09-05 08:57:23 -0700321 size_t FieldSize() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Ian Rogers6d4d9fc2011-11-30 16:24:48 -0800322 Primitive::Type type = GetTypeAsPrimitiveType();
323 return Primitive::FieldSize(type);
324 }
Ian Rogersc2b44472011-12-14 21:17:17 -0800325
326 // The returned const char* is only guaranteed to be valid for the lifetime of the FieldHelper.
327 // If you need it longer, copy it into a std::string.
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700328 const char* GetDeclaringClassDescriptor()
Ian Rogersb726dcb2012-09-05 08:57:23 -0700329 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Ian Rogers6d4d9fc2011-11-30 16:24:48 -0800330 uint16_t type_idx = field_->GetDeclaringClass()->GetDexTypeIndex();
Ian Rogersc2b44472011-12-14 21:17:17 -0800331 if (type_idx != DexFile::kDexNoIndex16) {
332 const DexFile& dex_file = GetDexFile();
333 return dex_file.GetTypeDescriptor(dex_file.GetTypeId(type_idx));
334 } else {
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700335 // Most likely a proxy class.
Ian Rogersc2b44472011-12-14 21:17:17 -0800336 ClassHelper kh(field_->GetDeclaringClass());
337 declaring_class_descriptor_ = kh.GetDescriptor();
338 return declaring_class_descriptor_.c_str();
339 }
Ian Rogers6d4d9fc2011-11-30 16:24:48 -0800340 }
341
342 private:
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800343 mirror::DexCache* GetDexCache() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
344 mirror::DexCache* result = dex_cache_;
Ian Rogers6d4d9fc2011-11-30 16:24:48 -0800345 if (result == NULL) {
346 result = field_->GetDeclaringClass()->GetDexCache();
347 dex_cache_ = result;
348 }
349 return result;
350 }
351 ClassLinker* GetClassLinker() {
352 ClassLinker* result = class_linker_;
353 if (result == NULL) {
354 result = Runtime::Current()->GetClassLinker();
355 class_linker_ = result;
356 }
357 return result;
358 }
Ian Rogersb726dcb2012-09-05 08:57:23 -0700359 const DexFile& GetDexFile() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Mathieu Chartier66f19252012-09-18 08:57:04 -0700360 if (dex_file_ == NULL) {
361 dex_file_ = GetDexCache()->GetDexFile();
Ian Rogers6d4d9fc2011-11-30 16:24:48 -0800362 }
Mathieu Chartier66f19252012-09-18 08:57:04 -0700363 return *dex_file_;
Ian Rogers6d4d9fc2011-11-30 16:24:48 -0800364 }
365
366 ClassLinker* class_linker_;
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800367 mirror::DexCache* dex_cache_;
Ian Rogers6d4d9fc2011-11-30 16:24:48 -0800368 const DexFile* dex_file_;
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800369 const mirror::Field* field_;
Ian Rogersc2b44472011-12-14 21:17:17 -0800370 std::string declaring_class_descriptor_;
Ian Rogers6d4d9fc2011-11-30 16:24:48 -0800371
372 DISALLOW_COPY_AND_ASSIGN(FieldHelper);
373};
374
375class MethodHelper {
376 public:
Ian Rogersca190662012-06-26 15:45:57 -0700377 MethodHelper()
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700378 : class_linker_(NULL), dex_cache_(NULL), dex_file_(NULL), method_(NULL), shorty_(NULL),
379 shorty_len_(0) {}
Ian Rogersca190662012-06-26 15:45:57 -0700380
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800381 explicit MethodHelper(const mirror::AbstractMethod* m)
Ian Rogersb726dcb2012-09-05 08:57:23 -0700382 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_)
Ian Rogersca190662012-06-26 15:45:57 -0700383 : class_linker_(NULL), dex_cache_(NULL), dex_file_(NULL), method_(NULL), shorty_(NULL),
384 shorty_len_(0) {
Ian Rogers6d4d9fc2011-11-30 16:24:48 -0800385 SetMethod(m);
386 }
Ian Rogersca190662012-06-26 15:45:57 -0700387
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800388 MethodHelper(const mirror::AbstractMethod* m, ClassLinker* l)
Ian Rogersb726dcb2012-09-05 08:57:23 -0700389 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_)
Ian Rogersca190662012-06-26 15:45:57 -0700390 : class_linker_(l), dex_cache_(NULL), dex_file_(NULL), method_(NULL), shorty_(NULL),
391 shorty_len_(0) {
Ian Rogers6d4d9fc2011-11-30 16:24:48 -0800392 SetMethod(m);
393 }
394
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800395 void ChangeMethod(mirror::AbstractMethod* new_m) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Ian Rogers6d4d9fc2011-11-30 16:24:48 -0800396 DCHECK(new_m != NULL);
397 if (dex_cache_ != NULL) {
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800398 mirror::Class* klass = new_m->GetDeclaringClass();
Ian Rogers6d4d9fc2011-11-30 16:24:48 -0800399 if (klass->IsProxyClass()) {
400 dex_cache_ = NULL;
401 dex_file_ = NULL;
402 } else {
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800403 mirror::DexCache* new_m_dex_cache = klass->GetDexCache();
Ian Rogers6d4d9fc2011-11-30 16:24:48 -0800404 if (new_m_dex_cache != dex_cache_) {
405 dex_cache_ = new_m_dex_cache;
406 dex_file_ = NULL;
407 }
408 }
409 }
410 SetMethod(new_m);
411 shorty_ = NULL;
412 }
Ian Rogersad0b3a32012-04-16 14:50:24 -0700413
Ian Rogersb726dcb2012-09-05 08:57:23 -0700414 const char* GetName() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Ian Rogers6d4d9fc2011-11-30 16:24:48 -0800415 const DexFile& dex_file = GetDexFile();
Ian Rogers19846512012-02-24 11:42:47 -0800416 uint32_t dex_method_idx = method_->GetDexMethodIndex();
417 if (dex_method_idx != DexFile::kDexNoIndex16) {
418 return dex_file.GetMethodName(dex_file.GetMethodId(dex_method_idx));
419 } else {
420 Runtime* runtime = Runtime::Current();
421 if (method_ == runtime->GetResolutionMethod()) {
Elliott Hughes81ff3182012-03-23 20:35:56 -0700422 return "<runtime internal resolution method>";
Ian Rogers19846512012-02-24 11:42:47 -0800423 } else if (method_ == runtime->GetCalleeSaveMethod(Runtime::kSaveAll)) {
Elliott Hughes81ff3182012-03-23 20:35:56 -0700424 return "<runtime internal callee-save all registers method>";
Ian Rogers19846512012-02-24 11:42:47 -0800425 } else if (method_ == runtime->GetCalleeSaveMethod(Runtime::kRefsOnly)) {
Elliott Hughes81ff3182012-03-23 20:35:56 -0700426 return "<runtime internal callee-save reference registers method>";
Ian Rogers19846512012-02-24 11:42:47 -0800427 } else if (method_ == runtime->GetCalleeSaveMethod(Runtime::kRefsAndArgs)) {
Elliott Hughes81ff3182012-03-23 20:35:56 -0700428 return "<runtime internal callee-save reference and argument registers method>";
Ian Rogers19846512012-02-24 11:42:47 -0800429 } else {
Elliott Hughes81ff3182012-03-23 20:35:56 -0700430 return "<unknown runtime internal method>";
Ian Rogers19846512012-02-24 11:42:47 -0800431 }
432 }
Ian Rogers6d4d9fc2011-11-30 16:24:48 -0800433 }
Ian Rogersad0b3a32012-04-16 14:50:24 -0700434
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800435 mirror::String* GetNameAsString() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Ian Rogers6d4d9fc2011-11-30 16:24:48 -0800436 const DexFile& dex_file = GetDexFile();
Ian Rogers19846512012-02-24 11:42:47 -0800437 uint32_t dex_method_idx = method_->GetDexMethodIndex();
438 const DexFile::MethodId& method_id = dex_file.GetMethodId(dex_method_idx);
Ian Rogers6d4d9fc2011-11-30 16:24:48 -0800439 return GetClassLinker()->ResolveString(dex_file, method_id.name_idx_, GetDexCache());
440 }
Ian Rogersad0b3a32012-04-16 14:50:24 -0700441
Ian Rogersb726dcb2012-09-05 08:57:23 -0700442 const char* GetShorty() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_)
443 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Ian Rogers6d4d9fc2011-11-30 16:24:48 -0800444 const char* result = shorty_;
445 if (result == NULL) {
446 const DexFile& dex_file = GetDexFile();
447 result = dex_file.GetMethodShorty(dex_file.GetMethodId(method_->GetDexMethodIndex()),
448 &shorty_len_);
449 shorty_ = result;
450 }
451 return result;
452 }
Ian Rogersad0b3a32012-04-16 14:50:24 -0700453
Ian Rogersb726dcb2012-09-05 08:57:23 -0700454 uint32_t GetShortyLength() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Ian Rogers6d4d9fc2011-11-30 16:24:48 -0800455 if (shorty_ == NULL) {
456 GetShorty();
457 }
458 return shorty_len_;
459 }
Ian Rogersad0b3a32012-04-16 14:50:24 -0700460
Ian Rogersb726dcb2012-09-05 08:57:23 -0700461 const std::string GetSignature() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Ian Rogers6d4d9fc2011-11-30 16:24:48 -0800462 const DexFile& dex_file = GetDexFile();
Ian Rogers19846512012-02-24 11:42:47 -0800463 uint32_t dex_method_idx = method_->GetDexMethodIndex();
464 if (dex_method_idx != DexFile::kDexNoIndex16) {
465 return dex_file.GetMethodSignature(dex_file.GetMethodId(dex_method_idx));
466 } else {
467 return "<no signature>";
468 }
Ian Rogers6d4d9fc2011-11-30 16:24:48 -0800469 }
Ian Rogersad0b3a32012-04-16 14:50:24 -0700470
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700471 const DexFile::ProtoId& GetPrototype()
Ian Rogersb726dcb2012-09-05 08:57:23 -0700472 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Ian Rogers6d4d9fc2011-11-30 16:24:48 -0800473 const DexFile& dex_file = GetDexFile();
474 return dex_file.GetMethodPrototype(dex_file.GetMethodId(method_->GetDexMethodIndex()));
475 }
Ian Rogersad0b3a32012-04-16 14:50:24 -0700476
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700477 const DexFile::TypeList* GetParameterTypeList()
Ian Rogersb726dcb2012-09-05 08:57:23 -0700478 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Ian Rogers6d4d9fc2011-11-30 16:24:48 -0800479 const DexFile::ProtoId& proto = GetPrototype();
480 return GetDexFile().GetProtoParameters(proto);
481 }
Ian Rogersad0b3a32012-04-16 14:50:24 -0700482
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800483 mirror::ObjectArray<mirror::Class>* GetParameterTypes(Thread* self)
Ian Rogers50b35e22012-10-04 10:09:15 -0700484 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Ian Rogers6d4d9fc2011-11-30 16:24:48 -0800485 const DexFile::TypeList* params = GetParameterTypeList();
Ian Rogers6d4d9fc2011-11-30 16:24:48 -0800486 uint32_t num_params = params == NULL ? 0 : params->Size();
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800487 SirtRef<mirror::ObjectArray<mirror::Class> >
488 result(self, GetClassLinker()->AllocClassArray(self, num_params));
Ian Rogers50b35e22012-10-04 10:09:15 -0700489 if (UNLIKELY(result.get() == NULL)) {
490 CHECK(self->IsExceptionPending());
491 return NULL;
492 }
Ian Rogers6d4d9fc2011-11-30 16:24:48 -0800493 for (uint32_t i = 0; i < num_params; i++) {
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800494 mirror::Class* param_type = GetClassFromTypeIdx(params->GetTypeItem(i).type_idx_);
jeffhao441d9122012-03-21 17:29:10 -0700495 if (param_type == NULL) {
496 DCHECK(Thread::Current()->IsExceptionPending());
497 return NULL;
498 }
Ian Rogers6d4d9fc2011-11-30 16:24:48 -0800499 result->Set(i, param_type);
500 }
Ian Rogers50b35e22012-10-04 10:09:15 -0700501 return result.get();
Ian Rogers6d4d9fc2011-11-30 16:24:48 -0800502 }
Ian Rogersad0b3a32012-04-16 14:50:24 -0700503
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800504 mirror::Class* GetReturnType() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Ian Rogers6d4d9fc2011-11-30 16:24:48 -0800505 const DexFile& dex_file = GetDexFile();
506 const DexFile::MethodId& method_id = dex_file.GetMethodId(method_->GetDexMethodIndex());
507 const DexFile::ProtoId& proto_id = dex_file.GetMethodPrototype(method_id);
508 uint16_t return_type_idx = proto_id.return_type_idx_;
509 return GetClassFromTypeIdx(return_type_idx);
510 }
Ian Rogersad0b3a32012-04-16 14:50:24 -0700511
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700512 const char* GetReturnTypeDescriptor()
Ian Rogersb726dcb2012-09-05 08:57:23 -0700513 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Ian Rogers6d4d9fc2011-11-30 16:24:48 -0800514 const DexFile& dex_file = GetDexFile();
515 const DexFile::MethodId& method_id = dex_file.GetMethodId(method_->GetDexMethodIndex());
516 const DexFile::ProtoId& proto_id = dex_file.GetMethodPrototype(method_id);
517 uint16_t return_type_idx = proto_id.return_type_idx_;
518 return dex_file.GetTypeDescriptor(dex_file.GetTypeId(return_type_idx));
519 }
Ian Rogersad0b3a32012-04-16 14:50:24 -0700520
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700521 int32_t GetLineNumFromDexPC(uint32_t dex_pc)
Ian Rogersb726dcb2012-09-05 08:57:23 -0700522 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Ian Rogers0399dde2012-06-06 17:09:28 -0700523 if (dex_pc == DexFile::kDexNoIndex) {
524 return method_->IsNative() ? -2 : -1;
525 } else {
526 const DexFile& dex_file = GetDexFile();
527 return dex_file.GetLineNumFromPC(method_, dex_pc);
528 }
Ian Rogers6d4d9fc2011-11-30 16:24:48 -0800529 }
Ian Rogersad0b3a32012-04-16 14:50:24 -0700530
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700531 const char* GetDeclaringClassDescriptor()
Ian Rogersb726dcb2012-09-05 08:57:23 -0700532 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800533 mirror::Class* klass = method_->GetDeclaringClass();
Ian Rogersc2b44472011-12-14 21:17:17 -0800534 DCHECK(!klass->IsProxyClass());
Ian Rogers6d4d9fc2011-11-30 16:24:48 -0800535 uint16_t type_idx = klass->GetDexTypeIndex();
536 const DexFile& dex_file = GetDexFile();
537 return dex_file.GetTypeDescriptor(dex_file.GetTypeId(type_idx));
538 }
Ian Rogersad0b3a32012-04-16 14:50:24 -0700539
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700540 const char* GetDeclaringClassSourceFile()
Ian Rogersb726dcb2012-09-05 08:57:23 -0700541 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Ian Rogers6d4d9fc2011-11-30 16:24:48 -0800542 const char* descriptor = GetDeclaringClassDescriptor();
543 const DexFile& dex_file = GetDexFile();
544 const DexFile::ClassDef* dex_class_def = dex_file.FindClassDef(descriptor);
Elliott Hughes12c51e32012-01-17 20:25:05 -0800545 CHECK(dex_class_def != NULL);
546 return dex_file.GetSourceFile(*dex_class_def);
Ian Rogers6d4d9fc2011-11-30 16:24:48 -0800547 }
Ian Rogersad0b3a32012-04-16 14:50:24 -0700548
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700549 uint32_t GetClassDefIndex()
Ian Rogersb726dcb2012-09-05 08:57:23 -0700550 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Ian Rogersad0b3a32012-04-16 14:50:24 -0700551 const char* descriptor = GetDeclaringClassDescriptor();
552 const DexFile& dex_file = GetDexFile();
553 uint32_t index;
554 CHECK(dex_file.FindClassDefIndex(descriptor, index));
555 return index;
556 }
557
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800558 mirror::ClassLoader* GetClassLoader()
Ian Rogersb726dcb2012-09-05 08:57:23 -0700559 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Ian Rogersad0b3a32012-04-16 14:50:24 -0700560 return method_->GetDeclaringClass()->GetClassLoader();
561 }
562
Ian Rogersaf6e67a2013-01-16 08:38:37 -0800563 bool IsStatic() const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Ian Rogers6d4d9fc2011-11-30 16:24:48 -0800564 return method_->IsStatic();
565 }
Ian Rogersad0b3a32012-04-16 14:50:24 -0700566
Ian Rogersb726dcb2012-09-05 08:57:23 -0700567 bool IsClassInitializer() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Ian Rogers6d4d9fc2011-11-30 16:24:48 -0800568 return IsStatic() && StringPiece(GetName()) == "<clinit>";
569 }
Ian Rogersad0b3a32012-04-16 14:50:24 -0700570
Ian Rogersb726dcb2012-09-05 08:57:23 -0700571 size_t NumArgs() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Ian Rogers6d4d9fc2011-11-30 16:24:48 -0800572 // "1 +" because the first in Args is the receiver.
573 // "- 1" because we don't count the return type.
574 return (IsStatic() ? 0 : 1) + GetShortyLength() - 1;
575 }
Ian Rogersad0b3a32012-04-16 14:50:24 -0700576
Ian Rogersaf6e67a2013-01-16 08:38:37 -0800577 // Get the primitive type associated with the given parameter.
578 Primitive::Type GetParamPrimitiveType(size_t param) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Ian Rogers6d4d9fc2011-11-30 16:24:48 -0800579 CHECK_LT(param, NumArgs());
580 if (IsStatic()) {
581 param++; // 0th argument must skip return value at start of the shorty
582 } else if (param == 0) {
Ian Rogersaf6e67a2013-01-16 08:38:37 -0800583 return Primitive::kPrimNot;
Ian Rogers6d4d9fc2011-11-30 16:24:48 -0800584 }
Ian Rogersaf6e67a2013-01-16 08:38:37 -0800585 return Primitive::GetType(GetShorty()[param]);
Ian Rogers6d4d9fc2011-11-30 16:24:48 -0800586 }
Ian Rogersad0b3a32012-04-16 14:50:24 -0700587
Ian Rogersaf6e67a2013-01-16 08:38:37 -0800588 // Is the specified parameter a long or double, where parameter 0 is 'this' for instance methods.
589 bool IsParamALongOrDouble(size_t param) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
590 Primitive::Type type = GetParamPrimitiveType(param);
591 return type == Primitive::kPrimLong || type == Primitive::kPrimDouble;
592 }
593
594 // Is the specified parameter a reference, where parameter 0 is 'this' for instance methods.
Ian Rogersb726dcb2012-09-05 08:57:23 -0700595 bool IsParamAReference(size_t param) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Ian Rogersaf6e67a2013-01-16 08:38:37 -0800596 return GetParamPrimitiveType(param) == Primitive::kPrimNot;
Ian Rogers6d4d9fc2011-11-30 16:24:48 -0800597 }
Ian Rogersad0b3a32012-04-16 14:50:24 -0700598
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700599 bool HasSameNameAndSignature(MethodHelper* other)
Ian Rogersb726dcb2012-09-05 08:57:23 -0700600 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Ian Rogers6d4d9fc2011-11-30 16:24:48 -0800601 if (GetDexCache() == other->GetDexCache()) {
602 const DexFile& dex_file = GetDexFile();
603 const DexFile::MethodId& mid = dex_file.GetMethodId(method_->GetDexMethodIndex());
604 const DexFile::MethodId& other_mid =
605 dex_file.GetMethodId(other->method_->GetDexMethodIndex());
Ian Rogers7b0c5b42012-02-16 15:29:07 -0800606 return mid.name_idx_ == other_mid.name_idx_ && mid.proto_idx_ == other_mid.proto_idx_;
Ian Rogers6d4d9fc2011-11-30 16:24:48 -0800607 }
Ian Rogers7b0c5b42012-02-16 15:29:07 -0800608 StringPiece name(GetName());
609 StringPiece other_name(other->GetName());
610 return name == other_name && GetSignature() == other->GetSignature();
Ian Rogers6d4d9fc2011-11-30 16:24:48 -0800611 }
Ian Rogersad0b3a32012-04-16 14:50:24 -0700612
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700613 const DexFile::CodeItem* GetCodeItem()
Ian Rogersb726dcb2012-09-05 08:57:23 -0700614 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Ian Rogers6d4d9fc2011-11-30 16:24:48 -0800615 return GetDexFile().GetCodeItem(method_->GetCodeItemOffset());
616 }
Ian Rogersad0b3a32012-04-16 14:50:24 -0700617
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700618 bool IsResolvedTypeIdx(uint16_t type_idx) const
Ian Rogersb726dcb2012-09-05 08:57:23 -0700619 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Ian Rogers6f1dfe42011-12-08 17:28:34 -0800620 return method_->GetDexCacheResolvedTypes()->Get(type_idx) != NULL;
621 }
Ian Rogersad0b3a32012-04-16 14:50:24 -0700622
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800623 mirror::Class* GetClassFromTypeIdx(uint16_t type_idx)
Ian Rogersb726dcb2012-09-05 08:57:23 -0700624 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800625 mirror::Class* type = method_->GetDexCacheResolvedTypes()->Get(type_idx);
Ian Rogers6d4d9fc2011-11-30 16:24:48 -0800626 if (type == NULL) {
627 type = GetClassLinker()->ResolveType(type_idx, method_);
628 CHECK(type != NULL || Thread::Current()->IsExceptionPending());
629 }
630 return type;
631 }
Ian Rogersad0b3a32012-04-16 14:50:24 -0700632
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700633 const char* GetTypeDescriptorFromTypeIdx(uint16_t type_idx)
Ian Rogersb726dcb2012-09-05 08:57:23 -0700634 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Ian Rogers6d4d9fc2011-11-30 16:24:48 -0800635 const DexFile& dex_file = GetDexFile();
636 return dex_file.GetTypeDescriptor(dex_file.GetTypeId(type_idx));
637 }
Ian Rogersad0b3a32012-04-16 14:50:24 -0700638
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800639 mirror::Class* GetDexCacheResolvedType(uint16_t type_idx)
Ian Rogersb726dcb2012-09-05 08:57:23 -0700640 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Ian Rogers2fa6b2e2012-10-17 00:10:17 -0700641 return method_->GetDexCacheResolvedTypes()->Get(type_idx);
Ian Rogers6d4d9fc2011-11-30 16:24:48 -0800642 }
Ian Rogersad0b3a32012-04-16 14:50:24 -0700643
Ian Rogersb726dcb2012-09-05 08:57:23 -0700644 const DexFile& GetDexFile() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Ian Rogers6d4d9fc2011-11-30 16:24:48 -0800645 const DexFile* result = dex_file_;
646 if (result == NULL) {
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800647 const mirror::DexCache* dex_cache = GetDexCache();
Ian Rogers4445a7e2012-10-05 17:19:13 -0700648 result = dex_file_ = dex_cache->GetDexFile();
Ian Rogers6d4d9fc2011-11-30 16:24:48 -0800649 }
650 return *result;
651 }
Ian Rogersad0b3a32012-04-16 14:50:24 -0700652
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800653 mirror::DexCache* GetDexCache() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
654 mirror::DexCache* result = dex_cache_;
Ian Rogersad0b3a32012-04-16 14:50:24 -0700655 if (result == NULL) {
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800656 mirror::Class* klass = method_->GetDeclaringClass();
Ian Rogersad0b3a32012-04-16 14:50:24 -0700657 result = klass->GetDexCache();
658 dex_cache_ = result;
659 }
660 return result;
661 }
Elliott Hughesa21039c2012-06-21 12:09:25 -0700662
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800663 mirror::String* ResolveString(uint32_t string_idx) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
664 mirror::String* s = method_->GetDexCacheStrings()->Get(string_idx);
Ian Rogers2fa6b2e2012-10-17 00:10:17 -0700665 if (UNLIKELY(s == NULL)) {
666 s = GetClassLinker()->ResolveString(GetDexFile(), string_idx, GetDexCache());
667 }
668 return s;
669 }
670
Ian Rogers6d4d9fc2011-11-30 16:24:48 -0800671 private:
672 // Set the method_ field, for proxy methods looking up the interface method via the resolved
673 // methods table.
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800674 void SetMethod(const mirror::AbstractMethod* method) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Ian Rogers6d4d9fc2011-11-30 16:24:48 -0800675 if (method != NULL) {
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800676 mirror::Class* klass = method->GetDeclaringClass();
Ian Rogers6d4d9fc2011-11-30 16:24:48 -0800677 if (klass->IsProxyClass()) {
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800678 mirror::AbstractMethod* interface_method =
Ian Rogers19846512012-02-24 11:42:47 -0800679 method->GetDexCacheResolvedMethods()->Get(method->GetDexMethodIndex());
680 CHECK(interface_method != NULL);
681 CHECK(interface_method == GetClassLinker()->FindMethodForProxy(klass, method));
682 method = interface_method;
Ian Rogers6d4d9fc2011-11-30 16:24:48 -0800683 }
684 }
685 method_ = method;
686 }
Ian Rogersad0b3a32012-04-16 14:50:24 -0700687
Ian Rogers6d4d9fc2011-11-30 16:24:48 -0800688 ClassLinker* GetClassLinker() {
689 ClassLinker* result = class_linker_;
690 if (result == NULL) {
691 result = Runtime::Current()->GetClassLinker();
692 class_linker_ = result;
693 }
694 return result;
695 }
696
697 ClassLinker* class_linker_;
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800698 mirror::DexCache* dex_cache_;
Ian Rogers6d4d9fc2011-11-30 16:24:48 -0800699 const DexFile* dex_file_;
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800700 const mirror::AbstractMethod* method_;
Ian Rogers6d4d9fc2011-11-30 16:24:48 -0800701 const char* shorty_;
Elliott Hughes45651fd2012-02-21 15:48:20 -0800702 uint32_t shorty_len_;
Ian Rogers6d4d9fc2011-11-30 16:24:48 -0800703
704 DISALLOW_COPY_AND_ASSIGN(MethodHelper);
705};
706
707} // namespace art
708
709#endif // ART_SRC_OBJECT_UTILS_H_