1/*
2 * Copyright (C) 2011 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#ifndef ART_RUNTIME_ART_METHOD_H_
18#define ART_RUNTIME_ART_METHOD_H_
19
20#include "dex_file.h"
21#include "gc_root.h"
22#include "invoke_type.h"
23#include "method_reference.h"
24#include "modifiers.h"
25#include "mirror/object.h"
26#include "object_callbacks.h"
27#include "quick/quick_method_frame_info.h"
28#include "read_barrier_option.h"
29#include "stack.h"
30#include "stack_map.h"
31#include "utils.h"
32
33namespace art {
34
35union JValue;
36class ScopedObjectAccessAlreadyRunnable;
37class StringPiece;
38class ShadowFrame;
39
40namespace mirror {
41class Array;
42class Class;
43class PointerArray;
44}  // namespace mirror
45
46typedef void (EntryPointFromInterpreter)(Thread* self, const DexFile::CodeItem* code_item,
47                                         ShadowFrame* shadow_frame, JValue* result);
48
49class ArtMethod FINAL {
50 public:
51  ArtMethod() : access_flags_(0), dex_code_item_offset_(0), dex_method_index_(0),
52      method_index_(0) { }
53
54  ArtMethod(const ArtMethod& src, size_t image_pointer_size) {
55    CopyFrom(&src, image_pointer_size);
56  }
57
58  static ArtMethod* FromReflectedMethod(const ScopedObjectAccessAlreadyRunnable& soa,
59                                        jobject jlr_method)
60      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
61
62  ALWAYS_INLINE mirror::Class* GetDeclaringClass() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
63
64  ALWAYS_INLINE mirror::Class* GetDeclaringClassNoBarrier()
65      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
66
67  ALWAYS_INLINE mirror::Class* GetDeclaringClassUnchecked()
68      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
69
70  void SetDeclaringClass(mirror::Class *new_declaring_class)
71      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
72
73  static MemberOffset DeclaringClassOffset() {
74    return MemberOffset(OFFSETOF_MEMBER(ArtMethod, declaring_class_));
75  }
76
77  ALWAYS_INLINE uint32_t GetAccessFlags() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
78
79  void SetAccessFlags(uint32_t new_access_flags) {
80    // Not called within a transaction.
81    access_flags_ = new_access_flags;
82  }
83
84  // Approximate what kind of method call would be used for this method.
85  InvokeType GetInvokeType() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
86
87  // Returns true if the method is declared public.
88  bool IsPublic() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
89    return (GetAccessFlags() & kAccPublic) != 0;
90  }
91
92  // Returns true if the method is declared private.
93  bool IsPrivate() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
94    return (GetAccessFlags() & kAccPrivate) != 0;
95  }
96
97  // Returns true if the method is declared static.
98  bool IsStatic() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
99    return (GetAccessFlags() & kAccStatic) != 0;
100  }
101
102  // Returns true if the method is a constructor.
103  bool IsConstructor() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
104    return (GetAccessFlags() & kAccConstructor) != 0;
105  }
106
107  // Returns true if the method is a class initializer.
108  bool IsClassInitializer() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
109    return IsConstructor() && IsStatic();
110  }
111
112  // Returns true if the method is static, private, or a constructor.
113  bool IsDirect() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
114    return IsDirect(GetAccessFlags());
115  }
116
117  static bool IsDirect(uint32_t access_flags) {
118    return (access_flags & (kAccStatic | kAccPrivate | kAccConstructor)) != 0;
119  }
120
121  // Returns true if the method is declared synchronized.
122  bool IsSynchronized() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
123    uint32_t synchonized = kAccSynchronized | kAccDeclaredSynchronized;
124    return (GetAccessFlags() & synchonized) != 0;
125  }
126
127  bool IsFinal() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
128    return (GetAccessFlags() & kAccFinal) != 0;
129  }
130
131  bool IsMiranda() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
132    return (GetAccessFlags() & kAccMiranda) != 0;
133  }
134
135  bool IsNative() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
136    return (GetAccessFlags() & kAccNative) != 0;
137  }
138
139  bool ShouldNotInline() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
140    return (GetAccessFlags() & kAccDontInline) != 0;
141  }
142
143  void SetShouldNotInline() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
144    SetAccessFlags(GetAccessFlags() | kAccDontInline);
145  }
146
147  bool IsFastNative() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
148    uint32_t mask = kAccFastNative | kAccNative;
149    return (GetAccessFlags() & mask) == mask;
150  }
151
152  bool IsAbstract() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
153    return (GetAccessFlags() & kAccAbstract) != 0;
154  }
155
156  bool IsSynthetic() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
157    return (GetAccessFlags() & kAccSynthetic) != 0;
158  }
159
160  bool IsProxyMethod() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
161
162  bool IsPreverified() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
163    return (GetAccessFlags() & kAccPreverified) != 0;
164  }
165
166  void SetPreverified() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
167    DCHECK(!IsPreverified());
168    SetAccessFlags(GetAccessFlags() | kAccPreverified);
169  }
170
171  bool IsOptimized(size_t pointer_size) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
172    // Temporary solution for detecting if a method has been optimized: the compiler
173    // does not create a GC map. Instead, the vmap table contains the stack map
174    // (as in stack_map.h).
175    return !IsNative()
176        && GetEntryPointFromQuickCompiledCodePtrSize(pointer_size) != nullptr
177        && GetQuickOatCodePointer(pointer_size) != nullptr
178        && GetNativeGcMap(pointer_size) == nullptr;
179  }
180
181  bool CheckIncompatibleClassChange(InvokeType type) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
182
183  uint16_t GetMethodIndex() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
184
185  // Doesn't do erroneous / unresolved class checks.
186  uint16_t GetMethodIndexDuringLinking() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
187
188  size_t GetVtableIndex() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
189    return GetMethodIndex();
190  }
191
192  void SetMethodIndex(uint16_t new_method_index) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
193    // Not called within a transaction.
194    method_index_ = new_method_index;
195  }
196
197  static MemberOffset DexMethodIndexOffset() {
198    return OFFSET_OF_OBJECT_MEMBER(ArtMethod, dex_method_index_);
199  }
200
201  static MemberOffset MethodIndexOffset() {
202    return OFFSET_OF_OBJECT_MEMBER(ArtMethod, method_index_);
203  }
204
205  uint32_t GetCodeItemOffset() {
206    return dex_code_item_offset_;
207  }
208
209  void SetCodeItemOffset(uint32_t new_code_off) {
210    // Not called within a transaction.
211    dex_code_item_offset_ = new_code_off;
212  }
213
214  // Number of 32bit registers that would be required to hold all the arguments
215  static size_t NumArgRegisters(const StringPiece& shorty);
216
217  ALWAYS_INLINE uint32_t GetDexMethodIndex() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
218
219  void SetDexMethodIndex(uint32_t new_idx) {
220    // Not called within a transaction.
221    dex_method_index_ = new_idx;
222  }
223
224  static MemberOffset DexCacheResolvedMethodsOffset() {
225    return OFFSET_OF_OBJECT_MEMBER(ArtMethod, dex_cache_resolved_methods_);
226  }
227
228  static MemberOffset DexCacheResolvedTypesOffset() {
229    return OFFSET_OF_OBJECT_MEMBER(ArtMethod, dex_cache_resolved_types_);
230  }
231
232  ALWAYS_INLINE mirror::PointerArray* GetDexCacheResolvedMethods()
233      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
234  ALWAYS_INLINE ArtMethod* GetDexCacheResolvedMethod(uint16_t method_idx, size_t ptr_size)
235      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
236  ALWAYS_INLINE void SetDexCacheResolvedMethod(uint16_t method_idx, ArtMethod* new_method,
237                                               size_t ptr_size)
238      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
239  ALWAYS_INLINE void SetDexCacheResolvedMethods(mirror::PointerArray* new_dex_cache_methods)
240      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
241  bool HasDexCacheResolvedMethods() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
242  bool HasSameDexCacheResolvedMethods(ArtMethod* other)
243      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
244  bool HasSameDexCacheResolvedMethods(mirror::PointerArray* other_cache)
245      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
246
247  template <bool kWithCheck = true>
248  mirror::Class* GetDexCacheResolvedType(uint32_t type_idx)
249      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
250  void SetDexCacheResolvedTypes(mirror::ObjectArray<mirror::Class>* new_dex_cache_types)
251      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
252  bool HasDexCacheResolvedTypes() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
253  bool HasSameDexCacheResolvedTypes(ArtMethod* other) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
254  bool HasSameDexCacheResolvedTypes(mirror::ObjectArray<mirror::Class>* other_cache)
255      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
256
257  // Get the Class* from the type index into this method's dex cache.
258  mirror::Class* GetClassFromTypeIndex(uint16_t type_idx, bool resolve)
259      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
260
261  // Find the method that this method overrides.
262  ArtMethod* FindOverriddenMethod(size_t pointer_size) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
263
264  // Find the method index for this method within other_dexfile. If this method isn't present then
265  // return DexFile::kDexNoIndex. The name_and_signature_idx MUST refer to a MethodId with the same
266  // name and signature in the other_dexfile, such as the method index used to resolve this method
267  // in the other_dexfile.
268  uint32_t FindDexMethodIndexInOtherDexFile(const DexFile& other_dexfile,
269                                            uint32_t name_and_signature_idx)
270      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
271
272  void Invoke(Thread* self, uint32_t* args, uint32_t args_size, JValue* result, const char* shorty)
273      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
274
275  EntryPointFromInterpreter* GetEntryPointFromInterpreter() {
276    return GetEntryPointFromInterpreterPtrSize(sizeof(void*));
277  }
278  EntryPointFromInterpreter* GetEntryPointFromInterpreterPtrSize(size_t pointer_size) {
279    return GetEntryPoint<EntryPointFromInterpreter*>(
280        EntryPointFromInterpreterOffset(pointer_size), pointer_size);
281  }
282
283  void SetEntryPointFromInterpreter(EntryPointFromInterpreter* entry_point_from_interpreter) {
284    SetEntryPointFromInterpreterPtrSize(entry_point_from_interpreter, sizeof(void*));
285  }
286  void SetEntryPointFromInterpreterPtrSize(EntryPointFromInterpreter* entry_point_from_interpreter,
287                                           size_t pointer_size) {
288    SetEntryPoint(EntryPointFromInterpreterOffset(pointer_size), entry_point_from_interpreter,
289                  pointer_size);
290  }
291
292  const void* GetEntryPointFromQuickCompiledCode() {
293    return GetEntryPointFromQuickCompiledCodePtrSize(sizeof(void*));
294  }
295  ALWAYS_INLINE const void* GetEntryPointFromQuickCompiledCodePtrSize(size_t pointer_size) {
296    return GetEntryPoint<const void*>(
297        EntryPointFromQuickCompiledCodeOffset(pointer_size), pointer_size);
298  }
299
300  void SetEntryPointFromQuickCompiledCode(const void* entry_point_from_quick_compiled_code) {
301    SetEntryPointFromQuickCompiledCodePtrSize(entry_point_from_quick_compiled_code,
302                                              sizeof(void*));
303  }
304  ALWAYS_INLINE void SetEntryPointFromQuickCompiledCodePtrSize(
305      const void* entry_point_from_quick_compiled_code, size_t pointer_size) {
306    SetEntryPoint(EntryPointFromQuickCompiledCodeOffset(pointer_size),
307                  entry_point_from_quick_compiled_code, pointer_size);
308  }
309
310  uint32_t GetCodeSize() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
311
312  // Check whether the given PC is within the quick compiled code associated with this method's
313  // quick entrypoint. This code isn't robust for instrumentation, etc. and is only used for
314  // debug purposes.
315  bool PcIsWithinQuickCode(uintptr_t pc) {
316    return PcIsWithinQuickCode(
317        reinterpret_cast<uintptr_t>(GetEntryPointFromQuickCompiledCode()), pc);
318  }
319
320  void AssertPcIsWithinQuickCode(uintptr_t pc) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
321
322  // Returns true if the entrypoint points to the interpreter, as
323  // opposed to the compiled code, that is, this method will be
324  // interpretered on invocation.
325  bool IsEntrypointInterpreter() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
326
327  uint32_t GetQuickOatCodeOffset();
328  void SetQuickOatCodeOffset(uint32_t code_offset);
329
330  ALWAYS_INLINE static const void* EntryPointToCodePointer(const void* entry_point) {
331    uintptr_t code = reinterpret_cast<uintptr_t>(entry_point);
332    // TODO: Make this Thumb2 specific. It is benign on other architectures as code is always at
333    //       least 2 byte aligned.
334    code &= ~0x1;
335    return reinterpret_cast<const void*>(code);
336  }
337
338  // Actual entry point pointer to compiled oat code or null.
339  const void* GetQuickOatEntryPoint(size_t pointer_size)
340      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
341  // Actual pointer to compiled oat code or null.
342  const void* GetQuickOatCodePointer(size_t pointer_size)
343      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
344    return EntryPointToCodePointer(GetQuickOatEntryPoint(pointer_size));
345  }
346
347  // Callers should wrap the uint8_t* in a MappingTable instance for convenient access.
348  const uint8_t* GetMappingTable(size_t pointer_size)
349      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
350  const uint8_t* GetMappingTable(const void* code_pointer, size_t pointer_size)
351      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
352
353  // Callers should wrap the uint8_t* in a VmapTable instance for convenient access.
354  const uint8_t* GetVmapTable(size_t pointer_size)
355      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
356  const uint8_t* GetVmapTable(const void* code_pointer, size_t pointer_size)
357      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
358
359  CodeInfo GetOptimizedCodeInfo() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
360
361  // Callers should wrap the uint8_t* in a GcMap instance for convenient access.
362  const uint8_t* GetNativeGcMap(size_t pointer_size)
363      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
364  const uint8_t* GetNativeGcMap(const void* code_pointer, size_t pointer_size)
365      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
366
367  template <bool kCheckFrameSize = true>
368  uint32_t GetFrameSizeInBytes() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
369    uint32_t result = GetQuickFrameInfo().FrameSizeInBytes();
370    if (kCheckFrameSize) {
371      DCHECK_LE(static_cast<size_t>(kStackAlignment), result);
372    }
373    return result;
374  }
375
376  QuickMethodFrameInfo GetQuickFrameInfo() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
377  QuickMethodFrameInfo GetQuickFrameInfo(const void* code_pointer)
378      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
379
380  FrameOffset GetReturnPcOffset() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
381    return GetReturnPcOffset(GetFrameSizeInBytes());
382  }
383
384  FrameOffset GetReturnPcOffset(uint32_t frame_size_in_bytes)
385      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
386    DCHECK_EQ(frame_size_in_bytes, GetFrameSizeInBytes());
387    return FrameOffset(frame_size_in_bytes - sizeof(void*));
388  }
389
390  FrameOffset GetHandleScopeOffset() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
391    constexpr size_t handle_scope_offset = sizeof(ArtMethod*);
392    DCHECK_LT(handle_scope_offset, GetFrameSizeInBytes());
393    return FrameOffset(handle_scope_offset);
394  }
395
396  void RegisterNative(const void* native_method, bool is_fast)
397      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
398
399  void UnregisterNative() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
400
401  static MemberOffset EntryPointFromInterpreterOffset(size_t pointer_size) {
402    return MemberOffset(PtrSizedFieldsOffset(pointer_size) + OFFSETOF_MEMBER(
403        PtrSizedFields, entry_point_from_interpreter_) / sizeof(void*) * pointer_size);
404  }
405
406  static MemberOffset EntryPointFromJniOffset(size_t pointer_size) {
407    return MemberOffset(PtrSizedFieldsOffset(pointer_size) + OFFSETOF_MEMBER(
408        PtrSizedFields, entry_point_from_jni_) / sizeof(void*) * pointer_size);
409  }
410
411  static MemberOffset EntryPointFromQuickCompiledCodeOffset(size_t pointer_size) {
412    return MemberOffset(PtrSizedFieldsOffset(pointer_size) + OFFSETOF_MEMBER(
413        PtrSizedFields, entry_point_from_quick_compiled_code_) / sizeof(void*) * pointer_size);
414  }
415
416  void* GetEntryPointFromJni() {
417    return GetEntryPointFromJniPtrSize(sizeof(void*));
418  }
419  ALWAYS_INLINE void* GetEntryPointFromJniPtrSize(size_t pointer_size) {
420    return GetEntryPoint<void*>(EntryPointFromJniOffset(pointer_size), pointer_size);
421  }
422
423  void SetEntryPointFromJni(const void* entrypoint) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
424    SetEntryPointFromJniPtrSize(entrypoint, sizeof(void*));
425  }
426  ALWAYS_INLINE void SetEntryPointFromJniPtrSize(const void* entrypoint, size_t pointer_size) {
427    SetEntryPoint(EntryPointFromJniOffset(pointer_size), entrypoint, pointer_size);
428  }
429
430  // Is this a CalleSaveMethod or ResolutionMethod and therefore doesn't adhere to normal
431  // conventions for a method of managed code. Returns false for Proxy methods.
432  ALWAYS_INLINE bool IsRuntimeMethod();
433
434  // Is this a hand crafted method used for something like describing callee saves?
435  bool IsCalleeSaveMethod() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
436
437  bool IsResolutionMethod() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
438
439  bool IsImtConflictMethod() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
440
441  bool IsImtUnimplementedMethod() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
442
443  uintptr_t NativeQuickPcOffset(const uintptr_t pc) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
444#ifdef NDEBUG
445  uintptr_t NativeQuickPcOffset(const uintptr_t pc, const void* quick_entry_point)
446      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
447    return pc - reinterpret_cast<uintptr_t>(quick_entry_point);
448  }
449#else
450  uintptr_t NativeQuickPcOffset(const uintptr_t pc, const void* quick_entry_point)
451      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
452#endif
453
454  // Converts a native PC to a dex PC.
455  uint32_t ToDexPc(const uintptr_t pc, bool abort_on_failure = true)
456      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
457
458  // Converts a dex PC to a native PC.
459  uintptr_t ToNativeQuickPc(const uint32_t dex_pc, bool abort_on_failure = true)
460      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
461
462  MethodReference ToMethodReference() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
463    return MethodReference(GetDexFile(), GetDexMethodIndex());
464  }
465
466  // Find the catch block for the given exception type and dex_pc. When a catch block is found,
467  // indicates whether the found catch block is responsible for clearing the exception or whether
468  // a move-exception instruction is present.
469  uint32_t FindCatchBlock(Handle<mirror::Class> exception_type, uint32_t dex_pc,
470                          bool* has_no_move_exception)
471      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
472
473  template<typename RootVisitorType>
474  void VisitRoots(RootVisitorType& visitor) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
475
476  const DexFile* GetDexFile() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
477
478  const char* GetDeclaringClassDescriptor() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
479
480  const char* GetShorty() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
481    uint32_t unused_length;
482    return GetShorty(&unused_length);
483  }
484
485  const char* GetShorty(uint32_t* out_length) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
486
487  const Signature GetSignature() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
488
489  ALWAYS_INLINE const char* GetName() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
490
491  mirror::String* GetNameAsString(Thread* self) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
492
493  const DexFile::CodeItem* GetCodeItem() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
494
495  bool IsResolvedTypeIdx(uint16_t type_idx) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
496
497  int32_t GetLineNumFromDexPC(uint32_t dex_pc) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
498
499  const DexFile::ProtoId& GetPrototype() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
500
501  const DexFile::TypeList* GetParameterTypeList() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
502
503  const char* GetDeclaringClassSourceFile() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
504
505  uint16_t GetClassDefIndex() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
506
507  const DexFile::ClassDef& GetClassDef() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
508
509  const char* GetReturnTypeDescriptor() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
510
511  const char* GetTypeDescriptorFromTypeIdx(uint16_t type_idx)
512      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
513
514  // May cause thread suspension due to GetClassFromTypeIdx calling ResolveType this caused a large
515  // number of bugs at call sites.
516  mirror::Class* GetReturnType(bool resolve = true) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
517
518  mirror::ClassLoader* GetClassLoader() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
519
520  mirror::DexCache* GetDexCache() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
521
522  ALWAYS_INLINE ArtMethod* GetInterfaceMethodIfProxy(size_t pointer_size)
523      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
524
525  // May cause thread suspension due to class resolution.
526  bool EqualParameters(Handle<mirror::ObjectArray<mirror::Class>> params)
527      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
528
529  // Size of an instance of this object.
530  static size_t ObjectSize(size_t pointer_size) {
531    return RoundUp(OFFSETOF_MEMBER(ArtMethod, ptr_sized_fields_), pointer_size) +
532        (sizeof(PtrSizedFields) / sizeof(void*)) * pointer_size;
533  }
534
535  void CopyFrom(const ArtMethod* src, size_t image_pointer_size)
536      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
537
538  ALWAYS_INLINE mirror::ObjectArray<mirror::Class>* GetDexCacheResolvedTypes()
539      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
540
541 protected:
542  // Field order required by test "ValidateFieldOrderOfJavaCppUnionClasses".
543  // The class we are a part of.
544  GcRoot<mirror::Class> declaring_class_;
545
546  // Short cuts to declaring_class_->dex_cache_ member for fast compiled code access.
547  GcRoot<mirror::PointerArray> dex_cache_resolved_methods_;
548
549  // Short cuts to declaring_class_->dex_cache_ member for fast compiled code access.
550  GcRoot<mirror::ObjectArray<mirror::Class>> dex_cache_resolved_types_;
551
552  // Access flags; low 16 bits are defined by spec.
553  uint32_t access_flags_;
554
555  /* Dex file fields. The defining dex file is available via declaring_class_->dex_cache_ */
556
557  // Offset to the CodeItem.
558  uint32_t dex_code_item_offset_;
559
560  // Index into method_ids of the dex file associated with this method.
561  uint32_t dex_method_index_;
562
563  /* End of dex file fields. */
564
565  // Entry within a dispatch table for this method. For static/direct methods the index is into
566  // the declaringClass.directMethods, for virtual methods the vtable and for interface methods the
567  // ifTable.
568  uint32_t method_index_;
569
570  // Fake padding field gets inserted here.
571
572  // Must be the last fields in the method.
573  // PACKED(4) is necessary for the correctness of
574  // RoundUp(OFFSETOF_MEMBER(ArtMethod, ptr_sized_fields_), pointer_size).
575  struct PACKED(4) PtrSizedFields {
576    // Method dispatch from the interpreter invokes this pointer which may cause a bridge into
577    // compiled code.
578    void* entry_point_from_interpreter_;
579
580    // Pointer to JNI function registered to this method, or a function to resolve the JNI function.
581    void* entry_point_from_jni_;
582
583    // Method dispatch from quick compiled code invokes this pointer which may cause bridging into
584    // the interpreter.
585    void* entry_point_from_quick_compiled_code_;
586  } ptr_sized_fields_;
587
588 private:
589  static size_t PtrSizedFieldsOffset(size_t pointer_size) {
590    // Round up to pointer size for padding field.
591    return RoundUp(OFFSETOF_MEMBER(ArtMethod, ptr_sized_fields_), pointer_size);
592  }
593
594  template<typename T>
595  ALWAYS_INLINE T GetEntryPoint(MemberOffset offset, size_t pointer_size) const {
596    DCHECK(ValidPointerSize(pointer_size)) << pointer_size;
597    const auto addr = reinterpret_cast<uintptr_t>(this) + offset.Uint32Value();
598    if (pointer_size == sizeof(uint32_t)) {
599      return reinterpret_cast<T>(*reinterpret_cast<const uint32_t*>(addr));
600    } else {
601      auto v = *reinterpret_cast<const uint64_t*>(addr);
602      DCHECK_EQ(reinterpret_cast<uint64_t>(reinterpret_cast<T>(v)), v) << "Conversion lost bits";
603      return reinterpret_cast<T>(v);
604    }
605  }
606
607  template<typename T>
608  ALWAYS_INLINE void SetEntryPoint(MemberOffset offset, T new_value, size_t pointer_size) {
609    DCHECK(ValidPointerSize(pointer_size)) << pointer_size;
610    const auto addr = reinterpret_cast<uintptr_t>(this) + offset.Uint32Value();
611    if (pointer_size == sizeof(uint32_t)) {
612      uintptr_t ptr = reinterpret_cast<uintptr_t>(new_value);
613      DCHECK_EQ(static_cast<uint32_t>(ptr), ptr) << "Conversion lost bits";
614      *reinterpret_cast<uint32_t*>(addr) = static_cast<uint32_t>(ptr);
615    } else {
616      *reinterpret_cast<uint64_t*>(addr) = reinterpret_cast<uintptr_t>(new_value);
617    }
618  }
619
620  // Code points to the start of the quick code.
621  static uint32_t GetCodeSize(const void* code);
622
623  static bool PcIsWithinQuickCode(uintptr_t code, uintptr_t pc) {
624    if (code == 0) {
625      return pc == 0;
626    }
627    /*
628     * During a stack walk, a return PC may point past-the-end of the code
629     * in the case that the last instruction is a call that isn't expected to
630     * return.  Thus, we check <= code + GetCodeSize().
631     *
632     * NOTE: For Thumb both pc and code are offset by 1 indicating the Thumb state.
633     */
634    return code <= pc && pc <= code + GetCodeSize(
635        EntryPointToCodePointer(reinterpret_cast<const void*>(code)));
636  }
637
638  DISALLOW_COPY_AND_ASSIGN(ArtMethod);  // Need to use CopyFrom to deal with 32 vs 64 bits.
639};
640
641}  // namespace art
642
643#endif  // ART_RUNTIME_ART_METHOD_H_
644