1725a957985171d712d5c048cc3d00ff14968784bjeffhao/*
2725a957985171d712d5c048cc3d00ff14968784bjeffhao * Copyright (C) 2011 The Android Open Source Project
3725a957985171d712d5c048cc3d00ff14968784bjeffhao *
4725a957985171d712d5c048cc3d00ff14968784bjeffhao * Licensed under the Apache License, Version 2.0 (the "License");
5725a957985171d712d5c048cc3d00ff14968784bjeffhao * you may not use this file except in compliance with the License.
6725a957985171d712d5c048cc3d00ff14968784bjeffhao * You may obtain a copy of the License at
7725a957985171d712d5c048cc3d00ff14968784bjeffhao *
8725a957985171d712d5c048cc3d00ff14968784bjeffhao *      http://www.apache.org/licenses/LICENSE-2.0
9725a957985171d712d5c048cc3d00ff14968784bjeffhao *
10725a957985171d712d5c048cc3d00ff14968784bjeffhao * Unless required by applicable law or agreed to in writing, software
11725a957985171d712d5c048cc3d00ff14968784bjeffhao * distributed under the License is distributed on an "AS IS" BASIS,
12725a957985171d712d5c048cc3d00ff14968784bjeffhao * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13725a957985171d712d5c048cc3d00ff14968784bjeffhao * See the License for the specific language governing permissions and
14725a957985171d712d5c048cc3d00ff14968784bjeffhao * limitations under the License.
15725a957985171d712d5c048cc3d00ff14968784bjeffhao */
16725a957985171d712d5c048cc3d00ff14968784bjeffhao
17fc0e3219edc9a5bf81b166e82fd5db2796eb6a0dBrian Carlstrom#ifndef ART_RUNTIME_INSTRUMENTATION_H_
18fc0e3219edc9a5bf81b166e82fd5db2796eb6a0dBrian Carlstrom#define ART_RUNTIME_INSTRUMENTATION_H_
19725a957985171d712d5c048cc3d00ff14968784bjeffhao
20576ca0cd692c0b6ae70e776de91015b8ff000a08Ian Rogers#include <stdint.h>
21576ca0cd692c0b6ae70e776de91015b8ff000a08Ian Rogers#include <list>
22e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier#include <unordered_set>
23576ca0cd692c0b6ae70e776de91015b8ff000a08Ian Rogers
24d582fa4ea62083a7598dded5b82dc2198b3daac7Ian Rogers#include "arch/instruction_set.h"
25542451cc546779f5c67840e105c51205a1b0a8fdAndreas Gampe#include "base/enums.h"
26761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes#include "base/macros.h"
27719d1a33f6569864f529e5a3fff59e7bca97aad0Ian Rogers#include "base/mutex.h"
2894f7b49578b6aaa80de8ffed230648d601393905Hiroshi Yamauchi#include "gc_root.h"
290462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz#include "safe_map.h"
302dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers
31725a957985171d712d5c048cc3d00ff14968784bjeffhaonamespace art {
322dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogersnamespace mirror {
33ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom  class Class;
34ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom  class Object;
35ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom  class Throwable;
3662d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers}  // namespace mirror
37c785344b87221f5e4e6473e5b762e4e61fe65dcfMathieu Chartierclass ArtField;
38e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartierclass ArtMethod;
3962d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogersunion JValue;
40725a957985171d712d5c048cc3d00ff14968784bjeffhaoclass Thread;
41725a957985171d712d5c048cc3d00ff14968784bjeffhao
4262d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogersnamespace instrumentation {
43725a957985171d712d5c048cc3d00ff14968784bjeffhao
44ee1997a3b83334985e757f369c09e111b121661bSebastien Hertz// Interpreter handler tables.
45ee1997a3b83334985e757f369c09e111b121661bSebastien Hertzenum InterpreterHandlerTable {
46ee1997a3b83334985e757f369c09e111b121661bSebastien Hertz  kMainHandlerTable = 0,          // Main handler table: no suspend check, no instrumentation.
47ee1997a3b83334985e757f369c09e111b121661bSebastien Hertz  kAlternativeHandlerTable = 1,   // Alternative handler table: suspend check and/or instrumentation
48ee1997a3b83334985e757f369c09e111b121661bSebastien Hertz                                  // enabled.
49ee1997a3b83334985e757f369c09e111b121661bSebastien Hertz  kNumHandlerTables
50ee1997a3b83334985e757f369c09e111b121661bSebastien Hertz};
51ee1997a3b83334985e757f369c09e111b121661bSebastien Hertz
5240da286d3207d88ed8ff3f5caac4873874603428Andreas Gampe// Do we want to deoptimize for method entry and exit listeners or just try to intercept
5340da286d3207d88ed8ff3f5caac4873874603428Andreas Gampe// invocations? Deoptimization forces all code to run in the interpreter and considerably hurts the
5440da286d3207d88ed8ff3f5caac4873874603428Andreas Gampe// application's performance.
5540da286d3207d88ed8ff3f5caac4873874603428Andreas Gampestatic constexpr bool kDeoptimizeForAccurateMethodEntryExitListeners = true;
5640da286d3207d88ed8ff3f5caac4873874603428Andreas Gampe
5762d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers// Instrumentation event listener API. Registered listeners will get the appropriate call back for
5862d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers// the events they are listening for. The call backs supply the thread, method and dex_pc the event
5962d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers// occurred upon. The thread may or may not be Thread::Current().
6062d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogersstruct InstrumentationListener {
6162d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers  InstrumentationListener() {}
6262d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers  virtual ~InstrumentationListener() {}
6362d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers
6462d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers  // Call-back for when a method is entered.
6562d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers  virtual void MethodEntered(Thread* thread, mirror::Object* this_object,
66e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier                             ArtMethod* method,
67bdf7f1c3ab65ccb70f62db5ab31dba060632d458Andreas Gampe                             uint32_t dex_pc) REQUIRES_SHARED(Locks::mutator_lock_) = 0;
6862d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers
6962d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers  // Call-back for when a method is exited.
7062d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers  virtual void MethodExited(Thread* thread, mirror::Object* this_object,
71e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier                            ArtMethod* method, uint32_t dex_pc,
7262d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers                            const JValue& return_value)
73bdf7f1c3ab65ccb70f62db5ab31dba060632d458Andreas Gampe      REQUIRES_SHARED(Locks::mutator_lock_) = 0;
7462d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers
7562d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers  // Call-back for when a method is popped due to an exception throw. A method will either cause a
7662d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers  // MethodExited call-back or a MethodUnwind call-back when its activation is removed.
7751db44a194bafc3810a41164a8b39614f10e79dfSebastien Hertz  virtual void MethodUnwind(Thread* thread, mirror::Object* this_object,
78e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier                            ArtMethod* method, uint32_t dex_pc)
79bdf7f1c3ab65ccb70f62db5ab31dba060632d458Andreas Gampe      REQUIRES_SHARED(Locks::mutator_lock_) = 0;
8062d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers
8162d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers  // Call-back for when the dex pc moves in a method.
8262d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers  virtual void DexPcMoved(Thread* thread, mirror::Object* this_object,
83e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier                          ArtMethod* method, uint32_t new_dex_pc)
84bdf7f1c3ab65ccb70f62db5ab31dba060632d458Andreas Gampe      REQUIRES_SHARED(Locks::mutator_lock_) = 0;
8562d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers
863f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertz  // Call-back for when we read from a field.
87e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier  virtual void FieldRead(Thread* thread, mirror::Object* this_object, ArtMethod* method,
88c785344b87221f5e4e6473e5b762e4e61fe65dcfMathieu Chartier                         uint32_t dex_pc, ArtField* field) = 0;
893f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertz
903f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertz  // Call-back for when we write into a field.
91e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier  virtual void FieldWritten(Thread* thread, mirror::Object* this_object, ArtMethod* method,
92c785344b87221f5e4e6473e5b762e4e61fe65dcfMathieu Chartier                            uint32_t dex_pc, ArtField* field, const JValue& field_value) = 0;
933f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertz
9462d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers  // Call-back when an exception is caught.
9514691c5e786e8c2c5734f687e4c96217340771beNicolas Geoffray  virtual void ExceptionCaught(Thread* thread, mirror::Throwable* exception_object)
96bdf7f1c3ab65ccb70f62db5ab31dba060632d458Andreas Gampe      REQUIRES_SHARED(Locks::mutator_lock_) = 0;
97e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier
9881f0f953c4bb159997046c962d44cb1898b1778dNicolas Geoffray  // Call-back for when we execute a branch.
9981f0f953c4bb159997046c962d44cb1898b1778dNicolas Geoffray  virtual void Branch(Thread* thread,
10081f0f953c4bb159997046c962d44cb1898b1778dNicolas Geoffray                      ArtMethod* method,
10181f0f953c4bb159997046c962d44cb1898b1778dNicolas Geoffray                      uint32_t dex_pc,
10281f0f953c4bb159997046c962d44cb1898b1778dNicolas Geoffray                      int32_t dex_pc_offset)
103bdf7f1c3ab65ccb70f62db5ab31dba060632d458Andreas Gampe      REQUIRES_SHARED(Locks::mutator_lock_) = 0;
1045550ca8bcc742b109d77e62f3a0877c667d894d3Nicolas Geoffray
1055550ca8bcc742b109d77e62f3a0877c667d894d3Nicolas Geoffray  // Call-back for when we get an invokevirtual or an invokeinterface.
1065550ca8bcc742b109d77e62f3a0877c667d894d3Nicolas Geoffray  virtual void InvokeVirtualOrInterface(Thread* thread,
1075550ca8bcc742b109d77e62f3a0877c667d894d3Nicolas Geoffray                                        mirror::Object* this_object,
1085550ca8bcc742b109d77e62f3a0877c667d894d3Nicolas Geoffray                                        ArtMethod* caller,
1095550ca8bcc742b109d77e62f3a0877c667d894d3Nicolas Geoffray                                        uint32_t dex_pc,
1105550ca8bcc742b109d77e62f3a0877c667d894d3Nicolas Geoffray                                        ArtMethod* callee)
1113fdb3fec5c36127d8568b2f89698906ba4b68576Mathieu Chartier      REQUIRES(Roles::uninterruptible_)
112bdf7f1c3ab65ccb70f62db5ab31dba060632d458Andreas Gampe      REQUIRES_SHARED(Locks::mutator_lock_) = 0;
113725a957985171d712d5c048cc3d00ff14968784bjeffhao};
114725a957985171d712d5c048cc3d00ff14968784bjeffhao
11562d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers// Instrumentation is a catch-all for when extra information is required from the runtime. The
11662d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers// typical use for instrumentation is for profiling and debugging. Instrumentation may add stubs
11762d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers// to method entry and exit, it may also force execution to be switched to the interpreter and
11862d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers// trigger deoptimization.
119725a957985171d712d5c048cc3d00ff14968784bjeffhaoclass Instrumentation {
120725a957985171d712d5c048cc3d00ff14968784bjeffhao public:
12162d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers  enum InstrumentationEvent {
122e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier    kMethodEntered = 0x1,
123e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier    kMethodExited = 0x2,
124e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier    kMethodUnwind = 0x4,
125e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier    kDexPcMoved = 0x8,
126e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier    kFieldRead = 0x10,
127e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier    kFieldWritten = 0x20,
128e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier    kExceptionCaught = 0x40,
12981f0f953c4bb159997046c962d44cb1898b1778dNicolas Geoffray    kBranch = 0x80,
1305550ca8bcc742b109d77e62f3a0877c667d894d3Nicolas Geoffray    kInvokeVirtualOrInterface = 0x100,
13162d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers  };
13262d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers
1330462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz  enum class InstrumentationLevel {
1340462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz    kInstrumentNothing,                   // execute without instrumentation
1350462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz    kInstrumentWithInstrumentationStubs,  // execute with instrumentation entry/exit stubs
1360462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz    kInstrumentWithInterpreter            // execute with interpreter
1370462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz  };
1380462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz
1393b05e9ba874449dbff65b01b8781001f7d93eea6Mathieu Chartier  Instrumentation();
14062d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers
14162d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers  // Add a listener to be notified of the masked together sent of instrumentation events. This
14262d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers  // suspend the runtime to install stubs. You are expected to hold the mutator lock as a proxy
14362d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers  // for saying you should have suspended all threads (installing stubs while threads are running
14462d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers  // will break).
14562d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers  void AddListener(InstrumentationListener* listener, uint32_t events)
14690443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier      REQUIRES(Locks::mutator_lock_, !Locks::thread_list_lock_, !Locks::classlinker_classes_lock_);
14762d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers
14862d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers  // Removes a listener possibly removing instrumentation stubs.
14962d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers  void RemoveListener(InstrumentationListener* listener, uint32_t events)
15090443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier      REQUIRES(Locks::mutator_lock_, !Locks::thread_list_lock_, !Locks::classlinker_classes_lock_);
15162d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers
152138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz  // Deoptimization.
153a76a6d4cb3dedec909bd927f20bc0ab23198a337Sebastien Hertz  void EnableDeoptimization()
154aa5168291c46f9b418d989bccf2d8e09338a83e6Mathieu Chartier      REQUIRES(Locks::mutator_lock_)
155aa5168291c46f9b418d989bccf2d8e09338a83e6Mathieu Chartier      REQUIRES(!deoptimized_methods_lock_);
156aa5168291c46f9b418d989bccf2d8e09338a83e6Mathieu Chartier  // Calls UndeoptimizeEverything which may visit class linker classes through ConfigureStubs.
1570462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz  void DisableDeoptimization(const char* key)
158aa5168291c46f9b418d989bccf2d8e09338a83e6Mathieu Chartier      REQUIRES(Locks::mutator_lock_, Roles::uninterruptible_)
159aa5168291c46f9b418d989bccf2d8e09338a83e6Mathieu Chartier      REQUIRES(!deoptimized_methods_lock_);
160aa5168291c46f9b418d989bccf2d8e09338a83e6Mathieu Chartier
161a76a6d4cb3dedec909bd927f20bc0ab23198a337Sebastien Hertz  bool AreAllMethodsDeoptimized() const {
162a76a6d4cb3dedec909bd927f20bc0ab23198a337Sebastien Hertz    return interpreter_stubs_installed_;
163a76a6d4cb3dedec909bd927f20bc0ab23198a337Sebastien Hertz  }
164bdf7f1c3ab65ccb70f62db5ab31dba060632d458Andreas Gampe  bool ShouldNotifyMethodEnterExitEvents() const REQUIRES_SHARED(Locks::mutator_lock_);
165138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz
166138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz  // Executes everything with interpreter.
1670462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz  void DeoptimizeEverything(const char* key)
168aa5168291c46f9b418d989bccf2d8e09338a83e6Mathieu Chartier      REQUIRES(Locks::mutator_lock_, Roles::uninterruptible_)
169aa5168291c46f9b418d989bccf2d8e09338a83e6Mathieu Chartier      REQUIRES(!Locks::thread_list_lock_,
170aa5168291c46f9b418d989bccf2d8e09338a83e6Mathieu Chartier               !Locks::classlinker_classes_lock_,
17190443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier               !deoptimized_methods_lock_);
172138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz
173aa5168291c46f9b418d989bccf2d8e09338a83e6Mathieu Chartier  // Executes everything with compiled code (or interpreter if there is no code). May visit class
174aa5168291c46f9b418d989bccf2d8e09338a83e6Mathieu Chartier  // linker classes through ConfigureStubs.
1750462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz  void UndeoptimizeEverything(const char* key)
176aa5168291c46f9b418d989bccf2d8e09338a83e6Mathieu Chartier      REQUIRES(Locks::mutator_lock_, Roles::uninterruptible_)
177aa5168291c46f9b418d989bccf2d8e09338a83e6Mathieu Chartier      REQUIRES(!Locks::thread_list_lock_,
178aa5168291c46f9b418d989bccf2d8e09338a83e6Mathieu Chartier               !Locks::classlinker_classes_lock_,
17990443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier               !deoptimized_methods_lock_);
180138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz
181138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz  // Deoptimize a method by forcing its execution with the interpreter. Nevertheless, a static
182138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz  // method (except a class initializer) set to the resolution trampoline will be deoptimized only
183138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz  // once its declaring class is initialized.
184e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier  void Deoptimize(ArtMethod* method)
18590443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier      REQUIRES(Locks::mutator_lock_, !Locks::thread_list_lock_, !deoptimized_methods_lock_);
186138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz
187138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz  // Undeoptimze the method by restoring its entrypoints. Nevertheless, a static method
188138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz  // (except a class initializer) set to the resolution trampoline will be updated only once its
189138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz  // declaring class is initialized.
190e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier  void Undeoptimize(ArtMethod* method)
19190443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier      REQUIRES(Locks::mutator_lock_, !Locks::thread_list_lock_, !deoptimized_methods_lock_);
192138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz
1930462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz  // Indicates whether the method has been deoptimized so it is executed with the interpreter.
194e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier  bool IsDeoptimized(ArtMethod* method)
195bdf7f1c3ab65ccb70f62db5ab31dba060632d458Andreas Gampe      REQUIRES(!deoptimized_methods_lock_) REQUIRES_SHARED(Locks::mutator_lock_);
196138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz
1970462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz  // Enable method tracing by installing instrumentation entry/exit stubs or interpreter.
1980462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz  void EnableMethodTracing(const char* key,
1990462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz                           bool needs_interpreter = kDeoptimizeForAccurateMethodEntryExitListeners)
200aa5168291c46f9b418d989bccf2d8e09338a83e6Mathieu Chartier      REQUIRES(Locks::mutator_lock_, Roles::uninterruptible_)
201aa5168291c46f9b418d989bccf2d8e09338a83e6Mathieu Chartier      REQUIRES(!Locks::thread_list_lock_,
202aa5168291c46f9b418d989bccf2d8e09338a83e6Mathieu Chartier               !Locks::classlinker_classes_lock_,
20390443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier               !deoptimized_methods_lock_);
204138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz
2050462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz  // Disable method tracing by uninstalling instrumentation entry/exit stubs or interpreter.
2060462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz  void DisableMethodTracing(const char* key)
207aa5168291c46f9b418d989bccf2d8e09338a83e6Mathieu Chartier      REQUIRES(Locks::mutator_lock_, Roles::uninterruptible_)
208aa5168291c46f9b418d989bccf2d8e09338a83e6Mathieu Chartier      REQUIRES(!Locks::thread_list_lock_,
209aa5168291c46f9b418d989bccf2d8e09338a83e6Mathieu Chartier               !Locks::classlinker_classes_lock_,
21090443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier               !deoptimized_methods_lock_);
211138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz
212ed2be1725fb79075892b1a9103487c9d9a95b350Sebastien Hertz  InterpreterHandlerTable GetInterpreterHandlerTable() const
213bdf7f1c3ab65ccb70f62db5ab31dba060632d458Andreas Gampe      REQUIRES_SHARED(Locks::mutator_lock_) {
214ee1997a3b83334985e757f369c09e111b121661bSebastien Hertz    return interpreter_handler_table_;
215ee1997a3b83334985e757f369c09e111b121661bSebastien Hertz  }
216ee1997a3b83334985e757f369c09e111b121661bSebastien Hertz
21790443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier  void InstrumentQuickAllocEntryPoints() REQUIRES(!Locks::instrument_entrypoints_lock_);
21890443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier  void UninstrumentQuickAllocEntryPoints() REQUIRES(!Locks::instrument_entrypoints_lock_);
2199ef78b59da51080882e47505896b420977fd79aeMathieu Chartier  void InstrumentQuickAllocEntryPointsLocked()
22090443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier      REQUIRES(Locks::instrument_entrypoints_lock_, !Locks::thread_list_lock_,
22190443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier               !Locks::runtime_shutdown_lock_);
2229ef78b59da51080882e47505896b420977fd79aeMathieu Chartier  void UninstrumentQuickAllocEntryPointsLocked()
22390443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier      REQUIRES(Locks::instrument_entrypoints_lock_, !Locks::thread_list_lock_,
22490443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier               !Locks::runtime_shutdown_lock_);
22590443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier  void ResetQuickAllocEntryPoints() REQUIRES(Locks::runtime_shutdown_lock_);
226fa82427c68b09f4aedbee319dc71579afbfc66f5Ian Rogers
22762d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers  // Update the code of a method respecting any installed stubs.
228e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier  void UpdateMethodsCode(ArtMethod* method, const void* quick_code)
229bdf7f1c3ab65ccb70f62db5ab31dba060632d458Andreas Gampe      REQUIRES_SHARED(Locks::mutator_lock_) REQUIRES(!deoptimized_methods_lock_);
23062d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers
2313fd448a8b7903b00fceaed5853306e2d7eb31c72Mingyao Yang  // Update the code of a method respecting any installed stubs from debugger.
232a0619e25aacf8b8074132f4951f75fdbcfd42925Nicolas Geoffray  void UpdateMethodsCodeForJavaDebuggable(ArtMethod* method, const void* quick_code)
233bdf7f1c3ab65ccb70f62db5ab31dba060632d458Andreas Gampe      REQUIRES_SHARED(Locks::mutator_lock_) REQUIRES(!deoptimized_methods_lock_);
2343fd448a8b7903b00fceaed5853306e2d7eb31c72Mingyao Yang
23562d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers  // Get the quick code for the given method. More efficient than asking the class linker as it
23662d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers  // will short-cut to GetCode if instrumentation and static method resolution stubs aren't
23762d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers  // installed.
238542451cc546779f5c67840e105c51205a1b0a8fdAndreas Gampe  const void* GetQuickCodeFor(ArtMethod* method, PointerSize pointer_size) const
239bdf7f1c3ab65ccb70f62db5ab31dba060632d458Andreas Gampe      REQUIRES_SHARED(Locks::mutator_lock_);
24062d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers
24162d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers  void ForceInterpretOnly() {
24262d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers    interpret_only_ = true;
24362d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers    forced_interpret_only_ = true;
24462d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers  }
24562d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers
246ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom  // Called by ArtMethod::Invoke to determine dispatch mechanism.
24762d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers  bool InterpretOnly() const {
24862d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers    return interpret_only_;
24962d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers  }
25062d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers
251563b47cc142e477da244539b1d63070425e7fd78Hiroshi Yamauchi  bool IsForcedInterpretOnly() const {
252563b47cc142e477da244539b1d63070425e7fd78Hiroshi Yamauchi    return forced_interpret_only_;
253563b47cc142e477da244539b1d63070425e7fd78Hiroshi Yamauchi  }
254563b47cc142e477da244539b1d63070425e7fd78Hiroshi Yamauchi
2556ea1a0e2168c8d9b6d97c075c73a72d84080f45bMingyao Yang  // Code is in boot image oat file which isn't compiled as debuggable.
2566ea1a0e2168c8d9b6d97c075c73a72d84080f45bMingyao Yang  // Need debug version (interpreter or jitted) if that's the case.
257a0619e25aacf8b8074132f4951f75fdbcfd42925Nicolas Geoffray  bool NeedDebugVersionFor(ArtMethod* method) const
258bdf7f1c3ab65ccb70f62db5ab31dba060632d458Andreas Gampe      REQUIRES_SHARED(Locks::mutator_lock_);
2596ea1a0e2168c8d9b6d97c075c73a72d84080f45bMingyao Yang
26062d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers  bool AreExitStubsInstalled() const {
26162d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers    return instrumentation_stubs_installed_;
26262d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers  }
26362d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers
264bdf7f1c3ab65ccb70f62db5ab31dba060632d458Andreas Gampe  bool HasMethodEntryListeners() const REQUIRES_SHARED(Locks::mutator_lock_) {
26574109f6683096de494b1457fa6d5b0ac33b4c98cSebastien Hertz    return have_method_entry_listeners_;
26674109f6683096de494b1457fa6d5b0ac33b4c98cSebastien Hertz  }
26774109f6683096de494b1457fa6d5b0ac33b4c98cSebastien Hertz
268bdf7f1c3ab65ccb70f62db5ab31dba060632d458Andreas Gampe  bool HasMethodExitListeners() const REQUIRES_SHARED(Locks::mutator_lock_) {
26974109f6683096de494b1457fa6d5b0ac33b4c98cSebastien Hertz    return have_method_exit_listeners_;
27074109f6683096de494b1457fa6d5b0ac33b4c98cSebastien Hertz  }
27174109f6683096de494b1457fa6d5b0ac33b4c98cSebastien Hertz
272bdf7f1c3ab65ccb70f62db5ab31dba060632d458Andreas Gampe  bool HasMethodUnwindListeners() const REQUIRES_SHARED(Locks::mutator_lock_) {
2730462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz    return have_method_unwind_listeners_;
2740462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz  }
2750462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz
276bdf7f1c3ab65ccb70f62db5ab31dba060632d458Andreas Gampe  bool HasDexPcListeners() const REQUIRES_SHARED(Locks::mutator_lock_) {
27774109f6683096de494b1457fa6d5b0ac33b4c98cSebastien Hertz    return have_dex_pc_listeners_;
27874109f6683096de494b1457fa6d5b0ac33b4c98cSebastien Hertz  }
27974109f6683096de494b1457fa6d5b0ac33b4c98cSebastien Hertz
280bdf7f1c3ab65ccb70f62db5ab31dba060632d458Andreas Gampe  bool HasFieldReadListeners() const REQUIRES_SHARED(Locks::mutator_lock_) {
2813f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertz    return have_field_read_listeners_;
2823f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertz  }
2833f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertz
284bdf7f1c3ab65ccb70f62db5ab31dba060632d458Andreas Gampe  bool HasFieldWriteListeners() const REQUIRES_SHARED(Locks::mutator_lock_) {
2853f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertz    return have_field_write_listeners_;
2863f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertz  }
2873f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertz
288bdf7f1c3ab65ccb70f62db5ab31dba060632d458Andreas Gampe  bool HasExceptionCaughtListeners() const REQUIRES_SHARED(Locks::mutator_lock_) {
2899f1020305292a21fd14a402b189c765a125226abSebastien Hertz    return have_exception_caught_listeners_;
2909f1020305292a21fd14a402b189c765a125226abSebastien Hertz  }
2919f1020305292a21fd14a402b189c765a125226abSebastien Hertz
292bdf7f1c3ab65ccb70f62db5ab31dba060632d458Andreas Gampe  bool HasBranchListeners() const REQUIRES_SHARED(Locks::mutator_lock_) {
29381f0f953c4bb159997046c962d44cb1898b1778dNicolas Geoffray    return have_branch_listeners_;
294e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier  }
295e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier
296bdf7f1c3ab65ccb70f62db5ab31dba060632d458Andreas Gampe  bool HasInvokeVirtualOrInterfaceListeners() const REQUIRES_SHARED(Locks::mutator_lock_) {
2975550ca8bcc742b109d77e62f3a0877c667d894d3Nicolas Geoffray    return have_invoke_virtual_or_interface_listeners_;
2985550ca8bcc742b109d77e62f3a0877c667d894d3Nicolas Geoffray  }
2995550ca8bcc742b109d77e62f3a0877c667d894d3Nicolas Geoffray
300bdf7f1c3ab65ccb70f62db5ab31dba060632d458Andreas Gampe  bool IsActive() const REQUIRES_SHARED(Locks::mutator_lock_) {
301ee1997a3b83334985e757f369c09e111b121661bSebastien Hertz    return have_dex_pc_listeners_ || have_method_entry_listeners_ || have_method_exit_listeners_ ||
30242cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz        have_field_read_listeners_ || have_field_write_listeners_ ||
303fd522f9039befff986701ff05054ffdd1be1dd33Bill Buzbee        have_exception_caught_listeners_ || have_method_unwind_listeners_ ||
304fd522f9039befff986701ff05054ffdd1be1dd33Bill Buzbee        have_branch_listeners_ || have_invoke_virtual_or_interface_listeners_;
305fd522f9039befff986701ff05054ffdd1be1dd33Bill Buzbee  }
306fd522f9039befff986701ff05054ffdd1be1dd33Bill Buzbee
307fd522f9039befff986701ff05054ffdd1be1dd33Bill Buzbee  // Any instrumentation *other* than what is needed for Jit profiling active?
308bdf7f1c3ab65ccb70f62db5ab31dba060632d458Andreas Gampe  bool NonJitProfilingActive() const REQUIRES_SHARED(Locks::mutator_lock_) {
309fd522f9039befff986701ff05054ffdd1be1dd33Bill Buzbee    return have_dex_pc_listeners_ || have_method_exit_listeners_ ||
310fd522f9039befff986701ff05054ffdd1be1dd33Bill Buzbee        have_field_read_listeners_ || have_field_write_listeners_ ||
3111d011d9306fd4ff57d72411775d415a86f5ed398Bill Buzbee        have_exception_caught_listeners_ || have_method_unwind_listeners_ ||
3121d011d9306fd4ff57d72411775d415a86f5ed398Bill Buzbee        have_branch_listeners_;
313ee1997a3b83334985e757f369c09e111b121661bSebastien Hertz  }
314ee1997a3b83334985e757f369c09e111b121661bSebastien Hertz
31562d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers  // Inform listeners that a method has been entered. A dex PC is provided as we may install
31662d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers  // listeners into executing code and get method enter events for methods already on the stack.
31762d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers  void MethodEnterEvent(Thread* thread, mirror::Object* this_object,
318e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier                        ArtMethod* method, uint32_t dex_pc) const
319bdf7f1c3ab65ccb70f62db5ab31dba060632d458Andreas Gampe      REQUIRES_SHARED(Locks::mutator_lock_) {
32074109f6683096de494b1457fa6d5b0ac33b4c98cSebastien Hertz    if (UNLIKELY(HasMethodEntryListeners())) {
32162d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers      MethodEnterEventImpl(thread, this_object, method, dex_pc);
32262d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers    }
32362d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers  }
32462d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers
32562d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers  // Inform listeners that a method has been exited.
32662d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers  void MethodExitEvent(Thread* thread, mirror::Object* this_object,
327e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier                       ArtMethod* method, uint32_t dex_pc,
32862d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers                       const JValue& return_value) const
329bdf7f1c3ab65ccb70f62db5ab31dba060632d458Andreas Gampe      REQUIRES_SHARED(Locks::mutator_lock_) {
33074109f6683096de494b1457fa6d5b0ac33b4c98cSebastien Hertz    if (UNLIKELY(HasMethodExitListeners())) {
33162d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers      MethodExitEventImpl(thread, this_object, method, dex_pc, return_value);
33262d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers    }
33362d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers  }
33462d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers
33562d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers  // Inform listeners that a method has been exited due to an exception.
33662d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers  void MethodUnwindEvent(Thread* thread, mirror::Object* this_object,
337e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier                         ArtMethod* method, uint32_t dex_pc) const
338bdf7f1c3ab65ccb70f62db5ab31dba060632d458Andreas Gampe      REQUIRES_SHARED(Locks::mutator_lock_);
33962d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers
34062d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers  // Inform listeners that the dex pc has moved (only supported by the interpreter).
34162d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers  void DexPcMovedEvent(Thread* thread, mirror::Object* this_object,
342e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier                       ArtMethod* method, uint32_t dex_pc) const
343bdf7f1c3ab65ccb70f62db5ab31dba060632d458Andreas Gampe      REQUIRES_SHARED(Locks::mutator_lock_) {
34474109f6683096de494b1457fa6d5b0ac33b4c98cSebastien Hertz    if (UNLIKELY(HasDexPcListeners())) {
34562d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers      DexPcMovedEventImpl(thread, this_object, method, dex_pc);
34662d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers    }
34762d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers  }
348725a957985171d712d5c048cc3d00ff14968784bjeffhao
34981f0f953c4bb159997046c962d44cb1898b1778dNicolas Geoffray  // Inform listeners that a branch has been taken (only supported by the interpreter).
35081f0f953c4bb159997046c962d44cb1898b1778dNicolas Geoffray  void Branch(Thread* thread, ArtMethod* method, uint32_t dex_pc, int32_t offset) const
351bdf7f1c3ab65ccb70f62db5ab31dba060632d458Andreas Gampe      REQUIRES_SHARED(Locks::mutator_lock_) {
35281f0f953c4bb159997046c962d44cb1898b1778dNicolas Geoffray    if (UNLIKELY(HasBranchListeners())) {
35381f0f953c4bb159997046c962d44cb1898b1778dNicolas Geoffray      BranchImpl(thread, method, dex_pc, offset);
354e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier    }
355e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier  }
356e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier
3573f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertz  // Inform listeners that we read a field (only supported by the interpreter).
3583f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertz  void FieldReadEvent(Thread* thread, mirror::Object* this_object,
359e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier                      ArtMethod* method, uint32_t dex_pc,
360c785344b87221f5e4e6473e5b762e4e61fe65dcfMathieu Chartier                      ArtField* field) const
361bdf7f1c3ab65ccb70f62db5ab31dba060632d458Andreas Gampe      REQUIRES_SHARED(Locks::mutator_lock_) {
3623f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertz    if (UNLIKELY(HasFieldReadListeners())) {
3633f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertz      FieldReadEventImpl(thread, this_object, method, dex_pc, field);
3643f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertz    }
3653f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertz  }
3663f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertz
3673f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertz  // Inform listeners that we write a field (only supported by the interpreter).
3683f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertz  void FieldWriteEvent(Thread* thread, mirror::Object* this_object,
369e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier                       ArtMethod* method, uint32_t dex_pc,
370c785344b87221f5e4e6473e5b762e4e61fe65dcfMathieu Chartier                       ArtField* field, const JValue& field_value) const
371bdf7f1c3ab65ccb70f62db5ab31dba060632d458Andreas Gampe      REQUIRES_SHARED(Locks::mutator_lock_) {
3723f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertz    if (UNLIKELY(HasFieldWriteListeners())) {
3733f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertz      FieldWriteEventImpl(thread, this_object, method, dex_pc, field, field_value);
3743f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertz    }
3753f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertz  }
3763f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertz
3775550ca8bcc742b109d77e62f3a0877c667d894d3Nicolas Geoffray  void InvokeVirtualOrInterface(Thread* thread,
3785550ca8bcc742b109d77e62f3a0877c667d894d3Nicolas Geoffray                                mirror::Object* this_object,
3795550ca8bcc742b109d77e62f3a0877c667d894d3Nicolas Geoffray                                ArtMethod* caller,
3805550ca8bcc742b109d77e62f3a0877c667d894d3Nicolas Geoffray                                uint32_t dex_pc,
3815550ca8bcc742b109d77e62f3a0877c667d894d3Nicolas Geoffray                                ArtMethod* callee) const
382bdf7f1c3ab65ccb70f62db5ab31dba060632d458Andreas Gampe      REQUIRES_SHARED(Locks::mutator_lock_) {
3835550ca8bcc742b109d77e62f3a0877c667d894d3Nicolas Geoffray    if (UNLIKELY(HasInvokeVirtualOrInterfaceListeners())) {
3845550ca8bcc742b109d77e62f3a0877c667d894d3Nicolas Geoffray      InvokeVirtualOrInterfaceImpl(thread, this_object, caller, dex_pc, callee);
3855550ca8bcc742b109d77e62f3a0877c667d894d3Nicolas Geoffray    }
3865550ca8bcc742b109d77e62f3a0877c667d894d3Nicolas Geoffray  }
3875550ca8bcc742b109d77e62f3a0877c667d894d3Nicolas Geoffray
38862d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers  // Inform listeners that an exception was caught.
38914691c5e786e8c2c5734f687e4c96217340771beNicolas Geoffray  void ExceptionCaughtEvent(Thread* thread, mirror::Throwable* exception_object) const
390bdf7f1c3ab65ccb70f62db5ab31dba060632d458Andreas Gampe      REQUIRES_SHARED(Locks::mutator_lock_);
391725a957985171d712d5c048cc3d00ff14968784bjeffhao
39262d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers  // Called when an instrumented method is entered. The intended link register (lr) is saved so
39362d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers  // that returning causes a branch to the method exit stub. Generates method enter events.
39462d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers  void PushInstrumentationStackFrame(Thread* self, mirror::Object* this_object,
395e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier                                     ArtMethod* method, uintptr_t lr,
3969a916d3c0d0574d106c764e737c67b52988d6139Jeff Hao                                     bool interpreter_entry)
397bdf7f1c3ab65ccb70f62db5ab31dba060632d458Andreas Gampe      REQUIRES_SHARED(Locks::mutator_lock_);
398725a957985171d712d5c048cc3d00ff14968784bjeffhao
39962d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers  // Called when an instrumented method is exited. Removes the pushed instrumentation frame
40062d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers  // returning the intended link register. Generates method exit events.
401d58342caa97108ba413bad467c285c0377f138f5Andreas Gampe  TwoWordReturn PopInstrumentationStackFrame(Thread* self, uintptr_t* return_pc,
402d58342caa97108ba413bad467c285c0377f138f5Andreas Gampe                                             uint64_t gpr_result, uint64_t fpr_result)
403bdf7f1c3ab65ccb70f62db5ab31dba060632d458Andreas Gampe      REQUIRES_SHARED(Locks::mutator_lock_) REQUIRES(!deoptimized_methods_lock_);
404725a957985171d712d5c048cc3d00ff14968784bjeffhao
40562d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers  // Pops an instrumentation frame from the current thread and generate an unwind event.
406f711f2cf3c28dfe865e36f17419a16f06a0ebb5aMingyao Yang  // Returns the return pc for the instrumentation frame that's popped.
407f711f2cf3c28dfe865e36f17419a16f06a0ebb5aMingyao Yang  uintptr_t PopMethodForUnwind(Thread* self, bool is_deoptimization) const
408bdf7f1c3ab65ccb70f62db5ab31dba060632d458Andreas Gampe      REQUIRES_SHARED(Locks::mutator_lock_);
40962d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers
41062d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers  // Call back for configure stubs.
411bdf7f1c3ab65ccb70f62db5ab31dba060632d458Andreas Gampe  void InstallStubsForClass(mirror::Class* klass) REQUIRES_SHARED(Locks::mutator_lock_)
41290443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier      REQUIRES(!deoptimized_methods_lock_);
413725a957985171d712d5c048cc3d00ff14968784bjeffhao
414e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier  void InstallStubsForMethod(ArtMethod* method)
415bdf7f1c3ab65ccb70f62db5ab31dba060632d458Andreas Gampe      REQUIRES_SHARED(Locks::mutator_lock_) REQUIRES(!deoptimized_methods_lock_);
416138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz
41799170c636dfae4908b102347cfe9f92bad1881ccMingyao Yang  // Install instrumentation exit stub on every method of the stack of the given thread.
41899170c636dfae4908b102347cfe9f92bad1881ccMingyao Yang  // This is used by the debugger to cause a deoptimization of the thread's stack after updating
41999170c636dfae4908b102347cfe9f92bad1881ccMingyao Yang  // local variable(s).
42099170c636dfae4908b102347cfe9f92bad1881ccMingyao Yang  void InstrumentThreadStack(Thread* thread)
421bdf7f1c3ab65ccb70f62db5ab31dba060632d458Andreas Gampe      REQUIRES_SHARED(Locks::mutator_lock_)
42299170c636dfae4908b102347cfe9f92bad1881ccMingyao Yang      REQUIRES(!Locks::thread_list_lock_);
42399170c636dfae4908b102347cfe9f92bad1881ccMingyao Yang
424b2feaafd89813af69c65da95e0b51b1a4cecaf0bSebastien Hertz  static size_t ComputeFrameId(Thread* self,
425b2feaafd89813af69c65da95e0b51b1a4cecaf0bSebastien Hertz                               size_t frame_depth,
426b2feaafd89813af69c65da95e0b51b1a4cecaf0bSebastien Hertz                               size_t inlined_frames_before_frame)
427bdf7f1c3ab65ccb70f62db5ab31dba060632d458Andreas Gampe      REQUIRES_SHARED(Locks::mutator_lock_);
428b2feaafd89813af69c65da95e0b51b1a4cecaf0bSebastien Hertz
429eebc3af4453f5c1fb5fd80c710cfd49566080d28Mathieu Chartier  // Does not hold lock, used to check if someone changed from not instrumented to instrumented
430eebc3af4453f5c1fb5fd80c710cfd49566080d28Mathieu Chartier  // during a GC suspend point.
431bdf7f1c3ab65ccb70f62db5ab31dba060632d458Andreas Gampe  bool AllocEntrypointsInstrumented() const REQUIRES_SHARED(Locks::mutator_lock_) {
43250e933188d993c6eb67560db1fcad67ba1d182e1Mathieu Chartier    return alloc_entrypoints_instrumented_;
433eebc3af4453f5c1fb5fd80c710cfd49566080d28Mathieu Chartier  }
434eebc3af4453f5c1fb5fd80c710cfd49566080d28Mathieu Chartier
4350462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz  InstrumentationLevel GetCurrentInstrumentationLevel() const;
4360462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz
437dba61481035b7944173181ec9ee02aea41dd0e29Alex Light private:
438dba61481035b7944173181ec9ee02aea41dd0e29Alex Light  // Returns true if moving to the given instrumentation level requires the installation of stubs.
439dba61481035b7944173181ec9ee02aea41dd0e29Alex Light  // False otherwise.
440dba61481035b7944173181ec9ee02aea41dd0e29Alex Light  bool RequiresInstrumentationInstallation(InstrumentationLevel new_level) const;
441dba61481035b7944173181ec9ee02aea41dd0e29Alex Light
44262d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers  // Does the job of installing or removing instrumentation code within methods.
4430462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz  // In order to support multiple clients using instrumentation at the same time,
4440462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz  // the caller must pass a unique key (a string) identifying it so we remind which
4450462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz  // instrumentation level it needs. Therefore the current instrumentation level
4460462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz  // becomes the highest instrumentation level required by a client.
4470462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz  void ConfigureStubs(const char* key, InstrumentationLevel desired_instrumentation_level)
448aa5168291c46f9b418d989bccf2d8e09338a83e6Mathieu Chartier      REQUIRES(Locks::mutator_lock_, Roles::uninterruptible_)
449aa5168291c46f9b418d989bccf2d8e09338a83e6Mathieu Chartier      REQUIRES(!deoptimized_methods_lock_,
450aa5168291c46f9b418d989bccf2d8e09338a83e6Mathieu Chartier               !Locks::thread_list_lock_,
45190443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier               !Locks::classlinker_classes_lock_);
45262d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers
45390443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier  void UpdateInterpreterHandlerTable() REQUIRES(Locks::mutator_lock_) {
4541452bee8f06b9f76a333ddf4760e4beaa82f8099buzbee    /*
4551452bee8f06b9f76a333ddf4760e4beaa82f8099buzbee     * TUNING: Dalvik's mterp stashes the actual current handler table base in a
4561452bee8f06b9f76a333ddf4760e4beaa82f8099buzbee     * tls field.  For Arm, this enables all suspend, debug & tracing checks to be
4571452bee8f06b9f76a333ddf4760e4beaa82f8099buzbee     * collapsed into a single conditionally-executed ldw instruction.
4581452bee8f06b9f76a333ddf4760e4beaa82f8099buzbee     * Move to Dalvik-style handler-table management for both the goto interpreter and
4591452bee8f06b9f76a333ddf4760e4beaa82f8099buzbee     * mterp.
4601452bee8f06b9f76a333ddf4760e4beaa82f8099buzbee     */
461ee1997a3b83334985e757f369c09e111b121661bSebastien Hertz    interpreter_handler_table_ = IsActive() ? kAlternativeHandlerTable : kMainHandlerTable;
462ee1997a3b83334985e757f369c09e111b121661bSebastien Hertz  }
463ee1997a3b83334985e757f369c09e111b121661bSebastien Hertz
464661974a5561e5ccdfbac8cb5d8df8b7e6f3483b8Mathieu Chartier  // No thread safety analysis to get around SetQuickAllocEntryPointsInstrumented requiring
465661974a5561e5ccdfbac8cb5d8df8b7e6f3483b8Mathieu Chartier  // exclusive access to mutator lock which you can't get if the runtime isn't started.
4669ef78b59da51080882e47505896b420977fd79aeMathieu Chartier  void SetEntrypointsInstrumented(bool instrumented) NO_THREAD_SAFETY_ANALYSIS;
467661974a5561e5ccdfbac8cb5d8df8b7e6f3483b8Mathieu Chartier
46862d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers  void MethodEnterEventImpl(Thread* thread, mirror::Object* this_object,
469e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier                            ArtMethod* method, uint32_t dex_pc) const
470bdf7f1c3ab65ccb70f62db5ab31dba060632d458Andreas Gampe      REQUIRES_SHARED(Locks::mutator_lock_);
47162d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers  void MethodExitEventImpl(Thread* thread, mirror::Object* this_object,
472e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier                           ArtMethod* method,
47362d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers                           uint32_t dex_pc, const JValue& return_value) const
474bdf7f1c3ab65ccb70f62db5ab31dba060632d458Andreas Gampe      REQUIRES_SHARED(Locks::mutator_lock_);
47562d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers  void DexPcMovedEventImpl(Thread* thread, mirror::Object* this_object,
476e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier                           ArtMethod* method, uint32_t dex_pc) const
477bdf7f1c3ab65ccb70f62db5ab31dba060632d458Andreas Gampe      REQUIRES_SHARED(Locks::mutator_lock_);
47881f0f953c4bb159997046c962d44cb1898b1778dNicolas Geoffray  void BranchImpl(Thread* thread, ArtMethod* method, uint32_t dex_pc, int32_t offset) const
479bdf7f1c3ab65ccb70f62db5ab31dba060632d458Andreas Gampe      REQUIRES_SHARED(Locks::mutator_lock_);
4805550ca8bcc742b109d77e62f3a0877c667d894d3Nicolas Geoffray  void InvokeVirtualOrInterfaceImpl(Thread* thread,
4815550ca8bcc742b109d77e62f3a0877c667d894d3Nicolas Geoffray                                    mirror::Object* this_object,
4825550ca8bcc742b109d77e62f3a0877c667d894d3Nicolas Geoffray                                    ArtMethod* caller,
4835550ca8bcc742b109d77e62f3a0877c667d894d3Nicolas Geoffray                                    uint32_t dex_pc,
4845550ca8bcc742b109d77e62f3a0877c667d894d3Nicolas Geoffray                                    ArtMethod* callee) const
485bdf7f1c3ab65ccb70f62db5ab31dba060632d458Andreas Gampe      REQUIRES_SHARED(Locks::mutator_lock_);
4863f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertz  void FieldReadEventImpl(Thread* thread, mirror::Object* this_object,
487e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier                           ArtMethod* method, uint32_t dex_pc,
488c785344b87221f5e4e6473e5b762e4e61fe65dcfMathieu Chartier                           ArtField* field) const
489bdf7f1c3ab65ccb70f62db5ab31dba060632d458Andreas Gampe      REQUIRES_SHARED(Locks::mutator_lock_);
4903f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertz  void FieldWriteEventImpl(Thread* thread, mirror::Object* this_object,
491e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier                           ArtMethod* method, uint32_t dex_pc,
492c785344b87221f5e4e6473e5b762e4e61fe65dcfMathieu Chartier                           ArtField* field, const JValue& field_value) const
493bdf7f1c3ab65ccb70f62db5ab31dba060632d458Andreas Gampe      REQUIRES_SHARED(Locks::mutator_lock_);
49462d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers
495799eb3a5555254427db269921042419bc30d4d86Hiroshi Yamauchi  // Read barrier-aware utility functions for accessing deoptimized_methods_
496e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier  bool AddDeoptimizedMethod(ArtMethod* method)
497bdf7f1c3ab65ccb70f62db5ab31dba060632d458Andreas Gampe      REQUIRES_SHARED(Locks::mutator_lock_) REQUIRES(deoptimized_methods_lock_);
498e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier  bool IsDeoptimizedMethod(ArtMethod* method)
499bdf7f1c3ab65ccb70f62db5ab31dba060632d458Andreas Gampe      REQUIRES_SHARED(Locks::mutator_lock_, deoptimized_methods_lock_);
500e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier  bool RemoveDeoptimizedMethod(ArtMethod* method)
501bdf7f1c3ab65ccb70f62db5ab31dba060632d458Andreas Gampe      REQUIRES_SHARED(Locks::mutator_lock_) REQUIRES(deoptimized_methods_lock_);
502e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier  ArtMethod* BeginDeoptimizedMethod()
503bdf7f1c3ab65ccb70f62db5ab31dba060632d458Andreas Gampe      REQUIRES_SHARED(Locks::mutator_lock_, deoptimized_methods_lock_);
504799eb3a5555254427db269921042419bc30d4d86Hiroshi Yamauchi  bool IsDeoptimizedMethodsEmpty() const
505bdf7f1c3ab65ccb70f62db5ab31dba060632d458Andreas Gampe      REQUIRES_SHARED(Locks::mutator_lock_, deoptimized_methods_lock_);
5063fd448a8b7903b00fceaed5853306e2d7eb31c72Mingyao Yang  void UpdateMethodsCodeImpl(ArtMethod* method, const void* quick_code)
507bdf7f1c3ab65ccb70f62db5ab31dba060632d458Andreas Gampe      REQUIRES_SHARED(Locks::mutator_lock_) REQUIRES(!deoptimized_methods_lock_);
5083fd448a8b7903b00fceaed5853306e2d7eb31c72Mingyao Yang
509799eb3a5555254427db269921042419bc30d4d86Hiroshi Yamauchi
510ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom  // Have we hijacked ArtMethod::code_ so that it calls instrumentation/interpreter code?
51162d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers  bool instrumentation_stubs_installed_;
51262d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers
513ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom  // Have we hijacked ArtMethod::code_ to reference the enter/exit stubs?
51462d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers  bool entry_exit_stubs_installed_;
51562d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers
516ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom  // Have we hijacked ArtMethod::code_ to reference the enter interpreter stub?
51762d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers  bool interpreter_stubs_installed_;
51862d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers
51962d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers  // Do we need the fidelity of events that we only get from running within the interpreter?
52062d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers  bool interpret_only_;
521725a957985171d712d5c048cc3d00ff14968784bjeffhao
52262d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers  // Did the runtime request we only run in the interpreter? ie -Xint mode.
52362d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers  bool forced_interpret_only_;
524725a957985171d712d5c048cc3d00ff14968784bjeffhao
52562d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers  // Do we have any listeners for method entry events? Short-cut to avoid taking the
52662d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers  // instrumentation_lock_.
527ed2be1725fb79075892b1a9103487c9d9a95b350Sebastien Hertz  bool have_method_entry_listeners_ GUARDED_BY(Locks::mutator_lock_);
52862d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers
52962d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers  // Do we have any listeners for method exit events? Short-cut to avoid taking the
53062d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers  // instrumentation_lock_.
531ed2be1725fb79075892b1a9103487c9d9a95b350Sebastien Hertz  bool have_method_exit_listeners_ GUARDED_BY(Locks::mutator_lock_);
53262d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers
53362d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers  // Do we have any listeners for method unwind events? Short-cut to avoid taking the
53462d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers  // instrumentation_lock_.
535ed2be1725fb79075892b1a9103487c9d9a95b350Sebastien Hertz  bool have_method_unwind_listeners_ GUARDED_BY(Locks::mutator_lock_);
53662d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers
53762d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers  // Do we have any listeners for dex move events? Short-cut to avoid taking the
53862d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers  // instrumentation_lock_.
539ed2be1725fb79075892b1a9103487c9d9a95b350Sebastien Hertz  bool have_dex_pc_listeners_ GUARDED_BY(Locks::mutator_lock_);
54062d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers
5413f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertz  // Do we have any listeners for field read events? Short-cut to avoid taking the
5423f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertz  // instrumentation_lock_.
543ed2be1725fb79075892b1a9103487c9d9a95b350Sebastien Hertz  bool have_field_read_listeners_ GUARDED_BY(Locks::mutator_lock_);
5443f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertz
5453f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertz  // Do we have any listeners for field write events? Short-cut to avoid taking the
5463f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertz  // instrumentation_lock_.
547ed2be1725fb79075892b1a9103487c9d9a95b350Sebastien Hertz  bool have_field_write_listeners_ GUARDED_BY(Locks::mutator_lock_);
5483f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertz
54962d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers  // Do we have any exception caught listeners? Short-cut to avoid taking the instrumentation_lock_.
550ed2be1725fb79075892b1a9103487c9d9a95b350Sebastien Hertz  bool have_exception_caught_listeners_ GUARDED_BY(Locks::mutator_lock_);
55162d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers
55281f0f953c4bb159997046c962d44cb1898b1778dNicolas Geoffray  // Do we have any branch listeners? Short-cut to avoid taking the instrumentation_lock_.
55381f0f953c4bb159997046c962d44cb1898b1778dNicolas Geoffray  bool have_branch_listeners_ GUARDED_BY(Locks::mutator_lock_);
554e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier
5555550ca8bcc742b109d77e62f3a0877c667d894d3Nicolas Geoffray  // Do we have any invoke listeners? Short-cut to avoid taking the instrumentation_lock_.
5565550ca8bcc742b109d77e62f3a0877c667d894d3Nicolas Geoffray  bool have_invoke_virtual_or_interface_listeners_ GUARDED_BY(Locks::mutator_lock_);
5575550ca8bcc742b109d77e62f3a0877c667d894d3Nicolas Geoffray
5580462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz  // Contains the instrumentation level required by each client of the instrumentation identified
5590462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz  // by a string key.
5600462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz  typedef SafeMap<const char*, InstrumentationLevel> InstrumentationLevelTable;
5610462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz  InstrumentationLevelTable requested_instrumentation_levels_ GUARDED_BY(Locks::mutator_lock_);
5620462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz
56362d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers  // The event listeners, written to with the mutator_lock_ exclusively held.
564514a616fd434212815bdd49cc1e2786817395969Nicolas Geoffray  // Mutators must be able to iterate over these lists concurrently, that is, with listeners being
565514a616fd434212815bdd49cc1e2786817395969Nicolas Geoffray  // added or removed while iterating. The modifying thread holds exclusive lock,
566514a616fd434212815bdd49cc1e2786817395969Nicolas Geoffray  // so other threads cannot iterate (i.e. read the data of the list) at the same time but they
567514a616fd434212815bdd49cc1e2786817395969Nicolas Geoffray  // do keep iterators that need to remain valid. This is the reason these listeners are std::list
568514a616fd434212815bdd49cc1e2786817395969Nicolas Geoffray  // and not for example std::vector: the existing storage for a std::list does not move.
569514a616fd434212815bdd49cc1e2786817395969Nicolas Geoffray  // Note that mutators cannot make a copy of these lists before iterating, as the instrumentation
570514a616fd434212815bdd49cc1e2786817395969Nicolas Geoffray  // listeners can also be deleted concurrently.
571514a616fd434212815bdd49cc1e2786817395969Nicolas Geoffray  // As a result, these lists are never trimmed. That's acceptable given the low number of
572514a616fd434212815bdd49cc1e2786817395969Nicolas Geoffray  // listeners we have.
57362d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers  std::list<InstrumentationListener*> method_entry_listeners_ GUARDED_BY(Locks::mutator_lock_);
57462d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers  std::list<InstrumentationListener*> method_exit_listeners_ GUARDED_BY(Locks::mutator_lock_);
57562d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers  std::list<InstrumentationListener*> method_unwind_listeners_ GUARDED_BY(Locks::mutator_lock_);
57681f0f953c4bb159997046c962d44cb1898b1778dNicolas Geoffray  std::list<InstrumentationListener*> branch_listeners_ GUARDED_BY(Locks::mutator_lock_);
5775550ca8bcc742b109d77e62f3a0877c667d894d3Nicolas Geoffray  std::list<InstrumentationListener*> invoke_virtual_or_interface_listeners_
5785550ca8bcc742b109d77e62f3a0877c667d894d3Nicolas Geoffray      GUARDED_BY(Locks::mutator_lock_);
579514a616fd434212815bdd49cc1e2786817395969Nicolas Geoffray  std::list<InstrumentationListener*> dex_pc_listeners_ GUARDED_BY(Locks::mutator_lock_);
580514a616fd434212815bdd49cc1e2786817395969Nicolas Geoffray  std::list<InstrumentationListener*> field_read_listeners_ GUARDED_BY(Locks::mutator_lock_);
581514a616fd434212815bdd49cc1e2786817395969Nicolas Geoffray  std::list<InstrumentationListener*> field_write_listeners_ GUARDED_BY(Locks::mutator_lock_);
582514a616fd434212815bdd49cc1e2786817395969Nicolas Geoffray  std::list<InstrumentationListener*> exception_caught_listeners_ GUARDED_BY(Locks::mutator_lock_);
583725a957985171d712d5c048cc3d00ff14968784bjeffhao
584138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz  // The set of methods being deoptimized (by the debugger) which must be executed with interpreter
585138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz  // only.
5863b05e9ba874449dbff65b01b8781001f7d93eea6Mathieu Chartier  mutable ReaderWriterMutex deoptimized_methods_lock_ DEFAULT_MUTEX_ACQUIRED_AFTER;
587e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier  std::unordered_set<ArtMethod*> deoptimized_methods_ GUARDED_BY(deoptimized_methods_lock_);
58811d40c250ec86c784cf76b8c31e1cf9285d555dcSebastien Hertz  bool deoptimization_enabled_;
589138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz
590fa82427c68b09f4aedbee319dc71579afbfc66f5Ian Rogers  // Current interpreter handler table. This is updated each time the thread state flags are
591fa82427c68b09f4aedbee319dc71579afbfc66f5Ian Rogers  // modified.
592ed2be1725fb79075892b1a9103487c9d9a95b350Sebastien Hertz  InterpreterHandlerTable interpreter_handler_table_ GUARDED_BY(Locks::mutator_lock_);
593ee1997a3b83334985e757f369c09e111b121661bSebastien Hertz
594fa82427c68b09f4aedbee319dc71579afbfc66f5Ian Rogers  // Greater than 0 if quick alloc entry points instrumented.
595eebc3af4453f5c1fb5fd80c710cfd49566080d28Mathieu Chartier  size_t quick_alloc_entry_points_instrumentation_counter_;
59650e933188d993c6eb67560db1fcad67ba1d182e1Mathieu Chartier
59750e933188d993c6eb67560db1fcad67ba1d182e1Mathieu Chartier  // alloc_entrypoints_instrumented_ is only updated with all the threads suspended, this is done
59850e933188d993c6eb67560db1fcad67ba1d182e1Mathieu Chartier  // to prevent races with the GC where the GC relies on thread suspension only see
59950e933188d993c6eb67560db1fcad67ba1d182e1Mathieu Chartier  // alloc_entrypoints_instrumented_ change during suspend points.
60050e933188d993c6eb67560db1fcad67ba1d182e1Mathieu Chartier  bool alloc_entrypoints_instrumented_;
60150e933188d993c6eb67560db1fcad67ba1d182e1Mathieu Chartier
6020462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz  friend class InstrumentationTest;  // For GetCurrentInstrumentationLevel and ConfigureStubs.
6030462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz
604725a957985171d712d5c048cc3d00ff14968784bjeffhao  DISALLOW_COPY_AND_ASSIGN(Instrumentation);
605725a957985171d712d5c048cc3d00ff14968784bjeffhao};
6066a3c1fcb4ba42ad4d5d142c17a3712a6ddd3866fIan Rogersstd::ostream& operator<<(std::ostream& os, const Instrumentation::InstrumentationEvent& rhs);
6070462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertzstd::ostream& operator<<(std::ostream& os, const Instrumentation::InstrumentationLevel& rhs);
608725a957985171d712d5c048cc3d00ff14968784bjeffhao
60962d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers// An element in the instrumentation side stack maintained in art::Thread.
61062d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogersstruct InstrumentationStackFrame {
611e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier  InstrumentationStackFrame(mirror::Object* this_object, ArtMethod* method,
6129a916d3c0d0574d106c764e737c67b52988d6139Jeff Hao                            uintptr_t return_pc, size_t frame_id, bool interpreter_entry)
6139a916d3c0d0574d106c764e737c67b52988d6139Jeff Hao      : this_object_(this_object), method_(method), return_pc_(return_pc), frame_id_(frame_id),
6149a916d3c0d0574d106c764e737c67b52988d6139Jeff Hao        interpreter_entry_(interpreter_entry) {
61562d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers  }
61662d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers
617bdf7f1c3ab65ccb70f62db5ab31dba060632d458Andreas Gampe  std::string Dump() const REQUIRES_SHARED(Locks::mutator_lock_);
61862d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers
61962d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers  mirror::Object* this_object_;
620e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier  ArtMethod* method_;
621138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz  uintptr_t return_pc_;
622138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz  size_t frame_id_;
623138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz  bool interpreter_entry_;
62462d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers};
62562d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers
62662d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers}  // namespace instrumentation
627725a957985171d712d5c048cc3d00ff14968784bjeffhao}  // namespace art
628725a957985171d712d5c048cc3d00ff14968784bjeffhao
629fc0e3219edc9a5bf81b166e82fd5db2796eb6a0dBrian Carlstrom#endif  // ART_RUNTIME_INSTRUMENTATION_H_
630