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_INSTRUMENTATION_H_ 18*795d594fSAndroid Build Coastguard Worker #define ART_RUNTIME_INSTRUMENTATION_H_ 19*795d594fSAndroid Build Coastguard Worker 20*795d594fSAndroid Build Coastguard Worker #include <stdint.h> 21*795d594fSAndroid Build Coastguard Worker 22*795d594fSAndroid Build Coastguard Worker #include <functional> 23*795d594fSAndroid Build Coastguard Worker #include <list> 24*795d594fSAndroid Build Coastguard Worker #include <memory> 25*795d594fSAndroid Build Coastguard Worker #include <optional> 26*795d594fSAndroid Build Coastguard Worker #include <queue> 27*795d594fSAndroid Build Coastguard Worker #include <unordered_set> 28*795d594fSAndroid Build Coastguard Worker 29*795d594fSAndroid Build Coastguard Worker #include "arch/instruction_set.h" 30*795d594fSAndroid Build Coastguard Worker #include "base/locks.h" 31*795d594fSAndroid Build Coastguard Worker #include "base/macros.h" 32*795d594fSAndroid Build Coastguard Worker #include "base/pointer_size.h" 33*795d594fSAndroid Build Coastguard Worker #include "base/safe_map.h" 34*795d594fSAndroid Build Coastguard Worker #include "gc_root.h" 35*795d594fSAndroid Build Coastguard Worker #include "jvalue.h" 36*795d594fSAndroid Build Coastguard Worker #include "offsets.h" 37*795d594fSAndroid Build Coastguard Worker 38*795d594fSAndroid Build Coastguard Worker namespace art HIDDEN { 39*795d594fSAndroid Build Coastguard Worker namespace mirror { 40*795d594fSAndroid Build Coastguard Worker class Class; 41*795d594fSAndroid Build Coastguard Worker class Object; 42*795d594fSAndroid Build Coastguard Worker class Throwable; 43*795d594fSAndroid Build Coastguard Worker } // namespace mirror 44*795d594fSAndroid Build Coastguard Worker class ArtField; 45*795d594fSAndroid Build Coastguard Worker class ArtMethod; 46*795d594fSAndroid Build Coastguard Worker class Context; 47*795d594fSAndroid Build Coastguard Worker template <typename T> class Handle; 48*795d594fSAndroid Build Coastguard Worker template <typename T> class MutableHandle; 49*795d594fSAndroid Build Coastguard Worker struct NthCallerVisitor; 50*795d594fSAndroid Build Coastguard Worker union JValue; 51*795d594fSAndroid Build Coastguard Worker class OatQuickMethodHeader; 52*795d594fSAndroid Build Coastguard Worker class SHARED_LOCKABLE ReaderWriterMutex; 53*795d594fSAndroid Build Coastguard Worker class ShadowFrame; 54*795d594fSAndroid Build Coastguard Worker class Thread; 55*795d594fSAndroid Build Coastguard Worker enum class DeoptimizationMethodType; 56*795d594fSAndroid Build Coastguard Worker 57*795d594fSAndroid Build Coastguard Worker namespace instrumentation { 58*795d594fSAndroid Build Coastguard Worker 59*795d594fSAndroid Build Coastguard Worker 60*795d594fSAndroid Build Coastguard Worker // Do we want to deoptimize for method entry and exit listeners or just try to intercept 61*795d594fSAndroid Build Coastguard Worker // invocations? Deoptimization forces all code to run in the interpreter and considerably hurts the 62*795d594fSAndroid Build Coastguard Worker // application's performance. 63*795d594fSAndroid Build Coastguard Worker static constexpr bool kDeoptimizeForAccurateMethodEntryExitListeners = true; 64*795d594fSAndroid Build Coastguard Worker 65*795d594fSAndroid Build Coastguard Worker // an optional frame is either Some(const ShadowFrame& current_frame) or None depending on if the 66*795d594fSAndroid Build Coastguard Worker // method being exited has a shadow-frame associed with the current stack frame. In cases where 67*795d594fSAndroid Build Coastguard Worker // there is no shadow-frame associated with this stack frame this will be None. 68*795d594fSAndroid Build Coastguard Worker using OptionalFrame = std::optional<std::reference_wrapper<const ShadowFrame>>; 69*795d594fSAndroid Build Coastguard Worker 70*795d594fSAndroid Build Coastguard Worker // Instrumentation event listener API. Registered listeners will get the appropriate call back for 71*795d594fSAndroid Build Coastguard Worker // the events they are listening for. The call backs supply the thread, method and dex_pc the event 72*795d594fSAndroid Build Coastguard Worker // occurred upon. The thread may or may not be Thread::Current(). 73*795d594fSAndroid Build Coastguard Worker struct InstrumentationListener { InstrumentationListenerInstrumentationListener74*795d594fSAndroid Build Coastguard Worker InstrumentationListener() {} ~InstrumentationListenerInstrumentationListener75*795d594fSAndroid Build Coastguard Worker virtual ~InstrumentationListener() {} 76*795d594fSAndroid Build Coastguard Worker 77*795d594fSAndroid Build Coastguard Worker // Call-back for when a method is entered. 78*795d594fSAndroid Build Coastguard Worker virtual void MethodEntered(Thread* thread, ArtMethod* method) 79*795d594fSAndroid Build Coastguard Worker REQUIRES_SHARED(Locks::mutator_lock_) = 0; 80*795d594fSAndroid Build Coastguard Worker 81*795d594fSAndroid Build Coastguard Worker virtual void MethodExited(Thread* thread, 82*795d594fSAndroid Build Coastguard Worker ArtMethod* method, 83*795d594fSAndroid Build Coastguard Worker OptionalFrame frame, 84*795d594fSAndroid Build Coastguard Worker MutableHandle<mirror::Object>& return_value) 85*795d594fSAndroid Build Coastguard Worker REQUIRES_SHARED(Locks::mutator_lock_); 86*795d594fSAndroid Build Coastguard Worker 87*795d594fSAndroid Build Coastguard Worker // Call-back for when a method is exited. The implementor should either handler-ize the return 88*795d594fSAndroid Build Coastguard Worker // value (if appropriate) or use the alternate MethodExited callback instead if they need to 89*795d594fSAndroid Build Coastguard Worker // go through a suspend point. 90*795d594fSAndroid Build Coastguard Worker virtual void MethodExited(Thread* thread, 91*795d594fSAndroid Build Coastguard Worker ArtMethod* method, 92*795d594fSAndroid Build Coastguard Worker OptionalFrame frame, 93*795d594fSAndroid Build Coastguard Worker JValue& return_value) 94*795d594fSAndroid Build Coastguard Worker REQUIRES_SHARED(Locks::mutator_lock_) = 0; 95*795d594fSAndroid Build Coastguard Worker 96*795d594fSAndroid Build Coastguard Worker // Call-back for when a method is popped due to an exception throw. A method will either cause a 97*795d594fSAndroid Build Coastguard Worker // MethodExited call-back or a MethodUnwind call-back when its activation is removed. 98*795d594fSAndroid Build Coastguard Worker virtual void MethodUnwind(Thread* thread, 99*795d594fSAndroid Build Coastguard Worker ArtMethod* method, 100*795d594fSAndroid Build Coastguard Worker uint32_t dex_pc) 101*795d594fSAndroid Build Coastguard Worker REQUIRES_SHARED(Locks::mutator_lock_) = 0; 102*795d594fSAndroid Build Coastguard Worker 103*795d594fSAndroid Build Coastguard Worker // Call-back for when the dex pc moves in a method. 104*795d594fSAndroid Build Coastguard Worker virtual void DexPcMoved(Thread* thread, 105*795d594fSAndroid Build Coastguard Worker Handle<mirror::Object> this_object, 106*795d594fSAndroid Build Coastguard Worker ArtMethod* method, 107*795d594fSAndroid Build Coastguard Worker uint32_t new_dex_pc) 108*795d594fSAndroid Build Coastguard Worker REQUIRES_SHARED(Locks::mutator_lock_) = 0; 109*795d594fSAndroid Build Coastguard Worker 110*795d594fSAndroid Build Coastguard Worker // Call-back for when we read from a field. 111*795d594fSAndroid Build Coastguard Worker virtual void FieldRead(Thread* thread, 112*795d594fSAndroid Build Coastguard Worker Handle<mirror::Object> this_object, 113*795d594fSAndroid Build Coastguard Worker ArtMethod* method, 114*795d594fSAndroid Build Coastguard Worker uint32_t dex_pc, 115*795d594fSAndroid Build Coastguard Worker ArtField* field) = 0; 116*795d594fSAndroid Build Coastguard Worker 117*795d594fSAndroid Build Coastguard Worker virtual void FieldWritten(Thread* thread, 118*795d594fSAndroid Build Coastguard Worker Handle<mirror::Object> this_object, 119*795d594fSAndroid Build Coastguard Worker ArtMethod* method, 120*795d594fSAndroid Build Coastguard Worker uint32_t dex_pc, 121*795d594fSAndroid Build Coastguard Worker ArtField* field, 122*795d594fSAndroid Build Coastguard Worker Handle<mirror::Object> field_value) 123*795d594fSAndroid Build Coastguard Worker REQUIRES_SHARED(Locks::mutator_lock_); 124*795d594fSAndroid Build Coastguard Worker 125*795d594fSAndroid Build Coastguard Worker // Call-back for when we write into a field. 126*795d594fSAndroid Build Coastguard Worker virtual void FieldWritten(Thread* thread, 127*795d594fSAndroid Build Coastguard Worker Handle<mirror::Object> this_object, 128*795d594fSAndroid Build Coastguard Worker ArtMethod* method, 129*795d594fSAndroid Build Coastguard Worker uint32_t dex_pc, 130*795d594fSAndroid Build Coastguard Worker ArtField* field, 131*795d594fSAndroid Build Coastguard Worker const JValue& field_value) 132*795d594fSAndroid Build Coastguard Worker REQUIRES_SHARED(Locks::mutator_lock_) = 0; 133*795d594fSAndroid Build Coastguard Worker 134*795d594fSAndroid Build Coastguard Worker // Call-back when an exception is thrown. 135*795d594fSAndroid Build Coastguard Worker virtual void ExceptionThrown(Thread* thread, 136*795d594fSAndroid Build Coastguard Worker Handle<mirror::Throwable> exception_object) 137*795d594fSAndroid Build Coastguard Worker REQUIRES_SHARED(Locks::mutator_lock_) = 0; 138*795d594fSAndroid Build Coastguard Worker 139*795d594fSAndroid Build Coastguard Worker // Call-back when an exception is caught/handled by java code. 140*795d594fSAndroid Build Coastguard Worker virtual void ExceptionHandled(Thread* thread, Handle<mirror::Throwable> exception_object) 141*795d594fSAndroid Build Coastguard Worker REQUIRES_SHARED(Locks::mutator_lock_) = 0; 142*795d594fSAndroid Build Coastguard Worker 143*795d594fSAndroid Build Coastguard Worker // Call-back for when we execute a branch. 144*795d594fSAndroid Build Coastguard Worker virtual void Branch(Thread* thread, 145*795d594fSAndroid Build Coastguard Worker ArtMethod* method, 146*795d594fSAndroid Build Coastguard Worker uint32_t dex_pc, 147*795d594fSAndroid Build Coastguard Worker int32_t dex_pc_offset) 148*795d594fSAndroid Build Coastguard Worker REQUIRES_SHARED(Locks::mutator_lock_) = 0; 149*795d594fSAndroid Build Coastguard Worker 150*795d594fSAndroid Build Coastguard Worker // Call-back when a shadow_frame with the needs_notify_pop_ boolean set is popped off the stack by 151*795d594fSAndroid Build Coastguard Worker // either return or exceptions. Normally instrumentation listeners should ensure that there are 152*795d594fSAndroid Build Coastguard Worker // shadow-frames by deoptimizing stacks. 153*795d594fSAndroid Build Coastguard Worker virtual void WatchedFramePop([[maybe_unused]] Thread* thread, 154*795d594fSAndroid Build Coastguard Worker [[maybe_unused]] const ShadowFrame& frame) 155*795d594fSAndroid Build Coastguard Worker REQUIRES_SHARED(Locks::mutator_lock_) = 0; 156*795d594fSAndroid Build Coastguard Worker }; 157*795d594fSAndroid Build Coastguard Worker 158*795d594fSAndroid Build Coastguard Worker class Instrumentation; 159*795d594fSAndroid Build Coastguard Worker // A helper to send instrumentation events while popping the stack in a safe way. 160*795d594fSAndroid Build Coastguard Worker class InstrumentationStackPopper { 161*795d594fSAndroid Build Coastguard Worker public: 162*795d594fSAndroid Build Coastguard Worker explicit InstrumentationStackPopper(Thread* self); 163*795d594fSAndroid Build Coastguard Worker ~InstrumentationStackPopper() REQUIRES_SHARED(Locks::mutator_lock_); 164*795d594fSAndroid Build Coastguard Worker 165*795d594fSAndroid Build Coastguard Worker // Increase the number of frames being popped up to `stack_pointer`. Return true if the 166*795d594fSAndroid Build Coastguard Worker // frames were popped without any exceptions, false otherwise. The exception that caused 167*795d594fSAndroid Build Coastguard Worker // the pop is 'exception'. 168*795d594fSAndroid Build Coastguard Worker bool PopFramesTo(uintptr_t stack_pointer, /*in-out*/MutableHandle<mirror::Throwable>& exception) 169*795d594fSAndroid Build Coastguard Worker REQUIRES_SHARED(Locks::mutator_lock_); 170*795d594fSAndroid Build Coastguard Worker 171*795d594fSAndroid Build Coastguard Worker private: 172*795d594fSAndroid Build Coastguard Worker Thread* self_; 173*795d594fSAndroid Build Coastguard Worker Instrumentation* instrumentation_; 174*795d594fSAndroid Build Coastguard Worker // The stack pointer limit for frames to pop. 175*795d594fSAndroid Build Coastguard Worker uintptr_t pop_until_; 176*795d594fSAndroid Build Coastguard Worker }; 177*795d594fSAndroid Build Coastguard Worker 178*795d594fSAndroid Build Coastguard Worker // Instrumentation is a catch-all for when extra information is required from the runtime. The 179*795d594fSAndroid Build Coastguard Worker // typical use for instrumentation is for profiling and debugging. Instrumentation may add stubs 180*795d594fSAndroid Build Coastguard Worker // to method entry and exit, it may also force execution to be switched to the interpreter and 181*795d594fSAndroid Build Coastguard Worker // trigger deoptimization. 182*795d594fSAndroid Build Coastguard Worker class Instrumentation { 183*795d594fSAndroid Build Coastguard Worker public: 184*795d594fSAndroid Build Coastguard Worker enum InstrumentationEvent { 185*795d594fSAndroid Build Coastguard Worker kMethodEntered = 0x1, 186*795d594fSAndroid Build Coastguard Worker kMethodExited = 0x2, 187*795d594fSAndroid Build Coastguard Worker kMethodUnwind = 0x4, 188*795d594fSAndroid Build Coastguard Worker kDexPcMoved = 0x8, 189*795d594fSAndroid Build Coastguard Worker kFieldRead = 0x10, 190*795d594fSAndroid Build Coastguard Worker kFieldWritten = 0x20, 191*795d594fSAndroid Build Coastguard Worker kExceptionThrown = 0x40, 192*795d594fSAndroid Build Coastguard Worker kBranch = 0x80, 193*795d594fSAndroid Build Coastguard Worker kWatchedFramePop = 0x200, 194*795d594fSAndroid Build Coastguard Worker kExceptionHandled = 0x400, 195*795d594fSAndroid Build Coastguard Worker }; 196*795d594fSAndroid Build Coastguard Worker 197*795d594fSAndroid Build Coastguard Worker enum class InstrumentationLevel { 198*795d594fSAndroid Build Coastguard Worker kInstrumentNothing, // execute without instrumentation 199*795d594fSAndroid Build Coastguard Worker kInstrumentWithEntryExitHooks, // execute with entry/exit hooks 200*795d594fSAndroid Build Coastguard Worker kInstrumentWithInterpreter // execute with interpreter 201*795d594fSAndroid Build Coastguard Worker }; 202*795d594fSAndroid Build Coastguard Worker 203*795d594fSAndroid Build Coastguard Worker static constexpr uint8_t kFastTraceListeners = 0b01; 204*795d594fSAndroid Build Coastguard Worker static constexpr uint8_t kSlowMethodEntryExitListeners = 0b10; 205*795d594fSAndroid Build Coastguard Worker 206*795d594fSAndroid Build Coastguard Worker Instrumentation(); 207*795d594fSAndroid Build Coastguard Worker RunExitHooksOffset()208*795d594fSAndroid Build Coastguard Worker static constexpr MemberOffset RunExitHooksOffset() { 209*795d594fSAndroid Build Coastguard Worker // Assert that run_entry_exit_hooks_ is 8bits wide. If the size changes 210*795d594fSAndroid Build Coastguard Worker // update the compare instructions in the code generator when generating checks for 211*795d594fSAndroid Build Coastguard Worker // MethodEntryExitHooks. 212*795d594fSAndroid Build Coastguard Worker static_assert(sizeof(run_exit_hooks_) == 1, "run_exit_hooks_ isn't expected size"); 213*795d594fSAndroid Build Coastguard Worker return MemberOffset(OFFSETOF_MEMBER(Instrumentation, run_exit_hooks_)); 214*795d594fSAndroid Build Coastguard Worker } 215*795d594fSAndroid Build Coastguard Worker HaveMethodEntryListenersOffset()216*795d594fSAndroid Build Coastguard Worker static constexpr MemberOffset HaveMethodEntryListenersOffset() { 217*795d594fSAndroid Build Coastguard Worker // Assert that have_method_entry_listeners_ is 8bits wide. If the size changes 218*795d594fSAndroid Build Coastguard Worker // update the compare instructions in the code generator when generating checks for 219*795d594fSAndroid Build Coastguard Worker // MethodEntryExitHooks. 220*795d594fSAndroid Build Coastguard Worker static_assert(sizeof(have_method_entry_listeners_) == 1, 221*795d594fSAndroid Build Coastguard Worker "have_method_entry_listeners_ isn't expected size"); 222*795d594fSAndroid Build Coastguard Worker return MemberOffset(OFFSETOF_MEMBER(Instrumentation, have_method_entry_listeners_)); 223*795d594fSAndroid Build Coastguard Worker } 224*795d594fSAndroid Build Coastguard Worker HaveMethodExitListenersOffset()225*795d594fSAndroid Build Coastguard Worker static constexpr MemberOffset HaveMethodExitListenersOffset() { 226*795d594fSAndroid Build Coastguard Worker // Assert that have_method_exit_slow_listeners_ is 8bits wide. If the size changes 227*795d594fSAndroid Build Coastguard Worker // update the compare instructions in the code generator when generating checks for 228*795d594fSAndroid Build Coastguard Worker // MethodEntryExitHooks. 229*795d594fSAndroid Build Coastguard Worker static_assert(sizeof(have_method_exit_listeners_) == 1, 230*795d594fSAndroid Build Coastguard Worker "have_method_exit_listeners_ isn't expected size"); 231*795d594fSAndroid Build Coastguard Worker return MemberOffset(OFFSETOF_MEMBER(Instrumentation, have_method_exit_listeners_)); 232*795d594fSAndroid Build Coastguard Worker } 233*795d594fSAndroid Build Coastguard Worker 234*795d594fSAndroid Build Coastguard Worker // Add a listener to be notified of the masked together sent of instrumentation events. This 235*795d594fSAndroid Build Coastguard Worker // suspend the runtime to install stubs. You are expected to hold the mutator lock as a proxy 236*795d594fSAndroid Build Coastguard Worker // for saying you should have suspended all threads (installing stubs while threads are running 237*795d594fSAndroid Build Coastguard Worker // will break). 238*795d594fSAndroid Build Coastguard Worker EXPORT void AddListener(InstrumentationListener* listener, 239*795d594fSAndroid Build Coastguard Worker uint32_t events, 240*795d594fSAndroid Build Coastguard Worker bool is_trace_listener = false) 241*795d594fSAndroid Build Coastguard Worker REQUIRES(Locks::mutator_lock_, !Locks::thread_list_lock_, !Locks::classlinker_classes_lock_); 242*795d594fSAndroid Build Coastguard Worker 243*795d594fSAndroid Build Coastguard Worker // Removes listeners for the specified events. 244*795d594fSAndroid Build Coastguard Worker EXPORT void RemoveListener(InstrumentationListener* listener, 245*795d594fSAndroid Build Coastguard Worker uint32_t events, 246*795d594fSAndroid Build Coastguard Worker bool is_trace_listener = false) 247*795d594fSAndroid Build Coastguard Worker REQUIRES(Locks::mutator_lock_, !Locks::thread_list_lock_, !Locks::classlinker_classes_lock_); 248*795d594fSAndroid Build Coastguard Worker 249*795d594fSAndroid Build Coastguard Worker // Calls UndeoptimizeEverything which may visit class linker classes through ConfigureStubs. 250*795d594fSAndroid Build Coastguard Worker // try_switch_to_non_debuggable specifies if we can switch the runtime back to non-debuggable. 251*795d594fSAndroid Build Coastguard Worker // When a debugger is attached to a non-debuggable app, we switch the runtime to debuggable and 252*795d594fSAndroid Build Coastguard Worker // when we are detaching the debugger we move back to non-debuggable. If we are disabling 253*795d594fSAndroid Build Coastguard Worker // deoptimization for other reasons (ex: removing the last breakpoint) while the debugger is still 254*795d594fSAndroid Build Coastguard Worker // connected, we pass false to stay in debuggable. Switching runtimes is expensive so we only want 255*795d594fSAndroid Build Coastguard Worker // to switch when we know debug features aren't needed anymore. 256*795d594fSAndroid Build Coastguard Worker EXPORT void DisableDeoptimization(const char* key, bool try_switch_to_non_debuggable) 257*795d594fSAndroid Build Coastguard Worker REQUIRES(Locks::mutator_lock_, Roles::uninterruptible_); 258*795d594fSAndroid Build Coastguard Worker 259*795d594fSAndroid Build Coastguard Worker // Enables entry exit hooks support. This is called in preparation for debug requests that require 260*795d594fSAndroid Build Coastguard Worker // calling method entry / exit hooks. 261*795d594fSAndroid Build Coastguard Worker EXPORT void EnableEntryExitHooks(const char* key) 262*795d594fSAndroid Build Coastguard Worker REQUIRES(Locks::mutator_lock_, Roles::uninterruptible_); 263*795d594fSAndroid Build Coastguard Worker AreAllMethodsDeoptimized()264*795d594fSAndroid Build Coastguard Worker bool AreAllMethodsDeoptimized() const { 265*795d594fSAndroid Build Coastguard Worker return InterpreterStubsInstalled(); 266*795d594fSAndroid Build Coastguard Worker } 267*795d594fSAndroid Build Coastguard Worker bool ShouldNotifyMethodEnterExitEvents() const REQUIRES_SHARED(Locks::mutator_lock_); 268*795d594fSAndroid Build Coastguard Worker 269*795d594fSAndroid Build Coastguard Worker // Executes everything with interpreter. 270*795d594fSAndroid Build Coastguard Worker EXPORT void DeoptimizeEverything(const char* key) 271*795d594fSAndroid Build Coastguard Worker REQUIRES(Locks::mutator_lock_, Roles::uninterruptible_) 272*795d594fSAndroid Build Coastguard Worker REQUIRES(!Locks::thread_list_lock_, !Locks::classlinker_classes_lock_); 273*795d594fSAndroid Build Coastguard Worker 274*795d594fSAndroid Build Coastguard Worker // Executes everything with compiled code (or interpreter if there is no code). May visit class 275*795d594fSAndroid Build Coastguard Worker // linker classes through ConfigureStubs. 276*795d594fSAndroid Build Coastguard Worker EXPORT void UndeoptimizeEverything(const char* key) 277*795d594fSAndroid Build Coastguard Worker REQUIRES(Locks::mutator_lock_, Roles::uninterruptible_) 278*795d594fSAndroid Build Coastguard Worker REQUIRES(!Locks::thread_list_lock_, !Locks::classlinker_classes_lock_); 279*795d594fSAndroid Build Coastguard Worker 280*795d594fSAndroid Build Coastguard Worker // Deoptimize a method by forcing its execution with the interpreter. Nevertheless, a static 281*795d594fSAndroid Build Coastguard Worker // method (except a class initializer) set to the resolution trampoline will be deoptimized only 282*795d594fSAndroid Build Coastguard Worker // once its declaring class is initialized. 283*795d594fSAndroid Build Coastguard Worker EXPORT void Deoptimize(ArtMethod* method) 284*795d594fSAndroid Build Coastguard Worker REQUIRES(Locks::mutator_lock_, !Locks::thread_list_lock_); 285*795d594fSAndroid Build Coastguard Worker 286*795d594fSAndroid Build Coastguard Worker // Undeoptimze the method by restoring its entrypoints. Nevertheless, a static method 287*795d594fSAndroid Build Coastguard Worker // (except a class initializer) set to the resolution trampoline will be updated only once its 288*795d594fSAndroid Build Coastguard Worker // declaring class is initialized. 289*795d594fSAndroid Build Coastguard Worker EXPORT void Undeoptimize(ArtMethod* method) 290*795d594fSAndroid Build Coastguard Worker REQUIRES(Locks::mutator_lock_, !Locks::thread_list_lock_); 291*795d594fSAndroid Build Coastguard Worker 292*795d594fSAndroid Build Coastguard Worker // Indicates whether the method has been deoptimized so it is executed with the interpreter. 293*795d594fSAndroid Build Coastguard Worker EXPORT bool IsDeoptimized(ArtMethod* method) REQUIRES_SHARED(Locks::mutator_lock_); 294*795d594fSAndroid Build Coastguard Worker 295*795d594fSAndroid Build Coastguard Worker // Indicates if any method needs to be deoptimized. This is used to avoid walking the stack to 296*795d594fSAndroid Build Coastguard Worker // determine if a deoptimization is required. 297*795d594fSAndroid Build Coastguard Worker bool IsDeoptimizedMethodsEmpty() const REQUIRES_SHARED(Locks::mutator_lock_); 298*795d594fSAndroid Build Coastguard Worker 299*795d594fSAndroid Build Coastguard Worker // Enable method tracing by installing instrumentation entry/exit stubs or interpreter. 300*795d594fSAndroid Build Coastguard Worker EXPORT void EnableMethodTracing( 301*795d594fSAndroid Build Coastguard Worker const char* key, 302*795d594fSAndroid Build Coastguard Worker InstrumentationListener* listener, 303*795d594fSAndroid Build Coastguard Worker bool needs_interpreter = kDeoptimizeForAccurateMethodEntryExitListeners) 304*795d594fSAndroid Build Coastguard Worker REQUIRES(Locks::mutator_lock_, Roles::uninterruptible_) 305*795d594fSAndroid Build Coastguard Worker REQUIRES(!Locks::thread_list_lock_, !Locks::classlinker_classes_lock_); 306*795d594fSAndroid Build Coastguard Worker 307*795d594fSAndroid Build Coastguard Worker // Disable method tracing by uninstalling instrumentation entry/exit stubs or interpreter. 308*795d594fSAndroid Build Coastguard Worker EXPORT void DisableMethodTracing(const char* key) 309*795d594fSAndroid Build Coastguard Worker REQUIRES(Locks::mutator_lock_, Roles::uninterruptible_) 310*795d594fSAndroid Build Coastguard Worker REQUIRES(!Locks::thread_list_lock_, !Locks::classlinker_classes_lock_); 311*795d594fSAndroid Build Coastguard Worker 312*795d594fSAndroid Build Coastguard Worker void InstrumentQuickAllocEntryPoints() REQUIRES(!Locks::instrument_entrypoints_lock_); 313*795d594fSAndroid Build Coastguard Worker void UninstrumentQuickAllocEntryPoints() REQUIRES(!Locks::instrument_entrypoints_lock_); 314*795d594fSAndroid Build Coastguard Worker void InstrumentQuickAllocEntryPointsLocked() 315*795d594fSAndroid Build Coastguard Worker REQUIRES(Locks::instrument_entrypoints_lock_, !Locks::thread_list_lock_, 316*795d594fSAndroid Build Coastguard Worker !Locks::runtime_shutdown_lock_); 317*795d594fSAndroid Build Coastguard Worker void UninstrumentQuickAllocEntryPointsLocked() 318*795d594fSAndroid Build Coastguard Worker REQUIRES(Locks::instrument_entrypoints_lock_, !Locks::thread_list_lock_, 319*795d594fSAndroid Build Coastguard Worker !Locks::runtime_shutdown_lock_); 320*795d594fSAndroid Build Coastguard Worker void ResetQuickAllocEntryPoints() REQUIRES(Locks::runtime_shutdown_lock_); 321*795d594fSAndroid Build Coastguard Worker 322*795d594fSAndroid Build Coastguard Worker // Returns a string representation of the given entry point. 323*795d594fSAndroid Build Coastguard Worker static std::string EntryPointString(const void* code); 324*795d594fSAndroid Build Coastguard Worker 325*795d594fSAndroid Build Coastguard Worker // Initialize the entrypoint of the method .`aot_code` is the AOT code. 326*795d594fSAndroid Build Coastguard Worker EXPORT void InitializeMethodsCode(ArtMethod* method, const void* aot_code) 327*795d594fSAndroid Build Coastguard Worker REQUIRES_SHARED(Locks::mutator_lock_); 328*795d594fSAndroid Build Coastguard Worker 329*795d594fSAndroid Build Coastguard Worker // Update the code of a method respecting any installed stubs. 330*795d594fSAndroid Build Coastguard Worker void UpdateMethodsCode(ArtMethod* method, const void* new_code) 331*795d594fSAndroid Build Coastguard Worker REQUIRES_SHARED(Locks::mutator_lock_); 332*795d594fSAndroid Build Coastguard Worker 333*795d594fSAndroid Build Coastguard Worker // Update the code of a native method to a JITed stub. 334*795d594fSAndroid Build Coastguard Worker void UpdateNativeMethodsCodeToJitCode(ArtMethod* method, const void* new_code) 335*795d594fSAndroid Build Coastguard Worker REQUIRES_SHARED(Locks::mutator_lock_); 336*795d594fSAndroid Build Coastguard Worker 337*795d594fSAndroid Build Coastguard Worker // Return the code that we can execute for an invoke including from the JIT. 338*795d594fSAndroid Build Coastguard Worker EXPORT const void* GetCodeForInvoke(ArtMethod* method) REQUIRES_SHARED(Locks::mutator_lock_); 339*795d594fSAndroid Build Coastguard Worker 340*795d594fSAndroid Build Coastguard Worker // Return the code that we can execute considering the current instrumentation level. 341*795d594fSAndroid Build Coastguard Worker // If interpreter stubs are installed return interpreter bridge. If the entry exit stubs 342*795d594fSAndroid Build Coastguard Worker // are installed return an instrumentation entry point. Otherwise, return the code that 343*795d594fSAndroid Build Coastguard Worker // can be executed including from the JIT. 344*795d594fSAndroid Build Coastguard Worker const void* GetMaybeInstrumentedCodeForInvoke(ArtMethod* method) 345*795d594fSAndroid Build Coastguard Worker REQUIRES_SHARED(Locks::mutator_lock_); 346*795d594fSAndroid Build Coastguard Worker ForceInterpretOnly()347*795d594fSAndroid Build Coastguard Worker void ForceInterpretOnly() { 348*795d594fSAndroid Build Coastguard Worker forced_interpret_only_ = true; 349*795d594fSAndroid Build Coastguard Worker } 350*795d594fSAndroid Build Coastguard Worker EntryExitStubsInstalled()351*795d594fSAndroid Build Coastguard Worker bool EntryExitStubsInstalled() const { 352*795d594fSAndroid Build Coastguard Worker return instrumentation_level_ == InstrumentationLevel::kInstrumentWithEntryExitHooks || 353*795d594fSAndroid Build Coastguard Worker instrumentation_level_ == InstrumentationLevel::kInstrumentWithInterpreter; 354*795d594fSAndroid Build Coastguard Worker } 355*795d594fSAndroid Build Coastguard Worker InterpreterStubsInstalled()356*795d594fSAndroid Build Coastguard Worker bool InterpreterStubsInstalled() const { 357*795d594fSAndroid Build Coastguard Worker return instrumentation_level_ == InstrumentationLevel::kInstrumentWithInterpreter; 358*795d594fSAndroid Build Coastguard Worker } 359*795d594fSAndroid Build Coastguard Worker 360*795d594fSAndroid Build Coastguard Worker // Called by ArtMethod::Invoke to determine dispatch mechanism. InterpretOnly()361*795d594fSAndroid Build Coastguard Worker bool InterpretOnly() const { 362*795d594fSAndroid Build Coastguard Worker return forced_interpret_only_ || InterpreterStubsInstalled(); 363*795d594fSAndroid Build Coastguard Worker } 364*795d594fSAndroid Build Coastguard Worker bool InterpretOnly(ArtMethod* method) REQUIRES_SHARED(Locks::mutator_lock_); 365*795d594fSAndroid Build Coastguard Worker IsForcedInterpretOnly()366*795d594fSAndroid Build Coastguard Worker bool IsForcedInterpretOnly() const { 367*795d594fSAndroid Build Coastguard Worker return forced_interpret_only_; 368*795d594fSAndroid Build Coastguard Worker } 369*795d594fSAndroid Build Coastguard Worker RunExitHooks()370*795d594fSAndroid Build Coastguard Worker bool RunExitHooks() const { 371*795d594fSAndroid Build Coastguard Worker return run_exit_hooks_; 372*795d594fSAndroid Build Coastguard Worker } 373*795d594fSAndroid Build Coastguard Worker HasMethodEntryListeners()374*795d594fSAndroid Build Coastguard Worker bool HasMethodEntryListeners() const REQUIRES_SHARED(Locks::mutator_lock_) { 375*795d594fSAndroid Build Coastguard Worker return have_method_entry_listeners_ != 0; 376*795d594fSAndroid Build Coastguard Worker } 377*795d594fSAndroid Build Coastguard Worker HasMethodExitListeners()378*795d594fSAndroid Build Coastguard Worker bool HasMethodExitListeners() const REQUIRES_SHARED(Locks::mutator_lock_) { 379*795d594fSAndroid Build Coastguard Worker return have_method_exit_listeners_ != 0; 380*795d594fSAndroid Build Coastguard Worker } 381*795d594fSAndroid Build Coastguard Worker HasFastMethodEntryListenersOnly()382*795d594fSAndroid Build Coastguard Worker bool HasFastMethodEntryListenersOnly() const REQUIRES_SHARED(Locks::mutator_lock_) { 383*795d594fSAndroid Build Coastguard Worker return have_method_entry_listeners_ == kFastTraceListeners; 384*795d594fSAndroid Build Coastguard Worker } 385*795d594fSAndroid Build Coastguard Worker HasFastMethodExitListenersOnly()386*795d594fSAndroid Build Coastguard Worker bool HasFastMethodExitListenersOnly() const REQUIRES_SHARED(Locks::mutator_lock_) { 387*795d594fSAndroid Build Coastguard Worker return have_method_exit_listeners_ == kFastTraceListeners; 388*795d594fSAndroid Build Coastguard Worker } 389*795d594fSAndroid Build Coastguard Worker HasMethodUnwindListeners()390*795d594fSAndroid Build Coastguard Worker bool HasMethodUnwindListeners() const REQUIRES_SHARED(Locks::mutator_lock_) { 391*795d594fSAndroid Build Coastguard Worker return have_method_unwind_listeners_; 392*795d594fSAndroid Build Coastguard Worker } 393*795d594fSAndroid Build Coastguard Worker HasDexPcListeners()394*795d594fSAndroid Build Coastguard Worker bool HasDexPcListeners() const REQUIRES_SHARED(Locks::mutator_lock_) { 395*795d594fSAndroid Build Coastguard Worker return have_dex_pc_listeners_; 396*795d594fSAndroid Build Coastguard Worker } 397*795d594fSAndroid Build Coastguard Worker HasFieldReadListeners()398*795d594fSAndroid Build Coastguard Worker bool HasFieldReadListeners() const REQUIRES_SHARED(Locks::mutator_lock_) { 399*795d594fSAndroid Build Coastguard Worker return have_field_read_listeners_; 400*795d594fSAndroid Build Coastguard Worker } 401*795d594fSAndroid Build Coastguard Worker HasFieldWriteListeners()402*795d594fSAndroid Build Coastguard Worker bool HasFieldWriteListeners() const REQUIRES_SHARED(Locks::mutator_lock_) { 403*795d594fSAndroid Build Coastguard Worker return have_field_write_listeners_; 404*795d594fSAndroid Build Coastguard Worker } 405*795d594fSAndroid Build Coastguard Worker HasExceptionThrownListeners()406*795d594fSAndroid Build Coastguard Worker bool HasExceptionThrownListeners() const REQUIRES_SHARED(Locks::mutator_lock_) { 407*795d594fSAndroid Build Coastguard Worker return have_exception_thrown_listeners_; 408*795d594fSAndroid Build Coastguard Worker } 409*795d594fSAndroid Build Coastguard Worker HasBranchListeners()410*795d594fSAndroid Build Coastguard Worker bool HasBranchListeners() const REQUIRES_SHARED(Locks::mutator_lock_) { 411*795d594fSAndroid Build Coastguard Worker return have_branch_listeners_; 412*795d594fSAndroid Build Coastguard Worker } 413*795d594fSAndroid Build Coastguard Worker HasWatchedFramePopListeners()414*795d594fSAndroid Build Coastguard Worker bool HasWatchedFramePopListeners() const REQUIRES_SHARED(Locks::mutator_lock_) { 415*795d594fSAndroid Build Coastguard Worker return have_watched_frame_pop_listeners_; 416*795d594fSAndroid Build Coastguard Worker } 417*795d594fSAndroid Build Coastguard Worker HasExceptionHandledListeners()418*795d594fSAndroid Build Coastguard Worker bool HasExceptionHandledListeners() const REQUIRES_SHARED(Locks::mutator_lock_) { 419*795d594fSAndroid Build Coastguard Worker return have_exception_handled_listeners_; 420*795d594fSAndroid Build Coastguard Worker } 421*795d594fSAndroid Build Coastguard Worker 422*795d594fSAndroid Build Coastguard Worker // Returns if dex pc events need to be reported for the specified method. 423*795d594fSAndroid Build Coastguard Worker // These events are reported when DexPCListeners are installed and at least one of the 424*795d594fSAndroid Build Coastguard Worker // following conditions hold: 425*795d594fSAndroid Build Coastguard Worker // 1. The method is deoptimized. This is done when there is a breakpoint on method. 426*795d594fSAndroid Build Coastguard Worker // 2. When the thread is deoptimized. This is used when single stepping a single thread. 427*795d594fSAndroid Build Coastguard Worker // 3. When interpreter stubs are installed. In this case no additional information is maintained 428*795d594fSAndroid Build Coastguard Worker // about which methods need dex pc move events. This is usually used for features which need 429*795d594fSAndroid Build Coastguard Worker // them for several methods across threads or need expensive processing. So it is OK to not 430*795d594fSAndroid Build Coastguard Worker // further optimize this case. 431*795d594fSAndroid Build Coastguard Worker // DexPCListeners are installed when there is a breakpoint on any method / single stepping 432*795d594fSAndroid Build Coastguard Worker // on any of thread. These are removed when the last breakpoint was removed. See AddListener and 433*795d594fSAndroid Build Coastguard Worker // RemoveListener for more details. 434*795d594fSAndroid Build Coastguard Worker bool NeedsDexPcEvents(ArtMethod* method, Thread* thread) REQUIRES_SHARED(Locks::mutator_lock_); 435*795d594fSAndroid Build Coastguard Worker NeedsSlowInterpreterForListeners()436*795d594fSAndroid Build Coastguard Worker bool NeedsSlowInterpreterForListeners() const REQUIRES_SHARED(Locks::mutator_lock_) { 437*795d594fSAndroid Build Coastguard Worker return have_field_read_listeners_ || 438*795d594fSAndroid Build Coastguard Worker have_field_write_listeners_ || 439*795d594fSAndroid Build Coastguard Worker have_watched_frame_pop_listeners_ || 440*795d594fSAndroid Build Coastguard Worker have_exception_handled_listeners_; 441*795d594fSAndroid Build Coastguard Worker } 442*795d594fSAndroid Build Coastguard Worker 443*795d594fSAndroid Build Coastguard Worker // Inform listeners that a method has been entered. A dex PC is provided as we may install 444*795d594fSAndroid Build Coastguard Worker // listeners into executing code and get method enter events for methods already on the stack. MethodEnterEvent(Thread * thread,ArtMethod * method)445*795d594fSAndroid Build Coastguard Worker void MethodEnterEvent(Thread* thread, ArtMethod* method) const 446*795d594fSAndroid Build Coastguard Worker REQUIRES_SHARED(Locks::mutator_lock_) { 447*795d594fSAndroid Build Coastguard Worker if (UNLIKELY(HasMethodEntryListeners())) { 448*795d594fSAndroid Build Coastguard Worker MethodEnterEventImpl(thread, method); 449*795d594fSAndroid Build Coastguard Worker } 450*795d594fSAndroid Build Coastguard Worker } 451*795d594fSAndroid Build Coastguard Worker 452*795d594fSAndroid Build Coastguard Worker // Inform listeners that a method has been exited. 453*795d594fSAndroid Build Coastguard Worker template<typename T> MethodExitEvent(Thread * thread,ArtMethod * method,OptionalFrame frame,T & return_value)454*795d594fSAndroid Build Coastguard Worker void MethodExitEvent(Thread* thread, 455*795d594fSAndroid Build Coastguard Worker ArtMethod* method, 456*795d594fSAndroid Build Coastguard Worker OptionalFrame frame, 457*795d594fSAndroid Build Coastguard Worker T& return_value) const 458*795d594fSAndroid Build Coastguard Worker REQUIRES_SHARED(Locks::mutator_lock_) { 459*795d594fSAndroid Build Coastguard Worker if (UNLIKELY(HasMethodExitListeners())) { 460*795d594fSAndroid Build Coastguard Worker MethodExitEventImpl(thread, method, frame, return_value); 461*795d594fSAndroid Build Coastguard Worker } 462*795d594fSAndroid Build Coastguard Worker } 463*795d594fSAndroid Build Coastguard Worker 464*795d594fSAndroid Build Coastguard Worker // Inform listeners that a method has been exited due to an exception. 465*795d594fSAndroid Build Coastguard Worker void MethodUnwindEvent(Thread* thread, 466*795d594fSAndroid Build Coastguard Worker ArtMethod* method, 467*795d594fSAndroid Build Coastguard Worker uint32_t dex_pc) const 468*795d594fSAndroid Build Coastguard Worker REQUIRES_SHARED(Locks::mutator_lock_); 469*795d594fSAndroid Build Coastguard Worker 470*795d594fSAndroid Build Coastguard Worker // Inform listeners that the dex pc has moved (only supported by the interpreter). DexPcMovedEvent(Thread * thread,ObjPtr<mirror::Object> this_object,ArtMethod * method,uint32_t dex_pc)471*795d594fSAndroid Build Coastguard Worker void DexPcMovedEvent(Thread* thread, 472*795d594fSAndroid Build Coastguard Worker ObjPtr<mirror::Object> this_object, 473*795d594fSAndroid Build Coastguard Worker ArtMethod* method, 474*795d594fSAndroid Build Coastguard Worker uint32_t dex_pc) const 475*795d594fSAndroid Build Coastguard Worker REQUIRES_SHARED(Locks::mutator_lock_) { 476*795d594fSAndroid Build Coastguard Worker if (UNLIKELY(HasDexPcListeners())) { 477*795d594fSAndroid Build Coastguard Worker DexPcMovedEventImpl(thread, this_object, method, dex_pc); 478*795d594fSAndroid Build Coastguard Worker } 479*795d594fSAndroid Build Coastguard Worker } 480*795d594fSAndroid Build Coastguard Worker 481*795d594fSAndroid Build Coastguard Worker // Inform listeners that a branch has been taken (only supported by the interpreter). Branch(Thread * thread,ArtMethod * method,uint32_t dex_pc,int32_t offset)482*795d594fSAndroid Build Coastguard Worker void Branch(Thread* thread, ArtMethod* method, uint32_t dex_pc, int32_t offset) const 483*795d594fSAndroid Build Coastguard Worker REQUIRES_SHARED(Locks::mutator_lock_) { 484*795d594fSAndroid Build Coastguard Worker if (UNLIKELY(HasBranchListeners())) { 485*795d594fSAndroid Build Coastguard Worker BranchImpl(thread, method, dex_pc, offset); 486*795d594fSAndroid Build Coastguard Worker } 487*795d594fSAndroid Build Coastguard Worker } 488*795d594fSAndroid Build Coastguard Worker 489*795d594fSAndroid Build Coastguard Worker // Inform listeners that we read a field (only supported by the interpreter). FieldReadEvent(Thread * thread,ObjPtr<mirror::Object> this_object,ArtMethod * method,uint32_t dex_pc,ArtField * field)490*795d594fSAndroid Build Coastguard Worker void FieldReadEvent(Thread* thread, 491*795d594fSAndroid Build Coastguard Worker ObjPtr<mirror::Object> this_object, 492*795d594fSAndroid Build Coastguard Worker ArtMethod* method, 493*795d594fSAndroid Build Coastguard Worker uint32_t dex_pc, 494*795d594fSAndroid Build Coastguard Worker ArtField* field) const 495*795d594fSAndroid Build Coastguard Worker REQUIRES_SHARED(Locks::mutator_lock_) { 496*795d594fSAndroid Build Coastguard Worker if (UNLIKELY(HasFieldReadListeners())) { 497*795d594fSAndroid Build Coastguard Worker FieldReadEventImpl(thread, this_object, method, dex_pc, field); 498*795d594fSAndroid Build Coastguard Worker } 499*795d594fSAndroid Build Coastguard Worker } 500*795d594fSAndroid Build Coastguard Worker 501*795d594fSAndroid Build Coastguard Worker // Inform listeners that we write a field (only supported by the interpreter). FieldWriteEvent(Thread * thread,ObjPtr<mirror::Object> this_object,ArtMethod * method,uint32_t dex_pc,ArtField * field,const JValue & field_value)502*795d594fSAndroid Build Coastguard Worker void FieldWriteEvent(Thread* thread, 503*795d594fSAndroid Build Coastguard Worker ObjPtr<mirror::Object> this_object, 504*795d594fSAndroid Build Coastguard Worker ArtMethod* method, 505*795d594fSAndroid Build Coastguard Worker uint32_t dex_pc, 506*795d594fSAndroid Build Coastguard Worker ArtField* field, 507*795d594fSAndroid Build Coastguard Worker const JValue& field_value) const 508*795d594fSAndroid Build Coastguard Worker REQUIRES_SHARED(Locks::mutator_lock_) { 509*795d594fSAndroid Build Coastguard Worker if (UNLIKELY(HasFieldWriteListeners())) { 510*795d594fSAndroid Build Coastguard Worker FieldWriteEventImpl(thread, this_object, method, dex_pc, field, field_value); 511*795d594fSAndroid Build Coastguard Worker } 512*795d594fSAndroid Build Coastguard Worker } 513*795d594fSAndroid Build Coastguard Worker 514*795d594fSAndroid Build Coastguard Worker // Inform listeners that a branch has been taken (only supported by the interpreter). WatchedFramePopped(Thread * thread,const ShadowFrame & frame)515*795d594fSAndroid Build Coastguard Worker void WatchedFramePopped(Thread* thread, const ShadowFrame& frame) const 516*795d594fSAndroid Build Coastguard Worker REQUIRES_SHARED(Locks::mutator_lock_) { 517*795d594fSAndroid Build Coastguard Worker if (UNLIKELY(HasWatchedFramePopListeners())) { 518*795d594fSAndroid Build Coastguard Worker WatchedFramePopImpl(thread, frame); 519*795d594fSAndroid Build Coastguard Worker } 520*795d594fSAndroid Build Coastguard Worker } 521*795d594fSAndroid Build Coastguard Worker 522*795d594fSAndroid Build Coastguard Worker // Inform listeners that an exception was thrown. 523*795d594fSAndroid Build Coastguard Worker void ExceptionThrownEvent(Thread* thread, ObjPtr<mirror::Throwable> exception_object) const 524*795d594fSAndroid Build Coastguard Worker REQUIRES_SHARED(Locks::mutator_lock_); 525*795d594fSAndroid Build Coastguard Worker 526*795d594fSAndroid Build Coastguard Worker // Inform listeners that an exception has been handled. This is not sent for native code or for 527*795d594fSAndroid Build Coastguard Worker // exceptions which reach the end of the thread's stack. 528*795d594fSAndroid Build Coastguard Worker void ExceptionHandledEvent(Thread* thread, ObjPtr<mirror::Throwable> exception_object) const 529*795d594fSAndroid Build Coastguard Worker REQUIRES_SHARED(Locks::mutator_lock_); 530*795d594fSAndroid Build Coastguard Worker 531*795d594fSAndroid Build Coastguard Worker JValue GetReturnValue(ArtMethod* method, bool* is_ref, uint64_t* gpr_result, uint64_t* fpr_result) 532*795d594fSAndroid Build Coastguard Worker REQUIRES_SHARED(Locks::mutator_lock_); 533*795d594fSAndroid Build Coastguard Worker bool PushDeoptContextIfNeeded(Thread* self, 534*795d594fSAndroid Build Coastguard Worker DeoptimizationMethodType deopt_type, 535*795d594fSAndroid Build Coastguard Worker bool is_ref, 536*795d594fSAndroid Build Coastguard Worker const JValue& result) REQUIRES_SHARED(Locks::mutator_lock_); 537*795d594fSAndroid Build Coastguard Worker 538*795d594fSAndroid Build Coastguard Worker // Deoptimize upon pending exception or if the caller requires it. Returns a long jump context if 539*795d594fSAndroid Build Coastguard Worker // a deoptimization is needed and taken. 540*795d594fSAndroid Build Coastguard Worker std::unique_ptr<Context> DeoptimizeIfNeeded(Thread* self, 541*795d594fSAndroid Build Coastguard Worker ArtMethod** sp, 542*795d594fSAndroid Build Coastguard Worker DeoptimizationMethodType type, 543*795d594fSAndroid Build Coastguard Worker JValue result, 544*795d594fSAndroid Build Coastguard Worker bool is_ref) REQUIRES_SHARED(Locks::mutator_lock_); 545*795d594fSAndroid Build Coastguard Worker // This returns if the caller of runtime method requires a deoptimization. This checks both if the 546*795d594fSAndroid Build Coastguard Worker // method requires a deopt or if this particular frame needs a deopt because of a class 547*795d594fSAndroid Build Coastguard Worker // redefinition. 548*795d594fSAndroid Build Coastguard Worker bool ShouldDeoptimizeCaller(Thread* self, ArtMethod** sp) REQUIRES_SHARED(Locks::mutator_lock_); 549*795d594fSAndroid Build Coastguard Worker bool ShouldDeoptimizeCaller(Thread* self, ArtMethod** sp, size_t frame_size) 550*795d594fSAndroid Build Coastguard Worker REQUIRES_SHARED(Locks::mutator_lock_); 551*795d594fSAndroid Build Coastguard Worker // This returns if the specified method requires a deoptimization. This doesn't account if a stack 552*795d594fSAndroid Build Coastguard Worker // frame involving this method requires a deoptimization. 553*795d594fSAndroid Build Coastguard Worker bool NeedsSlowInterpreterForMethod(Thread* self, ArtMethod* method) 554*795d594fSAndroid Build Coastguard Worker REQUIRES_SHARED(Locks::mutator_lock_); 555*795d594fSAndroid Build Coastguard Worker 556*795d594fSAndroid Build Coastguard Worker DeoptimizationMethodType GetDeoptimizationMethodType(ArtMethod* method) 557*795d594fSAndroid Build Coastguard Worker REQUIRES_SHARED(Locks::mutator_lock_); 558*795d594fSAndroid Build Coastguard Worker 559*795d594fSAndroid Build Coastguard Worker // Call back for configure stubs. 560*795d594fSAndroid Build Coastguard Worker void InstallStubsForClass(ObjPtr<mirror::Class> klass) REQUIRES_SHARED(Locks::mutator_lock_); 561*795d594fSAndroid Build Coastguard Worker 562*795d594fSAndroid Build Coastguard Worker void InstallStubsForMethod(ArtMethod* method) REQUIRES_SHARED(Locks::mutator_lock_); 563*795d594fSAndroid Build Coastguard Worker 564*795d594fSAndroid Build Coastguard Worker EXPORT void UpdateEntrypointsForDebuggable() REQUIRES(art::Locks::mutator_lock_); 565*795d594fSAndroid Build Coastguard Worker 566*795d594fSAndroid Build Coastguard Worker // Install instrumentation exit stub on every method of the stack of the given thread. 567*795d594fSAndroid Build Coastguard Worker // This is used by: 568*795d594fSAndroid Build Coastguard Worker // - the debugger to cause a deoptimization of the all frames in thread's stack (for 569*795d594fSAndroid Build Coastguard Worker // example, after updating local variables) 570*795d594fSAndroid Build Coastguard Worker // - to call method entry / exit hooks for tracing. For this we instrument 571*795d594fSAndroid Build Coastguard Worker // the stack frame to run entry / exit hooks but we don't need to deoptimize. 572*795d594fSAndroid Build Coastguard Worker // force_deopt indicates whether the frames need to deoptimize or not. 573*795d594fSAndroid Build Coastguard Worker EXPORT void InstrumentThreadStack(Thread* thread, bool force_deopt) 574*795d594fSAndroid Build Coastguard Worker REQUIRES(Locks::mutator_lock_); 575*795d594fSAndroid Build Coastguard Worker void InstrumentAllThreadStacks(bool force_deopt) REQUIRES(Locks::mutator_lock_) 576*795d594fSAndroid Build Coastguard Worker REQUIRES(!Locks::thread_list_lock_); 577*795d594fSAndroid Build Coastguard Worker 578*795d594fSAndroid Build Coastguard Worker // Force all currently running frames to be deoptimized back to interpreter. This should only be 579*795d594fSAndroid Build Coastguard Worker // used in cases where basically all compiled code has been invalidated. 580*795d594fSAndroid Build Coastguard Worker EXPORT void DeoptimizeAllThreadFrames() REQUIRES(art::Locks::mutator_lock_); 581*795d594fSAndroid Build Coastguard Worker 582*795d594fSAndroid Build Coastguard Worker static size_t ComputeFrameId(Thread* self, 583*795d594fSAndroid Build Coastguard Worker size_t frame_depth, 584*795d594fSAndroid Build Coastguard Worker size_t inlined_frames_before_frame) 585*795d594fSAndroid Build Coastguard Worker REQUIRES_SHARED(Locks::mutator_lock_); 586*795d594fSAndroid Build Coastguard Worker 587*795d594fSAndroid Build Coastguard Worker // Does not hold lock, used to check if someone changed from not instrumented to instrumented 588*795d594fSAndroid Build Coastguard Worker // during a GC suspend point. AllocEntrypointsInstrumented()589*795d594fSAndroid Build Coastguard Worker bool AllocEntrypointsInstrumented() const REQUIRES_SHARED(Locks::mutator_lock_) { 590*795d594fSAndroid Build Coastguard Worker return alloc_entrypoints_instrumented_; 591*795d594fSAndroid Build Coastguard Worker } 592*795d594fSAndroid Build Coastguard Worker 593*795d594fSAndroid Build Coastguard Worker bool ProcessMethodUnwindCallbacks(Thread* self, 594*795d594fSAndroid Build Coastguard Worker std::queue<ArtMethod*>& methods, 595*795d594fSAndroid Build Coastguard Worker MutableHandle<mirror::Throwable>& exception) 596*795d594fSAndroid Build Coastguard Worker REQUIRES_SHARED(Locks::mutator_lock_); 597*795d594fSAndroid Build Coastguard Worker 598*795d594fSAndroid Build Coastguard Worker EXPORT InstrumentationLevel GetCurrentInstrumentationLevel() const; 599*795d594fSAndroid Build Coastguard Worker 600*795d594fSAndroid Build Coastguard Worker bool MethodSupportsExitEvents(ArtMethod* method, const OatQuickMethodHeader* header) 601*795d594fSAndroid Build Coastguard Worker REQUIRES_SHARED(Locks::mutator_lock_); 602*795d594fSAndroid Build Coastguard Worker 603*795d594fSAndroid Build Coastguard Worker private: 604*795d594fSAndroid Build Coastguard Worker // Update the current instrumentation_level_. 605*795d594fSAndroid Build Coastguard Worker void UpdateInstrumentationLevel(InstrumentationLevel level); 606*795d594fSAndroid Build Coastguard Worker 607*795d594fSAndroid Build Coastguard Worker // Does the job of installing or removing instrumentation code within methods. 608*795d594fSAndroid Build Coastguard Worker // In order to support multiple clients using instrumentation at the same time, 609*795d594fSAndroid Build Coastguard Worker // the caller must pass a unique key (a string) identifying it so we remind which 610*795d594fSAndroid Build Coastguard Worker // instrumentation level it needs. Therefore the current instrumentation level 611*795d594fSAndroid Build Coastguard Worker // becomes the highest instrumentation level required by a client. 612*795d594fSAndroid Build Coastguard Worker void ConfigureStubs(const char* key, 613*795d594fSAndroid Build Coastguard Worker InstrumentationLevel desired_instrumentation_level, 614*795d594fSAndroid Build Coastguard Worker bool try_switch_to_non_debuggable) 615*795d594fSAndroid Build Coastguard Worker REQUIRES(Locks::mutator_lock_, Roles::uninterruptible_) 616*795d594fSAndroid Build Coastguard Worker REQUIRES(!Locks::thread_list_lock_, !Locks::classlinker_classes_lock_); 617*795d594fSAndroid Build Coastguard Worker void UpdateStubs(bool try_switch_to_non_debuggable) 618*795d594fSAndroid Build Coastguard Worker REQUIRES(Locks::mutator_lock_, Roles::uninterruptible_) 619*795d594fSAndroid Build Coastguard Worker REQUIRES(!Locks::thread_list_lock_, !Locks::classlinker_classes_lock_); 620*795d594fSAndroid Build Coastguard Worker 621*795d594fSAndroid Build Coastguard Worker // If there are no pending deoptimizations restores the stack to the normal state by updating the 622*795d594fSAndroid Build Coastguard Worker // return pcs to actual return addresses from the instrumentation stack and clears the 623*795d594fSAndroid Build Coastguard Worker // instrumentation stack. 624*795d594fSAndroid Build Coastguard Worker void MaybeRestoreInstrumentationStack() REQUIRES(Locks::mutator_lock_); 625*795d594fSAndroid Build Coastguard Worker 626*795d594fSAndroid Build Coastguard Worker // Switches the runtime state to non-java debuggable if entry / exit hooks are no longer required 627*795d594fSAndroid Build Coastguard Worker // and the runtime did not start off as java debuggable. 628*795d594fSAndroid Build Coastguard Worker void MaybeSwitchRuntimeDebugState(Thread* self) 629*795d594fSAndroid Build Coastguard Worker REQUIRES(Locks::mutator_lock_, Roles::uninterruptible_); 630*795d594fSAndroid Build Coastguard Worker 631*795d594fSAndroid Build Coastguard Worker // No thread safety analysis to get around SetQuickAllocEntryPointsInstrumented requiring 632*795d594fSAndroid Build Coastguard Worker // exclusive access to mutator lock which you can't get if the runtime isn't started. 633*795d594fSAndroid Build Coastguard Worker void SetEntrypointsInstrumented(bool instrumented) NO_THREAD_SAFETY_ANALYSIS; 634*795d594fSAndroid Build Coastguard Worker 635*795d594fSAndroid Build Coastguard Worker void MethodEnterEventImpl(Thread* thread, ArtMethod* method) const 636*795d594fSAndroid Build Coastguard Worker REQUIRES_SHARED(Locks::mutator_lock_); 637*795d594fSAndroid Build Coastguard Worker template <typename T> 638*795d594fSAndroid Build Coastguard Worker void MethodExitEventImpl(Thread* thread, 639*795d594fSAndroid Build Coastguard Worker ArtMethod* method, 640*795d594fSAndroid Build Coastguard Worker OptionalFrame frame, 641*795d594fSAndroid Build Coastguard Worker T& return_value) const 642*795d594fSAndroid Build Coastguard Worker REQUIRES_SHARED(Locks::mutator_lock_); 643*795d594fSAndroid Build Coastguard Worker void DexPcMovedEventImpl(Thread* thread, 644*795d594fSAndroid Build Coastguard Worker ObjPtr<mirror::Object> this_object, 645*795d594fSAndroid Build Coastguard Worker ArtMethod* method, 646*795d594fSAndroid Build Coastguard Worker uint32_t dex_pc) const 647*795d594fSAndroid Build Coastguard Worker REQUIRES_SHARED(Locks::mutator_lock_); 648*795d594fSAndroid Build Coastguard Worker void BranchImpl(Thread* thread, ArtMethod* method, uint32_t dex_pc, int32_t offset) const 649*795d594fSAndroid Build Coastguard Worker REQUIRES_SHARED(Locks::mutator_lock_); 650*795d594fSAndroid Build Coastguard Worker void WatchedFramePopImpl(Thread* thread, const ShadowFrame& frame) const 651*795d594fSAndroid Build Coastguard Worker REQUIRES_SHARED(Locks::mutator_lock_); 652*795d594fSAndroid Build Coastguard Worker void FieldReadEventImpl(Thread* thread, 653*795d594fSAndroid Build Coastguard Worker ObjPtr<mirror::Object> this_object, 654*795d594fSAndroid Build Coastguard Worker ArtMethod* method, 655*795d594fSAndroid Build Coastguard Worker uint32_t dex_pc, 656*795d594fSAndroid Build Coastguard Worker ArtField* field) const 657*795d594fSAndroid Build Coastguard Worker REQUIRES_SHARED(Locks::mutator_lock_); 658*795d594fSAndroid Build Coastguard Worker void FieldWriteEventImpl(Thread* thread, 659*795d594fSAndroid Build Coastguard Worker ObjPtr<mirror::Object> this_object, 660*795d594fSAndroid Build Coastguard Worker ArtMethod* method, 661*795d594fSAndroid Build Coastguard Worker uint32_t dex_pc, 662*795d594fSAndroid Build Coastguard Worker ArtField* field, 663*795d594fSAndroid Build Coastguard Worker const JValue& field_value) const 664*795d594fSAndroid Build Coastguard Worker REQUIRES_SHARED(Locks::mutator_lock_); 665*795d594fSAndroid Build Coastguard Worker 666*795d594fSAndroid Build Coastguard Worker // Read barrier-aware utility functions for accessing deoptimized_methods_ 667*795d594fSAndroid Build Coastguard Worker bool AddDeoptimizedMethod(ArtMethod* method) REQUIRES(Locks::mutator_lock_); 668*795d594fSAndroid Build Coastguard Worker bool IsDeoptimizedMethod(ArtMethod* method) REQUIRES_SHARED(Locks::mutator_lock_); 669*795d594fSAndroid Build Coastguard Worker bool RemoveDeoptimizedMethod(ArtMethod* method) REQUIRES(Locks::mutator_lock_); 670*795d594fSAndroid Build Coastguard Worker void UpdateMethodsCodeImpl(ArtMethod* method, const void* new_code) 671*795d594fSAndroid Build Coastguard Worker REQUIRES_SHARED(Locks::mutator_lock_); 672*795d594fSAndroid Build Coastguard Worker 673*795d594fSAndroid Build Coastguard Worker // We need to run method exit hooks for two reasons: 674*795d594fSAndroid Build Coastguard Worker // 1. When method exit listeners are installed 675*795d594fSAndroid Build Coastguard Worker // 2. When we need to check if the caller of this method needs a deoptimization. This is needed 676*795d594fSAndroid Build Coastguard Worker // only for deoptimizing the currently active invocations on stack when we deoptimize a method or 677*795d594fSAndroid Build Coastguard Worker // invalidate the JITed code when redefining the classes. So future invocations don't need to do 678*795d594fSAndroid Build Coastguard Worker // this check. 679*795d594fSAndroid Build Coastguard Worker // 680*795d594fSAndroid Build Coastguard Worker // For JITed code of non-native methods we already have a stack slot reserved for deoptimizing 681*795d594fSAndroid Build Coastguard Worker // on demand and we use that stack slot to check if the caller needs a deoptimization. JITed code 682*795d594fSAndroid Build Coastguard Worker // checks if there are any method exit listeners or if the stack slot is set to determine if 683*795d594fSAndroid Build Coastguard Worker // method exit hooks need to be executed. 684*795d594fSAndroid Build Coastguard Worker // 685*795d594fSAndroid Build Coastguard Worker // For JITed JNI stubs there is no reserved stack slot for this and we just use this variable to 686*795d594fSAndroid Build Coastguard Worker // check if we need to run method entry / exit hooks. This variable would be set when either of 687*795d594fSAndroid Build Coastguard Worker // the above conditions are true. If we need method exit hooks only for case 2, we would call exit 688*795d594fSAndroid Build Coastguard Worker // hooks for any future invocations which aren't necessary. 689*795d594fSAndroid Build Coastguard Worker // QuickToInterpreterBridge and GenericJniStub also use this for same reasons. 690*795d594fSAndroid Build Coastguard Worker // If calling entry / exit hooks becomes expensive we could do the same optimization we did for 691*795d594fSAndroid Build Coastguard Worker // JITed code by having a reserved stack slot. 692*795d594fSAndroid Build Coastguard Worker bool run_exit_hooks_; 693*795d594fSAndroid Build Coastguard Worker 694*795d594fSAndroid Build Coastguard Worker // The required level of instrumentation. This could be one of the following values: 695*795d594fSAndroid Build Coastguard Worker // kInstrumentNothing: no instrumentation support is needed 696*795d594fSAndroid Build Coastguard Worker // kInstrumentWithEntryExitHooks: needs support to call method entry/exit stubs. 697*795d594fSAndroid Build Coastguard Worker // kInstrumentWithInterpreter: only execute with interpreter 698*795d594fSAndroid Build Coastguard Worker Instrumentation::InstrumentationLevel instrumentation_level_; 699*795d594fSAndroid Build Coastguard Worker 700*795d594fSAndroid Build Coastguard Worker // Did the runtime request we only run in the interpreter? ie -Xint mode. 701*795d594fSAndroid Build Coastguard Worker bool forced_interpret_only_; 702*795d594fSAndroid Build Coastguard Worker 703*795d594fSAndroid Build Coastguard Worker // For method entry / exit events, we maintain fast trace listeners in a separate list to make 704*795d594fSAndroid Build Coastguard Worker // implementation of fast trace listeners more efficient by JITing the code to handle fast trace 705*795d594fSAndroid Build Coastguard Worker // events. We use a uint8_t (and not bool) to encode if there are none / fast / slow listeners. 706*795d594fSAndroid Build Coastguard Worker // Do we have any listeners for method entry events. 707*795d594fSAndroid Build Coastguard Worker uint8_t have_method_entry_listeners_ GUARDED_BY(Locks::mutator_lock_); 708*795d594fSAndroid Build Coastguard Worker 709*795d594fSAndroid Build Coastguard Worker // Do we have any listeners for method exit events. 710*795d594fSAndroid Build Coastguard Worker uint8_t have_method_exit_listeners_ GUARDED_BY(Locks::mutator_lock_); 711*795d594fSAndroid Build Coastguard Worker 712*795d594fSAndroid Build Coastguard Worker // Do we have any listeners for method unwind events? 713*795d594fSAndroid Build Coastguard Worker bool have_method_unwind_listeners_ GUARDED_BY(Locks::mutator_lock_); 714*795d594fSAndroid Build Coastguard Worker 715*795d594fSAndroid Build Coastguard Worker // Do we have any listeners for dex move events? 716*795d594fSAndroid Build Coastguard Worker bool have_dex_pc_listeners_ GUARDED_BY(Locks::mutator_lock_); 717*795d594fSAndroid Build Coastguard Worker 718*795d594fSAndroid Build Coastguard Worker // Do we have any listeners for field read events? 719*795d594fSAndroid Build Coastguard Worker bool have_field_read_listeners_ GUARDED_BY(Locks::mutator_lock_); 720*795d594fSAndroid Build Coastguard Worker 721*795d594fSAndroid Build Coastguard Worker // Do we have any listeners for field write events? 722*795d594fSAndroid Build Coastguard Worker bool have_field_write_listeners_ GUARDED_BY(Locks::mutator_lock_); 723*795d594fSAndroid Build Coastguard Worker 724*795d594fSAndroid Build Coastguard Worker // Do we have any exception thrown listeners? 725*795d594fSAndroid Build Coastguard Worker bool have_exception_thrown_listeners_ GUARDED_BY(Locks::mutator_lock_); 726*795d594fSAndroid Build Coastguard Worker 727*795d594fSAndroid Build Coastguard Worker // Do we have any frame pop listeners? 728*795d594fSAndroid Build Coastguard Worker bool have_watched_frame_pop_listeners_ GUARDED_BY(Locks::mutator_lock_); 729*795d594fSAndroid Build Coastguard Worker 730*795d594fSAndroid Build Coastguard Worker // Do we have any branch listeners? 731*795d594fSAndroid Build Coastguard Worker bool have_branch_listeners_ GUARDED_BY(Locks::mutator_lock_); 732*795d594fSAndroid Build Coastguard Worker 733*795d594fSAndroid Build Coastguard Worker // Do we have any exception handled listeners? 734*795d594fSAndroid Build Coastguard Worker bool have_exception_handled_listeners_ GUARDED_BY(Locks::mutator_lock_); 735*795d594fSAndroid Build Coastguard Worker 736*795d594fSAndroid Build Coastguard Worker // Contains the instrumentation level required by each client of the instrumentation identified 737*795d594fSAndroid Build Coastguard Worker // by a string key. 738*795d594fSAndroid Build Coastguard Worker using InstrumentationLevelTable = SafeMap<const char*, InstrumentationLevel>; 739*795d594fSAndroid Build Coastguard Worker InstrumentationLevelTable requested_instrumentation_levels_ GUARDED_BY(Locks::mutator_lock_); 740*795d594fSAndroid Build Coastguard Worker 741*795d594fSAndroid Build Coastguard Worker // The event listeners, written to with the mutator_lock_ exclusively held. 742*795d594fSAndroid Build Coastguard Worker // Mutators must be able to iterate over these lists concurrently, that is, with listeners being 743*795d594fSAndroid Build Coastguard Worker // added or removed while iterating. The modifying thread holds exclusive lock, 744*795d594fSAndroid Build Coastguard Worker // so other threads cannot iterate (i.e. read the data of the list) at the same time but they 745*795d594fSAndroid Build Coastguard Worker // do keep iterators that need to remain valid. This is the reason these listeners are std::list 746*795d594fSAndroid Build Coastguard Worker // and not for example std::vector: the existing storage for a std::list does not move. 747*795d594fSAndroid Build Coastguard Worker // Note that mutators cannot make a copy of these lists before iterating, as the instrumentation 748*795d594fSAndroid Build Coastguard Worker // listeners can also be deleted concurrently. 749*795d594fSAndroid Build Coastguard Worker // As a result, these lists are never trimmed. That's acceptable given the low number of 750*795d594fSAndroid Build Coastguard Worker // listeners we have. 751*795d594fSAndroid Build Coastguard Worker std::list<InstrumentationListener*> method_entry_slow_listeners_ GUARDED_BY(Locks::mutator_lock_); 752*795d594fSAndroid Build Coastguard Worker std::list<InstrumentationListener*> method_entry_fast_trace_listeners_ 753*795d594fSAndroid Build Coastguard Worker GUARDED_BY(Locks::mutator_lock_); 754*795d594fSAndroid Build Coastguard Worker std::list<InstrumentationListener*> method_exit_slow_listeners_ GUARDED_BY(Locks::mutator_lock_); 755*795d594fSAndroid Build Coastguard Worker std::list<InstrumentationListener*> method_exit_fast_trace_listeners_ 756*795d594fSAndroid Build Coastguard Worker GUARDED_BY(Locks::mutator_lock_); 757*795d594fSAndroid Build Coastguard Worker std::list<InstrumentationListener*> method_unwind_listeners_ GUARDED_BY(Locks::mutator_lock_); 758*795d594fSAndroid Build Coastguard Worker std::list<InstrumentationListener*> branch_listeners_ GUARDED_BY(Locks::mutator_lock_); 759*795d594fSAndroid Build Coastguard Worker std::list<InstrumentationListener*> dex_pc_listeners_ GUARDED_BY(Locks::mutator_lock_); 760*795d594fSAndroid Build Coastguard Worker std::list<InstrumentationListener*> field_read_listeners_ GUARDED_BY(Locks::mutator_lock_); 761*795d594fSAndroid Build Coastguard Worker std::list<InstrumentationListener*> field_write_listeners_ GUARDED_BY(Locks::mutator_lock_); 762*795d594fSAndroid Build Coastguard Worker std::list<InstrumentationListener*> exception_thrown_listeners_ GUARDED_BY(Locks::mutator_lock_); 763*795d594fSAndroid Build Coastguard Worker std::list<InstrumentationListener*> watched_frame_pop_listeners_ GUARDED_BY(Locks::mutator_lock_); 764*795d594fSAndroid Build Coastguard Worker std::list<InstrumentationListener*> exception_handled_listeners_ GUARDED_BY(Locks::mutator_lock_); 765*795d594fSAndroid Build Coastguard Worker 766*795d594fSAndroid Build Coastguard Worker // The set of methods being deoptimized (by the debugger) which must be executed with interpreter 767*795d594fSAndroid Build Coastguard Worker // only. 768*795d594fSAndroid Build Coastguard Worker std::unordered_set<ArtMethod*> deoptimized_methods_ GUARDED_BY(Locks::mutator_lock_); 769*795d594fSAndroid Build Coastguard Worker 770*795d594fSAndroid Build Coastguard Worker // Current interpreter handler table. This is updated each time the thread state flags are 771*795d594fSAndroid Build Coastguard Worker // modified. 772*795d594fSAndroid Build Coastguard Worker 773*795d594fSAndroid Build Coastguard Worker // Greater than 0 if quick alloc entry points instrumented. 774*795d594fSAndroid Build Coastguard Worker size_t quick_alloc_entry_points_instrumentation_counter_; 775*795d594fSAndroid Build Coastguard Worker 776*795d594fSAndroid Build Coastguard Worker // alloc_entrypoints_instrumented_ is only updated with all the threads suspended, this is done 777*795d594fSAndroid Build Coastguard Worker // to prevent races with the GC where the GC relies on thread suspension only see 778*795d594fSAndroid Build Coastguard Worker // alloc_entrypoints_instrumented_ change during suspend points. 779*795d594fSAndroid Build Coastguard Worker bool alloc_entrypoints_instrumented_; 780*795d594fSAndroid Build Coastguard Worker 781*795d594fSAndroid Build Coastguard Worker friend class InstrumentationTest; // For GetCurrentInstrumentationLevel and ConfigureStubs. 782*795d594fSAndroid Build Coastguard Worker friend class InstrumentationStackPopper; // For popping instrumentation frames. 783*795d594fSAndroid Build Coastguard Worker friend void InstrumentationInstallStack(Thread*, bool); 784*795d594fSAndroid Build Coastguard Worker 785*795d594fSAndroid Build Coastguard Worker DISALLOW_COPY_AND_ASSIGN(Instrumentation); 786*795d594fSAndroid Build Coastguard Worker }; 787*795d594fSAndroid Build Coastguard Worker std::ostream& operator<<(std::ostream& os, Instrumentation::InstrumentationEvent rhs); 788*795d594fSAndroid Build Coastguard Worker std::ostream& operator<<(std::ostream& os, Instrumentation::InstrumentationLevel rhs); 789*795d594fSAndroid Build Coastguard Worker 790*795d594fSAndroid Build Coastguard Worker } // namespace instrumentation 791*795d594fSAndroid Build Coastguard Worker } // namespace art 792*795d594fSAndroid Build Coastguard Worker 793*795d594fSAndroid Build Coastguard Worker #endif // ART_RUNTIME_INSTRUMENTATION_H_ 794