• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2011 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #ifndef ART_RUNTIME_INSTRUMENTATION_H_
18 #define ART_RUNTIME_INSTRUMENTATION_H_
19 
20 #include <stdint.h>
21 #include <list>
22 #include <unordered_set>
23 
24 #include "arch/instruction_set.h"
25 #include "base/enums.h"
26 #include "base/macros.h"
27 #include "base/mutex.h"
28 #include "gc_root.h"
29 #include "safe_map.h"
30 
31 namespace art {
32 namespace mirror {
33   class Class;
34   class Object;
35   class Throwable;
36 }  // namespace mirror
37 class ArtField;
38 class ArtMethod;
39 template <typename T> class Handle;
40 union JValue;
41 class Thread;
42 
43 namespace instrumentation {
44 
45 // Interpreter handler tables.
46 enum InterpreterHandlerTable {
47   kMainHandlerTable = 0,          // Main handler table: no suspend check, no instrumentation.
48   kAlternativeHandlerTable = 1,   // Alternative handler table: suspend check and/or instrumentation
49                                   // enabled.
50   kNumHandlerTables
51 };
52 
53 // Do we want to deoptimize for method entry and exit listeners or just try to intercept
54 // invocations? Deoptimization forces all code to run in the interpreter and considerably hurts the
55 // application's performance.
56 static constexpr bool kDeoptimizeForAccurateMethodEntryExitListeners = true;
57 
58 // Instrumentation event listener API. Registered listeners will get the appropriate call back for
59 // the events they are listening for. The call backs supply the thread, method and dex_pc the event
60 // occurred upon. The thread may or may not be Thread::Current().
61 struct InstrumentationListener {
InstrumentationListenerInstrumentationListener62   InstrumentationListener() {}
~InstrumentationListenerInstrumentationListener63   virtual ~InstrumentationListener() {}
64 
65   // Call-back for when a method is entered.
66   virtual void MethodEntered(Thread* thread,
67                              Handle<mirror::Object> this_object,
68                              ArtMethod* method,
69                              uint32_t dex_pc) REQUIRES_SHARED(Locks::mutator_lock_) = 0;
70 
71   virtual void MethodExited(Thread* thread,
72                             Handle<mirror::Object> this_object,
73                             ArtMethod* method,
74                             uint32_t dex_pc,
75                             Handle<mirror::Object> return_value)
76       REQUIRES_SHARED(Locks::mutator_lock_);
77 
78   // Call-back for when a method is exited. The implementor should either handler-ize the return
79   // value (if appropriate) or use the alternate MethodExited callback instead if they need to
80   // go through a suspend point.
81   virtual void MethodExited(Thread* thread,
82                             Handle<mirror::Object> this_object,
83                             ArtMethod* method,
84                             uint32_t dex_pc,
85                             const JValue& return_value)
86       REQUIRES_SHARED(Locks::mutator_lock_) = 0;
87 
88   // Call-back for when a method is popped due to an exception throw. A method will either cause a
89   // MethodExited call-back or a MethodUnwind call-back when its activation is removed.
90   virtual void MethodUnwind(Thread* thread,
91                             Handle<mirror::Object> this_object,
92                             ArtMethod* method,
93                             uint32_t dex_pc)
94       REQUIRES_SHARED(Locks::mutator_lock_) = 0;
95 
96   // Call-back for when the dex pc moves in a method.
97   virtual void DexPcMoved(Thread* thread,
98                           Handle<mirror::Object> this_object,
99                           ArtMethod* method,
100                           uint32_t new_dex_pc)
101       REQUIRES_SHARED(Locks::mutator_lock_) = 0;
102 
103   // Call-back for when we read from a field.
104   virtual void FieldRead(Thread* thread,
105                          Handle<mirror::Object> this_object,
106                          ArtMethod* method,
107                          uint32_t dex_pc,
108                          ArtField* field) = 0;
109 
110   virtual void FieldWritten(Thread* thread,
111                             Handle<mirror::Object> this_object,
112                             ArtMethod* method,
113                             uint32_t dex_pc,
114                             ArtField* field,
115                             Handle<mirror::Object> field_value)
116       REQUIRES_SHARED(Locks::mutator_lock_);
117 
118   // Call-back for when we write into a field.
119   virtual void FieldWritten(Thread* thread,
120                             Handle<mirror::Object> this_object,
121                             ArtMethod* method,
122                             uint32_t dex_pc,
123                             ArtField* field,
124                             const JValue& field_value)
125       REQUIRES_SHARED(Locks::mutator_lock_) = 0;
126 
127   // Call-back when an exception is caught.
128   virtual void ExceptionCaught(Thread* thread,
129                                Handle<mirror::Throwable> exception_object)
130       REQUIRES_SHARED(Locks::mutator_lock_) = 0;
131 
132   // Call-back for when we execute a branch.
133   virtual void Branch(Thread* thread,
134                       ArtMethod* method,
135                       uint32_t dex_pc,
136                       int32_t dex_pc_offset)
137       REQUIRES_SHARED(Locks::mutator_lock_) = 0;
138 
139   // Call-back for when we get an invokevirtual or an invokeinterface.
140   virtual void InvokeVirtualOrInterface(Thread* thread,
141                                         Handle<mirror::Object> this_object,
142                                         ArtMethod* caller,
143                                         uint32_t dex_pc,
144                                         ArtMethod* callee)
145       REQUIRES_SHARED(Locks::mutator_lock_) = 0;
146 };
147 
148 // Instrumentation is a catch-all for when extra information is required from the runtime. The
149 // typical use for instrumentation is for profiling and debugging. Instrumentation may add stubs
150 // to method entry and exit, it may also force execution to be switched to the interpreter and
151 // trigger deoptimization.
152 class Instrumentation {
153  public:
154   enum InstrumentationEvent {
155     kMethodEntered = 0x1,
156     kMethodExited = 0x2,
157     kMethodUnwind = 0x4,
158     kDexPcMoved = 0x8,
159     kFieldRead = 0x10,
160     kFieldWritten = 0x20,
161     kExceptionCaught = 0x40,
162     kBranch = 0x80,
163     kInvokeVirtualOrInterface = 0x100,
164   };
165 
166   enum class InstrumentationLevel {
167     kInstrumentNothing,                   // execute without instrumentation
168     kInstrumentWithInstrumentationStubs,  // execute with instrumentation entry/exit stubs
169     kInstrumentWithInterpreter            // execute with interpreter
170   };
171 
172   Instrumentation();
173 
174   // Add a listener to be notified of the masked together sent of instrumentation events. This
175   // suspend the runtime to install stubs. You are expected to hold the mutator lock as a proxy
176   // for saying you should have suspended all threads (installing stubs while threads are running
177   // will break).
178   void AddListener(InstrumentationListener* listener, uint32_t events)
179       REQUIRES(Locks::mutator_lock_, !Locks::thread_list_lock_, !Locks::classlinker_classes_lock_);
180 
181   // Removes a listener possibly removing instrumentation stubs.
182   void RemoveListener(InstrumentationListener* listener, uint32_t events)
183       REQUIRES(Locks::mutator_lock_, !Locks::thread_list_lock_, !Locks::classlinker_classes_lock_);
184 
185   // Deoptimization.
186   void EnableDeoptimization()
187       REQUIRES(Locks::mutator_lock_)
188       REQUIRES(!deoptimized_methods_lock_);
189   // Calls UndeoptimizeEverything which may visit class linker classes through ConfigureStubs.
190   void DisableDeoptimization(const char* key)
191       REQUIRES(Locks::mutator_lock_, Roles::uninterruptible_)
192       REQUIRES(!deoptimized_methods_lock_);
193 
AreAllMethodsDeoptimized()194   bool AreAllMethodsDeoptimized() const {
195     return interpreter_stubs_installed_;
196   }
197   bool ShouldNotifyMethodEnterExitEvents() const REQUIRES_SHARED(Locks::mutator_lock_);
198 
199   // Executes everything with interpreter.
200   void DeoptimizeEverything(const char* key)
201       REQUIRES(Locks::mutator_lock_, Roles::uninterruptible_)
202       REQUIRES(!Locks::thread_list_lock_,
203                !Locks::classlinker_classes_lock_,
204                !deoptimized_methods_lock_);
205 
206   // Executes everything with compiled code (or interpreter if there is no code). May visit class
207   // linker classes through ConfigureStubs.
208   void UndeoptimizeEverything(const char* key)
209       REQUIRES(Locks::mutator_lock_, Roles::uninterruptible_)
210       REQUIRES(!Locks::thread_list_lock_,
211                !Locks::classlinker_classes_lock_,
212                !deoptimized_methods_lock_);
213 
214   // Deoptimize a method by forcing its execution with the interpreter. Nevertheless, a static
215   // method (except a class initializer) set to the resolution trampoline will be deoptimized only
216   // once its declaring class is initialized.
217   void Deoptimize(ArtMethod* method)
218       REQUIRES(Locks::mutator_lock_, !Locks::thread_list_lock_, !deoptimized_methods_lock_);
219 
220   // Undeoptimze the method by restoring its entrypoints. Nevertheless, a static method
221   // (except a class initializer) set to the resolution trampoline will be updated only once its
222   // declaring class is initialized.
223   void Undeoptimize(ArtMethod* method)
224       REQUIRES(Locks::mutator_lock_, !Locks::thread_list_lock_, !deoptimized_methods_lock_);
225 
226   // Indicates whether the method has been deoptimized so it is executed with the interpreter.
227   bool IsDeoptimized(ArtMethod* method)
228       REQUIRES(!deoptimized_methods_lock_) REQUIRES_SHARED(Locks::mutator_lock_);
229 
230   // Enable method tracing by installing instrumentation entry/exit stubs or interpreter.
231   void EnableMethodTracing(const char* key,
232                            bool needs_interpreter = kDeoptimizeForAccurateMethodEntryExitListeners)
233       REQUIRES(Locks::mutator_lock_, Roles::uninterruptible_)
234       REQUIRES(!Locks::thread_list_lock_,
235                !Locks::classlinker_classes_lock_,
236                !deoptimized_methods_lock_);
237 
238   // Disable method tracing by uninstalling instrumentation entry/exit stubs or interpreter.
239   void DisableMethodTracing(const char* key)
240       REQUIRES(Locks::mutator_lock_, Roles::uninterruptible_)
241       REQUIRES(!Locks::thread_list_lock_,
242                !Locks::classlinker_classes_lock_,
243                !deoptimized_methods_lock_);
244 
GetInterpreterHandlerTable()245   InterpreterHandlerTable GetInterpreterHandlerTable() const
246       REQUIRES_SHARED(Locks::mutator_lock_) {
247     return interpreter_handler_table_;
248   }
249 
250   void InstrumentQuickAllocEntryPoints() REQUIRES(!Locks::instrument_entrypoints_lock_);
251   void UninstrumentQuickAllocEntryPoints() REQUIRES(!Locks::instrument_entrypoints_lock_);
252   void InstrumentQuickAllocEntryPointsLocked()
253       REQUIRES(Locks::instrument_entrypoints_lock_, !Locks::thread_list_lock_,
254                !Locks::runtime_shutdown_lock_);
255   void UninstrumentQuickAllocEntryPointsLocked()
256       REQUIRES(Locks::instrument_entrypoints_lock_, !Locks::thread_list_lock_,
257                !Locks::runtime_shutdown_lock_);
258   void ResetQuickAllocEntryPoints() REQUIRES(Locks::runtime_shutdown_lock_);
259 
260   // Update the code of a method respecting any installed stubs.
261   void UpdateMethodsCode(ArtMethod* method, const void* quick_code)
262       REQUIRES_SHARED(Locks::mutator_lock_) REQUIRES(!deoptimized_methods_lock_);
263 
264   // Update the code of a method respecting any installed stubs from debugger.
265   void UpdateMethodsCodeForJavaDebuggable(ArtMethod* method, const void* quick_code)
266       REQUIRES_SHARED(Locks::mutator_lock_) REQUIRES(!deoptimized_methods_lock_);
267 
268   // Get the quick code for the given method. More efficient than asking the class linker as it
269   // will short-cut to GetCode if instrumentation and static method resolution stubs aren't
270   // installed.
271   const void* GetQuickCodeFor(ArtMethod* method, PointerSize pointer_size) const
272       REQUIRES_SHARED(Locks::mutator_lock_);
273 
ForceInterpretOnly()274   void ForceInterpretOnly() {
275     interpret_only_ = true;
276     forced_interpret_only_ = true;
277   }
278 
279   // Called by ArtMethod::Invoke to determine dispatch mechanism.
InterpretOnly()280   bool InterpretOnly() const {
281     return interpret_only_;
282   }
283 
IsForcedInterpretOnly()284   bool IsForcedInterpretOnly() const {
285     return forced_interpret_only_;
286   }
287 
288   // Code is in boot image oat file which isn't compiled as debuggable.
289   // Need debug version (interpreter or jitted) if that's the case.
290   bool NeedDebugVersionFor(ArtMethod* method) const
291       REQUIRES_SHARED(Locks::mutator_lock_);
292 
AreExitStubsInstalled()293   bool AreExitStubsInstalled() const {
294     return instrumentation_stubs_installed_;
295   }
296 
HasMethodEntryListeners()297   bool HasMethodEntryListeners() const REQUIRES_SHARED(Locks::mutator_lock_) {
298     return have_method_entry_listeners_;
299   }
300 
HasMethodExitListeners()301   bool HasMethodExitListeners() const REQUIRES_SHARED(Locks::mutator_lock_) {
302     return have_method_exit_listeners_;
303   }
304 
HasMethodUnwindListeners()305   bool HasMethodUnwindListeners() const REQUIRES_SHARED(Locks::mutator_lock_) {
306     return have_method_unwind_listeners_;
307   }
308 
HasDexPcListeners()309   bool HasDexPcListeners() const REQUIRES_SHARED(Locks::mutator_lock_) {
310     return have_dex_pc_listeners_;
311   }
312 
HasFieldReadListeners()313   bool HasFieldReadListeners() const REQUIRES_SHARED(Locks::mutator_lock_) {
314     return have_field_read_listeners_;
315   }
316 
HasFieldWriteListeners()317   bool HasFieldWriteListeners() const REQUIRES_SHARED(Locks::mutator_lock_) {
318     return have_field_write_listeners_;
319   }
320 
HasExceptionCaughtListeners()321   bool HasExceptionCaughtListeners() const REQUIRES_SHARED(Locks::mutator_lock_) {
322     return have_exception_caught_listeners_;
323   }
324 
HasBranchListeners()325   bool HasBranchListeners() const REQUIRES_SHARED(Locks::mutator_lock_) {
326     return have_branch_listeners_;
327   }
328 
HasInvokeVirtualOrInterfaceListeners()329   bool HasInvokeVirtualOrInterfaceListeners() const REQUIRES_SHARED(Locks::mutator_lock_) {
330     return have_invoke_virtual_or_interface_listeners_;
331   }
332 
IsActive()333   bool IsActive() const REQUIRES_SHARED(Locks::mutator_lock_) {
334     return have_dex_pc_listeners_ || have_method_entry_listeners_ || have_method_exit_listeners_ ||
335         have_field_read_listeners_ || have_field_write_listeners_ ||
336         have_exception_caught_listeners_ || have_method_unwind_listeners_ ||
337         have_branch_listeners_ || have_invoke_virtual_or_interface_listeners_;
338   }
339 
340   // Any instrumentation *other* than what is needed for Jit profiling active?
NonJitProfilingActive()341   bool NonJitProfilingActive() const REQUIRES_SHARED(Locks::mutator_lock_) {
342     return have_dex_pc_listeners_ || have_method_exit_listeners_ ||
343         have_field_read_listeners_ || have_field_write_listeners_ ||
344         have_exception_caught_listeners_ || have_method_unwind_listeners_ ||
345         have_branch_listeners_;
346   }
347 
348   // Inform listeners that a method has been entered. A dex PC is provided as we may install
349   // listeners into executing code and get method enter events for methods already on the stack.
MethodEnterEvent(Thread * thread,mirror::Object * this_object,ArtMethod * method,uint32_t dex_pc)350   void MethodEnterEvent(Thread* thread, mirror::Object* this_object,
351                         ArtMethod* method, uint32_t dex_pc) const
352       REQUIRES_SHARED(Locks::mutator_lock_) {
353     if (UNLIKELY(HasMethodEntryListeners())) {
354       MethodEnterEventImpl(thread, this_object, method, dex_pc);
355     }
356   }
357 
358   // Inform listeners that a method has been exited.
MethodExitEvent(Thread * thread,mirror::Object * this_object,ArtMethod * method,uint32_t dex_pc,const JValue & return_value)359   void MethodExitEvent(Thread* thread,
360                        mirror::Object* this_object,
361                        ArtMethod* method,
362                        uint32_t dex_pc,
363                        const JValue& return_value) const
364       REQUIRES_SHARED(Locks::mutator_lock_) {
365     if (UNLIKELY(HasMethodExitListeners())) {
366       MethodExitEventImpl(thread, this_object, method, dex_pc, return_value);
367     }
368   }
369 
370   // Inform listeners that a method has been exited due to an exception.
371   void MethodUnwindEvent(Thread* thread, mirror::Object* this_object,
372                          ArtMethod* method, uint32_t dex_pc) const
373       REQUIRES_SHARED(Locks::mutator_lock_);
374 
375   // Inform listeners that the dex pc has moved (only supported by the interpreter).
DexPcMovedEvent(Thread * thread,mirror::Object * this_object,ArtMethod * method,uint32_t dex_pc)376   void DexPcMovedEvent(Thread* thread, mirror::Object* this_object,
377                        ArtMethod* method, uint32_t dex_pc) const
378       REQUIRES_SHARED(Locks::mutator_lock_) {
379     if (UNLIKELY(HasDexPcListeners())) {
380       DexPcMovedEventImpl(thread, this_object, method, dex_pc);
381     }
382   }
383 
384   // 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)385   void Branch(Thread* thread, ArtMethod* method, uint32_t dex_pc, int32_t offset) const
386       REQUIRES_SHARED(Locks::mutator_lock_) {
387     if (UNLIKELY(HasBranchListeners())) {
388       BranchImpl(thread, method, dex_pc, offset);
389     }
390   }
391 
392   // Inform listeners that we read a field (only supported by the interpreter).
FieldReadEvent(Thread * thread,mirror::Object * this_object,ArtMethod * method,uint32_t dex_pc,ArtField * field)393   void FieldReadEvent(Thread* thread, mirror::Object* this_object,
394                       ArtMethod* method, uint32_t dex_pc,
395                       ArtField* field) const
396       REQUIRES_SHARED(Locks::mutator_lock_) {
397     if (UNLIKELY(HasFieldReadListeners())) {
398       FieldReadEventImpl(thread, this_object, method, dex_pc, field);
399     }
400   }
401 
402   // Inform listeners that we write a field (only supported by the interpreter).
FieldWriteEvent(Thread * thread,mirror::Object * this_object,ArtMethod * method,uint32_t dex_pc,ArtField * field,const JValue & field_value)403   void FieldWriteEvent(Thread* thread, mirror::Object* this_object,
404                        ArtMethod* method, uint32_t dex_pc,
405                        ArtField* field, const JValue& field_value) const
406       REQUIRES_SHARED(Locks::mutator_lock_) {
407     if (UNLIKELY(HasFieldWriteListeners())) {
408       FieldWriteEventImpl(thread, this_object, method, dex_pc, field, field_value);
409     }
410   }
411 
InvokeVirtualOrInterface(Thread * thread,mirror::Object * this_object,ArtMethod * caller,uint32_t dex_pc,ArtMethod * callee)412   void InvokeVirtualOrInterface(Thread* thread,
413                                 mirror::Object* this_object,
414                                 ArtMethod* caller,
415                                 uint32_t dex_pc,
416                                 ArtMethod* callee) const
417       REQUIRES_SHARED(Locks::mutator_lock_) {
418     if (UNLIKELY(HasInvokeVirtualOrInterfaceListeners())) {
419       InvokeVirtualOrInterfaceImpl(thread, this_object, caller, dex_pc, callee);
420     }
421   }
422 
423   // Inform listeners that an exception was caught.
424   void ExceptionCaughtEvent(Thread* thread, mirror::Throwable* exception_object) const
425       REQUIRES_SHARED(Locks::mutator_lock_);
426 
427   // Called when an instrumented method is entered. The intended link register (lr) is saved so
428   // that returning causes a branch to the method exit stub. Generates method enter events.
429   void PushInstrumentationStackFrame(Thread* self, mirror::Object* this_object,
430                                      ArtMethod* method, uintptr_t lr,
431                                      bool interpreter_entry)
432       REQUIRES_SHARED(Locks::mutator_lock_);
433 
434   // Called when an instrumented method is exited. Removes the pushed instrumentation frame
435   // returning the intended link register. Generates method exit events. The gpr_result and
436   // fpr_result pointers are pointers to the locations where the integer/pointer and floating point
437   // result values of the function are stored. Both pointers must always be valid but the values
438   // held there will only be meaningful if interpreted as the appropriate type given the function
439   // being returned from.
440   TwoWordReturn PopInstrumentationStackFrame(Thread* self, uintptr_t* return_pc,
441                                              uint64_t* gpr_result, uint64_t* fpr_result)
442       REQUIRES_SHARED(Locks::mutator_lock_) REQUIRES(!deoptimized_methods_lock_);
443 
444   // Pops an instrumentation frame from the current thread and generate an unwind event.
445   // Returns the return pc for the instrumentation frame that's popped.
446   uintptr_t PopMethodForUnwind(Thread* self, bool is_deoptimization) const
447       REQUIRES_SHARED(Locks::mutator_lock_);
448 
449   // Call back for configure stubs.
450   void InstallStubsForClass(mirror::Class* klass) REQUIRES_SHARED(Locks::mutator_lock_)
451       REQUIRES(!deoptimized_methods_lock_);
452 
453   void InstallStubsForMethod(ArtMethod* method)
454       REQUIRES_SHARED(Locks::mutator_lock_) REQUIRES(!deoptimized_methods_lock_);
455 
456   // Install instrumentation exit stub on every method of the stack of the given thread.
457   // This is used by the debugger to cause a deoptimization of the thread's stack after updating
458   // local variable(s).
459   void InstrumentThreadStack(Thread* thread)
460       REQUIRES_SHARED(Locks::mutator_lock_)
461       REQUIRES(!Locks::thread_list_lock_);
462 
463   static size_t ComputeFrameId(Thread* self,
464                                size_t frame_depth,
465                                size_t inlined_frames_before_frame)
466       REQUIRES_SHARED(Locks::mutator_lock_);
467 
468   // Does not hold lock, used to check if someone changed from not instrumented to instrumented
469   // during a GC suspend point.
AllocEntrypointsInstrumented()470   bool AllocEntrypointsInstrumented() const REQUIRES_SHARED(Locks::mutator_lock_) {
471     return alloc_entrypoints_instrumented_;
472   }
473 
474   InstrumentationLevel GetCurrentInstrumentationLevel() const;
475 
476  private:
477   // Returns true if moving to the given instrumentation level requires the installation of stubs.
478   // False otherwise.
479   bool RequiresInstrumentationInstallation(InstrumentationLevel new_level) const;
480 
481   // Does the job of installing or removing instrumentation code within methods.
482   // In order to support multiple clients using instrumentation at the same time,
483   // the caller must pass a unique key (a string) identifying it so we remind which
484   // instrumentation level it needs. Therefore the current instrumentation level
485   // becomes the highest instrumentation level required by a client.
486   void ConfigureStubs(const char* key, InstrumentationLevel desired_instrumentation_level)
487       REQUIRES(Locks::mutator_lock_, Roles::uninterruptible_)
488       REQUIRES(!deoptimized_methods_lock_,
489                !Locks::thread_list_lock_,
490                !Locks::classlinker_classes_lock_);
491 
UpdateInterpreterHandlerTable()492   void UpdateInterpreterHandlerTable() REQUIRES(Locks::mutator_lock_) {
493     /*
494      * TUNING: Dalvik's mterp stashes the actual current handler table base in a
495      * tls field.  For Arm, this enables all suspend, debug & tracing checks to be
496      * collapsed into a single conditionally-executed ldw instruction.
497      * Move to Dalvik-style handler-table management for both the goto interpreter and
498      * mterp.
499      */
500     interpreter_handler_table_ = IsActive() ? kAlternativeHandlerTable : kMainHandlerTable;
501   }
502 
503   // No thread safety analysis to get around SetQuickAllocEntryPointsInstrumented requiring
504   // exclusive access to mutator lock which you can't get if the runtime isn't started.
505   void SetEntrypointsInstrumented(bool instrumented) NO_THREAD_SAFETY_ANALYSIS;
506 
507   void MethodEnterEventImpl(Thread* thread,
508                             ObjPtr<mirror::Object> this_object,
509                             ArtMethod* method,
510                             uint32_t dex_pc) const
511       REQUIRES_SHARED(Locks::mutator_lock_);
512   void MethodExitEventImpl(Thread* thread,
513                            ObjPtr<mirror::Object> this_object,
514                            ArtMethod* method,
515                            uint32_t dex_pc,
516                            const JValue& return_value) const
517       REQUIRES_SHARED(Locks::mutator_lock_);
518   void DexPcMovedEventImpl(Thread* thread,
519                            ObjPtr<mirror::Object> this_object,
520                            ArtMethod* method,
521                            uint32_t dex_pc) const
522       REQUIRES_SHARED(Locks::mutator_lock_);
523   void BranchImpl(Thread* thread, ArtMethod* method, uint32_t dex_pc, int32_t offset) const
524       REQUIRES_SHARED(Locks::mutator_lock_);
525   void InvokeVirtualOrInterfaceImpl(Thread* thread,
526                                     ObjPtr<mirror::Object> this_object,
527                                     ArtMethod* caller,
528                                     uint32_t dex_pc,
529                                     ArtMethod* callee) const
530       REQUIRES_SHARED(Locks::mutator_lock_);
531   void FieldReadEventImpl(Thread* thread,
532                           ObjPtr<mirror::Object> this_object,
533                           ArtMethod* method,
534                           uint32_t dex_pc,
535                           ArtField* field) const
536       REQUIRES_SHARED(Locks::mutator_lock_);
537   void FieldWriteEventImpl(Thread* thread,
538                            ObjPtr<mirror::Object> this_object,
539                            ArtMethod* method,
540                            uint32_t dex_pc,
541                            ArtField* field,
542                            const JValue& field_value) const
543       REQUIRES_SHARED(Locks::mutator_lock_);
544 
545   // Read barrier-aware utility functions for accessing deoptimized_methods_
546   bool AddDeoptimizedMethod(ArtMethod* method)
547       REQUIRES_SHARED(Locks::mutator_lock_) REQUIRES(deoptimized_methods_lock_);
548   bool IsDeoptimizedMethod(ArtMethod* method)
549       REQUIRES_SHARED(Locks::mutator_lock_, deoptimized_methods_lock_);
550   bool RemoveDeoptimizedMethod(ArtMethod* method)
551       REQUIRES_SHARED(Locks::mutator_lock_) REQUIRES(deoptimized_methods_lock_);
552   ArtMethod* BeginDeoptimizedMethod()
553       REQUIRES_SHARED(Locks::mutator_lock_, deoptimized_methods_lock_);
554   bool IsDeoptimizedMethodsEmpty() const
555       REQUIRES_SHARED(Locks::mutator_lock_, deoptimized_methods_lock_);
556   void UpdateMethodsCodeImpl(ArtMethod* method, const void* quick_code)
557       REQUIRES_SHARED(Locks::mutator_lock_) REQUIRES(!deoptimized_methods_lock_);
558 
559 
560   // Have we hijacked ArtMethod::code_ so that it calls instrumentation/interpreter code?
561   bool instrumentation_stubs_installed_;
562 
563   // Have we hijacked ArtMethod::code_ to reference the enter/exit stubs?
564   bool entry_exit_stubs_installed_;
565 
566   // Have we hijacked ArtMethod::code_ to reference the enter interpreter stub?
567   bool interpreter_stubs_installed_;
568 
569   // Do we need the fidelity of events that we only get from running within the interpreter?
570   bool interpret_only_;
571 
572   // Did the runtime request we only run in the interpreter? ie -Xint mode.
573   bool forced_interpret_only_;
574 
575   // Do we have any listeners for method entry events? Short-cut to avoid taking the
576   // instrumentation_lock_.
577   bool have_method_entry_listeners_ GUARDED_BY(Locks::mutator_lock_);
578 
579   // Do we have any listeners for method exit events? Short-cut to avoid taking the
580   // instrumentation_lock_.
581   bool have_method_exit_listeners_ GUARDED_BY(Locks::mutator_lock_);
582 
583   // Do we have any listeners for method unwind events? Short-cut to avoid taking the
584   // instrumentation_lock_.
585   bool have_method_unwind_listeners_ GUARDED_BY(Locks::mutator_lock_);
586 
587   // Do we have any listeners for dex move events? Short-cut to avoid taking the
588   // instrumentation_lock_.
589   bool have_dex_pc_listeners_ GUARDED_BY(Locks::mutator_lock_);
590 
591   // Do we have any listeners for field read events? Short-cut to avoid taking the
592   // instrumentation_lock_.
593   bool have_field_read_listeners_ GUARDED_BY(Locks::mutator_lock_);
594 
595   // Do we have any listeners for field write events? Short-cut to avoid taking the
596   // instrumentation_lock_.
597   bool have_field_write_listeners_ GUARDED_BY(Locks::mutator_lock_);
598 
599   // Do we have any exception caught listeners? Short-cut to avoid taking the instrumentation_lock_.
600   bool have_exception_caught_listeners_ GUARDED_BY(Locks::mutator_lock_);
601 
602   // Do we have any branch listeners? Short-cut to avoid taking the instrumentation_lock_.
603   bool have_branch_listeners_ GUARDED_BY(Locks::mutator_lock_);
604 
605   // Do we have any invoke listeners? Short-cut to avoid taking the instrumentation_lock_.
606   bool have_invoke_virtual_or_interface_listeners_ GUARDED_BY(Locks::mutator_lock_);
607 
608   // Contains the instrumentation level required by each client of the instrumentation identified
609   // by a string key.
610   typedef SafeMap<const char*, InstrumentationLevel> InstrumentationLevelTable;
611   InstrumentationLevelTable requested_instrumentation_levels_ GUARDED_BY(Locks::mutator_lock_);
612 
613   // The event listeners, written to with the mutator_lock_ exclusively held.
614   // Mutators must be able to iterate over these lists concurrently, that is, with listeners being
615   // added or removed while iterating. The modifying thread holds exclusive lock,
616   // so other threads cannot iterate (i.e. read the data of the list) at the same time but they
617   // do keep iterators that need to remain valid. This is the reason these listeners are std::list
618   // and not for example std::vector: the existing storage for a std::list does not move.
619   // Note that mutators cannot make a copy of these lists before iterating, as the instrumentation
620   // listeners can also be deleted concurrently.
621   // As a result, these lists are never trimmed. That's acceptable given the low number of
622   // listeners we have.
623   std::list<InstrumentationListener*> method_entry_listeners_ GUARDED_BY(Locks::mutator_lock_);
624   std::list<InstrumentationListener*> method_exit_listeners_ GUARDED_BY(Locks::mutator_lock_);
625   std::list<InstrumentationListener*> method_unwind_listeners_ GUARDED_BY(Locks::mutator_lock_);
626   std::list<InstrumentationListener*> branch_listeners_ GUARDED_BY(Locks::mutator_lock_);
627   std::list<InstrumentationListener*> invoke_virtual_or_interface_listeners_
628       GUARDED_BY(Locks::mutator_lock_);
629   std::list<InstrumentationListener*> dex_pc_listeners_ GUARDED_BY(Locks::mutator_lock_);
630   std::list<InstrumentationListener*> field_read_listeners_ GUARDED_BY(Locks::mutator_lock_);
631   std::list<InstrumentationListener*> field_write_listeners_ GUARDED_BY(Locks::mutator_lock_);
632   std::list<InstrumentationListener*> exception_caught_listeners_ GUARDED_BY(Locks::mutator_lock_);
633 
634   // The set of methods being deoptimized (by the debugger) which must be executed with interpreter
635   // only.
636   mutable ReaderWriterMutex deoptimized_methods_lock_ DEFAULT_MUTEX_ACQUIRED_AFTER;
637   std::unordered_set<ArtMethod*> deoptimized_methods_ GUARDED_BY(deoptimized_methods_lock_);
638   bool deoptimization_enabled_;
639 
640   // Current interpreter handler table. This is updated each time the thread state flags are
641   // modified.
642   InterpreterHandlerTable interpreter_handler_table_ GUARDED_BY(Locks::mutator_lock_);
643 
644   // Greater than 0 if quick alloc entry points instrumented.
645   size_t quick_alloc_entry_points_instrumentation_counter_;
646 
647   // alloc_entrypoints_instrumented_ is only updated with all the threads suspended, this is done
648   // to prevent races with the GC where the GC relies on thread suspension only see
649   // alloc_entrypoints_instrumented_ change during suspend points.
650   bool alloc_entrypoints_instrumented_;
651 
652   friend class InstrumentationTest;  // For GetCurrentInstrumentationLevel and ConfigureStubs.
653 
654   DISALLOW_COPY_AND_ASSIGN(Instrumentation);
655 };
656 std::ostream& operator<<(std::ostream& os, const Instrumentation::InstrumentationEvent& rhs);
657 std::ostream& operator<<(std::ostream& os, const Instrumentation::InstrumentationLevel& rhs);
658 
659 // An element in the instrumentation side stack maintained in art::Thread.
660 struct InstrumentationStackFrame {
InstrumentationStackFrameInstrumentationStackFrame661   InstrumentationStackFrame(mirror::Object* this_object, ArtMethod* method,
662                             uintptr_t return_pc, size_t frame_id, bool interpreter_entry)
663       : this_object_(this_object), method_(method), return_pc_(return_pc), frame_id_(frame_id),
664         interpreter_entry_(interpreter_entry) {
665   }
666 
667   std::string Dump() const REQUIRES_SHARED(Locks::mutator_lock_);
668 
669   mirror::Object* this_object_;
670   ArtMethod* method_;
671   uintptr_t return_pc_;
672   size_t frame_id_;
673   bool interpreter_entry_;
674 };
675 
676 }  // namespace instrumentation
677 }  // namespace art
678 
679 #endif  // ART_RUNTIME_INSTRUMENTATION_H_
680