blob: 29102437a2ed69163d03fa5ffd94b77594942c53 [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 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 Rogers05f30572013-02-20 12:13:11 -080049 void WaitIgnoringInterrupts() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
50 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 Rogers05f30572013-02-20 12:13:11 -080054 obj_->Notify(self_);
Ian Rogers672f5202012-01-12 18:06:40 -080055 }
56
Ian Rogersb726dcb2012-09-05 08:57:23 -070057 void NotifyAll() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Ian Rogers05f30572013-02-20 12:13:11 -080058 obj_->NotifyAll(self_);
Ian Rogers672f5202012-01-12 18:06:40 -080059 }
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) {}
Brian Carlstromea46f952013-07-30 01:26:50 -0700259 explicit FieldHelper(const mirror::ArtField* f) : class_linker_(NULL), dex_cache_(NULL), dex_file_(NULL), field_(f) {}
260 FieldHelper(const mirror::ArtField* 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
Brian Carlstromea46f952013-07-30 01:26:50 -0700263 void ChangeField(const mirror::ArtField* 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 Rogers50239c72013-06-17 14:53:22 -0700285 mirror::Class* GetType(bool resolve = true) 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 Rogers50239c72013-06-17 14:53:22 -0700291 if (resolve && (type == NULL)) {
Ian Rogersc2b44472011-12-14 21:17:17 -0800292 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_;
Brian Carlstromea46f952013-07-30 01:26:50 -0700369 const mirror::ArtField* 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
Brian Carlstromea46f952013-07-30 01:26:50 -0700381 explicit MethodHelper(const mirror::ArtMethod* 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
Brian Carlstromea46f952013-07-30 01:26:50 -0700388 MethodHelper(const mirror::ArtMethod* 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
Brian Carlstromea46f952013-07-30 01:26:50 -0700395 void ChangeMethod(mirror::ArtMethod* 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
Brian Carlstromea46f952013-07-30 01:26:50 -0700414 const mirror::ArtMethod* GetMethod() const {
Ian Rogers848871b2013-08-05 10:56:33 -0700415 return method_;
416 }
417
Ian Rogersb726dcb2012-09-05 08:57:23 -0700418 const char* GetName() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Ian Rogers6d4d9fc2011-11-30 16:24:48 -0800419 const DexFile& dex_file = GetDexFile();
Ian Rogers19846512012-02-24 11:42:47 -0800420 uint32_t dex_method_idx = method_->GetDexMethodIndex();
421 if (dex_method_idx != DexFile::kDexNoIndex16) {
422 return dex_file.GetMethodName(dex_file.GetMethodId(dex_method_idx));
423 } else {
424 Runtime* runtime = Runtime::Current();
425 if (method_ == runtime->GetResolutionMethod()) {
Elliott Hughes81ff3182012-03-23 20:35:56 -0700426 return "<runtime internal resolution method>";
Ian Rogers19846512012-02-24 11:42:47 -0800427 } else if (method_ == runtime->GetCalleeSaveMethod(Runtime::kSaveAll)) {
Elliott Hughes81ff3182012-03-23 20:35:56 -0700428 return "<runtime internal callee-save all registers method>";
Ian Rogers19846512012-02-24 11:42:47 -0800429 } else if (method_ == runtime->GetCalleeSaveMethod(Runtime::kRefsOnly)) {
Elliott Hughes81ff3182012-03-23 20:35:56 -0700430 return "<runtime internal callee-save reference registers method>";
Ian Rogers19846512012-02-24 11:42:47 -0800431 } else if (method_ == runtime->GetCalleeSaveMethod(Runtime::kRefsAndArgs)) {
Elliott Hughes81ff3182012-03-23 20:35:56 -0700432 return "<runtime internal callee-save reference and argument registers method>";
Ian Rogers19846512012-02-24 11:42:47 -0800433 } else {
Elliott Hughes81ff3182012-03-23 20:35:56 -0700434 return "<unknown runtime internal method>";
Ian Rogers19846512012-02-24 11:42:47 -0800435 }
436 }
Ian Rogers6d4d9fc2011-11-30 16:24:48 -0800437 }
Ian Rogersad0b3a32012-04-16 14:50:24 -0700438
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800439 mirror::String* GetNameAsString() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Ian Rogers6d4d9fc2011-11-30 16:24:48 -0800440 const DexFile& dex_file = GetDexFile();
Ian Rogers19846512012-02-24 11:42:47 -0800441 uint32_t dex_method_idx = method_->GetDexMethodIndex();
442 const DexFile::MethodId& method_id = dex_file.GetMethodId(dex_method_idx);
Ian Rogers6d4d9fc2011-11-30 16:24:48 -0800443 return GetClassLinker()->ResolveString(dex_file, method_id.name_idx_, GetDexCache());
444 }
Ian Rogersad0b3a32012-04-16 14:50:24 -0700445
Jeff Hao9a916d32013-06-27 18:45:37 -0700446 const char* GetShorty() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Ian Rogers6d4d9fc2011-11-30 16:24:48 -0800447 const char* result = shorty_;
448 if (result == NULL) {
449 const DexFile& dex_file = GetDexFile();
450 result = dex_file.GetMethodShorty(dex_file.GetMethodId(method_->GetDexMethodIndex()),
451 &shorty_len_);
452 shorty_ = result;
453 }
454 return result;
455 }
Ian Rogersad0b3a32012-04-16 14:50:24 -0700456
Ian Rogersb726dcb2012-09-05 08:57:23 -0700457 uint32_t GetShortyLength() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Ian Rogers6d4d9fc2011-11-30 16:24:48 -0800458 if (shorty_ == NULL) {
459 GetShorty();
460 }
461 return shorty_len_;
462 }
Ian Rogersad0b3a32012-04-16 14:50:24 -0700463
Ian Rogersb726dcb2012-09-05 08:57:23 -0700464 const std::string GetSignature() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Ian Rogers6d4d9fc2011-11-30 16:24:48 -0800465 const DexFile& dex_file = GetDexFile();
Ian Rogers19846512012-02-24 11:42:47 -0800466 uint32_t dex_method_idx = method_->GetDexMethodIndex();
467 if (dex_method_idx != DexFile::kDexNoIndex16) {
468 return dex_file.GetMethodSignature(dex_file.GetMethodId(dex_method_idx));
469 } else {
470 return "<no signature>";
471 }
Ian Rogers6d4d9fc2011-11-30 16:24:48 -0800472 }
Ian Rogersad0b3a32012-04-16 14:50:24 -0700473
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700474 const DexFile::ProtoId& GetPrototype()
Ian Rogersb726dcb2012-09-05 08:57:23 -0700475 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Ian Rogers6d4d9fc2011-11-30 16:24:48 -0800476 const DexFile& dex_file = GetDexFile();
477 return dex_file.GetMethodPrototype(dex_file.GetMethodId(method_->GetDexMethodIndex()));
478 }
Ian Rogersad0b3a32012-04-16 14:50:24 -0700479
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700480 const DexFile::TypeList* GetParameterTypeList()
Ian Rogersb726dcb2012-09-05 08:57:23 -0700481 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Ian Rogers6d4d9fc2011-11-30 16:24:48 -0800482 const DexFile::ProtoId& proto = GetPrototype();
483 return GetDexFile().GetProtoParameters(proto);
484 }
Ian Rogersad0b3a32012-04-16 14:50:24 -0700485
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800486 mirror::Class* GetReturnType() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Ian Rogers6d4d9fc2011-11-30 16:24:48 -0800487 const DexFile& dex_file = GetDexFile();
488 const DexFile::MethodId& method_id = dex_file.GetMethodId(method_->GetDexMethodIndex());
489 const DexFile::ProtoId& proto_id = dex_file.GetMethodPrototype(method_id);
490 uint16_t return_type_idx = proto_id.return_type_idx_;
491 return GetClassFromTypeIdx(return_type_idx);
492 }
Ian Rogersad0b3a32012-04-16 14:50:24 -0700493
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700494 const char* GetReturnTypeDescriptor()
Ian Rogersb726dcb2012-09-05 08:57:23 -0700495 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Ian Rogers6d4d9fc2011-11-30 16:24:48 -0800496 const DexFile& dex_file = GetDexFile();
497 const DexFile::MethodId& method_id = dex_file.GetMethodId(method_->GetDexMethodIndex());
498 const DexFile::ProtoId& proto_id = dex_file.GetMethodPrototype(method_id);
499 uint16_t return_type_idx = proto_id.return_type_idx_;
500 return dex_file.GetTypeDescriptor(dex_file.GetTypeId(return_type_idx));
501 }
Ian Rogersad0b3a32012-04-16 14:50:24 -0700502
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700503 int32_t GetLineNumFromDexPC(uint32_t dex_pc)
Ian Rogersb726dcb2012-09-05 08:57:23 -0700504 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Ian Rogers0399dde2012-06-06 17:09:28 -0700505 if (dex_pc == DexFile::kDexNoIndex) {
506 return method_->IsNative() ? -2 : -1;
507 } else {
508 const DexFile& dex_file = GetDexFile();
509 return dex_file.GetLineNumFromPC(method_, dex_pc);
510 }
Ian Rogers6d4d9fc2011-11-30 16:24:48 -0800511 }
Ian Rogersad0b3a32012-04-16 14:50:24 -0700512
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700513 const char* GetDeclaringClassDescriptor()
Ian Rogersb726dcb2012-09-05 08:57:23 -0700514 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800515 mirror::Class* klass = method_->GetDeclaringClass();
Ian Rogersc2b44472011-12-14 21:17:17 -0800516 DCHECK(!klass->IsProxyClass());
Ian Rogers6d4d9fc2011-11-30 16:24:48 -0800517 uint16_t type_idx = klass->GetDexTypeIndex();
518 const DexFile& dex_file = GetDexFile();
519 return dex_file.GetTypeDescriptor(dex_file.GetTypeId(type_idx));
520 }
Ian Rogersad0b3a32012-04-16 14:50:24 -0700521
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700522 const char* GetDeclaringClassSourceFile()
Ian Rogersb726dcb2012-09-05 08:57:23 -0700523 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Ian Rogers6d4d9fc2011-11-30 16:24:48 -0800524 const char* descriptor = GetDeclaringClassDescriptor();
525 const DexFile& dex_file = GetDexFile();
526 const DexFile::ClassDef* dex_class_def = dex_file.FindClassDef(descriptor);
Elliott Hughes12c51e32012-01-17 20:25:05 -0800527 CHECK(dex_class_def != NULL);
528 return dex_file.GetSourceFile(*dex_class_def);
Ian Rogers6d4d9fc2011-11-30 16:24:48 -0800529 }
Ian Rogersad0b3a32012-04-16 14:50:24 -0700530
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700531 uint32_t GetClassDefIndex()
Ian Rogersb726dcb2012-09-05 08:57:23 -0700532 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Ian Rogersad0b3a32012-04-16 14:50:24 -0700533 const char* descriptor = GetDeclaringClassDescriptor();
534 const DexFile& dex_file = GetDexFile();
535 uint32_t index;
536 CHECK(dex_file.FindClassDefIndex(descriptor, index));
537 return index;
538 }
539
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800540 mirror::ClassLoader* GetClassLoader()
Ian Rogersb726dcb2012-09-05 08:57:23 -0700541 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Ian Rogersad0b3a32012-04-16 14:50:24 -0700542 return method_->GetDeclaringClass()->GetClassLoader();
543 }
544
Ian Rogersaf6e67a2013-01-16 08:38:37 -0800545 bool IsStatic() const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Ian Rogers6d4d9fc2011-11-30 16:24:48 -0800546 return method_->IsStatic();
547 }
Ian Rogersad0b3a32012-04-16 14:50:24 -0700548
Ian Rogersb726dcb2012-09-05 08:57:23 -0700549 bool IsClassInitializer() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Ian Rogers6d4d9fc2011-11-30 16:24:48 -0800550 return IsStatic() && StringPiece(GetName()) == "<clinit>";
551 }
Ian Rogersad0b3a32012-04-16 14:50:24 -0700552
Ian Rogersb726dcb2012-09-05 08:57:23 -0700553 size_t NumArgs() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Ian Rogers6d4d9fc2011-11-30 16:24:48 -0800554 // "1 +" because the first in Args is the receiver.
555 // "- 1" because we don't count the return type.
556 return (IsStatic() ? 0 : 1) + GetShortyLength() - 1;
557 }
Ian Rogersad0b3a32012-04-16 14:50:24 -0700558
Ian Rogersaf6e67a2013-01-16 08:38:37 -0800559 // Get the primitive type associated with the given parameter.
560 Primitive::Type GetParamPrimitiveType(size_t param) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Ian Rogers6d4d9fc2011-11-30 16:24:48 -0800561 CHECK_LT(param, NumArgs());
562 if (IsStatic()) {
563 param++; // 0th argument must skip return value at start of the shorty
564 } else if (param == 0) {
Ian Rogersaf6e67a2013-01-16 08:38:37 -0800565 return Primitive::kPrimNot;
Ian Rogers6d4d9fc2011-11-30 16:24:48 -0800566 }
Ian Rogersaf6e67a2013-01-16 08:38:37 -0800567 return Primitive::GetType(GetShorty()[param]);
Ian Rogers6d4d9fc2011-11-30 16:24:48 -0800568 }
Ian Rogersad0b3a32012-04-16 14:50:24 -0700569
Ian Rogersaf6e67a2013-01-16 08:38:37 -0800570 // Is the specified parameter a long or double, where parameter 0 is 'this' for instance methods.
571 bool IsParamALongOrDouble(size_t param) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
572 Primitive::Type type = GetParamPrimitiveType(param);
573 return type == Primitive::kPrimLong || type == Primitive::kPrimDouble;
574 }
575
576 // Is the specified parameter a reference, where parameter 0 is 'this' for instance methods.
Ian Rogersb726dcb2012-09-05 08:57:23 -0700577 bool IsParamAReference(size_t param) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Ian Rogersaf6e67a2013-01-16 08:38:37 -0800578 return GetParamPrimitiveType(param) == Primitive::kPrimNot;
Ian Rogers6d4d9fc2011-11-30 16:24:48 -0800579 }
Ian Rogersad0b3a32012-04-16 14:50:24 -0700580
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700581 bool HasSameNameAndSignature(MethodHelper* other)
Ian Rogersb726dcb2012-09-05 08:57:23 -0700582 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Ian Rogers6d4d9fc2011-11-30 16:24:48 -0800583 if (GetDexCache() == other->GetDexCache()) {
584 const DexFile& dex_file = GetDexFile();
585 const DexFile::MethodId& mid = dex_file.GetMethodId(method_->GetDexMethodIndex());
586 const DexFile::MethodId& other_mid =
587 dex_file.GetMethodId(other->method_->GetDexMethodIndex());
Ian Rogers7b0c5b42012-02-16 15:29:07 -0800588 return mid.name_idx_ == other_mid.name_idx_ && mid.proto_idx_ == other_mid.proto_idx_;
Ian Rogers6d4d9fc2011-11-30 16:24:48 -0800589 }
Ian Rogers7b0c5b42012-02-16 15:29:07 -0800590 StringPiece name(GetName());
591 StringPiece other_name(other->GetName());
592 return name == other_name && GetSignature() == other->GetSignature();
Ian Rogers6d4d9fc2011-11-30 16:24:48 -0800593 }
Ian Rogersad0b3a32012-04-16 14:50:24 -0700594
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700595 const DexFile::CodeItem* GetCodeItem()
Ian Rogersb726dcb2012-09-05 08:57:23 -0700596 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Ian Rogers6d4d9fc2011-11-30 16:24:48 -0800597 return GetDexFile().GetCodeItem(method_->GetCodeItemOffset());
598 }
Ian Rogersad0b3a32012-04-16 14:50:24 -0700599
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700600 bool IsResolvedTypeIdx(uint16_t type_idx) const
Ian Rogersb726dcb2012-09-05 08:57:23 -0700601 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Ian Rogers6f1dfe42011-12-08 17:28:34 -0800602 return method_->GetDexCacheResolvedTypes()->Get(type_idx) != NULL;
603 }
Ian Rogersad0b3a32012-04-16 14:50:24 -0700604
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800605 mirror::Class* GetClassFromTypeIdx(uint16_t type_idx)
Ian Rogersb726dcb2012-09-05 08:57:23 -0700606 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800607 mirror::Class* type = method_->GetDexCacheResolvedTypes()->Get(type_idx);
Ian Rogers6d4d9fc2011-11-30 16:24:48 -0800608 if (type == NULL) {
609 type = GetClassLinker()->ResolveType(type_idx, method_);
610 CHECK(type != NULL || Thread::Current()->IsExceptionPending());
611 }
612 return type;
613 }
Ian Rogersad0b3a32012-04-16 14:50:24 -0700614
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700615 const char* GetTypeDescriptorFromTypeIdx(uint16_t type_idx)
Ian Rogersb726dcb2012-09-05 08:57:23 -0700616 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Ian Rogers6d4d9fc2011-11-30 16:24:48 -0800617 const DexFile& dex_file = GetDexFile();
618 return dex_file.GetTypeDescriptor(dex_file.GetTypeId(type_idx));
619 }
Ian Rogersad0b3a32012-04-16 14:50:24 -0700620
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800621 mirror::Class* GetDexCacheResolvedType(uint16_t type_idx)
Ian Rogersb726dcb2012-09-05 08:57:23 -0700622 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Ian Rogers2fa6b2e2012-10-17 00:10:17 -0700623 return method_->GetDexCacheResolvedTypes()->Get(type_idx);
Ian Rogers6d4d9fc2011-11-30 16:24:48 -0800624 }
Ian Rogersad0b3a32012-04-16 14:50:24 -0700625
Ian Rogersb726dcb2012-09-05 08:57:23 -0700626 const DexFile& GetDexFile() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Ian Rogers6d4d9fc2011-11-30 16:24:48 -0800627 const DexFile* result = dex_file_;
628 if (result == NULL) {
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800629 const mirror::DexCache* dex_cache = GetDexCache();
Ian Rogers4445a7e2012-10-05 17:19:13 -0700630 result = dex_file_ = dex_cache->GetDexFile();
Ian Rogers6d4d9fc2011-11-30 16:24:48 -0800631 }
632 return *result;
633 }
Ian Rogersad0b3a32012-04-16 14:50:24 -0700634
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800635 mirror::DexCache* GetDexCache() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
636 mirror::DexCache* result = dex_cache_;
Ian Rogersad0b3a32012-04-16 14:50:24 -0700637 if (result == NULL) {
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800638 mirror::Class* klass = method_->GetDeclaringClass();
Ian Rogersad0b3a32012-04-16 14:50:24 -0700639 result = klass->GetDexCache();
640 dex_cache_ = result;
641 }
642 return result;
643 }
Elliott Hughesa21039c2012-06-21 12:09:25 -0700644
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800645 mirror::String* ResolveString(uint32_t string_idx) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
646 mirror::String* s = method_->GetDexCacheStrings()->Get(string_idx);
Ian Rogers2fa6b2e2012-10-17 00:10:17 -0700647 if (UNLIKELY(s == NULL)) {
648 s = GetClassLinker()->ResolveString(GetDexFile(), string_idx, GetDexCache());
649 }
650 return s;
651 }
652
Ian Rogers6d4d9fc2011-11-30 16:24:48 -0800653 private:
654 // Set the method_ field, for proxy methods looking up the interface method via the resolved
655 // methods table.
Brian Carlstromea46f952013-07-30 01:26:50 -0700656 void SetMethod(const mirror::ArtMethod* method) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Ian Rogers6d4d9fc2011-11-30 16:24:48 -0800657 if (method != NULL) {
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800658 mirror::Class* klass = method->GetDeclaringClass();
Ian Rogers4f6ad8a2013-03-18 15:27:28 -0700659 if (UNLIKELY(klass->IsProxyClass())) {
Brian Carlstromea46f952013-07-30 01:26:50 -0700660 mirror::ArtMethod* interface_method =
Ian Rogers19846512012-02-24 11:42:47 -0800661 method->GetDexCacheResolvedMethods()->Get(method->GetDexMethodIndex());
Ian Rogers4f6ad8a2013-03-18 15:27:28 -0700662 DCHECK(interface_method != NULL);
663 DCHECK(interface_method == GetClassLinker()->FindMethodForProxy(klass, method));
Ian Rogers19846512012-02-24 11:42:47 -0800664 method = interface_method;
Ian Rogers6d4d9fc2011-11-30 16:24:48 -0800665 }
666 }
667 method_ = method;
668 }
Ian Rogersad0b3a32012-04-16 14:50:24 -0700669
Ian Rogers6d4d9fc2011-11-30 16:24:48 -0800670 ClassLinker* GetClassLinker() {
671 ClassLinker* result = class_linker_;
672 if (result == NULL) {
673 result = Runtime::Current()->GetClassLinker();
674 class_linker_ = result;
675 }
676 return result;
677 }
678
679 ClassLinker* class_linker_;
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800680 mirror::DexCache* dex_cache_;
Ian Rogers6d4d9fc2011-11-30 16:24:48 -0800681 const DexFile* dex_file_;
Brian Carlstromea46f952013-07-30 01:26:50 -0700682 const mirror::ArtMethod* method_;
Ian Rogers6d4d9fc2011-11-30 16:24:48 -0800683 const char* shorty_;
Elliott Hughes45651fd2012-02-21 15:48:20 -0800684 uint32_t shorty_len_;
Ian Rogers6d4d9fc2011-11-30 16:24:48 -0800685
686 DISALLOW_COPY_AND_ASSIGN(MethodHelper);
687};
688
689} // namespace art
690
Brian Carlstromfc0e3212013-07-17 14:40:12 -0700691#endif // ART_RUNTIME_OBJECT_UTILS_H_