xref: /aosp_15_r20/art/runtime/art_method.h (revision 795d594fd825385562da6b089ea9b2033f3abf5a)
1*795d594fSAndroid Build Coastguard Worker /*
2*795d594fSAndroid Build Coastguard Worker  * Copyright (C) 2011 The Android Open Source Project
3*795d594fSAndroid Build Coastguard Worker  *
4*795d594fSAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
5*795d594fSAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
6*795d594fSAndroid Build Coastguard Worker  * You may obtain a copy of the License at
7*795d594fSAndroid Build Coastguard Worker  *
8*795d594fSAndroid Build Coastguard Worker  *      http://www.apache.org/licenses/LICENSE-2.0
9*795d594fSAndroid Build Coastguard Worker  *
10*795d594fSAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
11*795d594fSAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
12*795d594fSAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*795d594fSAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
14*795d594fSAndroid Build Coastguard Worker  * limitations under the License.
15*795d594fSAndroid Build Coastguard Worker  */
16*795d594fSAndroid Build Coastguard Worker 
17*795d594fSAndroid Build Coastguard Worker #ifndef ART_RUNTIME_ART_METHOD_H_
18*795d594fSAndroid Build Coastguard Worker #define ART_RUNTIME_ART_METHOD_H_
19*795d594fSAndroid Build Coastguard Worker 
20*795d594fSAndroid Build Coastguard Worker #include <cstddef>
21*795d594fSAndroid Build Coastguard Worker #include <limits>
22*795d594fSAndroid Build Coastguard Worker 
23*795d594fSAndroid Build Coastguard Worker #include <android-base/logging.h>
24*795d594fSAndroid Build Coastguard Worker #include <jni.h>
25*795d594fSAndroid Build Coastguard Worker 
26*795d594fSAndroid Build Coastguard Worker #include "base/array_ref.h"
27*795d594fSAndroid Build Coastguard Worker #include "base/bit_utils.h"
28*795d594fSAndroid Build Coastguard Worker #include "base/casts.h"
29*795d594fSAndroid Build Coastguard Worker #include "base/logging.h"
30*795d594fSAndroid Build Coastguard Worker #include "base/macros.h"
31*795d594fSAndroid Build Coastguard Worker #include "base/pointer_size.h"
32*795d594fSAndroid Build Coastguard Worker #include "base/runtime_debug.h"
33*795d594fSAndroid Build Coastguard Worker #include "dex/dex_file_structs.h"
34*795d594fSAndroid Build Coastguard Worker #include "dex/modifiers.h"
35*795d594fSAndroid Build Coastguard Worker #include "dex/primitive.h"
36*795d594fSAndroid Build Coastguard Worker #include "interpreter/mterp/nterp.h"
37*795d594fSAndroid Build Coastguard Worker #include "gc_root.h"
38*795d594fSAndroid Build Coastguard Worker #include "intrinsics_enum.h"
39*795d594fSAndroid Build Coastguard Worker #include "obj_ptr.h"
40*795d594fSAndroid Build Coastguard Worker #include "offsets.h"
41*795d594fSAndroid Build Coastguard Worker #include "read_barrier_option.h"
42*795d594fSAndroid Build Coastguard Worker 
43*795d594fSAndroid Build Coastguard Worker namespace art HIDDEN {
44*795d594fSAndroid Build Coastguard Worker 
45*795d594fSAndroid Build Coastguard Worker class CodeItemDataAccessor;
46*795d594fSAndroid Build Coastguard Worker class CodeItemDebugInfoAccessor;
47*795d594fSAndroid Build Coastguard Worker class CodeItemInstructionAccessor;
48*795d594fSAndroid Build Coastguard Worker class DexFile;
49*795d594fSAndroid Build Coastguard Worker template<class T> class Handle;
50*795d594fSAndroid Build Coastguard Worker class ImtConflictTable;
51*795d594fSAndroid Build Coastguard Worker enum InvokeType : uint32_t;
52*795d594fSAndroid Build Coastguard Worker union JValue;
53*795d594fSAndroid Build Coastguard Worker template<typename T> class LengthPrefixedArray;
54*795d594fSAndroid Build Coastguard Worker class OatQuickMethodHeader;
55*795d594fSAndroid Build Coastguard Worker class ProfilingInfo;
56*795d594fSAndroid Build Coastguard Worker class ScopedObjectAccessAlreadyRunnable;
57*795d594fSAndroid Build Coastguard Worker class ShadowFrame;
58*795d594fSAndroid Build Coastguard Worker class Signature;
59*795d594fSAndroid Build Coastguard Worker 
60*795d594fSAndroid Build Coastguard Worker namespace mirror {
61*795d594fSAndroid Build Coastguard Worker class Array;
62*795d594fSAndroid Build Coastguard Worker class Class;
63*795d594fSAndroid Build Coastguard Worker class ClassLoader;
64*795d594fSAndroid Build Coastguard Worker class DexCache;
65*795d594fSAndroid Build Coastguard Worker class IfTable;
66*795d594fSAndroid Build Coastguard Worker class Object;
67*795d594fSAndroid Build Coastguard Worker template <typename MirrorType> class ObjectArray;
68*795d594fSAndroid Build Coastguard Worker class PointerArray;
69*795d594fSAndroid Build Coastguard Worker class String;
70*795d594fSAndroid Build Coastguard Worker }  // namespace mirror
71*795d594fSAndroid Build Coastguard Worker 
72*795d594fSAndroid Build Coastguard Worker namespace detail {
73*795d594fSAndroid Build Coastguard Worker template <char Shorty> struct ShortyTraits;
74*795d594fSAndroid Build Coastguard Worker template <> struct ShortyTraits<'V'>;
75*795d594fSAndroid Build Coastguard Worker template <> struct ShortyTraits<'Z'>;
76*795d594fSAndroid Build Coastguard Worker template <> struct ShortyTraits<'B'>;
77*795d594fSAndroid Build Coastguard Worker template <> struct ShortyTraits<'C'>;
78*795d594fSAndroid Build Coastguard Worker template <> struct ShortyTraits<'S'>;
79*795d594fSAndroid Build Coastguard Worker template <> struct ShortyTraits<'I'>;
80*795d594fSAndroid Build Coastguard Worker template <> struct ShortyTraits<'J'>;
81*795d594fSAndroid Build Coastguard Worker template <> struct ShortyTraits<'F'>;
82*795d594fSAndroid Build Coastguard Worker template <> struct ShortyTraits<'D'>;
83*795d594fSAndroid Build Coastguard Worker template <> struct ShortyTraits<'L'>;
84*795d594fSAndroid Build Coastguard Worker template <char Shorty> struct HandleShortyTraits;
85*795d594fSAndroid Build Coastguard Worker template <> struct HandleShortyTraits<'L'>;
86*795d594fSAndroid Build Coastguard Worker }  // namespace detail
87*795d594fSAndroid Build Coastguard Worker 
88*795d594fSAndroid Build Coastguard Worker class EXPORT ArtMethod final {
89*795d594fSAndroid Build Coastguard Worker  public:
90*795d594fSAndroid Build Coastguard Worker   // Should the class state be checked on sensitive operations?
91*795d594fSAndroid Build Coastguard Worker   DECLARE_RUNTIME_DEBUG_FLAG(kCheckDeclaringClassState);
92*795d594fSAndroid Build Coastguard Worker 
93*795d594fSAndroid Build Coastguard Worker   // The runtime dex_method_index is kDexNoIndex. To lower dependencies, we use this
94*795d594fSAndroid Build Coastguard Worker   // constexpr, and ensure that the value is correct in art_method.cc.
95*795d594fSAndroid Build Coastguard Worker   static constexpr uint32_t kRuntimeMethodDexMethodIndex = 0xFFFFFFFF;
96*795d594fSAndroid Build Coastguard Worker 
97*795d594fSAndroid Build Coastguard Worker   ArtMethod() : access_flags_(0), dex_method_index_(0),
98*795d594fSAndroid Build Coastguard Worker       method_index_(0), hotness_count_(0) { }
99*795d594fSAndroid Build Coastguard Worker 
100*795d594fSAndroid Build Coastguard Worker   ArtMethod(ArtMethod* src, PointerSize image_pointer_size) {
101*795d594fSAndroid Build Coastguard Worker     CopyFrom(src, image_pointer_size);
102*795d594fSAndroid Build Coastguard Worker   }
103*795d594fSAndroid Build Coastguard Worker 
104*795d594fSAndroid Build Coastguard Worker   static ArtMethod* FromReflectedMethod(const ScopedObjectAccessAlreadyRunnable& soa,
105*795d594fSAndroid Build Coastguard Worker                                         jobject jlr_method)
106*795d594fSAndroid Build Coastguard Worker       REQUIRES_SHARED(Locks::mutator_lock_);
107*795d594fSAndroid Build Coastguard Worker 
108*795d594fSAndroid Build Coastguard Worker   // Visit the declaring class in 'method' if it is within [start_boundary, end_boundary).
109*795d594fSAndroid Build Coastguard Worker   template<typename RootVisitorType>
110*795d594fSAndroid Build Coastguard Worker   static void VisitRoots(RootVisitorType& visitor,
111*795d594fSAndroid Build Coastguard Worker                          uint8_t* start_boundary,
112*795d594fSAndroid Build Coastguard Worker                          uint8_t* end_boundary,
113*795d594fSAndroid Build Coastguard Worker                          ArtMethod* method)
114*795d594fSAndroid Build Coastguard Worker       REQUIRES_SHARED(Locks::mutator_lock_);
115*795d594fSAndroid Build Coastguard Worker 
116*795d594fSAndroid Build Coastguard Worker   // Visit declaring classes of all the art-methods in 'array' that reside
117*795d594fSAndroid Build Coastguard Worker   // in [start_boundary, end_boundary).
118*795d594fSAndroid Build Coastguard Worker   template<PointerSize kPointerSize, typename RootVisitorType>
119*795d594fSAndroid Build Coastguard Worker   static void VisitArrayRoots(RootVisitorType& visitor,
120*795d594fSAndroid Build Coastguard Worker                               uint8_t* start_boundary,
121*795d594fSAndroid Build Coastguard Worker                               uint8_t* end_boundary,
122*795d594fSAndroid Build Coastguard Worker                               LengthPrefixedArray<ArtMethod>* array)
123*795d594fSAndroid Build Coastguard Worker       REQUIRES_SHARED(Locks::mutator_lock_);
124*795d594fSAndroid Build Coastguard Worker 
125*795d594fSAndroid Build Coastguard Worker   template <ReadBarrierOption kReadBarrierOption = kWithReadBarrier>
126*795d594fSAndroid Build Coastguard Worker   ALWAYS_INLINE ObjPtr<mirror::Class> GetDeclaringClass() REQUIRES_SHARED(Locks::mutator_lock_);
127*795d594fSAndroid Build Coastguard Worker 
128*795d594fSAndroid Build Coastguard Worker   template <ReadBarrierOption kReadBarrierOption = kWithReadBarrier>
129*795d594fSAndroid Build Coastguard Worker   ALWAYS_INLINE ObjPtr<mirror::Class> GetDeclaringClassUnchecked()
130*795d594fSAndroid Build Coastguard Worker       REQUIRES_SHARED(Locks::mutator_lock_);
131*795d594fSAndroid Build Coastguard Worker 
132*795d594fSAndroid Build Coastguard Worker   mirror::CompressedReference<mirror::Object>* GetDeclaringClassAddressWithoutBarrier() {
133*795d594fSAndroid Build Coastguard Worker     return declaring_class_.AddressWithoutBarrier();
134*795d594fSAndroid Build Coastguard Worker   }
135*795d594fSAndroid Build Coastguard Worker 
136*795d594fSAndroid Build Coastguard Worker   void SetDeclaringClass(ObjPtr<mirror::Class> new_declaring_class)
137*795d594fSAndroid Build Coastguard Worker       REQUIRES_SHARED(Locks::mutator_lock_);
138*795d594fSAndroid Build Coastguard Worker 
139*795d594fSAndroid Build Coastguard Worker   bool CASDeclaringClass(ObjPtr<mirror::Class> expected_class, ObjPtr<mirror::Class> desired_class)
140*795d594fSAndroid Build Coastguard Worker       REQUIRES_SHARED(Locks::mutator_lock_);
141*795d594fSAndroid Build Coastguard Worker 
142*795d594fSAndroid Build Coastguard Worker   static constexpr MemberOffset DeclaringClassOffset() {
143*795d594fSAndroid Build Coastguard Worker     return MemberOffset(OFFSETOF_MEMBER(ArtMethod, declaring_class_));
144*795d594fSAndroid Build Coastguard Worker   }
145*795d594fSAndroid Build Coastguard Worker 
146*795d594fSAndroid Build Coastguard Worker   uint32_t GetAccessFlags() const {
147*795d594fSAndroid Build Coastguard Worker     return access_flags_.load(std::memory_order_relaxed);
148*795d594fSAndroid Build Coastguard Worker   }
149*795d594fSAndroid Build Coastguard Worker 
150*795d594fSAndroid Build Coastguard Worker   // This version should only be called when it's certain there is no
151*795d594fSAndroid Build Coastguard Worker   // concurrency so there is no need to guarantee atomicity. For example,
152*795d594fSAndroid Build Coastguard Worker   // before the method is linked.
153*795d594fSAndroid Build Coastguard Worker   void SetAccessFlags(uint32_t new_access_flags) REQUIRES_SHARED(Locks::mutator_lock_) {
154*795d594fSAndroid Build Coastguard Worker     // The following check ensures that we do not set `Intrinsics::kNone` (see b/228049006).
155*795d594fSAndroid Build Coastguard Worker     DCHECK_IMPLIES((new_access_flags & kAccIntrinsic) != 0,
156*795d594fSAndroid Build Coastguard Worker                    (new_access_flags & kAccIntrinsicBits) != 0);
157*795d594fSAndroid Build Coastguard Worker     access_flags_.store(new_access_flags, std::memory_order_relaxed);
158*795d594fSAndroid Build Coastguard Worker   }
159*795d594fSAndroid Build Coastguard Worker 
160*795d594fSAndroid Build Coastguard Worker   static constexpr MemberOffset AccessFlagsOffset() {
161*795d594fSAndroid Build Coastguard Worker     return MemberOffset(OFFSETOF_MEMBER(ArtMethod, access_flags_));
162*795d594fSAndroid Build Coastguard Worker   }
163*795d594fSAndroid Build Coastguard Worker 
164*795d594fSAndroid Build Coastguard Worker   // Approximate what kind of method call would be used for this method.
165*795d594fSAndroid Build Coastguard Worker   InvokeType GetInvokeType() REQUIRES_SHARED(Locks::mutator_lock_);
166*795d594fSAndroid Build Coastguard Worker 
167*795d594fSAndroid Build Coastguard Worker   // Returns true if the method is declared public.
168*795d594fSAndroid Build Coastguard Worker   bool IsPublic() const {
169*795d594fSAndroid Build Coastguard Worker     return IsPublic(GetAccessFlags());
170*795d594fSAndroid Build Coastguard Worker   }
171*795d594fSAndroid Build Coastguard Worker 
172*795d594fSAndroid Build Coastguard Worker   static bool IsPublic(uint32_t access_flags) {
173*795d594fSAndroid Build Coastguard Worker     return (access_flags & kAccPublic) != 0;
174*795d594fSAndroid Build Coastguard Worker   }
175*795d594fSAndroid Build Coastguard Worker 
176*795d594fSAndroid Build Coastguard Worker   // Returns true if the method is declared private.
177*795d594fSAndroid Build Coastguard Worker   bool IsPrivate() const {
178*795d594fSAndroid Build Coastguard Worker     return IsPrivate(GetAccessFlags());
179*795d594fSAndroid Build Coastguard Worker   }
180*795d594fSAndroid Build Coastguard Worker 
181*795d594fSAndroid Build Coastguard Worker   static bool IsPrivate(uint32_t access_flags) {
182*795d594fSAndroid Build Coastguard Worker     return (access_flags & kAccPrivate) != 0;
183*795d594fSAndroid Build Coastguard Worker   }
184*795d594fSAndroid Build Coastguard Worker 
185*795d594fSAndroid Build Coastguard Worker   // Returns true if the method is declared static.
186*795d594fSAndroid Build Coastguard Worker   bool IsStatic() const {
187*795d594fSAndroid Build Coastguard Worker     return IsStatic(GetAccessFlags());
188*795d594fSAndroid Build Coastguard Worker   }
189*795d594fSAndroid Build Coastguard Worker 
190*795d594fSAndroid Build Coastguard Worker   static bool IsStatic(uint32_t access_flags) {
191*795d594fSAndroid Build Coastguard Worker     return (access_flags & kAccStatic) != 0;
192*795d594fSAndroid Build Coastguard Worker   }
193*795d594fSAndroid Build Coastguard Worker 
194*795d594fSAndroid Build Coastguard Worker   // Returns true if the method is a constructor according to access flags.
195*795d594fSAndroid Build Coastguard Worker   bool IsConstructor() const {
196*795d594fSAndroid Build Coastguard Worker     return IsConstructor(GetAccessFlags());
197*795d594fSAndroid Build Coastguard Worker   }
198*795d594fSAndroid Build Coastguard Worker 
199*795d594fSAndroid Build Coastguard Worker   static bool IsConstructor(uint32_t access_flags) {
200*795d594fSAndroid Build Coastguard Worker     return (access_flags & kAccConstructor) != 0;
201*795d594fSAndroid Build Coastguard Worker   }
202*795d594fSAndroid Build Coastguard Worker 
203*795d594fSAndroid Build Coastguard Worker   // Returns true if the method is a class initializer according to access flags.
204*795d594fSAndroid Build Coastguard Worker   bool IsClassInitializer() const {
205*795d594fSAndroid Build Coastguard Worker     return IsClassInitializer(GetAccessFlags());
206*795d594fSAndroid Build Coastguard Worker   }
207*795d594fSAndroid Build Coastguard Worker 
208*795d594fSAndroid Build Coastguard Worker   static bool IsClassInitializer(uint32_t access_flags) {
209*795d594fSAndroid Build Coastguard Worker     return IsConstructor(access_flags) && IsStatic(access_flags);
210*795d594fSAndroid Build Coastguard Worker   }
211*795d594fSAndroid Build Coastguard Worker 
212*795d594fSAndroid Build Coastguard Worker   // Returns true if the method is static, private, or a constructor.
213*795d594fSAndroid Build Coastguard Worker   bool IsDirect() const {
214*795d594fSAndroid Build Coastguard Worker     return IsDirect(GetAccessFlags());
215*795d594fSAndroid Build Coastguard Worker   }
216*795d594fSAndroid Build Coastguard Worker 
217*795d594fSAndroid Build Coastguard Worker   static bool IsDirect(uint32_t access_flags) {
218*795d594fSAndroid Build Coastguard Worker     constexpr uint32_t direct = kAccStatic | kAccPrivate | kAccConstructor;
219*795d594fSAndroid Build Coastguard Worker     return (access_flags & direct) != 0;
220*795d594fSAndroid Build Coastguard Worker   }
221*795d594fSAndroid Build Coastguard Worker 
222*795d594fSAndroid Build Coastguard Worker   // Returns true if the method is declared synchronized.
223*795d594fSAndroid Build Coastguard Worker   bool IsSynchronized() const {
224*795d594fSAndroid Build Coastguard Worker     return IsSynchronized(GetAccessFlags());
225*795d594fSAndroid Build Coastguard Worker   }
226*795d594fSAndroid Build Coastguard Worker 
227*795d594fSAndroid Build Coastguard Worker   static bool IsSynchronized(uint32_t access_flags) {
228*795d594fSAndroid Build Coastguard Worker     constexpr uint32_t synchonized = kAccSynchronized | kAccDeclaredSynchronized;
229*795d594fSAndroid Build Coastguard Worker     return (access_flags & synchonized) != 0;
230*795d594fSAndroid Build Coastguard Worker   }
231*795d594fSAndroid Build Coastguard Worker 
232*795d594fSAndroid Build Coastguard Worker   // Returns true if the method is declared final.
233*795d594fSAndroid Build Coastguard Worker   bool IsFinal() const {
234*795d594fSAndroid Build Coastguard Worker     return IsFinal(GetAccessFlags());
235*795d594fSAndroid Build Coastguard Worker   }
236*795d594fSAndroid Build Coastguard Worker 
237*795d594fSAndroid Build Coastguard Worker   static bool IsFinal(uint32_t access_flags) {
238*795d594fSAndroid Build Coastguard Worker     return (access_flags & kAccFinal) != 0;
239*795d594fSAndroid Build Coastguard Worker   }
240*795d594fSAndroid Build Coastguard Worker 
241*795d594fSAndroid Build Coastguard Worker   // Returns true if the method is an intrinsic.
242*795d594fSAndroid Build Coastguard Worker   bool IsIntrinsic() const {
243*795d594fSAndroid Build Coastguard Worker     return IsIntrinsic(GetAccessFlags());
244*795d594fSAndroid Build Coastguard Worker   }
245*795d594fSAndroid Build Coastguard Worker 
246*795d594fSAndroid Build Coastguard Worker   static bool IsIntrinsic(uint32_t access_flags) {
247*795d594fSAndroid Build Coastguard Worker     return (access_flags & kAccIntrinsic) != 0;
248*795d594fSAndroid Build Coastguard Worker   }
249*795d594fSAndroid Build Coastguard Worker 
250*795d594fSAndroid Build Coastguard Worker   ALWAYS_INLINE void SetIntrinsic(Intrinsics intrinsic) REQUIRES_SHARED(Locks::mutator_lock_);
251*795d594fSAndroid Build Coastguard Worker 
252*795d594fSAndroid Build Coastguard Worker   Intrinsics GetIntrinsic() const {
253*795d594fSAndroid Build Coastguard Worker     static const int kAccFlagsShift = CTZ(kAccIntrinsicBits);
254*795d594fSAndroid Build Coastguard Worker     static_assert(IsPowerOfTwo((kAccIntrinsicBits >> kAccFlagsShift) + 1),
255*795d594fSAndroid Build Coastguard Worker                   "kAccIntrinsicBits are not continuous");
256*795d594fSAndroid Build Coastguard Worker     static_assert((kAccIntrinsic & kAccIntrinsicBits) == 0,
257*795d594fSAndroid Build Coastguard Worker                   "kAccIntrinsic overlaps kAccIntrinsicBits");
258*795d594fSAndroid Build Coastguard Worker     DCHECK(IsIntrinsic());
259*795d594fSAndroid Build Coastguard Worker     return static_cast<Intrinsics>((GetAccessFlags() & kAccIntrinsicBits) >> kAccFlagsShift);
260*795d594fSAndroid Build Coastguard Worker   }
261*795d594fSAndroid Build Coastguard Worker 
262*795d594fSAndroid Build Coastguard Worker   void SetNotIntrinsic() REQUIRES_SHARED(Locks::mutator_lock_);
263*795d594fSAndroid Build Coastguard Worker 
264*795d594fSAndroid Build Coastguard Worker   // Returns true if the method is a copied method.
265*795d594fSAndroid Build Coastguard Worker   bool IsCopied() const {
266*795d594fSAndroid Build Coastguard Worker     return IsCopied(GetAccessFlags());
267*795d594fSAndroid Build Coastguard Worker   }
268*795d594fSAndroid Build Coastguard Worker 
269*795d594fSAndroid Build Coastguard Worker   static bool IsCopied(uint32_t access_flags) {
270*795d594fSAndroid Build Coastguard Worker     // We do not have intrinsics for any default methods and therefore intrinsics are never copied.
271*795d594fSAndroid Build Coastguard Worker     // So we are using a flag from the intrinsic flags range and need to check `kAccIntrinsic` too.
272*795d594fSAndroid Build Coastguard Worker     static_assert((kAccCopied & kAccIntrinsicBits) != 0,
273*795d594fSAndroid Build Coastguard Worker                   "kAccCopied deliberately overlaps intrinsic bits");
274*795d594fSAndroid Build Coastguard Worker     const bool copied = (access_flags & (kAccIntrinsic | kAccCopied)) == kAccCopied;
275*795d594fSAndroid Build Coastguard Worker     // (IsMiranda() || IsDefaultConflicting()) implies copied
276*795d594fSAndroid Build Coastguard Worker     DCHECK(!(IsMiranda(access_flags) || IsDefaultConflicting(access_flags)) || copied)
277*795d594fSAndroid Build Coastguard Worker         << "Miranda or default-conflict methods must always be copied.";
278*795d594fSAndroid Build Coastguard Worker     return copied;
279*795d594fSAndroid Build Coastguard Worker   }
280*795d594fSAndroid Build Coastguard Worker 
281*795d594fSAndroid Build Coastguard Worker   bool IsMiranda() const {
282*795d594fSAndroid Build Coastguard Worker     return IsMiranda(GetAccessFlags());
283*795d594fSAndroid Build Coastguard Worker   }
284*795d594fSAndroid Build Coastguard Worker 
285*795d594fSAndroid Build Coastguard Worker   static bool IsMiranda(uint32_t access_flags) {
286*795d594fSAndroid Build Coastguard Worker     // Miranda methods are marked as copied and abstract but not default.
287*795d594fSAndroid Build Coastguard Worker     // We need to check the kAccIntrinsic too, see `IsCopied()`.
288*795d594fSAndroid Build Coastguard Worker     static constexpr uint32_t kMask = kAccIntrinsic | kAccCopied | kAccAbstract | kAccDefault;
289*795d594fSAndroid Build Coastguard Worker     static constexpr uint32_t kValue = kAccCopied | kAccAbstract;
290*795d594fSAndroid Build Coastguard Worker     return (access_flags & kMask) == kValue;
291*795d594fSAndroid Build Coastguard Worker   }
292*795d594fSAndroid Build Coastguard Worker 
293*795d594fSAndroid Build Coastguard Worker   // A default conflict method is a special sentinel method that stands for a conflict between
294*795d594fSAndroid Build Coastguard Worker   // multiple default methods. It cannot be invoked, throwing an IncompatibleClassChangeError
295*795d594fSAndroid Build Coastguard Worker   // if one attempts to do so.
296*795d594fSAndroid Build Coastguard Worker   bool IsDefaultConflicting() const {
297*795d594fSAndroid Build Coastguard Worker     return IsDefaultConflicting(GetAccessFlags());
298*795d594fSAndroid Build Coastguard Worker   }
299*795d594fSAndroid Build Coastguard Worker 
300*795d594fSAndroid Build Coastguard Worker   static bool IsDefaultConflicting(uint32_t access_flags) {
301*795d594fSAndroid Build Coastguard Worker     // Default conflct methods are marked as copied, abstract and default.
302*795d594fSAndroid Build Coastguard Worker     // We need to check the kAccIntrinsic too, see `IsCopied()`.
303*795d594fSAndroid Build Coastguard Worker     static constexpr uint32_t kMask = kAccIntrinsic | kAccCopied | kAccAbstract | kAccDefault;
304*795d594fSAndroid Build Coastguard Worker     static constexpr uint32_t kValue = kAccCopied | kAccAbstract | kAccDefault;
305*795d594fSAndroid Build Coastguard Worker     return (access_flags & kMask) == kValue;
306*795d594fSAndroid Build Coastguard Worker   }
307*795d594fSAndroid Build Coastguard Worker 
308*795d594fSAndroid Build Coastguard Worker   // Returns true if invoking this method will not throw an AbstractMethodError or
309*795d594fSAndroid Build Coastguard Worker   // IncompatibleClassChangeError.
310*795d594fSAndroid Build Coastguard Worker   bool IsInvokable() const {
311*795d594fSAndroid Build Coastguard Worker     return IsInvokable(GetAccessFlags());
312*795d594fSAndroid Build Coastguard Worker   }
313*795d594fSAndroid Build Coastguard Worker 
314*795d594fSAndroid Build Coastguard Worker   static bool IsInvokable(uint32_t access_flags) {
315*795d594fSAndroid Build Coastguard Worker     // Default conflicting methods are marked with `kAccAbstract` (as well as `kAccCopied`
316*795d594fSAndroid Build Coastguard Worker     // and `kAccDefault`) but they are not considered abstract, see `IsAbstract()`.
317*795d594fSAndroid Build Coastguard Worker     DCHECK_EQ((access_flags & kAccAbstract) == 0,
318*795d594fSAndroid Build Coastguard Worker               !IsDefaultConflicting(access_flags) && !IsAbstract(access_flags));
319*795d594fSAndroid Build Coastguard Worker     return (access_flags & kAccAbstract) == 0;
320*795d594fSAndroid Build Coastguard Worker   }
321*795d594fSAndroid Build Coastguard Worker 
322*795d594fSAndroid Build Coastguard Worker   // Returns true if the method is marked as pre-compiled.
323*795d594fSAndroid Build Coastguard Worker   bool IsPreCompiled() const {
324*795d594fSAndroid Build Coastguard Worker     return IsPreCompiled(GetAccessFlags());
325*795d594fSAndroid Build Coastguard Worker   }
326*795d594fSAndroid Build Coastguard Worker 
327*795d594fSAndroid Build Coastguard Worker   static bool IsPreCompiled(uint32_t access_flags) {
328*795d594fSAndroid Build Coastguard Worker     // kAccCompileDontBother and kAccPreCompiled overlap with kAccIntrinsicBits.
329*795d594fSAndroid Build Coastguard Worker     static_assert((kAccCompileDontBother & kAccIntrinsicBits) != 0);
330*795d594fSAndroid Build Coastguard Worker     static_assert((kAccPreCompiled & kAccIntrinsicBits) != 0);
331*795d594fSAndroid Build Coastguard Worker     static constexpr uint32_t kMask = kAccIntrinsic | kAccCompileDontBother | kAccPreCompiled;
332*795d594fSAndroid Build Coastguard Worker     static constexpr uint32_t kValue = kAccCompileDontBother | kAccPreCompiled;
333*795d594fSAndroid Build Coastguard Worker     return (access_flags & kMask) == kValue;
334*795d594fSAndroid Build Coastguard Worker   }
335*795d594fSAndroid Build Coastguard Worker 
336*795d594fSAndroid Build Coastguard Worker   void SetPreCompiled() REQUIRES_SHARED(Locks::mutator_lock_) {
337*795d594fSAndroid Build Coastguard Worker     DCHECK(IsInvokable());
338*795d594fSAndroid Build Coastguard Worker     DCHECK(IsCompilable());
339*795d594fSAndroid Build Coastguard Worker     // kAccPreCompiled and kAccCompileDontBother overlaps with kAccIntrinsicBits.
340*795d594fSAndroid Build Coastguard Worker     // We don't mark the intrinsics as precompiled, which means in JIT zygote
341*795d594fSAndroid Build Coastguard Worker     // mode, compiled code for intrinsics will not be shared, and apps will
342*795d594fSAndroid Build Coastguard Worker     // compile intrinsics themselves if needed.
343*795d594fSAndroid Build Coastguard Worker     if (IsIntrinsic()) {
344*795d594fSAndroid Build Coastguard Worker       return;
345*795d594fSAndroid Build Coastguard Worker     }
346*795d594fSAndroid Build Coastguard Worker     AddAccessFlags(kAccPreCompiled | kAccCompileDontBother);
347*795d594fSAndroid Build Coastguard Worker   }
348*795d594fSAndroid Build Coastguard Worker 
349*795d594fSAndroid Build Coastguard Worker   void ClearPreCompiled() REQUIRES_SHARED(Locks::mutator_lock_) {
350*795d594fSAndroid Build Coastguard Worker     ClearAccessFlags(kAccPreCompiled | kAccCompileDontBother);
351*795d594fSAndroid Build Coastguard Worker   }
352*795d594fSAndroid Build Coastguard Worker 
353*795d594fSAndroid Build Coastguard Worker   // Returns true if the method resides in shared memory.
354*795d594fSAndroid Build Coastguard Worker   bool IsMemorySharedMethod() {
355*795d594fSAndroid Build Coastguard Worker     return IsMemorySharedMethod(GetAccessFlags());
356*795d594fSAndroid Build Coastguard Worker   }
357*795d594fSAndroid Build Coastguard Worker 
358*795d594fSAndroid Build Coastguard Worker   static bool IsMemorySharedMethod(uint32_t access_flags) {
359*795d594fSAndroid Build Coastguard Worker     // There's an overlap with `kAccMemorySharedMethod` and `kAccIntrinsicBits` but that's OK as
360*795d594fSAndroid Build Coastguard Worker     // intrinsics are always in the boot image and therefore memory shared.
361*795d594fSAndroid Build Coastguard Worker     static_assert((kAccMemorySharedMethod & kAccIntrinsicBits) != 0,
362*795d594fSAndroid Build Coastguard Worker                   "kAccMemorySharedMethod deliberately overlaps intrinsic bits");
363*795d594fSAndroid Build Coastguard Worker     if (IsIntrinsic(access_flags)) {
364*795d594fSAndroid Build Coastguard Worker       return true;
365*795d594fSAndroid Build Coastguard Worker     }
366*795d594fSAndroid Build Coastguard Worker 
367*795d594fSAndroid Build Coastguard Worker     return (access_flags & kAccMemorySharedMethod) != 0;
368*795d594fSAndroid Build Coastguard Worker   }
369*795d594fSAndroid Build Coastguard Worker 
370*795d594fSAndroid Build Coastguard Worker   void SetMemorySharedMethod() REQUIRES_SHARED(Locks::mutator_lock_) {
371*795d594fSAndroid Build Coastguard Worker     DCHECK(!IsIntrinsic());
372*795d594fSAndroid Build Coastguard Worker     DCHECK(!IsAbstract());
373*795d594fSAndroid Build Coastguard Worker     AddAccessFlags(kAccMemorySharedMethod);
374*795d594fSAndroid Build Coastguard Worker   }
375*795d594fSAndroid Build Coastguard Worker 
376*795d594fSAndroid Build Coastguard Worker   static uint32_t SetMemorySharedMethod(uint32_t access_flags) {
377*795d594fSAndroid Build Coastguard Worker     DCHECK(!IsIntrinsic(access_flags));
378*795d594fSAndroid Build Coastguard Worker     DCHECK(!IsAbstract(access_flags));
379*795d594fSAndroid Build Coastguard Worker     return access_flags | kAccMemorySharedMethod;
380*795d594fSAndroid Build Coastguard Worker   }
381*795d594fSAndroid Build Coastguard Worker 
382*795d594fSAndroid Build Coastguard Worker   void ClearMemorySharedMethod() REQUIRES_SHARED(Locks::mutator_lock_) {
383*795d594fSAndroid Build Coastguard Worker     uint32_t access_flags = GetAccessFlags();
384*795d594fSAndroid Build Coastguard Worker     if (IsIntrinsic(access_flags) || IsAbstract(access_flags)) {
385*795d594fSAndroid Build Coastguard Worker       return;
386*795d594fSAndroid Build Coastguard Worker     }
387*795d594fSAndroid Build Coastguard Worker     if (IsMemorySharedMethod(access_flags)) {
388*795d594fSAndroid Build Coastguard Worker       ClearAccessFlags(kAccMemorySharedMethod);
389*795d594fSAndroid Build Coastguard Worker     }
390*795d594fSAndroid Build Coastguard Worker   }
391*795d594fSAndroid Build Coastguard Worker 
392*795d594fSAndroid Build Coastguard Worker   // Returns true if the method can be compiled.
393*795d594fSAndroid Build Coastguard Worker   bool IsCompilable() const {
394*795d594fSAndroid Build Coastguard Worker     return IsCompilable(GetAccessFlags());
395*795d594fSAndroid Build Coastguard Worker   }
396*795d594fSAndroid Build Coastguard Worker 
397*795d594fSAndroid Build Coastguard Worker   static bool IsCompilable(uint32_t access_flags) {
398*795d594fSAndroid Build Coastguard Worker     if (IsIntrinsic(access_flags)) {
399*795d594fSAndroid Build Coastguard Worker       // kAccCompileDontBother overlaps with kAccIntrinsicBits.
400*795d594fSAndroid Build Coastguard Worker       return true;
401*795d594fSAndroid Build Coastguard Worker     }
402*795d594fSAndroid Build Coastguard Worker     if (IsPreCompiled(access_flags)) {
403*795d594fSAndroid Build Coastguard Worker       return true;
404*795d594fSAndroid Build Coastguard Worker     }
405*795d594fSAndroid Build Coastguard Worker     return (access_flags & kAccCompileDontBother) == 0;
406*795d594fSAndroid Build Coastguard Worker   }
407*795d594fSAndroid Build Coastguard Worker 
408*795d594fSAndroid Build Coastguard Worker   void ClearDontCompile() REQUIRES_SHARED(Locks::mutator_lock_) {
409*795d594fSAndroid Build Coastguard Worker     DCHECK(!IsMiranda());
410*795d594fSAndroid Build Coastguard Worker     ClearAccessFlags(kAccCompileDontBother);
411*795d594fSAndroid Build Coastguard Worker   }
412*795d594fSAndroid Build Coastguard Worker 
413*795d594fSAndroid Build Coastguard Worker   void SetDontCompile() REQUIRES_SHARED(Locks::mutator_lock_) {
414*795d594fSAndroid Build Coastguard Worker     DCHECK(!IsMiranda());
415*795d594fSAndroid Build Coastguard Worker     AddAccessFlags(kAccCompileDontBother);
416*795d594fSAndroid Build Coastguard Worker   }
417*795d594fSAndroid Build Coastguard Worker 
418*795d594fSAndroid Build Coastguard Worker   // This is set by the class linker.
419*795d594fSAndroid Build Coastguard Worker   bool IsDefault() const {
420*795d594fSAndroid Build Coastguard Worker     return IsDefault(GetAccessFlags());
421*795d594fSAndroid Build Coastguard Worker   }
422*795d594fSAndroid Build Coastguard Worker 
423*795d594fSAndroid Build Coastguard Worker   static bool IsDefault(uint32_t access_flags) {
424*795d594fSAndroid Build Coastguard Worker     // The intrinsic bits use `kAccDefault`. However, we don't generate intrinsics for default
425*795d594fSAndroid Build Coastguard Worker     // methods. Therefore, we check that both `kAccDefault` is set and `kAccIntrinsic` unset.
426*795d594fSAndroid Build Coastguard Worker     static_assert((kAccDefault & kAccIntrinsicBits) != 0,
427*795d594fSAndroid Build Coastguard Worker                   "kAccDefault deliberately overlaps intrinsic bits");
428*795d594fSAndroid Build Coastguard Worker     static constexpr uint32_t kMask = kAccIntrinsic | kAccDefault;
429*795d594fSAndroid Build Coastguard Worker     static constexpr uint32_t kValue = kAccDefault;
430*795d594fSAndroid Build Coastguard Worker     return (access_flags & kMask) == kValue;
431*795d594fSAndroid Build Coastguard Worker   }
432*795d594fSAndroid Build Coastguard Worker 
433*795d594fSAndroid Build Coastguard Worker   // Returns true if the method is obsolete.
434*795d594fSAndroid Build Coastguard Worker   bool IsObsolete() const {
435*795d594fSAndroid Build Coastguard Worker     return IsObsolete(GetAccessFlags());
436*795d594fSAndroid Build Coastguard Worker   }
437*795d594fSAndroid Build Coastguard Worker 
438*795d594fSAndroid Build Coastguard Worker   static bool IsObsolete(uint32_t access_flags) {
439*795d594fSAndroid Build Coastguard Worker     return (access_flags & kAccObsoleteMethod) != 0;
440*795d594fSAndroid Build Coastguard Worker   }
441*795d594fSAndroid Build Coastguard Worker 
442*795d594fSAndroid Build Coastguard Worker   void SetIsObsolete() REQUIRES_SHARED(Locks::mutator_lock_) {
443*795d594fSAndroid Build Coastguard Worker     AddAccessFlags(kAccObsoleteMethod);
444*795d594fSAndroid Build Coastguard Worker   }
445*795d594fSAndroid Build Coastguard Worker 
446*795d594fSAndroid Build Coastguard Worker   // Returns true if the method is native.
447*795d594fSAndroid Build Coastguard Worker   bool IsNative() const {
448*795d594fSAndroid Build Coastguard Worker     return IsNative(GetAccessFlags());
449*795d594fSAndroid Build Coastguard Worker   }
450*795d594fSAndroid Build Coastguard Worker 
451*795d594fSAndroid Build Coastguard Worker   static bool IsNative(uint32_t access_flags) {
452*795d594fSAndroid Build Coastguard Worker     return (access_flags & kAccNative) != 0;
453*795d594fSAndroid Build Coastguard Worker   }
454*795d594fSAndroid Build Coastguard Worker 
455*795d594fSAndroid Build Coastguard Worker   // Checks to see if the method was annotated with @dalvik.annotation.optimization.FastNative.
456*795d594fSAndroid Build Coastguard Worker   bool IsFastNative() const {
457*795d594fSAndroid Build Coastguard Worker     return IsFastNative(GetAccessFlags());
458*795d594fSAndroid Build Coastguard Worker   }
459*795d594fSAndroid Build Coastguard Worker 
460*795d594fSAndroid Build Coastguard Worker   static bool IsFastNative(uint32_t access_flags) {
461*795d594fSAndroid Build Coastguard Worker     // The presence of the annotation is checked by ClassLinker and recorded in access flags.
462*795d594fSAndroid Build Coastguard Worker     // The kAccFastNative flag value is used with a different meaning for non-native methods,
463*795d594fSAndroid Build Coastguard Worker     // so we need to check the kAccNative flag as well.
464*795d594fSAndroid Build Coastguard Worker     constexpr uint32_t mask = kAccFastNative | kAccNative;
465*795d594fSAndroid Build Coastguard Worker     return (access_flags & mask) == mask;
466*795d594fSAndroid Build Coastguard Worker   }
467*795d594fSAndroid Build Coastguard Worker 
468*795d594fSAndroid Build Coastguard Worker   // Checks to see if the method was annotated with @dalvik.annotation.optimization.CriticalNative.
469*795d594fSAndroid Build Coastguard Worker   bool IsCriticalNative() const {
470*795d594fSAndroid Build Coastguard Worker     return IsCriticalNative(GetAccessFlags());
471*795d594fSAndroid Build Coastguard Worker   }
472*795d594fSAndroid Build Coastguard Worker 
473*795d594fSAndroid Build Coastguard Worker   static bool IsCriticalNative(uint32_t access_flags) {
474*795d594fSAndroid Build Coastguard Worker     // The presence of the annotation is checked by ClassLinker and recorded in access flags.
475*795d594fSAndroid Build Coastguard Worker     // The kAccCriticalNative flag value is used with a different meaning for non-native methods,
476*795d594fSAndroid Build Coastguard Worker     // so we need to check the kAccNative flag as well.
477*795d594fSAndroid Build Coastguard Worker     constexpr uint32_t mask = kAccCriticalNative | kAccNative;
478*795d594fSAndroid Build Coastguard Worker     return (access_flags & mask) == mask;
479*795d594fSAndroid Build Coastguard Worker   }
480*795d594fSAndroid Build Coastguard Worker 
481*795d594fSAndroid Build Coastguard Worker   // Returns true if the method is managed (not native).
482*795d594fSAndroid Build Coastguard Worker   bool IsManaged() const {
483*795d594fSAndroid Build Coastguard Worker     return IsManaged(GetAccessFlags());
484*795d594fSAndroid Build Coastguard Worker   }
485*795d594fSAndroid Build Coastguard Worker 
486*795d594fSAndroid Build Coastguard Worker   static bool IsManaged(uint32_t access_flags) {
487*795d594fSAndroid Build Coastguard Worker     return !IsNative(access_flags);
488*795d594fSAndroid Build Coastguard Worker   }
489*795d594fSAndroid Build Coastguard Worker 
490*795d594fSAndroid Build Coastguard Worker   // Returns true if the method is managed (not native) and invokable.
491*795d594fSAndroid Build Coastguard Worker   bool IsManagedAndInvokable() const {
492*795d594fSAndroid Build Coastguard Worker     return IsManagedAndInvokable(GetAccessFlags());
493*795d594fSAndroid Build Coastguard Worker   }
494*795d594fSAndroid Build Coastguard Worker 
495*795d594fSAndroid Build Coastguard Worker   static bool IsManagedAndInvokable(uint32_t access_flags) {
496*795d594fSAndroid Build Coastguard Worker     return IsManaged(access_flags) && IsInvokable(access_flags);
497*795d594fSAndroid Build Coastguard Worker   }
498*795d594fSAndroid Build Coastguard Worker 
499*795d594fSAndroid Build Coastguard Worker   // Returns true if the method is abstract.
500*795d594fSAndroid Build Coastguard Worker   bool IsAbstract() const {
501*795d594fSAndroid Build Coastguard Worker     return IsAbstract(GetAccessFlags());
502*795d594fSAndroid Build Coastguard Worker   }
503*795d594fSAndroid Build Coastguard Worker 
504*795d594fSAndroid Build Coastguard Worker   static bool IsAbstract(uint32_t access_flags) {
505*795d594fSAndroid Build Coastguard Worker     // Default confliciting methods have `kAccAbstract` set but they are not actually abstract.
506*795d594fSAndroid Build Coastguard Worker     return (access_flags & kAccAbstract) != 0 && !IsDefaultConflicting(access_flags);
507*795d594fSAndroid Build Coastguard Worker   }
508*795d594fSAndroid Build Coastguard Worker 
509*795d594fSAndroid Build Coastguard Worker   // Returns true if the method is declared synthetic.
510*795d594fSAndroid Build Coastguard Worker   bool IsSynthetic() const {
511*795d594fSAndroid Build Coastguard Worker     return IsSynthetic(GetAccessFlags());
512*795d594fSAndroid Build Coastguard Worker   }
513*795d594fSAndroid Build Coastguard Worker 
514*795d594fSAndroid Build Coastguard Worker   static bool IsSynthetic(uint32_t access_flags) {
515*795d594fSAndroid Build Coastguard Worker     return (access_flags & kAccSynthetic) != 0;
516*795d594fSAndroid Build Coastguard Worker   }
517*795d594fSAndroid Build Coastguard Worker 
518*795d594fSAndroid Build Coastguard Worker   // Returns true if the method is declared varargs.
519*795d594fSAndroid Build Coastguard Worker   bool IsVarargs() const {
520*795d594fSAndroid Build Coastguard Worker     return IsVarargs(GetAccessFlags());
521*795d594fSAndroid Build Coastguard Worker   }
522*795d594fSAndroid Build Coastguard Worker 
523*795d594fSAndroid Build Coastguard Worker   static bool IsVarargs(uint32_t access_flags) {
524*795d594fSAndroid Build Coastguard Worker     return (access_flags & kAccVarargs) != 0;
525*795d594fSAndroid Build Coastguard Worker   }
526*795d594fSAndroid Build Coastguard Worker 
527*795d594fSAndroid Build Coastguard Worker   bool IsProxyMethod() REQUIRES_SHARED(Locks::mutator_lock_);
528*795d594fSAndroid Build Coastguard Worker 
529*795d594fSAndroid Build Coastguard Worker   bool IsSignaturePolymorphic() REQUIRES_SHARED(Locks::mutator_lock_);
530*795d594fSAndroid Build Coastguard Worker 
531*795d594fSAndroid Build Coastguard Worker   bool SkipAccessChecks() const {
532*795d594fSAndroid Build Coastguard Worker     // The kAccSkipAccessChecks flag value is used with a different meaning for native methods,
533*795d594fSAndroid Build Coastguard Worker     // so we need to check the kAccNative flag as well.
534*795d594fSAndroid Build Coastguard Worker     return (GetAccessFlags() & (kAccSkipAccessChecks | kAccNative)) == kAccSkipAccessChecks;
535*795d594fSAndroid Build Coastguard Worker   }
536*795d594fSAndroid Build Coastguard Worker 
537*795d594fSAndroid Build Coastguard Worker   void SetSkipAccessChecks() REQUIRES_SHARED(Locks::mutator_lock_) {
538*795d594fSAndroid Build Coastguard Worker     // SkipAccessChecks() is applicable only to non-native methods.
539*795d594fSAndroid Build Coastguard Worker     DCHECK(!IsNative());
540*795d594fSAndroid Build Coastguard Worker     AddAccessFlags(kAccSkipAccessChecks);
541*795d594fSAndroid Build Coastguard Worker   }
542*795d594fSAndroid Build Coastguard Worker   void ClearSkipAccessChecks() REQUIRES_SHARED(Locks::mutator_lock_) {
543*795d594fSAndroid Build Coastguard Worker     // SkipAccessChecks() is applicable only to non-native methods.
544*795d594fSAndroid Build Coastguard Worker     DCHECK(!IsNative());
545*795d594fSAndroid Build Coastguard Worker     ClearAccessFlags(kAccSkipAccessChecks);
546*795d594fSAndroid Build Coastguard Worker   }
547*795d594fSAndroid Build Coastguard Worker 
548*795d594fSAndroid Build Coastguard Worker   // Returns true if the method has previously been warm.
549*795d594fSAndroid Build Coastguard Worker   bool PreviouslyWarm() const {
550*795d594fSAndroid Build Coastguard Worker     return PreviouslyWarm(GetAccessFlags());
551*795d594fSAndroid Build Coastguard Worker   }
552*795d594fSAndroid Build Coastguard Worker 
553*795d594fSAndroid Build Coastguard Worker   static bool PreviouslyWarm(uint32_t access_flags) {
554*795d594fSAndroid Build Coastguard Worker     // kAccPreviouslyWarm overlaps with kAccIntrinsicBits. Return true for intrinsics.
555*795d594fSAndroid Build Coastguard Worker     constexpr uint32_t mask = kAccPreviouslyWarm | kAccIntrinsic;
556*795d594fSAndroid Build Coastguard Worker     return (access_flags & mask) != 0u;
557*795d594fSAndroid Build Coastguard Worker   }
558*795d594fSAndroid Build Coastguard Worker 
559*795d594fSAndroid Build Coastguard Worker   void SetPreviouslyWarm() REQUIRES_SHARED(Locks::mutator_lock_) {
560*795d594fSAndroid Build Coastguard Worker     if (IsIntrinsic()) {
561*795d594fSAndroid Build Coastguard Worker       // kAccPreviouslyWarm overlaps with kAccIntrinsicBits.
562*795d594fSAndroid Build Coastguard Worker       return;
563*795d594fSAndroid Build Coastguard Worker     }
564*795d594fSAndroid Build Coastguard Worker     AddAccessFlags(kAccPreviouslyWarm);
565*795d594fSAndroid Build Coastguard Worker   }
566*795d594fSAndroid Build Coastguard Worker 
567*795d594fSAndroid Build Coastguard Worker   // Should this method be run in the interpreter and count locks (e.g., failed structured-
568*795d594fSAndroid Build Coastguard Worker   // locking verification)?
569*795d594fSAndroid Build Coastguard Worker   bool MustCountLocks() const {
570*795d594fSAndroid Build Coastguard Worker     return MustCountLocks(GetAccessFlags());
571*795d594fSAndroid Build Coastguard Worker   }
572*795d594fSAndroid Build Coastguard Worker 
573*795d594fSAndroid Build Coastguard Worker   static bool MustCountLocks(uint32_t access_flags) {
574*795d594fSAndroid Build Coastguard Worker     if (IsIntrinsic(access_flags)) {
575*795d594fSAndroid Build Coastguard Worker       return false;
576*795d594fSAndroid Build Coastguard Worker     }
577*795d594fSAndroid Build Coastguard Worker     return (access_flags & kAccMustCountLocks) != 0;
578*795d594fSAndroid Build Coastguard Worker   }
579*795d594fSAndroid Build Coastguard Worker 
580*795d594fSAndroid Build Coastguard Worker   void ClearMustCountLocks() REQUIRES_SHARED(Locks::mutator_lock_) {
581*795d594fSAndroid Build Coastguard Worker     ClearAccessFlags(kAccMustCountLocks);
582*795d594fSAndroid Build Coastguard Worker   }
583*795d594fSAndroid Build Coastguard Worker 
584*795d594fSAndroid Build Coastguard Worker   void SetMustCountLocks() REQUIRES_SHARED(Locks::mutator_lock_) {
585*795d594fSAndroid Build Coastguard Worker     ClearAccessFlags(kAccSkipAccessChecks);
586*795d594fSAndroid Build Coastguard Worker     AddAccessFlags(kAccMustCountLocks);
587*795d594fSAndroid Build Coastguard Worker   }
588*795d594fSAndroid Build Coastguard Worker 
589*795d594fSAndroid Build Coastguard Worker   // Returns true if the method is using the nterp entrypoint fast path.
590*795d594fSAndroid Build Coastguard Worker   bool HasNterpEntryPointFastPathFlag() const {
591*795d594fSAndroid Build Coastguard Worker     return HasNterpEntryPointFastPathFlag(GetAccessFlags());
592*795d594fSAndroid Build Coastguard Worker   }
593*795d594fSAndroid Build Coastguard Worker 
594*795d594fSAndroid Build Coastguard Worker   static bool HasNterpEntryPointFastPathFlag(uint32_t access_flags) {
595*795d594fSAndroid Build Coastguard Worker     constexpr uint32_t mask = kAccNative | kAccNterpEntryPointFastPathFlag;
596*795d594fSAndroid Build Coastguard Worker     return (access_flags & mask) == kAccNterpEntryPointFastPathFlag;
597*795d594fSAndroid Build Coastguard Worker   }
598*795d594fSAndroid Build Coastguard Worker 
599*795d594fSAndroid Build Coastguard Worker   void SetNterpEntryPointFastPathFlag() REQUIRES_SHARED(Locks::mutator_lock_) {
600*795d594fSAndroid Build Coastguard Worker     DCHECK(!IsNative());
601*795d594fSAndroid Build Coastguard Worker     AddAccessFlags(kAccNterpEntryPointFastPathFlag);
602*795d594fSAndroid Build Coastguard Worker   }
603*795d594fSAndroid Build Coastguard Worker 
604*795d594fSAndroid Build Coastguard Worker   void ClearNterpEntryPointFastPathFlag() REQUIRES_SHARED(Locks::mutator_lock_) {
605*795d594fSAndroid Build Coastguard Worker     DCHECK(!IsNative());
606*795d594fSAndroid Build Coastguard Worker     ClearAccessFlags(kAccNterpEntryPointFastPathFlag);
607*795d594fSAndroid Build Coastguard Worker   }
608*795d594fSAndroid Build Coastguard Worker 
609*795d594fSAndroid Build Coastguard Worker   void SetNterpInvokeFastPathFlag() REQUIRES_SHARED(Locks::mutator_lock_) {
610*795d594fSAndroid Build Coastguard Worker     AddAccessFlags(kAccNterpInvokeFastPathFlag);
611*795d594fSAndroid Build Coastguard Worker   }
612*795d594fSAndroid Build Coastguard Worker 
613*795d594fSAndroid Build Coastguard Worker   void ClearNterpInvokeFastPathFlag() REQUIRES_SHARED(Locks::mutator_lock_) {
614*795d594fSAndroid Build Coastguard Worker     ClearAccessFlags(kAccNterpInvokeFastPathFlag);
615*795d594fSAndroid Build Coastguard Worker   }
616*795d594fSAndroid Build Coastguard Worker 
617*795d594fSAndroid Build Coastguard Worker   static uint32_t ClearNterpFastPathFlags(uint32_t access_flags) {
618*795d594fSAndroid Build Coastguard Worker     // `kAccNterpEntryPointFastPathFlag` has a different use for native methods.
619*795d594fSAndroid Build Coastguard Worker     if (!IsNative(access_flags)) {
620*795d594fSAndroid Build Coastguard Worker       access_flags &= ~kAccNterpEntryPointFastPathFlag;
621*795d594fSAndroid Build Coastguard Worker     }
622*795d594fSAndroid Build Coastguard Worker     access_flags &= ~kAccNterpInvokeFastPathFlag;
623*795d594fSAndroid Build Coastguard Worker     return access_flags;
624*795d594fSAndroid Build Coastguard Worker   }
625*795d594fSAndroid Build Coastguard Worker 
626*795d594fSAndroid Build Coastguard Worker   // Returns whether the method is a string constructor. The method must not
627*795d594fSAndroid Build Coastguard Worker   // be a class initializer. (Class initializers are called from a different
628*795d594fSAndroid Build Coastguard Worker   // context where we do not need to check for string constructors.)
629*795d594fSAndroid Build Coastguard Worker   bool IsStringConstructor() REQUIRES_SHARED(Locks::mutator_lock_);
630*795d594fSAndroid Build Coastguard Worker 
631*795d594fSAndroid Build Coastguard Worker   // Returns true if this method could be overridden by a default method.
632*795d594fSAndroid Build Coastguard Worker   bool IsOverridableByDefaultMethod() REQUIRES_SHARED(Locks::mutator_lock_);
633*795d594fSAndroid Build Coastguard Worker 
634*795d594fSAndroid Build Coastguard Worker   bool CheckIncompatibleClassChange(InvokeType type) REQUIRES_SHARED(Locks::mutator_lock_);
635*795d594fSAndroid Build Coastguard Worker 
636*795d594fSAndroid Build Coastguard Worker   // Throws the error that would result from trying to invoke this method (i.e.
637*795d594fSAndroid Build Coastguard Worker   // IncompatibleClassChangeError, AbstractMethodError, or IllegalAccessError).
638*795d594fSAndroid Build Coastguard Worker   // Only call if !IsInvokable();
639*795d594fSAndroid Build Coastguard Worker   void ThrowInvocationTimeError(ObjPtr<mirror::Object> receiver)
640*795d594fSAndroid Build Coastguard Worker       REQUIRES_SHARED(Locks::mutator_lock_);
641*795d594fSAndroid Build Coastguard Worker 
642*795d594fSAndroid Build Coastguard Worker   uint16_t GetMethodIndex() REQUIRES_SHARED(Locks::mutator_lock_);
643*795d594fSAndroid Build Coastguard Worker 
644*795d594fSAndroid Build Coastguard Worker   // Doesn't do erroneous / unresolved class checks.
645*795d594fSAndroid Build Coastguard Worker   uint16_t GetMethodIndexDuringLinking() REQUIRES_SHARED(Locks::mutator_lock_);
646*795d594fSAndroid Build Coastguard Worker 
647*795d594fSAndroid Build Coastguard Worker   size_t GetVtableIndex() REQUIRES_SHARED(Locks::mutator_lock_) {
648*795d594fSAndroid Build Coastguard Worker     return GetMethodIndex();
649*795d594fSAndroid Build Coastguard Worker   }
650*795d594fSAndroid Build Coastguard Worker 
651*795d594fSAndroid Build Coastguard Worker   void SetMethodIndex(uint16_t new_method_index) REQUIRES_SHARED(Locks::mutator_lock_) {
652*795d594fSAndroid Build Coastguard Worker     // Not called within a transaction.
653*795d594fSAndroid Build Coastguard Worker     method_index_ = new_method_index;
654*795d594fSAndroid Build Coastguard Worker   }
655*795d594fSAndroid Build Coastguard Worker 
656*795d594fSAndroid Build Coastguard Worker   static constexpr MemberOffset DexMethodIndexOffset() {
657*795d594fSAndroid Build Coastguard Worker     return MemberOffset(OFFSETOF_MEMBER(ArtMethod, dex_method_index_));
658*795d594fSAndroid Build Coastguard Worker   }
659*795d594fSAndroid Build Coastguard Worker 
660*795d594fSAndroid Build Coastguard Worker   static constexpr MemberOffset MethodIndexOffset() {
661*795d594fSAndroid Build Coastguard Worker     return MemberOffset(OFFSETOF_MEMBER(ArtMethod, method_index_));
662*795d594fSAndroid Build Coastguard Worker   }
663*795d594fSAndroid Build Coastguard Worker 
664*795d594fSAndroid Build Coastguard Worker   static constexpr MemberOffset ImtIndexOffset() {
665*795d594fSAndroid Build Coastguard Worker     return MemberOffset(OFFSETOF_MEMBER(ArtMethod, imt_index_));
666*795d594fSAndroid Build Coastguard Worker   }
667*795d594fSAndroid Build Coastguard Worker 
668*795d594fSAndroid Build Coastguard Worker   // Number of 32bit registers that would be required to hold all the arguments
669*795d594fSAndroid Build Coastguard Worker   static size_t NumArgRegisters(std::string_view shorty);
670*795d594fSAndroid Build Coastguard Worker 
671*795d594fSAndroid Build Coastguard Worker   ALWAYS_INLINE uint32_t GetDexMethodIndex() const {
672*795d594fSAndroid Build Coastguard Worker     return dex_method_index_;
673*795d594fSAndroid Build Coastguard Worker   }
674*795d594fSAndroid Build Coastguard Worker 
675*795d594fSAndroid Build Coastguard Worker   void SetDexMethodIndex(uint32_t new_idx) REQUIRES_SHARED(Locks::mutator_lock_) {
676*795d594fSAndroid Build Coastguard Worker     // Not called within a transaction.
677*795d594fSAndroid Build Coastguard Worker     dex_method_index_ = new_idx;
678*795d594fSAndroid Build Coastguard Worker   }
679*795d594fSAndroid Build Coastguard Worker 
680*795d594fSAndroid Build Coastguard Worker   // Lookup the Class from the type index into this method's dex cache.
681*795d594fSAndroid Build Coastguard Worker   ObjPtr<mirror::Class> LookupResolvedClassFromTypeIndex(dex::TypeIndex type_idx)
682*795d594fSAndroid Build Coastguard Worker       REQUIRES_SHARED(Locks::mutator_lock_);
683*795d594fSAndroid Build Coastguard Worker   // Resolve the Class from the type index into this method's dex cache.
684*795d594fSAndroid Build Coastguard Worker   ObjPtr<mirror::Class> ResolveClassFromTypeIndex(dex::TypeIndex type_idx)
685*795d594fSAndroid Build Coastguard Worker       REQUIRES_SHARED(Locks::mutator_lock_);
686*795d594fSAndroid Build Coastguard Worker 
687*795d594fSAndroid Build Coastguard Worker   // Returns true if this method has the same name and signature of the other method.
688*795d594fSAndroid Build Coastguard Worker   bool HasSameNameAndSignature(ArtMethod* other) REQUIRES_SHARED(Locks::mutator_lock_);
689*795d594fSAndroid Build Coastguard Worker 
690*795d594fSAndroid Build Coastguard Worker   // Find the method that this method overrides.
691*795d594fSAndroid Build Coastguard Worker   ArtMethod* FindOverriddenMethod(PointerSize pointer_size)
692*795d594fSAndroid Build Coastguard Worker       REQUIRES_SHARED(Locks::mutator_lock_);
693*795d594fSAndroid Build Coastguard Worker 
694*795d594fSAndroid Build Coastguard Worker   // Find the method index for this method within other_dexfile. If this method isn't present then
695*795d594fSAndroid Build Coastguard Worker   // return dex::kDexNoIndex. The name_and_signature_idx MUST refer to a MethodId with the same
696*795d594fSAndroid Build Coastguard Worker   // name and signature in the other_dexfile, such as the method index used to resolve this method
697*795d594fSAndroid Build Coastguard Worker   // in the other_dexfile.
698*795d594fSAndroid Build Coastguard Worker   uint32_t FindDexMethodIndexInOtherDexFile(const DexFile& other_dexfile,
699*795d594fSAndroid Build Coastguard Worker                                             uint32_t name_and_signature_idx)
700*795d594fSAndroid Build Coastguard Worker       REQUIRES_SHARED(Locks::mutator_lock_);
701*795d594fSAndroid Build Coastguard Worker 
702*795d594fSAndroid Build Coastguard Worker   void Invoke(Thread* self, uint32_t* args, uint32_t args_size, JValue* result, const char* shorty)
703*795d594fSAndroid Build Coastguard Worker       REQUIRES_SHARED(Locks::mutator_lock_);
704*795d594fSAndroid Build Coastguard Worker 
705*795d594fSAndroid Build Coastguard Worker   template <char ReturnType, char... ArgType>
706*795d594fSAndroid Build Coastguard Worker   typename detail::ShortyTraits<ReturnType>::Type
707*795d594fSAndroid Build Coastguard Worker   InvokeStatic(Thread* self, typename detail::ShortyTraits<ArgType>::Type... args)
708*795d594fSAndroid Build Coastguard Worker       REQUIRES_SHARED(Locks::mutator_lock_);
709*795d594fSAndroid Build Coastguard Worker 
710*795d594fSAndroid Build Coastguard Worker   template <char ReturnType, char... ArgType>
711*795d594fSAndroid Build Coastguard Worker   typename detail::ShortyTraits<ReturnType>::Type
712*795d594fSAndroid Build Coastguard Worker   InvokeInstance(Thread* self,
713*795d594fSAndroid Build Coastguard Worker                  ObjPtr<mirror::Object> receiver,
714*795d594fSAndroid Build Coastguard Worker                  typename detail::ShortyTraits<ArgType>::Type... args)
715*795d594fSAndroid Build Coastguard Worker       REQUIRES_SHARED(Locks::mutator_lock_);
716*795d594fSAndroid Build Coastguard Worker 
717*795d594fSAndroid Build Coastguard Worker   template <char ReturnType, char... ArgType>
718*795d594fSAndroid Build Coastguard Worker   typename detail::ShortyTraits<ReturnType>::Type
719*795d594fSAndroid Build Coastguard Worker   InvokeFinal(Thread* self,
720*795d594fSAndroid Build Coastguard Worker               ObjPtr<mirror::Object> receiver,
721*795d594fSAndroid Build Coastguard Worker               typename detail::ShortyTraits<ArgType>::Type... args)
722*795d594fSAndroid Build Coastguard Worker       REQUIRES_SHARED(Locks::mutator_lock_);
723*795d594fSAndroid Build Coastguard Worker 
724*795d594fSAndroid Build Coastguard Worker   template <char ReturnType, char... ArgType>
725*795d594fSAndroid Build Coastguard Worker   typename detail::ShortyTraits<ReturnType>::Type
726*795d594fSAndroid Build Coastguard Worker   InvokeVirtual(Thread* self,
727*795d594fSAndroid Build Coastguard Worker                 ObjPtr<mirror::Object> receiver,
728*795d594fSAndroid Build Coastguard Worker                 typename detail::ShortyTraits<ArgType>::Type... args)
729*795d594fSAndroid Build Coastguard Worker       REQUIRES_SHARED(Locks::mutator_lock_);
730*795d594fSAndroid Build Coastguard Worker 
731*795d594fSAndroid Build Coastguard Worker   template <char ReturnType, char... ArgType>
732*795d594fSAndroid Build Coastguard Worker   typename detail::ShortyTraits<ReturnType>::Type
733*795d594fSAndroid Build Coastguard Worker   InvokeInterface(Thread* self,
734*795d594fSAndroid Build Coastguard Worker                   ObjPtr<mirror::Object> receiver,
735*795d594fSAndroid Build Coastguard Worker                   typename detail::ShortyTraits<ArgType>::Type... args)
736*795d594fSAndroid Build Coastguard Worker       REQUIRES_SHARED(Locks::mutator_lock_);
737*795d594fSAndroid Build Coastguard Worker 
738*795d594fSAndroid Build Coastguard Worker   template <char... ArgType, typename HandleScopeType>
739*795d594fSAndroid Build Coastguard Worker   Handle<mirror::Object> NewObject(HandleScopeType& hs,
740*795d594fSAndroid Build Coastguard Worker                                    Thread* self,
741*795d594fSAndroid Build Coastguard Worker                                    typename detail::HandleShortyTraits<ArgType>::Type... args)
742*795d594fSAndroid Build Coastguard Worker       REQUIRES_SHARED(Locks::mutator_lock_);
743*795d594fSAndroid Build Coastguard Worker 
744*795d594fSAndroid Build Coastguard Worker   template <char... ArgType>
745*795d594fSAndroid Build Coastguard Worker   ObjPtr<mirror::Object> NewObject(Thread* self,
746*795d594fSAndroid Build Coastguard Worker                                    typename detail::HandleShortyTraits<ArgType>::Type... args)
747*795d594fSAndroid Build Coastguard Worker       REQUIRES_SHARED(Locks::mutator_lock_);
748*795d594fSAndroid Build Coastguard Worker 
749*795d594fSAndroid Build Coastguard Worker   // Returns true if the method needs a class initialization check according to access flags.
750*795d594fSAndroid Build Coastguard Worker   // Only static methods other than the class initializer need this check.
751*795d594fSAndroid Build Coastguard Worker   // The caller is responsible for performing the actual check.
752*795d594fSAndroid Build Coastguard Worker   bool NeedsClinitCheckBeforeCall() const {
753*795d594fSAndroid Build Coastguard Worker     return NeedsClinitCheckBeforeCall(GetAccessFlags());
754*795d594fSAndroid Build Coastguard Worker   }
755*795d594fSAndroid Build Coastguard Worker 
756*795d594fSAndroid Build Coastguard Worker   static bool NeedsClinitCheckBeforeCall(uint32_t access_flags) {
757*795d594fSAndroid Build Coastguard Worker     // The class initializer is special as it is invoked during initialization
758*795d594fSAndroid Build Coastguard Worker     // and does not need the check.
759*795d594fSAndroid Build Coastguard Worker     return IsStatic(access_flags) && !IsConstructor(access_flags);
760*795d594fSAndroid Build Coastguard Worker   }
761*795d594fSAndroid Build Coastguard Worker 
762*795d594fSAndroid Build Coastguard Worker   // Check if the method needs a class initialization check before call
763*795d594fSAndroid Build Coastguard Worker   // and its declaring class is not yet visibly initialized.
764*795d594fSAndroid Build Coastguard Worker   // (The class needs to be visibly initialized before we can use entrypoints
765*795d594fSAndroid Build Coastguard Worker   // to compiled code for static methods. See b/18161648 .)
766*795d594fSAndroid Build Coastguard Worker   template <ReadBarrierOption kReadBarrierOption = kWithReadBarrier>
767*795d594fSAndroid Build Coastguard Worker   bool StillNeedsClinitCheck() REQUIRES_SHARED(Locks::mutator_lock_);
768*795d594fSAndroid Build Coastguard Worker 
769*795d594fSAndroid Build Coastguard Worker   // Similar to `StillNeedsClinitCheck()` but the method's declaring class may
770*795d594fSAndroid Build Coastguard Worker   // be dead but not yet reclaimed by the GC, so we cannot do a full read barrier
771*795d594fSAndroid Build Coastguard Worker   // but we still want to check the class status in the to-space class if any.
772*795d594fSAndroid Build Coastguard Worker   // Note: JIT can hold and use such methods during managed heap GC.
773*795d594fSAndroid Build Coastguard Worker   bool StillNeedsClinitCheckMayBeDead() REQUIRES_SHARED(Locks::mutator_lock_);
774*795d594fSAndroid Build Coastguard Worker 
775*795d594fSAndroid Build Coastguard Worker   // Check if the declaring class has been verified and look at the to-space
776*795d594fSAndroid Build Coastguard Worker   // class object, if any, as in `StillNeedsClinitCheckMayBeDead()`.
777*795d594fSAndroid Build Coastguard Worker   bool IsDeclaringClassVerifiedMayBeDead() REQUIRES_SHARED(Locks::mutator_lock_);
778*795d594fSAndroid Build Coastguard Worker 
779*795d594fSAndroid Build Coastguard Worker   const void* GetEntryPointFromQuickCompiledCode() const {
780*795d594fSAndroid Build Coastguard Worker     return GetEntryPointFromQuickCompiledCodePtrSize(kRuntimePointerSize);
781*795d594fSAndroid Build Coastguard Worker   }
782*795d594fSAndroid Build Coastguard Worker   ALWAYS_INLINE
783*795d594fSAndroid Build Coastguard Worker   const void* GetEntryPointFromQuickCompiledCodePtrSize(PointerSize pointer_size) const {
784*795d594fSAndroid Build Coastguard Worker     return GetNativePointer<const void*>(
785*795d594fSAndroid Build Coastguard Worker         EntryPointFromQuickCompiledCodeOffset(pointer_size), pointer_size);
786*795d594fSAndroid Build Coastguard Worker   }
787*795d594fSAndroid Build Coastguard Worker 
788*795d594fSAndroid Build Coastguard Worker   void SetEntryPointFromQuickCompiledCode(const void* entry_point_from_quick_compiled_code)
789*795d594fSAndroid Build Coastguard Worker       REQUIRES_SHARED(Locks::mutator_lock_) {
790*795d594fSAndroid Build Coastguard Worker     SetEntryPointFromQuickCompiledCodePtrSize(entry_point_from_quick_compiled_code,
791*795d594fSAndroid Build Coastguard Worker                                               kRuntimePointerSize);
792*795d594fSAndroid Build Coastguard Worker   }
793*795d594fSAndroid Build Coastguard Worker   ALWAYS_INLINE void SetEntryPointFromQuickCompiledCodePtrSize(
794*795d594fSAndroid Build Coastguard Worker       const void* entry_point_from_quick_compiled_code, PointerSize pointer_size)
795*795d594fSAndroid Build Coastguard Worker       REQUIRES_SHARED(Locks::mutator_lock_) {
796*795d594fSAndroid Build Coastguard Worker     SetNativePointer(EntryPointFromQuickCompiledCodeOffset(pointer_size),
797*795d594fSAndroid Build Coastguard Worker                      entry_point_from_quick_compiled_code,
798*795d594fSAndroid Build Coastguard Worker                      pointer_size);
799*795d594fSAndroid Build Coastguard Worker   }
800*795d594fSAndroid Build Coastguard Worker 
801*795d594fSAndroid Build Coastguard Worker   static constexpr MemberOffset DataOffset(PointerSize pointer_size) {
802*795d594fSAndroid Build Coastguard Worker     return MemberOffset(PtrSizedFieldsOffset(pointer_size) + OFFSETOF_MEMBER(
803*795d594fSAndroid Build Coastguard Worker         PtrSizedFields, data_) / sizeof(void*) * static_cast<size_t>(pointer_size));
804*795d594fSAndroid Build Coastguard Worker   }
805*795d594fSAndroid Build Coastguard Worker 
806*795d594fSAndroid Build Coastguard Worker   static constexpr MemberOffset EntryPointFromJniOffset(PointerSize pointer_size) {
807*795d594fSAndroid Build Coastguard Worker     return DataOffset(pointer_size);
808*795d594fSAndroid Build Coastguard Worker   }
809*795d594fSAndroid Build Coastguard Worker 
810*795d594fSAndroid Build Coastguard Worker   static constexpr MemberOffset EntryPointFromQuickCompiledCodeOffset(PointerSize pointer_size) {
811*795d594fSAndroid Build Coastguard Worker     return MemberOffset(PtrSizedFieldsOffset(pointer_size) + OFFSETOF_MEMBER(
812*795d594fSAndroid Build Coastguard Worker         PtrSizedFields, entry_point_from_quick_compiled_code_) / sizeof(void*)
813*795d594fSAndroid Build Coastguard Worker             * static_cast<size_t>(pointer_size));
814*795d594fSAndroid Build Coastguard Worker   }
815*795d594fSAndroid Build Coastguard Worker 
816*795d594fSAndroid Build Coastguard Worker   ImtConflictTable* GetImtConflictTable(PointerSize pointer_size) const {
817*795d594fSAndroid Build Coastguard Worker     DCHECK(IsRuntimeMethod());
818*795d594fSAndroid Build Coastguard Worker     return reinterpret_cast<ImtConflictTable*>(GetDataPtrSize(pointer_size));
819*795d594fSAndroid Build Coastguard Worker   }
820*795d594fSAndroid Build Coastguard Worker 
821*795d594fSAndroid Build Coastguard Worker   ALWAYS_INLINE void SetImtConflictTable(ImtConflictTable* table, PointerSize pointer_size)
822*795d594fSAndroid Build Coastguard Worker       REQUIRES_SHARED(Locks::mutator_lock_) {
823*795d594fSAndroid Build Coastguard Worker     DCHECK(IsRuntimeMethod());
824*795d594fSAndroid Build Coastguard Worker     SetDataPtrSize(table, pointer_size);
825*795d594fSAndroid Build Coastguard Worker   }
826*795d594fSAndroid Build Coastguard Worker 
827*795d594fSAndroid Build Coastguard Worker   ALWAYS_INLINE bool HasSingleImplementation() REQUIRES_SHARED(Locks::mutator_lock_);
828*795d594fSAndroid Build Coastguard Worker 
829*795d594fSAndroid Build Coastguard Worker   ALWAYS_INLINE void SetHasSingleImplementation(bool single_impl)
830*795d594fSAndroid Build Coastguard Worker       REQUIRES_SHARED(Locks::mutator_lock_) {
831*795d594fSAndroid Build Coastguard Worker     DCHECK(!IsIntrinsic()) << "conflict with intrinsic bits";
832*795d594fSAndroid Build Coastguard Worker     if (single_impl) {
833*795d594fSAndroid Build Coastguard Worker       AddAccessFlags(kAccSingleImplementation);
834*795d594fSAndroid Build Coastguard Worker     } else {
835*795d594fSAndroid Build Coastguard Worker       ClearAccessFlags(kAccSingleImplementation);
836*795d594fSAndroid Build Coastguard Worker     }
837*795d594fSAndroid Build Coastguard Worker   }
838*795d594fSAndroid Build Coastguard Worker 
839*795d594fSAndroid Build Coastguard Worker   ALWAYS_INLINE bool HasSingleImplementationFlag() const {
840*795d594fSAndroid Build Coastguard Worker     return (GetAccessFlags() & kAccSingleImplementation) != 0;
841*795d594fSAndroid Build Coastguard Worker   }
842*795d594fSAndroid Build Coastguard Worker 
843*795d594fSAndroid Build Coastguard Worker   static uint32_t SetHasSingleImplementation(uint32_t access_flags, bool single_impl) {
844*795d594fSAndroid Build Coastguard Worker     DCHECK(!IsIntrinsic(access_flags)) << "conflict with intrinsic bits";
845*795d594fSAndroid Build Coastguard Worker     if (single_impl) {
846*795d594fSAndroid Build Coastguard Worker       return access_flags | kAccSingleImplementation;
847*795d594fSAndroid Build Coastguard Worker     } else {
848*795d594fSAndroid Build Coastguard Worker       return access_flags & ~kAccSingleImplementation;
849*795d594fSAndroid Build Coastguard Worker     }
850*795d594fSAndroid Build Coastguard Worker   }
851*795d594fSAndroid Build Coastguard Worker 
852*795d594fSAndroid Build Coastguard Worker   // Takes a method and returns a 'canonical' one if the method is default (and therefore
853*795d594fSAndroid Build Coastguard Worker   // potentially copied from some other class). For example, this ensures that the debugger does not
854*795d594fSAndroid Build Coastguard Worker   // get confused as to which method we are in.
855*795d594fSAndroid Build Coastguard Worker   ArtMethod* GetCanonicalMethod(PointerSize pointer_size = kRuntimePointerSize)
856*795d594fSAndroid Build Coastguard Worker       REQUIRES_SHARED(Locks::mutator_lock_);
857*795d594fSAndroid Build Coastguard Worker 
858*795d594fSAndroid Build Coastguard Worker   ArtMethod* GetSingleImplementation(PointerSize pointer_size);
859*795d594fSAndroid Build Coastguard Worker 
860*795d594fSAndroid Build Coastguard Worker   ALWAYS_INLINE void SetSingleImplementation(ArtMethod* method, PointerSize pointer_size)
861*795d594fSAndroid Build Coastguard Worker       REQUIRES_SHARED(Locks::mutator_lock_) {
862*795d594fSAndroid Build Coastguard Worker     DCHECK(!IsNative());
863*795d594fSAndroid Build Coastguard Worker     // Non-abstract method's single implementation is just itself.
864*795d594fSAndroid Build Coastguard Worker     DCHECK(IsAbstract());
865*795d594fSAndroid Build Coastguard Worker     DCHECK(method == nullptr || method->IsInvokable());
866*795d594fSAndroid Build Coastguard Worker     SetDataPtrSize(method, pointer_size);
867*795d594fSAndroid Build Coastguard Worker   }
868*795d594fSAndroid Build Coastguard Worker 
869*795d594fSAndroid Build Coastguard Worker   void* GetEntryPointFromJni() const {
870*795d594fSAndroid Build Coastguard Worker     DCHECK(IsNative());
871*795d594fSAndroid Build Coastguard Worker     return GetEntryPointFromJniPtrSize(kRuntimePointerSize);
872*795d594fSAndroid Build Coastguard Worker   }
873*795d594fSAndroid Build Coastguard Worker 
874*795d594fSAndroid Build Coastguard Worker   ALWAYS_INLINE void* GetEntryPointFromJniPtrSize(PointerSize pointer_size) const {
875*795d594fSAndroid Build Coastguard Worker     return GetDataPtrSize(pointer_size);
876*795d594fSAndroid Build Coastguard Worker   }
877*795d594fSAndroid Build Coastguard Worker 
878*795d594fSAndroid Build Coastguard Worker   void SetEntryPointFromJni(const void* entrypoint)
879*795d594fSAndroid Build Coastguard Worker       REQUIRES_SHARED(Locks::mutator_lock_) {
880*795d594fSAndroid Build Coastguard Worker     // The resolution method also has a JNI entrypoint for direct calls from
881*795d594fSAndroid Build Coastguard Worker     // compiled code to the JNI dlsym lookup stub for @CriticalNative.
882*795d594fSAndroid Build Coastguard Worker     DCHECK(IsNative() || IsRuntimeMethod());
883*795d594fSAndroid Build Coastguard Worker     SetEntryPointFromJniPtrSize(entrypoint, kRuntimePointerSize);
884*795d594fSAndroid Build Coastguard Worker   }
885*795d594fSAndroid Build Coastguard Worker 
886*795d594fSAndroid Build Coastguard Worker   ALWAYS_INLINE void SetEntryPointFromJniPtrSize(const void* entrypoint, PointerSize pointer_size)
887*795d594fSAndroid Build Coastguard Worker       REQUIRES_SHARED(Locks::mutator_lock_) {
888*795d594fSAndroid Build Coastguard Worker     SetDataPtrSize(entrypoint, pointer_size);
889*795d594fSAndroid Build Coastguard Worker   }
890*795d594fSAndroid Build Coastguard Worker 
891*795d594fSAndroid Build Coastguard Worker   ALWAYS_INLINE void* GetDataPtrSize(PointerSize pointer_size) const {
892*795d594fSAndroid Build Coastguard Worker     DCHECK(IsImagePointerSize(pointer_size));
893*795d594fSAndroid Build Coastguard Worker     return GetNativePointer<void*>(DataOffset(pointer_size), pointer_size);
894*795d594fSAndroid Build Coastguard Worker   }
895*795d594fSAndroid Build Coastguard Worker 
896*795d594fSAndroid Build Coastguard Worker   ALWAYS_INLINE void SetDataPtrSize(const void* data, PointerSize pointer_size)
897*795d594fSAndroid Build Coastguard Worker       REQUIRES_SHARED(Locks::mutator_lock_) {
898*795d594fSAndroid Build Coastguard Worker     DCHECK(IsImagePointerSize(pointer_size));
899*795d594fSAndroid Build Coastguard Worker     SetNativePointer(DataOffset(pointer_size), data, pointer_size);
900*795d594fSAndroid Build Coastguard Worker   }
901*795d594fSAndroid Build Coastguard Worker 
902*795d594fSAndroid Build Coastguard Worker   // Is this a CalleSaveMethod or ResolutionMethod and therefore doesn't adhere to normal
903*795d594fSAndroid Build Coastguard Worker   // conventions for a method of managed code. Returns false for Proxy methods.
904*795d594fSAndroid Build Coastguard Worker   ALWAYS_INLINE bool IsRuntimeMethod() const {
905*795d594fSAndroid Build Coastguard Worker     return dex_method_index_ == kRuntimeMethodDexMethodIndex;
906*795d594fSAndroid Build Coastguard Worker   }
907*795d594fSAndroid Build Coastguard Worker 
908*795d594fSAndroid Build Coastguard Worker   bool HasCodeItem() REQUIRES_SHARED(Locks::mutator_lock_) {
909*795d594fSAndroid Build Coastguard Worker     uint32_t access_flags = GetAccessFlags();
910*795d594fSAndroid Build Coastguard Worker     return !IsNative(access_flags) &&
911*795d594fSAndroid Build Coastguard Worker            !IsAbstract(access_flags) &&
912*795d594fSAndroid Build Coastguard Worker            !IsDefaultConflicting(access_flags) &&
913*795d594fSAndroid Build Coastguard Worker            !IsRuntimeMethod() &&
914*795d594fSAndroid Build Coastguard Worker            !IsProxyMethod();
915*795d594fSAndroid Build Coastguard Worker   }
916*795d594fSAndroid Build Coastguard Worker 
917*795d594fSAndroid Build Coastguard Worker   // We need to explicitly indicate whether the code item is obtained from the compact dex file,
918*795d594fSAndroid Build Coastguard Worker   // because in JVMTI, we obtain the code item from the standard dex file to update the method.
919*795d594fSAndroid Build Coastguard Worker   void SetCodeItem(const dex::CodeItem* code_item, bool is_compact_dex_code_item)
920*795d594fSAndroid Build Coastguard Worker       REQUIRES_SHARED(Locks::mutator_lock_);
921*795d594fSAndroid Build Coastguard Worker 
922*795d594fSAndroid Build Coastguard Worker   // Is this a hand crafted method used for something like describing callee saves?
923*795d594fSAndroid Build Coastguard Worker   bool IsCalleeSaveMethod() REQUIRES_SHARED(Locks::mutator_lock_);
924*795d594fSAndroid Build Coastguard Worker 
925*795d594fSAndroid Build Coastguard Worker   bool IsResolutionMethod() REQUIRES_SHARED(Locks::mutator_lock_);
926*795d594fSAndroid Build Coastguard Worker 
927*795d594fSAndroid Build Coastguard Worker   bool IsImtUnimplementedMethod() REQUIRES_SHARED(Locks::mutator_lock_);
928*795d594fSAndroid Build Coastguard Worker 
929*795d594fSAndroid Build Coastguard Worker   // Find the catch block for the given exception type and dex_pc. When a catch block is found,
930*795d594fSAndroid Build Coastguard Worker   // indicates whether the found catch block is responsible for clearing the exception or whether
931*795d594fSAndroid Build Coastguard Worker   // a move-exception instruction is present.
932*795d594fSAndroid Build Coastguard Worker   uint32_t FindCatchBlock(Handle<mirror::Class> exception_type, uint32_t dex_pc,
933*795d594fSAndroid Build Coastguard Worker                           bool* has_no_move_exception)
934*795d594fSAndroid Build Coastguard Worker       REQUIRES_SHARED(Locks::mutator_lock_);
935*795d594fSAndroid Build Coastguard Worker 
936*795d594fSAndroid Build Coastguard Worker   // NO_THREAD_SAFETY_ANALYSIS since we don't know what the callback requires.
937*795d594fSAndroid Build Coastguard Worker   template<ReadBarrierOption kReadBarrierOption = kWithReadBarrier,
938*795d594fSAndroid Build Coastguard Worker            bool kVisitProxyMethod = true,
939*795d594fSAndroid Build Coastguard Worker            typename RootVisitorType>
940*795d594fSAndroid Build Coastguard Worker   void VisitRoots(RootVisitorType& visitor, PointerSize pointer_size) NO_THREAD_SAFETY_ANALYSIS;
941*795d594fSAndroid Build Coastguard Worker 
942*795d594fSAndroid Build Coastguard Worker   const DexFile* GetDexFile() REQUIRES_SHARED(Locks::mutator_lock_);
943*795d594fSAndroid Build Coastguard Worker 
944*795d594fSAndroid Build Coastguard Worker   const char* GetDeclaringClassDescriptor() REQUIRES_SHARED(Locks::mutator_lock_);
945*795d594fSAndroid Build Coastguard Worker   std::string_view GetDeclaringClassDescriptorView() REQUIRES_SHARED(Locks::mutator_lock_);
946*795d594fSAndroid Build Coastguard Worker 
947*795d594fSAndroid Build Coastguard Worker   ALWAYS_INLINE const char* GetShorty() REQUIRES_SHARED(Locks::mutator_lock_);
948*795d594fSAndroid Build Coastguard Worker 
949*795d594fSAndroid Build Coastguard Worker   const char* GetShorty(uint32_t* out_length) REQUIRES_SHARED(Locks::mutator_lock_);
950*795d594fSAndroid Build Coastguard Worker 
951*795d594fSAndroid Build Coastguard Worker   std::string_view GetShortyView() REQUIRES_SHARED(Locks::mutator_lock_);
952*795d594fSAndroid Build Coastguard Worker 
953*795d594fSAndroid Build Coastguard Worker   const Signature GetSignature() REQUIRES_SHARED(Locks::mutator_lock_);
954*795d594fSAndroid Build Coastguard Worker 
955*795d594fSAndroid Build Coastguard Worker   ALWAYS_INLINE const char* GetName() REQUIRES_SHARED(Locks::mutator_lock_);
956*795d594fSAndroid Build Coastguard Worker 
957*795d594fSAndroid Build Coastguard Worker   ALWAYS_INLINE std::string_view GetNameView() REQUIRES_SHARED(Locks::mutator_lock_);
958*795d594fSAndroid Build Coastguard Worker 
959*795d594fSAndroid Build Coastguard Worker   ObjPtr<mirror::String> ResolveNameString() REQUIRES_SHARED(Locks::mutator_lock_);
960*795d594fSAndroid Build Coastguard Worker 
961*795d594fSAndroid Build Coastguard Worker   bool NameEquals(ObjPtr<mirror::String> name) REQUIRES_SHARED(Locks::mutator_lock_);
962*795d594fSAndroid Build Coastguard Worker 
963*795d594fSAndroid Build Coastguard Worker   const dex::CodeItem* GetCodeItem() REQUIRES_SHARED(Locks::mutator_lock_);
964*795d594fSAndroid Build Coastguard Worker 
965*795d594fSAndroid Build Coastguard Worker   int32_t GetLineNumFromDexPC(uint32_t dex_pc) REQUIRES_SHARED(Locks::mutator_lock_);
966*795d594fSAndroid Build Coastguard Worker 
967*795d594fSAndroid Build Coastguard Worker   const dex::ProtoId& GetPrototype() REQUIRES_SHARED(Locks::mutator_lock_);
968*795d594fSAndroid Build Coastguard Worker 
969*795d594fSAndroid Build Coastguard Worker   const dex::TypeList* GetParameterTypeList() REQUIRES_SHARED(Locks::mutator_lock_);
970*795d594fSAndroid Build Coastguard Worker 
971*795d594fSAndroid Build Coastguard Worker   const char* GetDeclaringClassSourceFile() REQUIRES_SHARED(Locks::mutator_lock_);
972*795d594fSAndroid Build Coastguard Worker 
973*795d594fSAndroid Build Coastguard Worker   uint16_t GetClassDefIndex() REQUIRES_SHARED(Locks::mutator_lock_);
974*795d594fSAndroid Build Coastguard Worker 
975*795d594fSAndroid Build Coastguard Worker   const dex::ClassDef& GetClassDef() REQUIRES_SHARED(Locks::mutator_lock_);
976*795d594fSAndroid Build Coastguard Worker 
977*795d594fSAndroid Build Coastguard Worker   ALWAYS_INLINE size_t GetNumberOfParameters() REQUIRES_SHARED(Locks::mutator_lock_);
978*795d594fSAndroid Build Coastguard Worker 
979*795d594fSAndroid Build Coastguard Worker   const char* GetReturnTypeDescriptor() REQUIRES_SHARED(Locks::mutator_lock_);
980*795d594fSAndroid Build Coastguard Worker   std::string_view GetReturnTypeDescriptorView() REQUIRES_SHARED(Locks::mutator_lock_);
981*795d594fSAndroid Build Coastguard Worker 
982*795d594fSAndroid Build Coastguard Worker   ALWAYS_INLINE Primitive::Type GetReturnTypePrimitive() REQUIRES_SHARED(Locks::mutator_lock_);
983*795d594fSAndroid Build Coastguard Worker 
984*795d594fSAndroid Build Coastguard Worker   const char* GetTypeDescriptorFromTypeIdx(dex::TypeIndex type_idx)
985*795d594fSAndroid Build Coastguard Worker       REQUIRES_SHARED(Locks::mutator_lock_);
986*795d594fSAndroid Build Coastguard Worker 
987*795d594fSAndroid Build Coastguard Worker   // Lookup return type.
988*795d594fSAndroid Build Coastguard Worker   ObjPtr<mirror::Class> LookupResolvedReturnType() REQUIRES_SHARED(Locks::mutator_lock_);
989*795d594fSAndroid Build Coastguard Worker   // Resolve return type. May cause thread suspension due to GetClassFromTypeIdx
990*795d594fSAndroid Build Coastguard Worker   // calling ResolveType this caused a large number of bugs at call sites.
991*795d594fSAndroid Build Coastguard Worker   ObjPtr<mirror::Class> ResolveReturnType() REQUIRES_SHARED(Locks::mutator_lock_);
992*795d594fSAndroid Build Coastguard Worker 
993*795d594fSAndroid Build Coastguard Worker   ObjPtr<mirror::ClassLoader> GetClassLoader() REQUIRES_SHARED(Locks::mutator_lock_);
994*795d594fSAndroid Build Coastguard Worker 
995*795d594fSAndroid Build Coastguard Worker   template <ReadBarrierOption kReadBarrierOption = kWithReadBarrier>
996*795d594fSAndroid Build Coastguard Worker   ObjPtr<mirror::DexCache> GetDexCache() REQUIRES_SHARED(Locks::mutator_lock_);
997*795d594fSAndroid Build Coastguard Worker   template <ReadBarrierOption kReadBarrierOption>
998*795d594fSAndroid Build Coastguard Worker   ObjPtr<mirror::DexCache> GetObsoleteDexCache() REQUIRES_SHARED(Locks::mutator_lock_);
999*795d594fSAndroid Build Coastguard Worker 
1000*795d594fSAndroid Build Coastguard Worker   ALWAYS_INLINE ArtMethod* GetInterfaceMethodForProxyUnchecked(PointerSize pointer_size)
1001*795d594fSAndroid Build Coastguard Worker       REQUIRES_SHARED(Locks::mutator_lock_);
1002*795d594fSAndroid Build Coastguard Worker   ALWAYS_INLINE ArtMethod* GetInterfaceMethodIfProxy(PointerSize pointer_size)
1003*795d594fSAndroid Build Coastguard Worker       REQUIRES_SHARED(Locks::mutator_lock_);
1004*795d594fSAndroid Build Coastguard Worker 
1005*795d594fSAndroid Build Coastguard Worker   ArtMethod* GetNonObsoleteMethod() REQUIRES_SHARED(Locks::mutator_lock_);
1006*795d594fSAndroid Build Coastguard Worker 
1007*795d594fSAndroid Build Coastguard Worker   // May cause thread suspension due to class resolution.
1008*795d594fSAndroid Build Coastguard Worker   bool EqualParameters(Handle<mirror::ObjectArray<mirror::Class>> params)
1009*795d594fSAndroid Build Coastguard Worker       REQUIRES_SHARED(Locks::mutator_lock_);
1010*795d594fSAndroid Build Coastguard Worker 
1011*795d594fSAndroid Build Coastguard Worker   // Size of an instance of this native class.
1012*795d594fSAndroid Build Coastguard Worker   static constexpr size_t Size(PointerSize pointer_size) {
1013*795d594fSAndroid Build Coastguard Worker     return PtrSizedFieldsOffset(pointer_size) +
1014*795d594fSAndroid Build Coastguard Worker         (sizeof(PtrSizedFields) / sizeof(void*)) * static_cast<size_t>(pointer_size);
1015*795d594fSAndroid Build Coastguard Worker   }
1016*795d594fSAndroid Build Coastguard Worker 
1017*795d594fSAndroid Build Coastguard Worker   // Alignment of an instance of this native class.
1018*795d594fSAndroid Build Coastguard Worker   static constexpr size_t Alignment(PointerSize pointer_size) {
1019*795d594fSAndroid Build Coastguard Worker     // The ArtMethod alignment is the same as image pointer size. This differs from
1020*795d594fSAndroid Build Coastguard Worker     // alignof(ArtMethod) if cross-compiling with pointer_size != sizeof(void*).
1021*795d594fSAndroid Build Coastguard Worker     return static_cast<size_t>(pointer_size);
1022*795d594fSAndroid Build Coastguard Worker   }
1023*795d594fSAndroid Build Coastguard Worker 
1024*795d594fSAndroid Build Coastguard Worker   void CopyFrom(ArtMethod* src, PointerSize image_pointer_size)
1025*795d594fSAndroid Build Coastguard Worker       REQUIRES_SHARED(Locks::mutator_lock_);
1026*795d594fSAndroid Build Coastguard Worker 
1027*795d594fSAndroid Build Coastguard Worker   ALWAYS_INLINE void ResetCounter(uint16_t new_value);
1028*795d594fSAndroid Build Coastguard Worker   ALWAYS_INLINE void UpdateCounter(int32_t new_samples);
1029*795d594fSAndroid Build Coastguard Worker   ALWAYS_INLINE void SetHotCounter();
1030*795d594fSAndroid Build Coastguard Worker   ALWAYS_INLINE bool CounterIsHot();
1031*795d594fSAndroid Build Coastguard Worker   ALWAYS_INLINE uint16_t GetCounter();
1032*795d594fSAndroid Build Coastguard Worker   ALWAYS_INLINE bool CounterHasChanged(uint16_t threshold);
1033*795d594fSAndroid Build Coastguard Worker 
1034*795d594fSAndroid Build Coastguard Worker   ALWAYS_INLINE static constexpr uint16_t MaxCounter() {
1035*795d594fSAndroid Build Coastguard Worker     return std::numeric_limits<decltype(hotness_count_)>::max();
1036*795d594fSAndroid Build Coastguard Worker   }
1037*795d594fSAndroid Build Coastguard Worker 
1038*795d594fSAndroid Build Coastguard Worker   ALWAYS_INLINE uint32_t GetImtIndex() REQUIRES_SHARED(Locks::mutator_lock_);
1039*795d594fSAndroid Build Coastguard Worker 
1040*795d594fSAndroid Build Coastguard Worker   void CalculateAndSetImtIndex() REQUIRES_SHARED(Locks::mutator_lock_);
1041*795d594fSAndroid Build Coastguard Worker 
1042*795d594fSAndroid Build Coastguard Worker   static constexpr MemberOffset HotnessCountOffset() {
1043*795d594fSAndroid Build Coastguard Worker     return MemberOffset(OFFSETOF_MEMBER(ArtMethod, hotness_count_));
1044*795d594fSAndroid Build Coastguard Worker   }
1045*795d594fSAndroid Build Coastguard Worker 
1046*795d594fSAndroid Build Coastguard Worker   // Returns the method header for the compiled code containing 'pc'. Note that runtime
1047*795d594fSAndroid Build Coastguard Worker   // methods will return null for this method, as they are not oat based.
1048*795d594fSAndroid Build Coastguard Worker   const OatQuickMethodHeader* GetOatQuickMethodHeader(uintptr_t pc)
1049*795d594fSAndroid Build Coastguard Worker       REQUIRES_SHARED(Locks::mutator_lock_);
1050*795d594fSAndroid Build Coastguard Worker 
1051*795d594fSAndroid Build Coastguard Worker   // Get compiled code for the method, return null if no code exists.
1052*795d594fSAndroid Build Coastguard Worker   const void* GetOatMethodQuickCode(PointerSize pointer_size)
1053*795d594fSAndroid Build Coastguard Worker       REQUIRES_SHARED(Locks::mutator_lock_);
1054*795d594fSAndroid Build Coastguard Worker 
1055*795d594fSAndroid Build Coastguard Worker   // Returns a human-readable signature for 'm'. Something like "a.b.C.m" or
1056*795d594fSAndroid Build Coastguard Worker   // "a.b.C.m(II)V" (depending on the value of 'with_signature').
1057*795d594fSAndroid Build Coastguard Worker   static std::string PrettyMethod(ArtMethod* m, bool with_signature = true)
1058*795d594fSAndroid Build Coastguard Worker       REQUIRES_SHARED(Locks::mutator_lock_);
1059*795d594fSAndroid Build Coastguard Worker   std::string PrettyMethod(bool with_signature = true)
1060*795d594fSAndroid Build Coastguard Worker       REQUIRES_SHARED(Locks::mutator_lock_);
1061*795d594fSAndroid Build Coastguard Worker   // Returns the JNI native function name for the non-overloaded method 'm'.
1062*795d594fSAndroid Build Coastguard Worker   std::string JniShortName()
1063*795d594fSAndroid Build Coastguard Worker       REQUIRES_SHARED(Locks::mutator_lock_);
1064*795d594fSAndroid Build Coastguard Worker   // Returns the JNI native function name for the overloaded method 'm'.
1065*795d594fSAndroid Build Coastguard Worker   std::string JniLongName()
1066*795d594fSAndroid Build Coastguard Worker       REQUIRES_SHARED(Locks::mutator_lock_);
1067*795d594fSAndroid Build Coastguard Worker 
1068*795d594fSAndroid Build Coastguard Worker   // Visit the individual members of an ArtMethod.  Used by imgdiag.
1069*795d594fSAndroid Build Coastguard Worker   // As imgdiag does not support mixing instruction sets or pointer sizes (e.g., using imgdiag32
1070*795d594fSAndroid Build Coastguard Worker   // to inspect 64-bit images, etc.), we can go beneath the accessors directly to the class members.
1071*795d594fSAndroid Build Coastguard Worker   template <typename VisitorFunc>
1072*795d594fSAndroid Build Coastguard Worker   void VisitMembers(VisitorFunc& visitor) REQUIRES_SHARED(Locks::mutator_lock_) {
1073*795d594fSAndroid Build Coastguard Worker     DCHECK(IsImagePointerSize(kRuntimePointerSize));
1074*795d594fSAndroid Build Coastguard Worker     visitor(this, &declaring_class_, "declaring_class_");
1075*795d594fSAndroid Build Coastguard Worker     visitor(this, &access_flags_, "access_flags_");
1076*795d594fSAndroid Build Coastguard Worker     visitor(this, &dex_method_index_, "dex_method_index_");
1077*795d594fSAndroid Build Coastguard Worker     visitor(this, &method_index_, "method_index_");
1078*795d594fSAndroid Build Coastguard Worker     visitor(this, &hotness_count_, "hotness_count_");
1079*795d594fSAndroid Build Coastguard Worker     visitor(this, &ptr_sized_fields_.data_, "ptr_sized_fields_.data_");
1080*795d594fSAndroid Build Coastguard Worker     visitor(this,
1081*795d594fSAndroid Build Coastguard Worker             &ptr_sized_fields_.entry_point_from_quick_compiled_code_,
1082*795d594fSAndroid Build Coastguard Worker             "ptr_sized_fields_.entry_point_from_quick_compiled_code_");
1083*795d594fSAndroid Build Coastguard Worker   }
1084*795d594fSAndroid Build Coastguard Worker 
1085*795d594fSAndroid Build Coastguard Worker   // Returns the dex instructions of the code item for the art method. Returns an empty array for
1086*795d594fSAndroid Build Coastguard Worker   // the null code item case.
1087*795d594fSAndroid Build Coastguard Worker   ALWAYS_INLINE CodeItemInstructionAccessor DexInstructions()
1088*795d594fSAndroid Build Coastguard Worker       REQUIRES_SHARED(Locks::mutator_lock_);
1089*795d594fSAndroid Build Coastguard Worker 
1090*795d594fSAndroid Build Coastguard Worker   // Returns the dex code item data section of the DexFile for the art method.
1091*795d594fSAndroid Build Coastguard Worker   ALWAYS_INLINE CodeItemDataAccessor DexInstructionData()
1092*795d594fSAndroid Build Coastguard Worker       REQUIRES_SHARED(Locks::mutator_lock_);
1093*795d594fSAndroid Build Coastguard Worker 
1094*795d594fSAndroid Build Coastguard Worker   // Returns the dex code item debug info section of the DexFile for the art method.
1095*795d594fSAndroid Build Coastguard Worker   ALWAYS_INLINE CodeItemDebugInfoAccessor DexInstructionDebugInfo()
1096*795d594fSAndroid Build Coastguard Worker       REQUIRES_SHARED(Locks::mutator_lock_);
1097*795d594fSAndroid Build Coastguard Worker 
1098*795d594fSAndroid Build Coastguard Worker   GcRoot<mirror::Class>& DeclaringClassRoot() {
1099*795d594fSAndroid Build Coastguard Worker     return declaring_class_;
1100*795d594fSAndroid Build Coastguard Worker   }
1101*795d594fSAndroid Build Coastguard Worker 
1102*795d594fSAndroid Build Coastguard Worker  protected:
1103*795d594fSAndroid Build Coastguard Worker   // Field order required by test "ValidateFieldOrderOfJavaCppUnionClasses".
1104*795d594fSAndroid Build Coastguard Worker   // The class we are a part of.
1105*795d594fSAndroid Build Coastguard Worker   GcRoot<mirror::Class> declaring_class_;
1106*795d594fSAndroid Build Coastguard Worker 
1107*795d594fSAndroid Build Coastguard Worker   // Access flags; low 16 bits are defined by spec.
1108*795d594fSAndroid Build Coastguard Worker   // Getting and setting this flag needs to be atomic when concurrency is
1109*795d594fSAndroid Build Coastguard Worker   // possible, e.g. after this method's class is linked. Such as when setting
1110*795d594fSAndroid Build Coastguard Worker   // verifier flags and single-implementation flag.
1111*795d594fSAndroid Build Coastguard Worker   std::atomic<std::uint32_t> access_flags_;
1112*795d594fSAndroid Build Coastguard Worker 
1113*795d594fSAndroid Build Coastguard Worker   /* Dex file fields. The defining dex file is available via declaring_class_->dex_cache_ */
1114*795d594fSAndroid Build Coastguard Worker 
1115*795d594fSAndroid Build Coastguard Worker   // Index into method_ids of the dex file associated with this method.
1116*795d594fSAndroid Build Coastguard Worker   uint32_t dex_method_index_;
1117*795d594fSAndroid Build Coastguard Worker 
1118*795d594fSAndroid Build Coastguard Worker   /* End of dex file fields. */
1119*795d594fSAndroid Build Coastguard Worker 
1120*795d594fSAndroid Build Coastguard Worker   // Entry within a dispatch table for this method. For static/direct methods the index is into
1121*795d594fSAndroid Build Coastguard Worker   // the declaringClass.directMethods, for virtual methods the vtable and for interface methods the
1122*795d594fSAndroid Build Coastguard Worker   // interface's method array in `IfTable`s of implementing classes.
1123*795d594fSAndroid Build Coastguard Worker   uint16_t method_index_;
1124*795d594fSAndroid Build Coastguard Worker 
1125*795d594fSAndroid Build Coastguard Worker   union {
1126*795d594fSAndroid Build Coastguard Worker     // Non-abstract methods: The hotness we measure for this method. Not atomic,
1127*795d594fSAndroid Build Coastguard Worker     // as we allow missing increments: if the method is hot, we will see it eventually.
1128*795d594fSAndroid Build Coastguard Worker     uint16_t hotness_count_;
1129*795d594fSAndroid Build Coastguard Worker     // Abstract methods: IMT index.
1130*795d594fSAndroid Build Coastguard Worker     uint16_t imt_index_;
1131*795d594fSAndroid Build Coastguard Worker   };
1132*795d594fSAndroid Build Coastguard Worker 
1133*795d594fSAndroid Build Coastguard Worker   // Fake padding field gets inserted here.
1134*795d594fSAndroid Build Coastguard Worker 
1135*795d594fSAndroid Build Coastguard Worker   // Must be the last fields in the method.
1136*795d594fSAndroid Build Coastguard Worker   struct PtrSizedFields {
1137*795d594fSAndroid Build Coastguard Worker     // Depending on the method type, the data is
1138*795d594fSAndroid Build Coastguard Worker     //   - native method: pointer to the JNI function registered to this method
1139*795d594fSAndroid Build Coastguard Worker     //                    or a function to resolve the JNI function,
1140*795d594fSAndroid Build Coastguard Worker     //   - resolution method: pointer to a function to resolve the method and
1141*795d594fSAndroid Build Coastguard Worker     //                        the JNI function for @CriticalNative.
1142*795d594fSAndroid Build Coastguard Worker     //   - conflict method: ImtConflictTable,
1143*795d594fSAndroid Build Coastguard Worker     //   - abstract/interface method: the single-implementation if any,
1144*795d594fSAndroid Build Coastguard Worker     //   - proxy method: the original interface method or constructor,
1145*795d594fSAndroid Build Coastguard Worker     //   - default conflict method: null
1146*795d594fSAndroid Build Coastguard Worker     //   - other methods: during AOT the code item offset, at runtime a pointer
1147*795d594fSAndroid Build Coastguard Worker     //                    to the code item.
1148*795d594fSAndroid Build Coastguard Worker     void* data_;
1149*795d594fSAndroid Build Coastguard Worker 
1150*795d594fSAndroid Build Coastguard Worker     // Method dispatch from quick compiled code invokes this pointer which may cause bridging into
1151*795d594fSAndroid Build Coastguard Worker     // the interpreter.
1152*795d594fSAndroid Build Coastguard Worker     void* entry_point_from_quick_compiled_code_;
1153*795d594fSAndroid Build Coastguard Worker   } ptr_sized_fields_;
1154*795d594fSAndroid Build Coastguard Worker 
1155*795d594fSAndroid Build Coastguard Worker  private:
1156*795d594fSAndroid Build Coastguard Worker   uint16_t FindObsoleteDexClassDefIndex() REQUIRES_SHARED(Locks::mutator_lock_);
1157*795d594fSAndroid Build Coastguard Worker 
1158*795d594fSAndroid Build Coastguard Worker   static constexpr size_t PtrSizedFieldsOffset(PointerSize pointer_size) {
1159*795d594fSAndroid Build Coastguard Worker     // Round up to pointer size for padding field. Tested in art_method.cc.
1160*795d594fSAndroid Build Coastguard Worker     return RoundUp(offsetof(ArtMethod, hotness_count_) + sizeof(hotness_count_),
1161*795d594fSAndroid Build Coastguard Worker                    static_cast<size_t>(pointer_size));
1162*795d594fSAndroid Build Coastguard Worker   }
1163*795d594fSAndroid Build Coastguard Worker 
1164*795d594fSAndroid Build Coastguard Worker   // Compare given pointer size to the image pointer size.
1165*795d594fSAndroid Build Coastguard Worker   static bool IsImagePointerSize(PointerSize pointer_size);
1166*795d594fSAndroid Build Coastguard Worker 
1167*795d594fSAndroid Build Coastguard Worker   dex::TypeIndex GetReturnTypeIndex() REQUIRES_SHARED(Locks::mutator_lock_);
1168*795d594fSAndroid Build Coastguard Worker 
1169*795d594fSAndroid Build Coastguard Worker   template<typename T>
1170*795d594fSAndroid Build Coastguard Worker   ALWAYS_INLINE T GetNativePointer(MemberOffset offset, PointerSize pointer_size) const {
1171*795d594fSAndroid Build Coastguard Worker     static_assert(std::is_pointer<T>::value, "T must be a pointer type");
1172*795d594fSAndroid Build Coastguard Worker     const auto addr = reinterpret_cast<uintptr_t>(this) + offset.Uint32Value();
1173*795d594fSAndroid Build Coastguard Worker     if (pointer_size == PointerSize::k32) {
1174*795d594fSAndroid Build Coastguard Worker       return reinterpret_cast<T>(*reinterpret_cast<const uint32_t*>(addr));
1175*795d594fSAndroid Build Coastguard Worker     } else {
1176*795d594fSAndroid Build Coastguard Worker       auto v = *reinterpret_cast<const uint64_t*>(addr);
1177*795d594fSAndroid Build Coastguard Worker       return reinterpret_cast<T>(dchecked_integral_cast<uintptr_t>(v));
1178*795d594fSAndroid Build Coastguard Worker     }
1179*795d594fSAndroid Build Coastguard Worker   }
1180*795d594fSAndroid Build Coastguard Worker 
1181*795d594fSAndroid Build Coastguard Worker   template<typename T>
1182*795d594fSAndroid Build Coastguard Worker   ALWAYS_INLINE void SetNativePointer(MemberOffset offset, T new_value, PointerSize pointer_size)
1183*795d594fSAndroid Build Coastguard Worker       REQUIRES_SHARED(Locks::mutator_lock_) {
1184*795d594fSAndroid Build Coastguard Worker     static_assert(std::is_pointer<T>::value, "T must be a pointer type");
1185*795d594fSAndroid Build Coastguard Worker     const auto addr = reinterpret_cast<uintptr_t>(this) + offset.Uint32Value();
1186*795d594fSAndroid Build Coastguard Worker     if (pointer_size == PointerSize::k32) {
1187*795d594fSAndroid Build Coastguard Worker       uintptr_t ptr = reinterpret_cast<uintptr_t>(new_value);
1188*795d594fSAndroid Build Coastguard Worker       *reinterpret_cast<uint32_t*>(addr) = dchecked_integral_cast<uint32_t>(ptr);
1189*795d594fSAndroid Build Coastguard Worker     } else {
1190*795d594fSAndroid Build Coastguard Worker       *reinterpret_cast<uint64_t*>(addr) = reinterpret_cast<uintptr_t>(new_value);
1191*795d594fSAndroid Build Coastguard Worker     }
1192*795d594fSAndroid Build Coastguard Worker   }
1193*795d594fSAndroid Build Coastguard Worker 
1194*795d594fSAndroid Build Coastguard Worker   static inline bool IsValidIntrinsicUpdate(uint32_t modifier) {
1195*795d594fSAndroid Build Coastguard Worker     return (((modifier & kAccIntrinsic) == kAccIntrinsic) &&
1196*795d594fSAndroid Build Coastguard Worker             ((modifier & ~(kAccIntrinsic | kAccIntrinsicBits)) == 0) &&
1197*795d594fSAndroid Build Coastguard Worker             ((modifier & kAccIntrinsicBits) != 0));  // b/228049006: ensure intrinsic is not `kNone`
1198*795d594fSAndroid Build Coastguard Worker   }
1199*795d594fSAndroid Build Coastguard Worker 
1200*795d594fSAndroid Build Coastguard Worker   static inline bool OverlapsIntrinsicBits(uint32_t modifier) {
1201*795d594fSAndroid Build Coastguard Worker     return (modifier & kAccIntrinsicBits) != 0;
1202*795d594fSAndroid Build Coastguard Worker   }
1203*795d594fSAndroid Build Coastguard Worker 
1204*795d594fSAndroid Build Coastguard Worker   // This setter guarantees atomicity.
1205*795d594fSAndroid Build Coastguard Worker   void AddAccessFlags(uint32_t flag) REQUIRES_SHARED(Locks::mutator_lock_) {
1206*795d594fSAndroid Build Coastguard Worker     DCHECK_IMPLIES(IsIntrinsic(), !OverlapsIntrinsicBits(flag) || IsValidIntrinsicUpdate(flag));
1207*795d594fSAndroid Build Coastguard Worker     // None of the readers rely ordering.
1208*795d594fSAndroid Build Coastguard Worker     access_flags_.fetch_or(flag, std::memory_order_relaxed);
1209*795d594fSAndroid Build Coastguard Worker   }
1210*795d594fSAndroid Build Coastguard Worker 
1211*795d594fSAndroid Build Coastguard Worker   // This setter guarantees atomicity.
1212*795d594fSAndroid Build Coastguard Worker   void ClearAccessFlags(uint32_t flag) REQUIRES_SHARED(Locks::mutator_lock_) {
1213*795d594fSAndroid Build Coastguard Worker     DCHECK_IMPLIES(IsIntrinsic(), !OverlapsIntrinsicBits(flag) || IsValidIntrinsicUpdate(flag));
1214*795d594fSAndroid Build Coastguard Worker     access_flags_.fetch_and(~flag, std::memory_order_relaxed);
1215*795d594fSAndroid Build Coastguard Worker   }
1216*795d594fSAndroid Build Coastguard Worker 
1217*795d594fSAndroid Build Coastguard Worker   // Helper method for checking the class status of a possibly dead declaring class.
1218*795d594fSAndroid Build Coastguard Worker   // See `StillNeedsClinitCheckMayBeDead()` and `IsDeclaringClassVerifierMayBeDead()`.
1219*795d594fSAndroid Build Coastguard Worker   ObjPtr<mirror::Class> GetDeclaringClassMayBeDead() REQUIRES_SHARED(Locks::mutator_lock_);
1220*795d594fSAndroid Build Coastguard Worker 
1221*795d594fSAndroid Build Coastguard Worker   // Used by GetName and GetNameView to share common code.
1222*795d594fSAndroid Build Coastguard Worker   const char* GetRuntimeMethodName() REQUIRES_SHARED(Locks::mutator_lock_);
1223*795d594fSAndroid Build Coastguard Worker 
1224*795d594fSAndroid Build Coastguard Worker   DISALLOW_COPY_AND_ASSIGN(ArtMethod);  // Need to use CopyFrom to deal with 32 vs 64 bits.
1225*795d594fSAndroid Build Coastguard Worker };
1226*795d594fSAndroid Build Coastguard Worker 
1227*795d594fSAndroid Build Coastguard Worker class MethodCallback {
1228*795d594fSAndroid Build Coastguard Worker  public:
1229*795d594fSAndroid Build Coastguard Worker   virtual ~MethodCallback() {}
1230*795d594fSAndroid Build Coastguard Worker 
1231*795d594fSAndroid Build Coastguard Worker   virtual void RegisterNativeMethod(ArtMethod* method,
1232*795d594fSAndroid Build Coastguard Worker                                     const void* original_implementation,
1233*795d594fSAndroid Build Coastguard Worker                                     /*out*/void** new_implementation)
1234*795d594fSAndroid Build Coastguard Worker       REQUIRES_SHARED(Locks::mutator_lock_) = 0;
1235*795d594fSAndroid Build Coastguard Worker };
1236*795d594fSAndroid Build Coastguard Worker 
1237*795d594fSAndroid Build Coastguard Worker }  // namespace art
1238*795d594fSAndroid Build Coastguard Worker 
1239*795d594fSAndroid Build Coastguard Worker #endif  // ART_RUNTIME_ART_METHOD_H_
1240