xref: /aosp_15_r20/art/runtime/instrumentation.h (revision 795d594fd825385562da6b089ea9b2033f3abf5a)
1*795d594fSAndroid Build Coastguard Worker /*
2*795d594fSAndroid Build Coastguard Worker  * Copyright (C) 2011 The Android Open Source Project
3*795d594fSAndroid Build Coastguard Worker  *
4*795d594fSAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
5*795d594fSAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
6*795d594fSAndroid Build Coastguard Worker  * You may obtain a copy of the License at
7*795d594fSAndroid Build Coastguard Worker  *
8*795d594fSAndroid Build Coastguard Worker  *      http://www.apache.org/licenses/LICENSE-2.0
9*795d594fSAndroid Build Coastguard Worker  *
10*795d594fSAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
11*795d594fSAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
12*795d594fSAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*795d594fSAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
14*795d594fSAndroid Build Coastguard Worker  * limitations under the License.
15*795d594fSAndroid Build Coastguard Worker  */
16*795d594fSAndroid Build Coastguard Worker 
17*795d594fSAndroid Build Coastguard Worker #ifndef ART_RUNTIME_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