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