blob: 71cc7af2e254b93a5057a6ed82db5b3f946f7086 [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"
23#include "locks.h"
24#include "modifiers.h"
25#include "object.h"
Mathieu Chartier83c8ee02014-01-28 14:50:23 -080026#include "object_callbacks.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;
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
40class StaticStorageBase;
41
Jeff Hao790ad902013-05-22 15:02:08 -070042typedef void (EntryPointFromInterpreter)(Thread* self, MethodHelper& mh,
43 const DexFile::CodeItem* code_item, ShadowFrame* shadow_frame, JValue* result);
Jeff Hao16743632013-05-08 10:59:04 -070044
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080045// C++ mirror of java.lang.reflect.Method and java.lang.reflect.Constructor
Brian Carlstromea46f952013-07-30 01:26:50 -070046class MANAGED ArtMethod : public Object {
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080047 public:
Ian Rogersef7d42f2014-01-06 12:55:46 -080048 Class* GetDeclaringClass() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080049
50 void SetDeclaringClass(Class *new_declaring_class) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
51
52 static MemberOffset DeclaringClassOffset() {
Brian Carlstromea46f952013-07-30 01:26:50 -070053 return MemberOffset(OFFSETOF_MEMBER(ArtMethod, declaring_class_));
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080054 }
55
Ian Rogersef7d42f2014-01-06 12:55:46 -080056 uint32_t GetAccessFlags() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
Jeff Hao5d917302013-02-27 17:57:33 -080057
Ian Rogersef7d42f2014-01-06 12:55:46 -080058 void SetAccessFlags(uint32_t new_access_flags) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +010059 // Not called within a transaction.
60 SetField32<false>(OFFSET_OF_OBJECT_MEMBER(ArtMethod, access_flags_), new_access_flags, false);
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080061 }
62
63 // Approximate what kind of method call would be used for this method.
Ian Rogersef7d42f2014-01-06 12:55:46 -080064 InvokeType GetInvokeType() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080065
66 // Returns true if the method is declared public.
Ian Rogersef7d42f2014-01-06 12:55:46 -080067 bool IsPublic() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080068 return (GetAccessFlags() & kAccPublic) != 0;
69 }
70
71 // Returns true if the method is declared private.
Ian Rogersef7d42f2014-01-06 12:55:46 -080072 bool IsPrivate() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080073 return (GetAccessFlags() & kAccPrivate) != 0;
74 }
75
76 // Returns true if the method is declared static.
Ian Rogersef7d42f2014-01-06 12:55:46 -080077 bool IsStatic() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080078 return (GetAccessFlags() & kAccStatic) != 0;
79 }
80
81 // Returns true if the method is a constructor.
Ian Rogersef7d42f2014-01-06 12:55:46 -080082 bool IsConstructor() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080083 return (GetAccessFlags() & kAccConstructor) != 0;
84 }
85
86 // Returns true if the method is static, private, or a constructor.
Ian Rogersef7d42f2014-01-06 12:55:46 -080087 bool IsDirect() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080088 return IsDirect(GetAccessFlags());
89 }
90
91 static bool IsDirect(uint32_t access_flags) {
92 return (access_flags & (kAccStatic | kAccPrivate | kAccConstructor)) != 0;
93 }
94
95 // Returns true if the method is declared synchronized.
Ian Rogersef7d42f2014-01-06 12:55:46 -080096 bool IsSynchronized() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080097 uint32_t synchonized = kAccSynchronized | kAccDeclaredSynchronized;
98 return (GetAccessFlags() & synchonized) != 0;
99 }
100
Ian Rogersef7d42f2014-01-06 12:55:46 -0800101 bool IsFinal() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800102 return (GetAccessFlags() & kAccFinal) != 0;
103 }
104
Ian Rogersef7d42f2014-01-06 12:55:46 -0800105 bool IsMiranda() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800106 return (GetAccessFlags() & kAccMiranda) != 0;
107 }
108
Ian Rogersef7d42f2014-01-06 12:55:46 -0800109 bool IsNative() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800110 return (GetAccessFlags() & kAccNative) != 0;
111 }
112
Ian Rogersef7d42f2014-01-06 12:55:46 -0800113 bool IsFastNative() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Ian Rogers16ce0922014-01-10 14:59:36 -0800114 uint32_t mask = kAccFastNative | kAccNative;
115 return (GetAccessFlags() & mask) == mask;
Ian Rogers1eb512d2013-10-18 15:42:20 -0700116 }
117
Ian Rogersef7d42f2014-01-06 12:55:46 -0800118 bool IsAbstract() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800119 return (GetAccessFlags() & kAccAbstract) != 0;
120 }
121
Ian Rogersef7d42f2014-01-06 12:55:46 -0800122 bool IsSynthetic() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800123 return (GetAccessFlags() & kAccSynthetic) != 0;
124 }
125
Ian Rogersef7d42f2014-01-06 12:55:46 -0800126 bool IsProxyMethod() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800127
Ian Rogersef7d42f2014-01-06 12:55:46 -0800128 bool IsPreverified() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Sebastien Hertz233ea8e2013-06-06 11:57:09 +0200129 return (GetAccessFlags() & kAccPreverified) != 0;
130 }
131
Ian Rogersef7d42f2014-01-06 12:55:46 -0800132 void SetPreverified() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
133 DCHECK(!IsPreverified());
Sebastien Hertz233ea8e2013-06-06 11:57:09 +0200134 SetAccessFlags(GetAccessFlags() | kAccPreverified);
135 }
136
Ian Rogersef7d42f2014-01-06 12:55:46 -0800137 bool IsPortableCompiled() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
138 return (GetAccessFlags() & kAccPortableCompiled) != 0;
139 }
140
141 void SetIsPortableCompiled() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
142 DCHECK(!IsPortableCompiled());
143 SetAccessFlags(GetAccessFlags() | kAccPortableCompiled);
144 }
145
146 void ClearIsPortableCompiled() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
147 DCHECK(IsPortableCompiled());
148 SetAccessFlags(GetAccessFlags() & ~kAccPortableCompiled);
149 }
150
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800151 bool CheckIncompatibleClassChange(InvokeType type) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
152
Ian Rogersef7d42f2014-01-06 12:55:46 -0800153 uint16_t GetMethodIndex() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800154
Ian Rogersef7d42f2014-01-06 12:55:46 -0800155 size_t GetVtableIndex() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800156 return GetMethodIndex();
157 }
158
Ian Rogersef7d42f2014-01-06 12:55:46 -0800159 void SetMethodIndex(uint16_t new_method_index) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100160 // Not called within a transaction.
161 SetField32<false>(OFFSET_OF_OBJECT_MEMBER(ArtMethod, method_index_), new_method_index, false);
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800162 }
163
164 static MemberOffset MethodIndexOffset() {
Brian Carlstromea46f952013-07-30 01:26:50 -0700165 return OFFSET_OF_OBJECT_MEMBER(ArtMethod, method_index_);
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800166 }
167
Ian Rogersef7d42f2014-01-06 12:55:46 -0800168 uint32_t GetCodeItemOffset() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
169 return GetField32(OFFSET_OF_OBJECT_MEMBER(ArtMethod, dex_code_item_offset_), false);
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800170 }
171
172 void SetCodeItemOffset(uint32_t new_code_off) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100173 // Not called within a transaction.
174 SetField32<false>(OFFSET_OF_OBJECT_MEMBER(ArtMethod, dex_code_item_offset_), new_code_off, false);
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800175 }
176
177 // Number of 32bit registers that would be required to hold all the arguments
178 static size_t NumArgRegisters(const StringPiece& shorty);
179
Ian Rogersef7d42f2014-01-06 12:55:46 -0800180 uint32_t GetDexMethodIndex() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800181
182 void SetDexMethodIndex(uint32_t new_idx) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100183 // Not called within a transaction.
184 SetField32<false>(OFFSET_OF_OBJECT_MEMBER(ArtMethod, dex_method_index_), new_idx, false);
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800185 }
186
Ian Rogersef7d42f2014-01-06 12:55:46 -0800187 ObjectArray<String>* GetDexCacheStrings() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800188 void SetDexCacheStrings(ObjectArray<String>* new_dex_cache_strings)
189 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
190
191 static MemberOffset DexCacheStringsOffset() {
Brian Carlstromea46f952013-07-30 01:26:50 -0700192 return OFFSET_OF_OBJECT_MEMBER(ArtMethod, dex_cache_strings_);
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800193 }
194
195 static MemberOffset DexCacheResolvedMethodsOffset() {
Brian Carlstromea46f952013-07-30 01:26:50 -0700196 return OFFSET_OF_OBJECT_MEMBER(ArtMethod, dex_cache_resolved_methods_);
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800197 }
198
199 static MemberOffset DexCacheResolvedTypesOffset() {
Brian Carlstromea46f952013-07-30 01:26:50 -0700200 return OFFSET_OF_OBJECT_MEMBER(ArtMethod, dex_cache_resolved_types_);
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800201 }
202
Ian Rogersef7d42f2014-01-06 12:55:46 -0800203 ObjectArray<ArtMethod>* GetDexCacheResolvedMethods() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
Brian Carlstromea46f952013-07-30 01:26:50 -0700204 void SetDexCacheResolvedMethods(ObjectArray<ArtMethod>* new_dex_cache_methods)
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800205 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
206
Ian Rogersef7d42f2014-01-06 12:55:46 -0800207 ObjectArray<Class>* GetDexCacheResolvedTypes() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800208 void SetDexCacheResolvedTypes(ObjectArray<Class>* new_dex_cache_types)
209 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
210
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800211 // Find the method that this method overrides
Ian Rogersef7d42f2014-01-06 12:55:46 -0800212 ArtMethod* FindOverriddenMethod() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800213
Ian Rogers0177e532014-02-11 16:30:46 -0800214 void Invoke(Thread* self, uint32_t* args, uint32_t args_size, JValue* result,
215 const char* shorty) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800216
Ian Rogersef7d42f2014-01-06 12:55:46 -0800217 EntryPointFromInterpreter* GetEntryPointFromInterpreter() {
218 return GetFieldPtr<EntryPointFromInterpreter*>(
219 OFFSET_OF_OBJECT_MEMBER(ArtMethod, entry_point_from_interpreter_), false);
Jeff Hao16743632013-05-08 10:59:04 -0700220 }
221
222 void SetEntryPointFromInterpreter(EntryPointFromInterpreter* entry_point_from_interpreter) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100223 SetFieldPtr<false>(OFFSET_OF_OBJECT_MEMBER(ArtMethod, entry_point_from_interpreter_),
224 entry_point_from_interpreter, false);
Jeff Hao16743632013-05-08 10:59:04 -0700225 }
226
Ian Rogersef7d42f2014-01-06 12:55:46 -0800227 static MemberOffset EntryPointFromPortableCompiledCodeOffset() {
228 return MemberOffset(OFFSETOF_MEMBER(ArtMethod, entry_point_from_portable_compiled_code_));
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800229 }
230
Ian Rogersef7d42f2014-01-06 12:55:46 -0800231 const void* GetEntryPointFromPortableCompiledCode() {
232 return GetFieldPtr<const void*>(EntryPointFromPortableCompiledCodeOffset(), false);
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800233 }
234
Ian Rogersef7d42f2014-01-06 12:55:46 -0800235 void SetEntryPointFromPortableCompiledCode(const void* entry_point_from_portable_compiled_code) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100236 SetFieldPtr<false>(EntryPointFromPortableCompiledCodeOffset(),
237 entry_point_from_portable_compiled_code, false);
Ian Rogersef7d42f2014-01-06 12:55:46 -0800238 }
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800239
Ian Rogersef7d42f2014-01-06 12:55:46 -0800240 static MemberOffset EntryPointFromQuickCompiledCodeOffset() {
241 return MemberOffset(OFFSETOF_MEMBER(ArtMethod, entry_point_from_quick_compiled_code_));
242 }
243
244 const void* GetEntryPointFromQuickCompiledCode() {
245 return GetFieldPtr<const void*>(EntryPointFromQuickCompiledCodeOffset(), false);
246 }
247
248 void SetEntryPointFromQuickCompiledCode(const void* entry_point_from_quick_compiled_code) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100249 SetFieldPtr<false>(EntryPointFromQuickCompiledCodeOffset(),
250 entry_point_from_quick_compiled_code, false);
Ian Rogersef7d42f2014-01-06 12:55:46 -0800251 }
252
253
254 uint32_t GetCodeSize() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
255
256 bool IsWithinQuickCode(uintptr_t pc) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
257 uintptr_t code = reinterpret_cast<uintptr_t>(GetEntryPointFromQuickCompiledCode());
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800258 if (code == 0) {
259 return pc == 0;
260 }
261 /*
262 * During a stack walk, a return PC may point to the end of the code + 1
263 * (in the case that the last instruction is a call that isn't expected to
264 * return. Thus, we check <= code + GetCodeSize().
265 */
266 return (code <= pc && pc <= code + GetCodeSize());
267 }
268
Ian Rogersef7d42f2014-01-06 12:55:46 -0800269 void AssertPcIsWithinQuickCode(uintptr_t pc) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800270
Ian Rogersef7d42f2014-01-06 12:55:46 -0800271 uint32_t GetQuickOatCodeOffset();
272 uint32_t GetPortableOatCodeOffset();
273 void SetQuickOatCodeOffset(uint32_t code_offset);
274 void SetPortableOatCodeOffset(uint32_t code_offset);
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800275
Ian Rogers1809a722013-08-09 22:05:32 -0700276 // Callers should wrap the uint8_t* in a MappingTable instance for convenient access.
Ian Rogersef7d42f2014-01-06 12:55:46 -0800277 const uint8_t* GetMappingTable() {
278 return GetFieldPtr<const uint8_t*>(OFFSET_OF_OBJECT_MEMBER(ArtMethod, quick_mapping_table_),
279 false);
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800280 }
281
Ian Rogers1809a722013-08-09 22:05:32 -0700282 void SetMappingTable(const uint8_t* mapping_table) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100283 SetFieldPtr<false>(OFFSET_OF_OBJECT_MEMBER(ArtMethod, quick_mapping_table_),
284 mapping_table, false);
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800285 }
286
Ian Rogersef7d42f2014-01-06 12:55:46 -0800287 uint32_t GetOatMappingTableOffset();
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800288
289 void SetOatMappingTableOffset(uint32_t mapping_table_offset);
290
Ian Rogers1809a722013-08-09 22:05:32 -0700291 // Callers should wrap the uint8_t* in a VmapTable instance for convenient access.
Ian Rogersef7d42f2014-01-06 12:55:46 -0800292 const uint8_t* GetVmapTable() {
293 return GetFieldPtr<const uint8_t*>(OFFSET_OF_OBJECT_MEMBER(ArtMethod, quick_vmap_table_),
294 false);
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800295 }
296
Ian Rogers1809a722013-08-09 22:05:32 -0700297 void SetVmapTable(const uint8_t* vmap_table) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100298 SetFieldPtr<false>(OFFSET_OF_OBJECT_MEMBER(ArtMethod, quick_vmap_table_), vmap_table, false);
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800299 }
300
Ian Rogersef7d42f2014-01-06 12:55:46 -0800301 uint32_t GetOatVmapTableOffset();
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800302
303 void SetOatVmapTableOffset(uint32_t vmap_table_offset);
304
Ian Rogersef7d42f2014-01-06 12:55:46 -0800305 const uint8_t* GetNativeGcMap() {
Brian Carlstromea46f952013-07-30 01:26:50 -0700306 return GetFieldPtr<uint8_t*>(OFFSET_OF_OBJECT_MEMBER(ArtMethod, gc_map_), false);
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800307 }
308 void SetNativeGcMap(const uint8_t* data) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100309 SetFieldPtr<false>(OFFSET_OF_OBJECT_MEMBER(ArtMethod, gc_map_), data, false);
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800310 }
311
312 // When building the oat need a convenient place to stuff the offset of the native GC map.
313 void SetOatNativeGcMapOffset(uint32_t gc_map_offset);
Ian Rogersef7d42f2014-01-06 12:55:46 -0800314 uint32_t GetOatNativeGcMapOffset();
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800315
Ian Rogersef7d42f2014-01-06 12:55:46 -0800316 size_t GetFrameSizeInBytes() {
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800317 DCHECK_EQ(sizeof(size_t), sizeof(uint32_t));
Ian Rogersef7d42f2014-01-06 12:55:46 -0800318 size_t result = GetField32(OFFSET_OF_OBJECT_MEMBER(ArtMethod, quick_frame_size_in_bytes_), false);
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800319 DCHECK_LE(static_cast<size_t>(kStackAlignment), result);
320 return result;
321 }
322
323 void SetFrameSizeInBytes(size_t new_frame_size_in_bytes) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100324 // Not called within a transaction.
325 SetField32<false>(OFFSET_OF_OBJECT_MEMBER(ArtMethod, quick_frame_size_in_bytes_),
326 new_frame_size_in_bytes, false);
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800327 }
328
Ian Rogersef7d42f2014-01-06 12:55:46 -0800329 size_t GetReturnPcOffsetInBytes() {
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800330 return GetFrameSizeInBytes() - kPointerSize;
331 }
332
Ian Rogersef7d42f2014-01-06 12:55:46 -0800333 size_t GetSirtOffsetInBytes() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Ian Rogers62d6c772013-02-27 08:32:07 -0800334 CHECK(IsNative());
335 return kPointerSize;
336 }
337
Ian Rogersef7d42f2014-01-06 12:55:46 -0800338 bool IsRegistered();
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800339
Ian Rogers1eb512d2013-10-18 15:42:20 -0700340 void RegisterNative(Thread* self, const void* native_method, bool is_fast)
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800341 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
342
343 void UnregisterNative(Thread* self) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
344
345 static MemberOffset NativeMethodOffset() {
Ian Rogersef7d42f2014-01-06 12:55:46 -0800346 return OFFSET_OF_OBJECT_MEMBER(ArtMethod, entry_point_from_jni_);
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800347 }
348
Ian Rogersef7d42f2014-01-06 12:55:46 -0800349 const void* GetNativeMethod() {
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800350 return reinterpret_cast<const void*>(GetField32(NativeMethodOffset(), false));
351 }
352
353 void SetNativeMethod(const void*);
354
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800355 static MemberOffset GetMethodIndexOffset() {
Brian Carlstromea46f952013-07-30 01:26:50 -0700356 return OFFSET_OF_OBJECT_MEMBER(ArtMethod, method_index_);
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800357 }
358
Ian Rogersef7d42f2014-01-06 12:55:46 -0800359 uint32_t GetCoreSpillMask() {
360 return GetField32(OFFSET_OF_OBJECT_MEMBER(ArtMethod, quick_core_spill_mask_), false);
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800361 }
362
363 void SetCoreSpillMask(uint32_t core_spill_mask) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100364 // Computed during compilation.
365 // Not called within a transaction.
366 SetField32<false>(OFFSET_OF_OBJECT_MEMBER(ArtMethod, quick_core_spill_mask_), core_spill_mask, false);
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800367 }
368
Ian Rogersef7d42f2014-01-06 12:55:46 -0800369 uint32_t GetFpSpillMask() {
370 return GetField32(OFFSET_OF_OBJECT_MEMBER(ArtMethod, quick_fp_spill_mask_), false);
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800371 }
372
373 void SetFpSpillMask(uint32_t fp_spill_mask) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100374 // Computed during compilation.
375 // Not called within a transaction.
376 SetField32<false>(OFFSET_OF_OBJECT_MEMBER(ArtMethod, quick_fp_spill_mask_), fp_spill_mask, false);
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800377 }
378
379 // Is this a CalleSaveMethod or ResolutionMethod and therefore doesn't adhere to normal
380 // conventions for a method of managed code. Returns false for Proxy methods.
Ian Rogersef7d42f2014-01-06 12:55:46 -0800381 bool IsRuntimeMethod() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800382
383 // Is this a hand crafted method used for something like describing callee saves?
Ian Rogersef7d42f2014-01-06 12:55:46 -0800384 bool IsCalleeSaveMethod() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800385
Ian Rogersef7d42f2014-01-06 12:55:46 -0800386 bool IsResolutionMethod() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800387
Ian Rogersef7d42f2014-01-06 12:55:46 -0800388 bool IsImtConflictMethod() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
Jeff Hao88474b42013-10-23 16:24:40 -0700389
Ian Rogersef7d42f2014-01-06 12:55:46 -0800390 uintptr_t NativePcOffset(const uintptr_t pc) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800391
392 // Converts a native PC to a dex PC.
Ian Rogersef7d42f2014-01-06 12:55:46 -0800393 uint32_t ToDexPc(const uintptr_t pc) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800394
395 // Converts a dex PC to a native PC.
Ian Rogersef7d42f2014-01-06 12:55:46 -0800396 uintptr_t ToNativePc(const uint32_t dex_pc) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800397
Ian Rogersc449aa82013-07-29 14:35:46 -0700398 // Find the catch block for the given exception type and dex_pc. When a catch block is found,
399 // indicates whether the found catch block is responsible for clearing the exception or whether
400 // a move-exception instruction is present.
Ian Rogersef7d42f2014-01-06 12:55:46 -0800401 uint32_t FindCatchBlock(Class* exception_type, uint32_t dex_pc, bool* has_no_move_exception)
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800402 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
403
Brian Carlstromea46f952013-07-30 01:26:50 -0700404 static void SetClass(Class* java_lang_reflect_ArtMethod);
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800405
Brian Carlstromea46f952013-07-30 01:26:50 -0700406 static Class* GetJavaLangReflectArtMethod() {
407 return java_lang_reflect_ArtMethod_;
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800408 }
409
Brian Carlstromea46f952013-07-30 01:26:50 -0700410 static void ResetClass();
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800411
Mathieu Chartier83c8ee02014-01-28 14:50:23 -0800412 static void VisitRoots(RootCallback* callback, void* arg)
Mathieu Chartierc528dba2013-11-26 12:00:11 -0800413 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
414
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800415 protected:
416 // Field order required by test "ValidateFieldOrderOfJavaCppUnionClasses".
Ian Rogersef7d42f2014-01-06 12:55:46 -0800417 // The class we are a part of.
418 HeapReference<Class> declaring_class_;
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800419
Ian Rogersef7d42f2014-01-06 12:55:46 -0800420 // Short cuts to declaring_class_->dex_cache_ member for fast compiled code access.
421 HeapReference<ObjectArray<ArtMethod> > dex_cache_resolved_methods_;
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800422
Ian Rogersef7d42f2014-01-06 12:55:46 -0800423 // Short cuts to declaring_class_->dex_cache_ member for fast compiled code access.
424 HeapReference<ObjectArray<Class> > dex_cache_resolved_types_;
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800425
Ian Rogersef7d42f2014-01-06 12:55:46 -0800426 // Short cuts to declaring_class_->dex_cache_ member for fast compiled code access.
427 HeapReference<ObjectArray<String> > dex_cache_strings_;
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800428
Ian Rogersef7d42f2014-01-06 12:55:46 -0800429 // Method dispatch from the interpreter invokes this pointer which may cause a bridge into
430 // compiled code.
431 uint64_t entry_point_from_interpreter_;
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800432
Ian Rogersef7d42f2014-01-06 12:55:46 -0800433 // Pointer to JNI function registered to this method, or a function to resolve the JNI function.
434 uint64_t entry_point_from_jni_;
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800435
Ian Rogersef7d42f2014-01-06 12:55:46 -0800436 // Method dispatch from portable compiled code invokes this pointer which may cause bridging into
437 // quick compiled code or the interpreter.
438 uint64_t entry_point_from_portable_compiled_code_;
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800439
Ian Rogersef7d42f2014-01-06 12:55:46 -0800440 // Method dispatch from quick compiled code invokes this pointer which may cause bridging into
441 // portable compiled code or the interpreter.
442 uint64_t entry_point_from_quick_compiled_code_;
Jeff Haoaa4a7932013-05-13 11:28:27 -0700443
Ian Rogersef7d42f2014-01-06 12:55:46 -0800444 // Pointer to a data structure created by the compiler and used by the garbage collector to
445 // determine which registers hold live references to objects within the heap. Keyed by native PC
446 // offsets for the quick compiler and dex PCs for the portable.
447 uint64_t gc_map_;
Jeff Hao16743632013-05-08 10:59:04 -0700448
Ian Rogersef7d42f2014-01-06 12:55:46 -0800449 // --- Quick compiler meta-data. ---
450 // TODO: merge and place in native heap, such as done with the code size.
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800451
Ian Rogersef7d42f2014-01-06 12:55:46 -0800452 // Pointer to a data structure created by the quick compiler to map between dex PCs and native
453 // PCs, and vice-versa.
454 uint64_t quick_mapping_table_;
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800455
456 // When a register is promoted into a register, the spill mask holds which registers hold dex
457 // registers. The first promoted register's corresponding dex register is vmap_table_[1], the Nth
458 // is vmap_table_[N]. vmap_table_[0] holds the length of the table.
Ian Rogersef7d42f2014-01-06 12:55:46 -0800459 uint64_t quick_vmap_table_;
460
461 // --- End of quick compiler meta-data. ---
462
463 // Access flags; low 16 bits are defined by spec.
464 uint32_t access_flags_;
465
466 /* Dex file fields. The defining dex file is available via declaring_class_->dex_cache_ */
467
468 // Offset to the CodeItem.
469 uint32_t dex_code_item_offset_;
470
471 // Index into method_ids of the dex file associated with this method.
472 uint32_t dex_method_index_;
473
474 /* End of dex file fields. */
475
476 // Entry within a dispatch table for this method. For static/direct methods the index is into
477 // the declaringClass.directMethods, for virtual methods the vtable and for interface methods the
478 // ifTable.
479 uint32_t method_index_;
480
481 // --- Quick compiler meta-data. ---
482 // TODO: merge and place in native heap, such as done with the code size.
483
484 // Bit map of spilled machine registers.
485 uint32_t quick_core_spill_mask_;
486
487 // Bit map of spilled floating point machine registers.
488 uint32_t quick_fp_spill_mask_;
489
490 // Fixed frame size for this method when executed.
491 uint32_t quick_frame_size_in_bytes_;
492
493 // --- End of quick compiler meta-data. ---
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800494
Brian Carlstromea46f952013-07-30 01:26:50 -0700495 static Class* java_lang_reflect_ArtMethod_;
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800496
Mathieu Chartier02e25112013-08-14 16:14:24 -0700497 private:
Brian Carlstromea46f952013-07-30 01:26:50 -0700498 friend struct art::ArtMethodOffsets; // for verifying offset information
499 DISALLOW_IMPLICIT_CONSTRUCTORS(ArtMethod);
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800500};
501
Brian Carlstromea46f952013-07-30 01:26:50 -0700502class MANAGED ArtMethodClass : public Class {
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800503 private:
Brian Carlstromea46f952013-07-30 01:26:50 -0700504 DISALLOW_IMPLICIT_CONSTRUCTORS(ArtMethodClass);
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800505};
506
507} // namespace mirror
508} // namespace art
509
Brian Carlstromea46f952013-07-30 01:26:50 -0700510#endif // ART_RUNTIME_MIRROR_ART_METHOD_H_