blob: 1c21b81f28ab669888b49ba589f281f2ebe91db4 [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
20#include "class.h"
Jeff Hao790ad902013-05-22 15:02:08 -070021#include "dex_file.h"
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080022#include "invoke_type.h"
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080023#include "modifiers.h"
24#include "object.h"
Mathieu Chartier83c8ee02014-01-28 14:50:23 -080025#include "object_callbacks.h"
Vladimir Marko7624d252014-05-02 14:40:15 +010026#include "quick/quick_method_frame_info.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;
33struct MethodClassOffsets;
Jeff Hao790ad902013-05-22 15:02:08 -070034class MethodHelper;
Mathieu Chartier2b7c4d12014-05-19 10:52:16 -070035class ScopedObjectAccessAlreadyRunnable;
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080036class StringPiece;
Jeff Hao16743632013-05-08 10:59:04 -070037class ShadowFrame;
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080038
39namespace mirror {
40
41class StaticStorageBase;
42
Jeff Hao790ad902013-05-22 15:02:08 -070043typedef void (EntryPointFromInterpreter)(Thread* self, MethodHelper& mh,
44 const DexFile::CodeItem* code_item, ShadowFrame* shadow_frame, JValue* result);
Jeff Hao16743632013-05-08 10:59:04 -070045
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080046// C++ mirror of java.lang.reflect.Method and java.lang.reflect.Constructor
Brian Carlstromea46f952013-07-30 01:26:50 -070047class MANAGED ArtMethod : public Object {
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080048 public:
Mathieu Chartier2b7c4d12014-05-19 10:52:16 -070049 static ArtMethod* FromReflectedMethod(const ScopedObjectAccessAlreadyRunnable& soa,
50 jobject jlr_method)
Ian Rogers62f05122014-03-21 11:21:29 -070051 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
52
Ian Rogersb0fa5dc2014-04-28 16:47:08 -070053 Class* GetDeclaringClass() ALWAYS_INLINE SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080054
55 void SetDeclaringClass(Class *new_declaring_class) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
56
57 static MemberOffset DeclaringClassOffset() {
Brian Carlstromea46f952013-07-30 01:26:50 -070058 return MemberOffset(OFFSETOF_MEMBER(ArtMethod, declaring_class_));
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080059 }
60
Ian Rogersef7d42f2014-01-06 12:55:46 -080061 uint32_t GetAccessFlags() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
Jeff Hao5d917302013-02-27 17:57:33 -080062
Ian Rogersef7d42f2014-01-06 12:55:46 -080063 void SetAccessFlags(uint32_t new_access_flags) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +010064 // Not called within a transaction.
Ian Rogersb0fa5dc2014-04-28 16:47:08 -070065 SetField32<false>(OFFSET_OF_OBJECT_MEMBER(ArtMethod, access_flags_), new_access_flags);
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080066 }
67
68 // Approximate what kind of method call would be used for this method.
Ian Rogersef7d42f2014-01-06 12:55:46 -080069 InvokeType GetInvokeType() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080070
71 // Returns true if the method is declared public.
Ian Rogersef7d42f2014-01-06 12:55:46 -080072 bool IsPublic() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080073 return (GetAccessFlags() & kAccPublic) != 0;
74 }
75
76 // Returns true if the method is declared private.
Ian Rogersef7d42f2014-01-06 12:55:46 -080077 bool IsPrivate() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080078 return (GetAccessFlags() & kAccPrivate) != 0;
79 }
80
81 // Returns true if the method is declared static.
Ian Rogersef7d42f2014-01-06 12:55:46 -080082 bool IsStatic() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080083 return (GetAccessFlags() & kAccStatic) != 0;
84 }
85
86 // Returns true if the method is a constructor.
Ian Rogersef7d42f2014-01-06 12:55:46 -080087 bool IsConstructor() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080088 return (GetAccessFlags() & kAccConstructor) != 0;
89 }
90
Mathieu Chartierbfd9a432014-05-21 17:43:44 -070091 // Returns true if the method is a class initializer.
92 bool IsClassInitializer() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
93 return IsConstructor() && IsStatic();
94 }
95
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080096 // Returns true if the method is static, private, or a constructor.
Ian Rogersef7d42f2014-01-06 12:55:46 -080097 bool IsDirect() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080098 return IsDirect(GetAccessFlags());
99 }
100
101 static bool IsDirect(uint32_t access_flags) {
102 return (access_flags & (kAccStatic | kAccPrivate | kAccConstructor)) != 0;
103 }
104
105 // Returns true if the method is declared synchronized.
Ian Rogersef7d42f2014-01-06 12:55:46 -0800106 bool IsSynchronized() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800107 uint32_t synchonized = kAccSynchronized | kAccDeclaredSynchronized;
108 return (GetAccessFlags() & synchonized) != 0;
109 }
110
Ian Rogersef7d42f2014-01-06 12:55:46 -0800111 bool IsFinal() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800112 return (GetAccessFlags() & kAccFinal) != 0;
113 }
114
Ian Rogersef7d42f2014-01-06 12:55:46 -0800115 bool IsMiranda() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800116 return (GetAccessFlags() & kAccMiranda) != 0;
117 }
118
Ian Rogersef7d42f2014-01-06 12:55:46 -0800119 bool IsNative() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800120 return (GetAccessFlags() & kAccNative) != 0;
121 }
122
Ian Rogersef7d42f2014-01-06 12:55:46 -0800123 bool IsFastNative() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Ian Rogers16ce0922014-01-10 14:59:36 -0800124 uint32_t mask = kAccFastNative | kAccNative;
125 return (GetAccessFlags() & mask) == mask;
Ian Rogers1eb512d2013-10-18 15:42:20 -0700126 }
127
Ian Rogersef7d42f2014-01-06 12:55:46 -0800128 bool IsAbstract() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800129 return (GetAccessFlags() & kAccAbstract) != 0;
130 }
131
Ian Rogersef7d42f2014-01-06 12:55:46 -0800132 bool IsSynthetic() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800133 return (GetAccessFlags() & kAccSynthetic) != 0;
134 }
135
Ian Rogersef7d42f2014-01-06 12:55:46 -0800136 bool IsProxyMethod() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800137
Ian Rogersef7d42f2014-01-06 12:55:46 -0800138 bool IsPreverified() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Sebastien Hertz233ea8e2013-06-06 11:57:09 +0200139 return (GetAccessFlags() & kAccPreverified) != 0;
140 }
141
Ian Rogersef7d42f2014-01-06 12:55:46 -0800142 void SetPreverified() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
143 DCHECK(!IsPreverified());
Sebastien Hertz233ea8e2013-06-06 11:57:09 +0200144 SetAccessFlags(GetAccessFlags() | kAccPreverified);
145 }
146
Ian Rogersef7d42f2014-01-06 12:55:46 -0800147 bool IsPortableCompiled() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
148 return (GetAccessFlags() & kAccPortableCompiled) != 0;
149 }
150
151 void SetIsPortableCompiled() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
152 DCHECK(!IsPortableCompiled());
153 SetAccessFlags(GetAccessFlags() | kAccPortableCompiled);
154 }
155
156 void ClearIsPortableCompiled() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
157 DCHECK(IsPortableCompiled());
158 SetAccessFlags(GetAccessFlags() & ~kAccPortableCompiled);
159 }
160
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800161 bool CheckIncompatibleClassChange(InvokeType type) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
162
Ian Rogersef7d42f2014-01-06 12:55:46 -0800163 uint16_t GetMethodIndex() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800164
Ian Rogersef7d42f2014-01-06 12:55:46 -0800165 size_t GetVtableIndex() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800166 return GetMethodIndex();
167 }
168
Ian Rogersef7d42f2014-01-06 12:55:46 -0800169 void SetMethodIndex(uint16_t new_method_index) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100170 // Not called within a transaction.
Ian Rogersb0fa5dc2014-04-28 16:47:08 -0700171 SetField32<false>(OFFSET_OF_OBJECT_MEMBER(ArtMethod, method_index_), new_method_index);
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800172 }
173
174 static MemberOffset MethodIndexOffset() {
Brian Carlstromea46f952013-07-30 01:26:50 -0700175 return OFFSET_OF_OBJECT_MEMBER(ArtMethod, method_index_);
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800176 }
177
Ian Rogersef7d42f2014-01-06 12:55:46 -0800178 uint32_t GetCodeItemOffset() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Ian Rogersb0fa5dc2014-04-28 16:47:08 -0700179 return GetField32(OFFSET_OF_OBJECT_MEMBER(ArtMethod, dex_code_item_offset_));
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800180 }
181
Ian Rogersb0fa5dc2014-04-28 16:47:08 -0700182 void SetCodeItemOffset(uint32_t new_code_off) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100183 // Not called within a transaction.
Ian Rogersb0fa5dc2014-04-28 16:47:08 -0700184 SetField32<false>(OFFSET_OF_OBJECT_MEMBER(ArtMethod, dex_code_item_offset_), new_code_off);
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800185 }
186
187 // Number of 32bit registers that would be required to hold all the arguments
188 static size_t NumArgRegisters(const StringPiece& shorty);
189
Ian Rogersef7d42f2014-01-06 12:55:46 -0800190 uint32_t GetDexMethodIndex() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800191
Ian Rogersb0fa5dc2014-04-28 16:47:08 -0700192 void SetDexMethodIndex(uint32_t new_idx) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100193 // Not called within a transaction.
Ian Rogersb0fa5dc2014-04-28 16:47:08 -0700194 SetField32<false>(OFFSET_OF_OBJECT_MEMBER(ArtMethod, dex_method_index_), new_idx);
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800195 }
196
Ian Rogersef7d42f2014-01-06 12:55:46 -0800197 ObjectArray<String>* GetDexCacheStrings() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800198 void SetDexCacheStrings(ObjectArray<String>* new_dex_cache_strings)
199 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
200
201 static MemberOffset DexCacheStringsOffset() {
Brian Carlstromea46f952013-07-30 01:26:50 -0700202 return OFFSET_OF_OBJECT_MEMBER(ArtMethod, dex_cache_strings_);
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800203 }
204
205 static MemberOffset DexCacheResolvedMethodsOffset() {
Brian Carlstromea46f952013-07-30 01:26:50 -0700206 return OFFSET_OF_OBJECT_MEMBER(ArtMethod, dex_cache_resolved_methods_);
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800207 }
208
209 static MemberOffset DexCacheResolvedTypesOffset() {
Brian Carlstromea46f952013-07-30 01:26:50 -0700210 return OFFSET_OF_OBJECT_MEMBER(ArtMethod, dex_cache_resolved_types_);
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800211 }
212
Ian Rogersef7d42f2014-01-06 12:55:46 -0800213 ObjectArray<ArtMethod>* GetDexCacheResolvedMethods() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
Brian Carlstromea46f952013-07-30 01:26:50 -0700214 void SetDexCacheResolvedMethods(ObjectArray<ArtMethod>* new_dex_cache_methods)
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800215 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
216
Ian Rogersef7d42f2014-01-06 12:55:46 -0800217 ObjectArray<Class>* GetDexCacheResolvedTypes() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800218 void SetDexCacheResolvedTypes(ObjectArray<Class>* new_dex_cache_types)
219 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
220
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800221 // Find the method that this method overrides
Ian Rogersef7d42f2014-01-06 12:55:46 -0800222 ArtMethod* FindOverriddenMethod() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800223
Mathieu Chartierbfd9a432014-05-21 17:43:44 -0700224 void Invoke(Thread* self, uint32_t* args, uint32_t args_size, JValue* result, const char* shorty)
225 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800226
Mathieu Chartier4e305412014-02-19 10:54:44 -0800227 template<VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags>
Ian Rogersb0fa5dc2014-04-28 16:47:08 -0700228 EntryPointFromInterpreter* GetEntryPointFromInterpreter()
229 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Mathieu Chartier4e305412014-02-19 10:54:44 -0800230 return GetFieldPtr<EntryPointFromInterpreter*, kVerifyFlags>(
Mathieu Chartierbfd9a432014-05-21 17:43:44 -0700231 OFFSET_OF_OBJECT_MEMBER(ArtMethod, entry_point_from_interpreter_));
Jeff Hao16743632013-05-08 10:59:04 -0700232 }
233
Mathieu Chartier4e305412014-02-19 10:54:44 -0800234 template<VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags>
Ian Rogersb0fa5dc2014-04-28 16:47:08 -0700235 void SetEntryPointFromInterpreter(EntryPointFromInterpreter* entry_point_from_interpreter)
236 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Mathieu Chartier4e305412014-02-19 10:54:44 -0800237 SetFieldPtr<false, true, kVerifyFlags>(
238 OFFSET_OF_OBJECT_MEMBER(ArtMethod, entry_point_from_interpreter_),
Ian Rogersb0fa5dc2014-04-28 16:47:08 -0700239 entry_point_from_interpreter);
Jeff Hao16743632013-05-08 10:59:04 -0700240 }
241
Ian Rogersef7d42f2014-01-06 12:55:46 -0800242 static MemberOffset EntryPointFromPortableCompiledCodeOffset() {
243 return MemberOffset(OFFSETOF_MEMBER(ArtMethod, entry_point_from_portable_compiled_code_));
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800244 }
245
Mathieu Chartier4e305412014-02-19 10:54:44 -0800246 template<VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags>
Ian Rogersb0fa5dc2014-04-28 16:47:08 -0700247 const void* GetEntryPointFromPortableCompiledCode() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Mathieu Chartier4e305412014-02-19 10:54:44 -0800248 return GetFieldPtr<const void*, kVerifyFlags>(
Ian Rogersb0fa5dc2014-04-28 16:47:08 -0700249 EntryPointFromPortableCompiledCodeOffset());
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800250 }
251
Mathieu Chartier4e305412014-02-19 10:54:44 -0800252 template<VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags>
Ian Rogersb0fa5dc2014-04-28 16:47:08 -0700253 void SetEntryPointFromPortableCompiledCode(const void* entry_point_from_portable_compiled_code)
254 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Mathieu Chartier4e305412014-02-19 10:54:44 -0800255 SetFieldPtr<false, true, kVerifyFlags>(
Ian Rogersb0fa5dc2014-04-28 16:47:08 -0700256 EntryPointFromPortableCompiledCodeOffset(), entry_point_from_portable_compiled_code);
Ian Rogersef7d42f2014-01-06 12:55:46 -0800257 }
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800258
Ian Rogersef7d42f2014-01-06 12:55:46 -0800259 static MemberOffset EntryPointFromQuickCompiledCodeOffset() {
260 return MemberOffset(OFFSETOF_MEMBER(ArtMethod, entry_point_from_quick_compiled_code_));
261 }
262
Mathieu Chartier4e305412014-02-19 10:54:44 -0800263 template<VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags>
Ian Rogersb0fa5dc2014-04-28 16:47:08 -0700264 const void* GetEntryPointFromQuickCompiledCode() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
265 return GetFieldPtr<const void*, kVerifyFlags>(EntryPointFromQuickCompiledCodeOffset());
Ian Rogersef7d42f2014-01-06 12:55:46 -0800266 }
267
Mathieu Chartier4e305412014-02-19 10:54:44 -0800268 template<VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags>
Ian Rogersb0fa5dc2014-04-28 16:47:08 -0700269 void SetEntryPointFromQuickCompiledCode(const void* entry_point_from_quick_compiled_code)
270 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Mathieu Chartier4e305412014-02-19 10:54:44 -0800271 SetFieldPtr<false, true, kVerifyFlags>(
Ian Rogersb0fa5dc2014-04-28 16:47:08 -0700272 EntryPointFromQuickCompiledCodeOffset(), entry_point_from_quick_compiled_code);
Ian Rogersef7d42f2014-01-06 12:55:46 -0800273 }
274
Ian Rogersef7d42f2014-01-06 12:55:46 -0800275 uint32_t GetCodeSize() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
276
277 bool IsWithinQuickCode(uintptr_t pc) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
278 uintptr_t code = reinterpret_cast<uintptr_t>(GetEntryPointFromQuickCompiledCode());
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800279 if (code == 0) {
280 return pc == 0;
281 }
282 /*
Vladimir Marko96c6ab92014-04-08 14:00:50 +0100283 * During a stack walk, a return PC may point past-the-end of the code
284 * in the case that the last instruction is a call that isn't expected to
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800285 * return. Thus, we check <= code + GetCodeSize().
Vladimir Marko96c6ab92014-04-08 14:00:50 +0100286 *
287 * NOTE: For Thumb both pc and code are offset by 1 indicating the Thumb state.
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800288 */
Mathieu Chartierbfd9a432014-05-21 17:43:44 -0700289 return code <= pc && pc <= code + GetCodeSize();
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800290 }
291
Ian Rogersef7d42f2014-01-06 12:55:46 -0800292 void AssertPcIsWithinQuickCode(uintptr_t pc) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800293
Ian Rogersb0fa5dc2014-04-28 16:47:08 -0700294 uint32_t GetQuickOatCodeOffset() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
295 uint32_t GetPortableOatCodeOffset() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
296 void SetQuickOatCodeOffset(uint32_t code_offset) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
297 void SetPortableOatCodeOffset(uint32_t code_offset) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800298
Vladimir Marko8a630572014-04-09 18:45:35 +0100299 static const void* EntryPointToCodePointer(const void* entry_point) ALWAYS_INLINE {
300 uintptr_t code = reinterpret_cast<uintptr_t>(entry_point);
301 code &= ~0x1; // TODO: Make this Thumb2 specific.
302 return reinterpret_cast<const void*>(code);
303 }
304
Vladimir Marko4c1c5102014-05-14 16:51:16 +0100305 // Actual entry point pointer to compiled oat code or nullptr.
306 const void* GetQuickOatEntryPoint() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
Vladimir Marko8a630572014-04-09 18:45:35 +0100307 // Actual pointer to compiled oat code or nullptr.
Vladimir Marko4c1c5102014-05-14 16:51:16 +0100308 const void* GetQuickOatCodePointer() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
Vladimir Marko8a630572014-04-09 18:45:35 +0100309
Ian Rogers1809a722013-08-09 22:05:32 -0700310 // Callers should wrap the uint8_t* in a MappingTable instance for convenient access.
Vladimir Marko8a630572014-04-09 18:45:35 +0100311 const uint8_t* GetMappingTable() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
Vladimir Marko4c1c5102014-05-14 16:51:16 +0100312 const uint8_t* GetMappingTable(const void* code_pointer)
313 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800314
Ian Rogers1809a722013-08-09 22:05:32 -0700315 // Callers should wrap the uint8_t* in a VmapTable instance for convenient access.
Vladimir Marko8a630572014-04-09 18:45:35 +0100316 const uint8_t* GetVmapTable() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
Vladimir Marko4c1c5102014-05-14 16:51:16 +0100317 const uint8_t* GetVmapTable(const void* code_pointer)
318 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800319
Ian Rogersb0fa5dc2014-04-28 16:47:08 -0700320 const uint8_t* GetNativeGcMap() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
321 return GetFieldPtr<uint8_t*>(OFFSET_OF_OBJECT_MEMBER(ArtMethod, gc_map_));
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800322 }
Mathieu Chartier4e305412014-02-19 10:54:44 -0800323 template<VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags>
Ian Rogersb0fa5dc2014-04-28 16:47:08 -0700324 void SetNativeGcMap(const uint8_t* data) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
325 SetFieldPtr<false, true, kVerifyFlags>(OFFSET_OF_OBJECT_MEMBER(ArtMethod, gc_map_), data);
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800326 }
327
328 // When building the oat need a convenient place to stuff the offset of the native GC map.
Ian Rogersb0fa5dc2014-04-28 16:47:08 -0700329 void SetOatNativeGcMapOffset(uint32_t gc_map_offset) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
330 uint32_t GetOatNativeGcMapOffset() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800331
Andreas Gampe90546832014-03-12 18:07:19 -0700332 template <bool kCheckFrameSize = true>
Ian Rogersb0fa5dc2014-04-28 16:47:08 -0700333 uint32_t GetFrameSizeInBytes() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Vladimir Marko7624d252014-05-02 14:40:15 +0100334 uint32_t result = GetQuickFrameInfo().FrameSizeInBytes();
Andreas Gampe90546832014-03-12 18:07:19 -0700335 if (kCheckFrameSize) {
336 DCHECK_LE(static_cast<size_t>(kStackAlignment), result);
337 }
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800338 return result;
339 }
340
Vladimir Marko7624d252014-05-02 14:40:15 +0100341 QuickMethodFrameInfo GetQuickFrameInfo() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
Vladimir Marko4c1c5102014-05-14 16:51:16 +0100342 QuickMethodFrameInfo GetQuickFrameInfo(const void* code_pointer)
343 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800344
Ian Rogersb0fa5dc2014-04-28 16:47:08 -0700345 size_t GetReturnPcOffsetInBytes() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Vladimir Marko4c1c5102014-05-14 16:51:16 +0100346 return GetReturnPcOffsetInBytes(GetFrameSizeInBytes());
347 }
348
349 size_t GetReturnPcOffsetInBytes(uint32_t frame_size_in_bytes)
350 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
351 DCHECK_EQ(frame_size_in_bytes, GetFrameSizeInBytes());
352 return frame_size_in_bytes - kPointerSize;
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800353 }
354
Mathieu Chartiereb8167a2014-05-07 15:43:14 -0700355 size_t GetHandleScopeOffsetInBytes() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Ian Rogers62d6c772013-02-27 08:32:07 -0800356 return kPointerSize;
357 }
358
Ian Rogersb0fa5dc2014-04-28 16:47:08 -0700359 bool IsRegistered() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800360
Ian Rogers1eb512d2013-10-18 15:42:20 -0700361 void RegisterNative(Thread* self, const void* native_method, bool is_fast)
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800362 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
363
364 void UnregisterNative(Thread* self) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
365
366 static MemberOffset NativeMethodOffset() {
Ian Rogersef7d42f2014-01-06 12:55:46 -0800367 return OFFSET_OF_OBJECT_MEMBER(ArtMethod, entry_point_from_jni_);
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800368 }
369
Ian Rogersb0fa5dc2014-04-28 16:47:08 -0700370 const void* GetNativeMethod() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
371 return GetFieldPtr<const void*>(NativeMethodOffset());
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800372 }
373
Mathieu Chartier4e305412014-02-19 10:54:44 -0800374 template<VerifyObjectFlags kVerifyFlags = kDefaultVerifyFlags>
Ian Rogersb0fa5dc2014-04-28 16:47:08 -0700375 void SetNativeMethod(const void*) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800376
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800377 static MemberOffset GetMethodIndexOffset() {
Brian Carlstromea46f952013-07-30 01:26:50 -0700378 return OFFSET_OF_OBJECT_MEMBER(ArtMethod, method_index_);
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800379 }
380
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800381 // Is this a CalleSaveMethod or ResolutionMethod and therefore doesn't adhere to normal
382 // conventions for a method of managed code. Returns false for Proxy methods.
Ian Rogersef7d42f2014-01-06 12:55:46 -0800383 bool IsRuntimeMethod() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800384
385 // Is this a hand crafted method used for something like describing callee saves?
Ian Rogersef7d42f2014-01-06 12:55:46 -0800386 bool IsCalleeSaveMethod() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800387
Ian Rogersef7d42f2014-01-06 12:55:46 -0800388 bool IsResolutionMethod() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800389
Ian Rogersef7d42f2014-01-06 12:55:46 -0800390 bool IsImtConflictMethod() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
Jeff Hao88474b42013-10-23 16:24:40 -0700391
Ian Rogersef7d42f2014-01-06 12:55:46 -0800392 uintptr_t NativePcOffset(const uintptr_t pc) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
Vladimir Marko4c1c5102014-05-14 16:51:16 +0100393 uintptr_t NativePcOffset(const uintptr_t pc, const void* quick_entry_point)
394 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800395
396 // Converts a native PC to a dex PC.
Dave Allisonb373e092014-02-20 16:06:36 -0800397 uint32_t ToDexPc(const uintptr_t pc, bool abort_on_failure = true)
398 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800399
400 // Converts a dex PC to a native PC.
Ian Rogersef7d42f2014-01-06 12:55:46 -0800401 uintptr_t ToNativePc(const uint32_t dex_pc) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800402
Ian Rogersc449aa82013-07-29 14:35:46 -0700403 // Find the catch block for the given exception type and dex_pc. When a catch block is found,
404 // indicates whether the found catch block is responsible for clearing the exception or whether
405 // a move-exception instruction is present.
Mathieu Chartierbfd9a432014-05-21 17:43:44 -0700406 static uint32_t FindCatchBlock(Handle<ArtMethod> h_this, Handle<Class> exception_type,
407 uint32_t dex_pc, bool* has_no_move_exception)
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800408 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
409
Brian Carlstromea46f952013-07-30 01:26:50 -0700410 static void SetClass(Class* java_lang_reflect_ArtMethod);
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800411
Brian Carlstromea46f952013-07-30 01:26:50 -0700412 static Class* GetJavaLangReflectArtMethod() {
Hiroshi Yamauchibd0fb612014-05-20 13:46:00 -0700413 DCHECK(java_lang_reflect_ArtMethod_ != nullptr);
Brian Carlstromea46f952013-07-30 01:26:50 -0700414 return java_lang_reflect_ArtMethod_;
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800415 }
416
Brian Carlstromea46f952013-07-30 01:26:50 -0700417 static void ResetClass();
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800418
Mathieu Chartier83c8ee02014-01-28 14:50:23 -0800419 static void VisitRoots(RootCallback* callback, void* arg)
Mathieu Chartierc528dba2013-11-26 12:00:11 -0800420 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
421
Mathieu Chartierbfd9a432014-05-21 17:43:44 -0700422 const DexFile* GetDexFile() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
423 const char* GetDeclaringClassDescriptor() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
424 const char* GetShorty() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
425 uint32_t unused_length;
426 return GetShorty(&unused_length);
427 }
428 const char* GetShorty(uint32_t* out_length) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
429 const Signature GetSignature() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
430 const char* GetName() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
431 const DexFile::CodeItem* GetCodeItem() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
432 bool IsResolvedTypeIdx(uint16_t type_idx) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
433 int32_t GetLineNumFromDexPC(uint32_t dex_pc) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
434 const DexFile::ProtoId& GetPrototype() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
435 const DexFile::TypeList* GetParameterTypeList() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
436 const char* GetDeclaringClassSourceFile() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
437 uint16_t GetClassDefIndex() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
438 const DexFile::ClassDef& GetClassDef() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
439 const char* GetReturnTypeDescriptor() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
440 const char* GetTypeDescriptorFromTypeIdx(uint16_t type_idx)
441 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
442 mirror::ClassLoader* GetClassLoader() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
443 mirror::DexCache* GetDexCache() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
444 ArtMethod* GetInterfaceMethodIfProxy() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
445
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800446 protected:
447 // Field order required by test "ValidateFieldOrderOfJavaCppUnionClasses".
Ian Rogersef7d42f2014-01-06 12:55:46 -0800448 // The class we are a part of.
449 HeapReference<Class> declaring_class_;
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800450
Ian Rogersef7d42f2014-01-06 12:55:46 -0800451 // Short cuts to declaring_class_->dex_cache_ member for fast compiled code access.
Ian Rogers700a4022014-05-19 16:49:03 -0700452 HeapReference<ObjectArray<ArtMethod>> dex_cache_resolved_methods_;
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800453
Ian Rogersef7d42f2014-01-06 12:55:46 -0800454 // Short cuts to declaring_class_->dex_cache_ member for fast compiled code access.
Ian Rogers700a4022014-05-19 16:49:03 -0700455 HeapReference<ObjectArray<Class>> dex_cache_resolved_types_;
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800456
Ian Rogersef7d42f2014-01-06 12:55:46 -0800457 // Short cuts to declaring_class_->dex_cache_ member for fast compiled code access.
Ian Rogers700a4022014-05-19 16:49:03 -0700458 HeapReference<ObjectArray<String>> dex_cache_strings_;
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800459
Ian Rogersef7d42f2014-01-06 12:55:46 -0800460 // Method dispatch from the interpreter invokes this pointer which may cause a bridge into
461 // compiled code.
462 uint64_t entry_point_from_interpreter_;
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800463
Ian Rogersef7d42f2014-01-06 12:55:46 -0800464 // Pointer to JNI function registered to this method, or a function to resolve the JNI function.
465 uint64_t entry_point_from_jni_;
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800466
Ian Rogersef7d42f2014-01-06 12:55:46 -0800467 // Method dispatch from portable compiled code invokes this pointer which may cause bridging into
468 // quick compiled code or the interpreter.
469 uint64_t entry_point_from_portable_compiled_code_;
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800470
Ian Rogersef7d42f2014-01-06 12:55:46 -0800471 // Method dispatch from quick compiled code invokes this pointer which may cause bridging into
472 // portable compiled code or the interpreter.
473 uint64_t entry_point_from_quick_compiled_code_;
Jeff Haoaa4a7932013-05-13 11:28:27 -0700474
Ian Rogersef7d42f2014-01-06 12:55:46 -0800475 // Pointer to a data structure created by the compiler and used by the garbage collector to
476 // determine which registers hold live references to objects within the heap. Keyed by native PC
477 // offsets for the quick compiler and dex PCs for the portable.
478 uint64_t gc_map_;
Jeff Hao16743632013-05-08 10:59:04 -0700479
Ian Rogersef7d42f2014-01-06 12:55:46 -0800480 // Access flags; low 16 bits are defined by spec.
481 uint32_t access_flags_;
482
483 /* Dex file fields. The defining dex file is available via declaring_class_->dex_cache_ */
484
485 // Offset to the CodeItem.
486 uint32_t dex_code_item_offset_;
487
488 // Index into method_ids of the dex file associated with this method.
489 uint32_t dex_method_index_;
490
491 /* End of dex file fields. */
492
493 // Entry within a dispatch table for this method. For static/direct methods the index is into
494 // the declaringClass.directMethods, for virtual methods the vtable and for interface methods the
495 // ifTable.
496 uint32_t method_index_;
497
Brian Carlstromea46f952013-07-30 01:26:50 -0700498 static Class* java_lang_reflect_ArtMethod_;
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800499
Mathieu Chartier02e25112013-08-14 16:14:24 -0700500 private:
Brian Carlstromea46f952013-07-30 01:26:50 -0700501 friend struct art::ArtMethodOffsets; // for verifying offset information
502 DISALLOW_IMPLICIT_CONSTRUCTORS(ArtMethod);
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800503};
504
Brian Carlstromea46f952013-07-30 01:26:50 -0700505class MANAGED ArtMethodClass : public Class {
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800506 private:
Brian Carlstromea46f952013-07-30 01:26:50 -0700507 DISALLOW_IMPLICIT_CONSTRUCTORS(ArtMethodClass);
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800508};
509
510} // namespace mirror
511} // namespace art
512
Brian Carlstromea46f952013-07-30 01:26:50 -0700513#endif // ART_RUNTIME_MIRROR_ART_METHOD_H_