blob: 081bee1d88f00a110c22db4a29a916796d6f9012 [file] [log] [blame]
Ian Rogers2dd0e2c2013-01-24 12:42:14 -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 Carlstromea46f952013-07-30 01:26:50 -070017#ifndef ART_RUNTIME_MIRROR_ART_METHOD_H_
18#define ART_RUNTIME_MIRROR_ART_METHOD_H_
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080019
Jeff Hao790ad902013-05-22 15:02:08 -070020#include "dex_file.h"
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080021#include "invoke_type.h"
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080022#include "modifiers.h"
23#include "object.h"
Mathieu Chartier83c8ee02014-01-28 14:50:23 -080024#include "object_callbacks.h"
Vladimir Marko7624d252014-05-02 14:40:15 +010025#include "quick/quick_method_frame_info.h"
Mingyao Yang98d1cc82014-05-15 17:02:16 -070026#include "read_barrier_option.h"
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080027
28namespace art {
29
Brian Carlstromea46f952013-07-30 01:26:50 -070030struct ArtMethodOffsets;
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080031struct ConstructorMethodOffsets;
32union JValue;
Jeff Hao790ad902013-05-22 15:02:08 -070033class MethodHelper;
Mathieu Chartier2b7c4d12014-05-19 10:52:16 -070034class ScopedObjectAccessAlreadyRunnable;
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080035class StringPiece;
Jeff Hao16743632013-05-08 10:59:04 -070036class ShadowFrame;
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080037
38namespace mirror {
39
Jeff Hao790ad902013-05-22 15:02:08 -070040typedef void (EntryPointFromInterpreter)(Thread* self, MethodHelper& mh,
41 const DexFile::CodeItem* code_item, ShadowFrame* shadow_frame, JValue* result);
Jeff Hao16743632013-05-08 10:59:04 -070042
Mingyao Yang98d1cc82014-05-15 17:02:16 -070043// C++ mirror of java.lang.reflect.ArtMethod.
44class MANAGED ArtMethod FINAL : public Object {
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080045 public:
Mingyao Yang98d1cc82014-05-15 17:02:16 -070046 // Size of java.lang.reflect.ArtMethod.class.
47 static uint32_t ClassSize();
48
49 // Size of an instance of java.lang.reflect.ArtMethod not including its value array.
50 static constexpr uint32_t InstanceSize() {
51 return sizeof(ArtMethod);
52 }
53
Mathieu Chartier2b7c4d12014-05-19 10:52:16 -070054 static ArtMethod* FromReflectedMethod(const ScopedObjectAccessAlreadyRunnable& soa,
55 jobject jlr_method)
Ian Rogers62f05122014-03-21 11:21:29 -070056 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
57
Ian Rogersb0fa5dc2014-04-28 16:47:08 -070058 Class* GetDeclaringClass() ALWAYS_INLINE SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080059
60 void SetDeclaringClass(Class *new_declaring_class) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
61
62 static MemberOffset DeclaringClassOffset() {
Brian Carlstromea46f952013-07-30 01:26:50 -070063 return MemberOffset(OFFSETOF_MEMBER(ArtMethod, declaring_class_));
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080064 }
65
Ian Rogersef7d42f2014-01-06 12:55:46 -080066 uint32_t GetAccessFlags() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
Jeff Hao5d917302013-02-27 17:57:33 -080067
Ian Rogersef7d42f2014-01-06 12:55:46 -080068 void SetAccessFlags(uint32_t new_access_flags) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +010069 // Not called within a transaction.
Ian Rogersb0fa5dc2014-04-28 16:47:08 -070070 SetField32<false>(OFFSET_OF_OBJECT_MEMBER(ArtMethod, access_flags_), new_access_flags);
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080071 }
72
73 // Approximate what kind of method call would be used for this method.
Ian Rogersef7d42f2014-01-06 12:55:46 -080074 InvokeType GetInvokeType() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080075
76 // Returns true if the method is declared public.
Ian Rogersef7d42f2014-01-06 12:55:46 -080077 bool IsPublic() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080078 return (GetAccessFlags() & kAccPublic) != 0;
79 }
80
81 // Returns true if the method is declared private.
Ian Rogersef7d42f2014-01-06 12:55:46 -080082 bool IsPrivate() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080083 return (GetAccessFlags() & kAccPrivate) != 0;
84 }
85
86 // Returns true if the method is declared static.
Ian Rogersef7d42f2014-01-06 12:55:46 -080087 bool IsStatic() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080088 return (GetAccessFlags() & kAccStatic) != 0;
89 }
90
91 // Returns true if the method is a constructor.
Ian Rogersef7d42f2014-01-06 12:55:46 -080092 bool IsConstructor() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080093 return (GetAccessFlags() & kAccConstructor) != 0;
94 }
95
Mathieu Chartierbfd9a432014-05-21 17:43:44 -070096 // Returns true if the method is a class initializer.
97 bool IsClassInitializer() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
98 return IsConstructor() && IsStatic();
99 }
100
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800101 // Returns true if the method is static, private, or a constructor.
Ian Rogersef7d42f2014-01-06 12:55:46 -0800102 bool IsDirect() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800103 return IsDirect(GetAccessFlags());
104 }
105
106 static bool IsDirect(uint32_t access_flags) {
107 return (access_flags & (kAccStatic | kAccPrivate | kAccConstructor)) != 0;
108 }
109
110 // Returns true if the method is declared synchronized.
Ian Rogersef7d42f2014-01-06 12:55:46 -0800111 bool IsSynchronized() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800112 uint32_t synchonized = kAccSynchronized | kAccDeclaredSynchronized;
113 return (GetAccessFlags() & synchonized) != 0;
114 }
115
Ian Rogersef7d42f2014-01-06 12:55:46 -0800116 bool IsFinal() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800117 return (GetAccessFlags() & kAccFinal) != 0;
118 }
119
Ian Rogersef7d42f2014-01-06 12:55:46 -0800120 bool IsMiranda() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800121 return (GetAccessFlags() & kAccMiranda) != 0;
122 }
123
Ian Rogersef7d42f2014-01-06 12:55:46 -0800124 bool IsNative() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800125 return (GetAccessFlags() & kAccNative) != 0;
126 }
127
Ian Rogersef7d42f2014-01-06 12:55:46 -0800128 bool IsFastNative() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Ian Rogers16ce0922014-01-10 14:59:36 -0800129 uint32_t mask = kAccFastNative | kAccNative;
130 return (GetAccessFlags() & mask) == mask;
Ian Rogers1eb512d2013-10-18 15:42:20 -0700131 }
132
Ian Rogersef7d42f2014-01-06 12:55:46 -0800133 bool IsAbstract() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800134 return (GetAccessFlags() & kAccAbstract) != 0;
135 }
136
Ian Rogersef7d42f2014-01-06 12:55:46 -0800137 bool IsSynthetic() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800138 return (GetAccessFlags() & kAccSynthetic) != 0;
139 }
140
Ian Rogersef7d42f2014-01-06 12:55:46 -0800141 bool IsProxyMethod() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800142
Ian Rogersef7d42f2014-01-06 12:55:46 -0800143 bool IsPreverified() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Sebastien Hertz233ea8e2013-06-06 11:57:09 +0200144 return (GetAccessFlags() & kAccPreverified) != 0;
145 }
146
Ian Rogersef7d42f2014-01-06 12:55:46 -0800147 void SetPreverified() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
148 DCHECK(!IsPreverified());
Sebastien Hertz233ea8e2013-06-06 11:57:09 +0200149 SetAccessFlags(GetAccessFlags() | kAccPreverified);
150 }
151
Ian Rogersef7d42f2014-01-06 12:55:46 -0800152 bool IsPortableCompiled() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
153 return (GetAccessFlags() & kAccPortableCompiled) != 0;
154 }
155
156 void SetIsPortableCompiled() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
157 DCHECK(!IsPortableCompiled());
158 SetAccessFlags(GetAccessFlags() | kAccPortableCompiled);
159 }
160
161 void ClearIsPortableCompiled() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
162 DCHECK(IsPortableCompiled());
163 SetAccessFlags(GetAccessFlags() & ~kAccPortableCompiled);
164 }
165
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800166 bool CheckIncompatibleClassChange(InvokeType type) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
167
Ian Rogersef7d42f2014-01-06 12:55:46 -0800168 uint16_t GetMethodIndex() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800169
Ian Rogersef7d42f2014-01-06 12:55:46 -0800170 size_t GetVtableIndex() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800171 return GetMethodIndex();
172 }
173
Ian Rogersef7d42f2014-01-06 12:55:46 -0800174 void SetMethodIndex(uint16_t new_method_index) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100175 // Not called within a transaction.
Ian Rogersb0fa5dc2014-04-28 16:47:08 -0700176 SetField32<false>(OFFSET_OF_OBJECT_MEMBER(ArtMethod, method_index_), new_method_index);
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800177 }
178
179 static MemberOffset MethodIndexOffset() {
Brian Carlstromea46f952013-07-30 01:26:50 -0700180 return OFFSET_OF_OBJECT_MEMBER(ArtMethod, method_index_);
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800181 }
182
Ian Rogersef7d42f2014-01-06 12:55:46 -0800183 uint32_t GetCodeItemOffset() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Ian Rogersb0fa5dc2014-04-28 16:47:08 -0700184 return GetField32(OFFSET_OF_OBJECT_MEMBER(ArtMethod, dex_code_item_offset_));
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800185 }
186
Ian Rogersb0fa5dc2014-04-28 16:47:08 -0700187 void SetCodeItemOffset(uint32_t new_code_off) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100188 // Not called within a transaction.
Ian Rogersb0fa5dc2014-04-28 16:47:08 -0700189 SetField32<false>(OFFSET_OF_OBJECT_MEMBER(ArtMethod, dex_code_item_offset_), new_code_off);
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800190 }
191
192 // Number of 32bit registers that would be required to hold all the arguments
193 static size_t NumArgRegisters(const StringPiece& shorty);
194
Ian Rogersef7d42f2014-01-06 12:55:46 -0800195 uint32_t GetDexMethodIndex() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800196
Ian Rogersb0fa5dc2014-04-28 16:47:08 -0700197 void SetDexMethodIndex(uint32_t new_idx) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100198 // Not called within a transaction.
Ian Rogersb0fa5dc2014-04-28 16:47:08 -0700199 SetField32<false>(OFFSET_OF_OBJECT_MEMBER(ArtMethod, dex_method_index_), new_idx);
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800200 }
201
Ian Rogersef7d42f2014-01-06 12:55:46 -0800202 ObjectArray<String>* GetDexCacheStrings() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800203 void SetDexCacheStrings(ObjectArray<String>* new_dex_cache_strings)
204 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
205
206 static MemberOffset DexCacheStringsOffset() {
Brian Carlstromea46f952013-07-30 01:26:50 -0700207 return OFFSET_OF_OBJECT_MEMBER(ArtMethod, dex_cache_strings_);
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800208 }
209
210 static MemberOffset DexCacheResolvedMethodsOffset() {
Brian Carlstromea46f952013-07-30 01:26:50 -0700211 return OFFSET_OF_OBJECT_MEMBER(ArtMethod, dex_cache_resolved_methods_);
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800212 }
213
214 static MemberOffset DexCacheResolvedTypesOffset() {
Brian Carlstromea46f952013-07-30 01:26:50 -0700215 return OFFSET_OF_OBJECT_MEMBER(ArtMethod, dex_cache_resolved_types_);
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800216 }
217
Ian Rogersef7d42f2014-01-06 12:55:46 -0800218 ObjectArray<ArtMethod>* GetDexCacheResolvedMethods() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
Brian Carlstromea46f952013-07-30 01:26:50 -0700219 void SetDexCacheResolvedMethods(ObjectArray<ArtMethod>* new_dex_cache_methods)
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800220 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
221
Ian Rogersef7d42f2014-01-06 12:55:46 -0800222 ObjectArray<Class>* GetDexCacheResolvedTypes() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800223 void SetDexCacheResolvedTypes(ObjectArray<Class>* new_dex_cache_types)
224 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
225
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800226 // Find the method that this method overrides
Ian Rogersef7d42f2014-01-06 12:55:46 -0800227 ArtMethod* FindOverriddenMethod() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800228
Mathieu Chartierbfd9a432014-05-21 17:43:44 -0700229 void Invoke(Thread* self, uint32_t* args, uint32_t args_size, JValue* result, const char* shorty)
230 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800231
Mathieu Chartier4e305412014-02-19 10:54:44 -0800232 template<VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags>
Ian Rogersb0fa5dc2014-04-28 16:47:08 -0700233 EntryPointFromInterpreter* GetEntryPointFromInterpreter()
234 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Mathieu Chartier4e305412014-02-19 10:54:44 -0800235 return GetFieldPtr<EntryPointFromInterpreter*, kVerifyFlags>(
Mathieu Chartierbfd9a432014-05-21 17:43:44 -0700236 OFFSET_OF_OBJECT_MEMBER(ArtMethod, entry_point_from_interpreter_));
Jeff Hao16743632013-05-08 10:59:04 -0700237 }
238
Mathieu Chartier4e305412014-02-19 10:54:44 -0800239 template<VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags>
Ian Rogersb0fa5dc2014-04-28 16:47:08 -0700240 void SetEntryPointFromInterpreter(EntryPointFromInterpreter* entry_point_from_interpreter)
241 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Mathieu Chartier4e305412014-02-19 10:54:44 -0800242 SetFieldPtr<false, true, kVerifyFlags>(
243 OFFSET_OF_OBJECT_MEMBER(ArtMethod, entry_point_from_interpreter_),
Ian Rogersb0fa5dc2014-04-28 16:47:08 -0700244 entry_point_from_interpreter);
Jeff Hao16743632013-05-08 10:59:04 -0700245 }
246
Ian Rogersef7d42f2014-01-06 12:55:46 -0800247 static MemberOffset EntryPointFromPortableCompiledCodeOffset() {
248 return MemberOffset(OFFSETOF_MEMBER(ArtMethod, entry_point_from_portable_compiled_code_));
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800249 }
250
Mathieu Chartier4e305412014-02-19 10:54:44 -0800251 template<VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags>
Ian Rogersb0fa5dc2014-04-28 16:47:08 -0700252 const void* GetEntryPointFromPortableCompiledCode() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Mathieu Chartier4e305412014-02-19 10:54:44 -0800253 return GetFieldPtr<const void*, kVerifyFlags>(
Ian Rogersb0fa5dc2014-04-28 16:47:08 -0700254 EntryPointFromPortableCompiledCodeOffset());
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800255 }
256
Mathieu Chartier4e305412014-02-19 10:54:44 -0800257 template<VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags>
Ian Rogersb0fa5dc2014-04-28 16:47:08 -0700258 void SetEntryPointFromPortableCompiledCode(const void* entry_point_from_portable_compiled_code)
259 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Mathieu Chartier4e305412014-02-19 10:54:44 -0800260 SetFieldPtr<false, true, kVerifyFlags>(
Ian Rogersb0fa5dc2014-04-28 16:47:08 -0700261 EntryPointFromPortableCompiledCodeOffset(), entry_point_from_portable_compiled_code);
Ian Rogersef7d42f2014-01-06 12:55:46 -0800262 }
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800263
Ian Rogersef7d42f2014-01-06 12:55:46 -0800264 static MemberOffset EntryPointFromQuickCompiledCodeOffset() {
265 return MemberOffset(OFFSETOF_MEMBER(ArtMethod, entry_point_from_quick_compiled_code_));
266 }
267
Mathieu Chartier4e305412014-02-19 10:54:44 -0800268 template<VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags>
Ian Rogersb0fa5dc2014-04-28 16:47:08 -0700269 const void* GetEntryPointFromQuickCompiledCode() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
270 return GetFieldPtr<const void*, kVerifyFlags>(EntryPointFromQuickCompiledCodeOffset());
Ian Rogersef7d42f2014-01-06 12:55:46 -0800271 }
272
Mathieu Chartier4e305412014-02-19 10:54:44 -0800273 template<VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags>
Ian Rogersb0fa5dc2014-04-28 16:47:08 -0700274 void SetEntryPointFromQuickCompiledCode(const void* entry_point_from_quick_compiled_code)
275 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Mathieu Chartier4e305412014-02-19 10:54:44 -0800276 SetFieldPtr<false, true, kVerifyFlags>(
Ian Rogersb0fa5dc2014-04-28 16:47:08 -0700277 EntryPointFromQuickCompiledCodeOffset(), entry_point_from_quick_compiled_code);
Ian Rogersef7d42f2014-01-06 12:55:46 -0800278 }
279
Ian Rogersef7d42f2014-01-06 12:55:46 -0800280 uint32_t GetCodeSize() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
281
282 bool IsWithinQuickCode(uintptr_t pc) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
283 uintptr_t code = reinterpret_cast<uintptr_t>(GetEntryPointFromQuickCompiledCode());
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800284 if (code == 0) {
285 return pc == 0;
286 }
287 /*
Vladimir Marko96c6ab92014-04-08 14:00:50 +0100288 * During a stack walk, a return PC may point past-the-end of the code
289 * in the case that the last instruction is a call that isn't expected to
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800290 * return. Thus, we check <= code + GetCodeSize().
Vladimir Marko96c6ab92014-04-08 14:00:50 +0100291 *
292 * NOTE: For Thumb both pc and code are offset by 1 indicating the Thumb state.
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800293 */
Mathieu Chartierbfd9a432014-05-21 17:43:44 -0700294 return code <= pc && pc <= code + GetCodeSize();
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800295 }
296
Ian Rogersef7d42f2014-01-06 12:55:46 -0800297 void AssertPcIsWithinQuickCode(uintptr_t pc) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800298
Ian Rogersb0fa5dc2014-04-28 16:47:08 -0700299 uint32_t GetQuickOatCodeOffset() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
300 uint32_t GetPortableOatCodeOffset() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
301 void SetQuickOatCodeOffset(uint32_t code_offset) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
302 void SetPortableOatCodeOffset(uint32_t code_offset) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800303
Vladimir Marko8a630572014-04-09 18:45:35 +0100304 static const void* EntryPointToCodePointer(const void* entry_point) ALWAYS_INLINE {
305 uintptr_t code = reinterpret_cast<uintptr_t>(entry_point);
306 code &= ~0x1; // TODO: Make this Thumb2 specific.
307 return reinterpret_cast<const void*>(code);
308 }
309
Vladimir Marko4c1c5102014-05-14 16:51:16 +0100310 // Actual entry point pointer to compiled oat code or nullptr.
311 const void* GetQuickOatEntryPoint() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
Vladimir Marko8a630572014-04-09 18:45:35 +0100312 // Actual pointer to compiled oat code or nullptr.
Vladimir Marko4c1c5102014-05-14 16:51:16 +0100313 const void* GetQuickOatCodePointer() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
Vladimir Marko8a630572014-04-09 18:45:35 +0100314
Ian Rogers1809a722013-08-09 22:05:32 -0700315 // Callers should wrap the uint8_t* in a MappingTable instance for convenient access.
Vladimir Marko8a630572014-04-09 18:45:35 +0100316 const uint8_t* GetMappingTable() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
Vladimir Marko4c1c5102014-05-14 16:51:16 +0100317 const uint8_t* GetMappingTable(const void* code_pointer)
318 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800319
Ian Rogers1809a722013-08-09 22:05:32 -0700320 // Callers should wrap the uint8_t* in a VmapTable instance for convenient access.
Vladimir Marko8a630572014-04-09 18:45:35 +0100321 const uint8_t* GetVmapTable() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
Vladimir Marko4c1c5102014-05-14 16:51:16 +0100322 const uint8_t* GetVmapTable(const void* code_pointer)
323 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800324
Ian Rogersb0fa5dc2014-04-28 16:47:08 -0700325 const uint8_t* GetNativeGcMap() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
326 return GetFieldPtr<uint8_t*>(OFFSET_OF_OBJECT_MEMBER(ArtMethod, gc_map_));
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800327 }
Mathieu Chartier4e305412014-02-19 10:54:44 -0800328 template<VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags>
Ian Rogersb0fa5dc2014-04-28 16:47:08 -0700329 void SetNativeGcMap(const uint8_t* data) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
330 SetFieldPtr<false, true, kVerifyFlags>(OFFSET_OF_OBJECT_MEMBER(ArtMethod, gc_map_), data);
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800331 }
332
333 // When building the oat need a convenient place to stuff the offset of the native GC map.
Ian Rogersb0fa5dc2014-04-28 16:47:08 -0700334 void SetOatNativeGcMapOffset(uint32_t gc_map_offset) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
335 uint32_t GetOatNativeGcMapOffset() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800336
Andreas Gampe90546832014-03-12 18:07:19 -0700337 template <bool kCheckFrameSize = true>
Ian Rogersb0fa5dc2014-04-28 16:47:08 -0700338 uint32_t GetFrameSizeInBytes() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Vladimir Marko7624d252014-05-02 14:40:15 +0100339 uint32_t result = GetQuickFrameInfo().FrameSizeInBytes();
Andreas Gampe90546832014-03-12 18:07:19 -0700340 if (kCheckFrameSize) {
341 DCHECK_LE(static_cast<size_t>(kStackAlignment), result);
342 }
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800343 return result;
344 }
345
Vladimir Marko7624d252014-05-02 14:40:15 +0100346 QuickMethodFrameInfo GetQuickFrameInfo() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
Vladimir Marko4c1c5102014-05-14 16:51:16 +0100347 QuickMethodFrameInfo GetQuickFrameInfo(const void* code_pointer)
348 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800349
Ian Rogersb0fa5dc2014-04-28 16:47:08 -0700350 size_t GetReturnPcOffsetInBytes() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Vladimir Marko4c1c5102014-05-14 16:51:16 +0100351 return GetReturnPcOffsetInBytes(GetFrameSizeInBytes());
352 }
353
354 size_t GetReturnPcOffsetInBytes(uint32_t frame_size_in_bytes)
355 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
356 DCHECK_EQ(frame_size_in_bytes, GetFrameSizeInBytes());
357 return frame_size_in_bytes - kPointerSize;
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800358 }
359
Mathieu Chartiereb8167a2014-05-07 15:43:14 -0700360 size_t GetHandleScopeOffsetInBytes() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Ian Rogers62d6c772013-02-27 08:32:07 -0800361 return kPointerSize;
362 }
363
Ian Rogers1eb512d2013-10-18 15:42:20 -0700364 void RegisterNative(Thread* self, const void* native_method, bool is_fast)
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800365 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
366
367 void UnregisterNative(Thread* self) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
368
369 static MemberOffset NativeMethodOffset() {
Ian Rogersef7d42f2014-01-06 12:55:46 -0800370 return OFFSET_OF_OBJECT_MEMBER(ArtMethod, entry_point_from_jni_);
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800371 }
372
Ian Rogersb0fa5dc2014-04-28 16:47:08 -0700373 const void* GetNativeMethod() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
374 return GetFieldPtr<const void*>(NativeMethodOffset());
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800375 }
376
Mathieu Chartier4e305412014-02-19 10:54:44 -0800377 template<VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags>
Ian Rogersb0fa5dc2014-04-28 16:47:08 -0700378 void SetNativeMethod(const void*) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800379
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800380 static MemberOffset GetMethodIndexOffset() {
Brian Carlstromea46f952013-07-30 01:26:50 -0700381 return OFFSET_OF_OBJECT_MEMBER(ArtMethod, method_index_);
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800382 }
383
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800384 // Is this a CalleSaveMethod or ResolutionMethod and therefore doesn't adhere to normal
385 // conventions for a method of managed code. Returns false for Proxy methods.
Ian Rogersef7d42f2014-01-06 12:55:46 -0800386 bool IsRuntimeMethod() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800387
388 // Is this a hand crafted method used for something like describing callee saves?
Ian Rogersef7d42f2014-01-06 12:55:46 -0800389 bool IsCalleeSaveMethod() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800390
Ian Rogersef7d42f2014-01-06 12:55:46 -0800391 bool IsResolutionMethod() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800392
Ian Rogersef7d42f2014-01-06 12:55:46 -0800393 bool IsImtConflictMethod() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
Jeff Hao88474b42013-10-23 16:24:40 -0700394
Ian Rogersef7d42f2014-01-06 12:55:46 -0800395 uintptr_t NativePcOffset(const uintptr_t pc) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
Vladimir Marko4c1c5102014-05-14 16:51:16 +0100396 uintptr_t NativePcOffset(const uintptr_t pc, const void* quick_entry_point)
397 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800398
399 // Converts a native PC to a dex PC.
Dave Allisonb373e092014-02-20 16:06:36 -0800400 uint32_t ToDexPc(const uintptr_t pc, bool abort_on_failure = true)
401 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800402
403 // Converts a dex PC to a native PC.
Ian Rogersef7d42f2014-01-06 12:55:46 -0800404 uintptr_t ToNativePc(const uint32_t dex_pc) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800405
Ian Rogersc449aa82013-07-29 14:35:46 -0700406 // Find the catch block for the given exception type and dex_pc. When a catch block is found,
407 // indicates whether the found catch block is responsible for clearing the exception or whether
408 // a move-exception instruction is present.
Mathieu Chartierbfd9a432014-05-21 17:43:44 -0700409 static uint32_t FindCatchBlock(Handle<ArtMethod> h_this, Handle<Class> exception_type,
410 uint32_t dex_pc, bool* has_no_move_exception)
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800411 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
412
Brian Carlstromea46f952013-07-30 01:26:50 -0700413 static void SetClass(Class* java_lang_reflect_ArtMethod);
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800414
Hiroshi Yamauchi4f1ebc22014-06-25 14:30:41 -0700415 template<ReadBarrierOption kReadBarrierOption = kWithReadBarrier>
Mingyao Yang98d1cc82014-05-15 17:02:16 -0700416 static Class* GetJavaLangReflectArtMethod() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800417
Brian Carlstromea46f952013-07-30 01:26:50 -0700418 static void ResetClass();
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800419
Mathieu Chartier83c8ee02014-01-28 14:50:23 -0800420 static void VisitRoots(RootCallback* callback, void* arg)
Mathieu Chartierc528dba2013-11-26 12:00:11 -0800421 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
422
Mathieu Chartierbfd9a432014-05-21 17:43:44 -0700423 const DexFile* GetDexFile() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
Mingyao Yang98d1cc82014-05-15 17:02:16 -0700424
Mathieu Chartierbfd9a432014-05-21 17:43:44 -0700425 const char* GetDeclaringClassDescriptor() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
Mingyao Yang98d1cc82014-05-15 17:02:16 -0700426
Mathieu Chartierbfd9a432014-05-21 17:43:44 -0700427 const char* GetShorty() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
428 uint32_t unused_length;
429 return GetShorty(&unused_length);
430 }
Mingyao Yang98d1cc82014-05-15 17:02:16 -0700431
Mathieu Chartierbfd9a432014-05-21 17:43:44 -0700432 const char* GetShorty(uint32_t* out_length) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
Mingyao Yang98d1cc82014-05-15 17:02:16 -0700433
Mathieu Chartierbfd9a432014-05-21 17:43:44 -0700434 const Signature GetSignature() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
Mingyao Yang98d1cc82014-05-15 17:02:16 -0700435
Mathieu Chartierbfd9a432014-05-21 17:43:44 -0700436 const char* GetName() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
Mingyao Yang98d1cc82014-05-15 17:02:16 -0700437
Mathieu Chartierbfd9a432014-05-21 17:43:44 -0700438 const DexFile::CodeItem* GetCodeItem() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
Mingyao Yang98d1cc82014-05-15 17:02:16 -0700439
Mathieu Chartierbfd9a432014-05-21 17:43:44 -0700440 bool IsResolvedTypeIdx(uint16_t type_idx) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
Mingyao Yang98d1cc82014-05-15 17:02:16 -0700441
Mathieu Chartierbfd9a432014-05-21 17:43:44 -0700442 int32_t GetLineNumFromDexPC(uint32_t dex_pc) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
Mingyao Yang98d1cc82014-05-15 17:02:16 -0700443
Mathieu Chartierbfd9a432014-05-21 17:43:44 -0700444 const DexFile::ProtoId& GetPrototype() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
Mingyao Yang98d1cc82014-05-15 17:02:16 -0700445
Mathieu Chartierbfd9a432014-05-21 17:43:44 -0700446 const DexFile::TypeList* GetParameterTypeList() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
Mingyao Yang98d1cc82014-05-15 17:02:16 -0700447
Mathieu Chartierbfd9a432014-05-21 17:43:44 -0700448 const char* GetDeclaringClassSourceFile() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
Mingyao Yang98d1cc82014-05-15 17:02:16 -0700449
Mathieu Chartierbfd9a432014-05-21 17:43:44 -0700450 uint16_t GetClassDefIndex() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
Mingyao Yang98d1cc82014-05-15 17:02:16 -0700451
Mathieu Chartierbfd9a432014-05-21 17:43:44 -0700452 const DexFile::ClassDef& GetClassDef() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
Mingyao Yang98d1cc82014-05-15 17:02:16 -0700453
Mathieu Chartierbfd9a432014-05-21 17:43:44 -0700454 const char* GetReturnTypeDescriptor() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
Mingyao Yang98d1cc82014-05-15 17:02:16 -0700455
Mathieu Chartierbfd9a432014-05-21 17:43:44 -0700456 const char* GetTypeDescriptorFromTypeIdx(uint16_t type_idx)
457 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
Mingyao Yang98d1cc82014-05-15 17:02:16 -0700458
Mathieu Chartierbfd9a432014-05-21 17:43:44 -0700459 mirror::ClassLoader* GetClassLoader() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
Mingyao Yang98d1cc82014-05-15 17:02:16 -0700460
Mathieu Chartierbfd9a432014-05-21 17:43:44 -0700461 mirror::DexCache* GetDexCache() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
Mingyao Yang98d1cc82014-05-15 17:02:16 -0700462
Mathieu Chartierbfd9a432014-05-21 17:43:44 -0700463 ArtMethod* GetInterfaceMethodIfProxy() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
464
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800465 protected:
466 // Field order required by test "ValidateFieldOrderOfJavaCppUnionClasses".
Ian Rogersef7d42f2014-01-06 12:55:46 -0800467 // The class we are a part of.
468 HeapReference<Class> declaring_class_;
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800469
Ian Rogersef7d42f2014-01-06 12:55:46 -0800470 // Short cuts to declaring_class_->dex_cache_ member for fast compiled code access.
Ian Rogers700a4022014-05-19 16:49:03 -0700471 HeapReference<ObjectArray<ArtMethod>> dex_cache_resolved_methods_;
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800472
Ian Rogersef7d42f2014-01-06 12:55:46 -0800473 // Short cuts to declaring_class_->dex_cache_ member for fast compiled code access.
Ian Rogers700a4022014-05-19 16:49:03 -0700474 HeapReference<ObjectArray<Class>> dex_cache_resolved_types_;
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800475
Ian Rogersef7d42f2014-01-06 12:55:46 -0800476 // Short cuts to declaring_class_->dex_cache_ member for fast compiled code access.
Ian Rogers700a4022014-05-19 16:49:03 -0700477 HeapReference<ObjectArray<String>> dex_cache_strings_;
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800478
Ian Rogersef7d42f2014-01-06 12:55:46 -0800479 // Method dispatch from the interpreter invokes this pointer which may cause a bridge into
480 // compiled code.
481 uint64_t entry_point_from_interpreter_;
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800482
Ian Rogersef7d42f2014-01-06 12:55:46 -0800483 // Pointer to JNI function registered to this method, or a function to resolve the JNI function.
484 uint64_t entry_point_from_jni_;
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800485
Ian Rogersef7d42f2014-01-06 12:55:46 -0800486 // Method dispatch from portable compiled code invokes this pointer which may cause bridging into
487 // quick compiled code or the interpreter.
488 uint64_t entry_point_from_portable_compiled_code_;
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800489
Ian Rogersef7d42f2014-01-06 12:55:46 -0800490 // Method dispatch from quick compiled code invokes this pointer which may cause bridging into
491 // portable compiled code or the interpreter.
492 uint64_t entry_point_from_quick_compiled_code_;
Jeff Haoaa4a7932013-05-13 11:28:27 -0700493
Ian Rogersef7d42f2014-01-06 12:55:46 -0800494 // Pointer to a data structure created by the compiler and used by the garbage collector to
495 // determine which registers hold live references to objects within the heap. Keyed by native PC
496 // offsets for the quick compiler and dex PCs for the portable.
497 uint64_t gc_map_;
Jeff Hao16743632013-05-08 10:59:04 -0700498
Ian Rogersef7d42f2014-01-06 12:55:46 -0800499 // Access flags; low 16 bits are defined by spec.
500 uint32_t access_flags_;
501
502 /* Dex file fields. The defining dex file is available via declaring_class_->dex_cache_ */
503
504 // Offset to the CodeItem.
505 uint32_t dex_code_item_offset_;
506
507 // Index into method_ids of the dex file associated with this method.
508 uint32_t dex_method_index_;
509
510 /* End of dex file fields. */
511
512 // Entry within a dispatch table for this method. For static/direct methods the index is into
513 // the declaringClass.directMethods, for virtual methods the vtable and for interface methods the
514 // ifTable.
515 uint32_t method_index_;
516
Brian Carlstromea46f952013-07-30 01:26:50 -0700517 static Class* java_lang_reflect_ArtMethod_;
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800518
Mathieu Chartier02e25112013-08-14 16:14:24 -0700519 private:
Brian Carlstromea46f952013-07-30 01:26:50 -0700520 friend struct art::ArtMethodOffsets; // for verifying offset information
521 DISALLOW_IMPLICIT_CONSTRUCTORS(ArtMethod);
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800522};
523
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800524} // namespace mirror
525} // namespace art
526
Brian Carlstromea46f952013-07-30 01:26:50 -0700527#endif // ART_RUNTIME_MIRROR_ART_METHOD_H_