instrumentation.h revision b2feaafd89813af69c65da95e0b51b1a4cecaf0b
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"
25761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes#include "base/macros.h"
26719d1a33f6569864f529e5a3fff59e7bca97aad0Ian Rogers#include "base/mutex.h"
2794f7b49578b6aaa80de8ffed230648d601393905Hiroshi Yamauchi#include "gc_root.h"
280462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz#include "safe_map.h"
292dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers
30725a957985171d712d5c048cc3d00ff14968784bjeffhaonamespace art {
312dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogersnamespace mirror {
32ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom  class Class;
33ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom  class Object;
34ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom  class Throwable;
3562d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers}  // namespace mirror
36c785344b87221f5e4e6473e5b762e4e61fe65dcfMathieu Chartierclass ArtField;
37e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartierclass ArtMethod;
3862d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogersunion JValue;
39725a957985171d712d5c048cc3d00ff14968784bjeffhaoclass Thread;
40725a957985171d712d5c048cc3d00ff14968784bjeffhao
4162d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogersnamespace instrumentation {
42725a957985171d712d5c048cc3d00ff14968784bjeffhao
43ee1997a3b83334985e757f369c09e111b121661bSebastien Hertz// Interpreter handler tables.
44ee1997a3b83334985e757f369c09e111b121661bSebastien Hertzenum InterpreterHandlerTable {
45ee1997a3b83334985e757f369c09e111b121661bSebastien Hertz  kMainHandlerTable = 0,          // Main handler table: no suspend check, no instrumentation.
46ee1997a3b83334985e757f369c09e111b121661bSebastien Hertz  kAlternativeHandlerTable = 1,   // Alternative handler table: suspend check and/or instrumentation
47ee1997a3b83334985e757f369c09e111b121661bSebastien Hertz                                  // enabled.
48ee1997a3b83334985e757f369c09e111b121661bSebastien Hertz  kNumHandlerTables
49ee1997a3b83334985e757f369c09e111b121661bSebastien Hertz};
50ee1997a3b83334985e757f369c09e111b121661bSebastien Hertz
5140da286d3207d88ed8ff3f5caac4873874603428Andreas Gampe// Do we want to deoptimize for method entry and exit listeners or just try to intercept
5240da286d3207d88ed8ff3f5caac4873874603428Andreas Gampe// invocations? Deoptimization forces all code to run in the interpreter and considerably hurts the
5340da286d3207d88ed8ff3f5caac4873874603428Andreas Gampe// application's performance.
5440da286d3207d88ed8ff3f5caac4873874603428Andreas Gampestatic constexpr bool kDeoptimizeForAccurateMethodEntryExitListeners = true;
5540da286d3207d88ed8ff3f5caac4873874603428Andreas Gampe
5662d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers// Instrumentation event listener API. Registered listeners will get the appropriate call back for
5762d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers// the events they are listening for. The call backs supply the thread, method and dex_pc the event
5862d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers// occurred upon. The thread may or may not be Thread::Current().
5962d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogersstruct InstrumentationListener {
6062d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers  InstrumentationListener() {}
6162d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers  virtual ~InstrumentationListener() {}
6262d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers
6362d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers  // Call-back for when a method is entered.
6462d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers  virtual void MethodEntered(Thread* thread, mirror::Object* this_object,
65e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier                             ArtMethod* method,
6690443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier                             uint32_t dex_pc) SHARED_REQUIRES(Locks::mutator_lock_) = 0;
6762d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers
6862d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers  // Call-back for when a method is exited.
6962d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers  virtual void MethodExited(Thread* thread, mirror::Object* this_object,
70e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier                            ArtMethod* method, uint32_t dex_pc,
7162d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers                            const JValue& return_value)
7290443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier      SHARED_REQUIRES(Locks::mutator_lock_) = 0;
7362d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers
7462d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers  // Call-back for when a method is popped due to an exception throw. A method will either cause a
7562d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers  // MethodExited call-back or a MethodUnwind call-back when its activation is removed.
7651db44a194bafc3810a41164a8b39614f10e79dfSebastien Hertz  virtual void MethodUnwind(Thread* thread, mirror::Object* this_object,
77e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier                            ArtMethod* method, uint32_t dex_pc)
7890443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier      SHARED_REQUIRES(Locks::mutator_lock_) = 0;
7962d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers
8062d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers  // Call-back for when the dex pc moves in a method.
8162d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers  virtual void DexPcMoved(Thread* thread, mirror::Object* this_object,
82e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier                          ArtMethod* method, uint32_t new_dex_pc)
8390443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier      SHARED_REQUIRES(Locks::mutator_lock_) = 0;
8462d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers
853f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertz  // Call-back for when we read from a field.
86e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier  virtual void FieldRead(Thread* thread, mirror::Object* this_object, ArtMethod* method,
87c785344b87221f5e4e6473e5b762e4e61fe65dcfMathieu Chartier                         uint32_t dex_pc, ArtField* field) = 0;
883f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertz
893f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertz  // Call-back for when we write into a field.
90e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier  virtual void FieldWritten(Thread* thread, mirror::Object* this_object, ArtMethod* method,
91c785344b87221f5e4e6473e5b762e4e61fe65dcfMathieu Chartier                            uint32_t dex_pc, ArtField* field, const JValue& field_value) = 0;
923f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertz
9362d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers  // Call-back when an exception is caught.
9414691c5e786e8c2c5734f687e4c96217340771beNicolas Geoffray  virtual void ExceptionCaught(Thread* thread, mirror::Throwable* exception_object)
9590443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier      SHARED_REQUIRES(Locks::mutator_lock_) = 0;
96e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier
97e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier  // Call-back for when we get a backward branch.
98e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier  virtual void BackwardBranch(Thread* thread, ArtMethod* method, int32_t dex_pc_offset)
9990443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier      SHARED_REQUIRES(Locks::mutator_lock_) = 0;
1005550ca8bcc742b109d77e62f3a0877c667d894d3Nicolas Geoffray
1015550ca8bcc742b109d77e62f3a0877c667d894d3Nicolas Geoffray  // Call-back for when we get an invokevirtual or an invokeinterface.
1025550ca8bcc742b109d77e62f3a0877c667d894d3Nicolas Geoffray  virtual void InvokeVirtualOrInterface(Thread* thread,
1035550ca8bcc742b109d77e62f3a0877c667d894d3Nicolas Geoffray                                        mirror::Object* this_object,
1045550ca8bcc742b109d77e62f3a0877c667d894d3Nicolas Geoffray                                        ArtMethod* caller,
1055550ca8bcc742b109d77e62f3a0877c667d894d3Nicolas Geoffray                                        uint32_t dex_pc,
1065550ca8bcc742b109d77e62f3a0877c667d894d3Nicolas Geoffray                                        ArtMethod* callee)
1075550ca8bcc742b109d77e62f3a0877c667d894d3Nicolas Geoffray      SHARED_REQUIRES(Locks::mutator_lock_) = 0;
108725a957985171d712d5c048cc3d00ff14968784bjeffhao};
109725a957985171d712d5c048cc3d00ff14968784bjeffhao
11062d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers// Instrumentation is a catch-all for when extra information is required from the runtime. The
11162d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers// typical use for instrumentation is for profiling and debugging. Instrumentation may add stubs
11262d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers// to method entry and exit, it may also force execution to be switched to the interpreter and
11362d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers// trigger deoptimization.
114725a957985171d712d5c048cc3d00ff14968784bjeffhaoclass Instrumentation {
115725a957985171d712d5c048cc3d00ff14968784bjeffhao public:
11662d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers  enum InstrumentationEvent {
117e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier    kMethodEntered = 0x1,
118e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier    kMethodExited = 0x2,
119e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier    kMethodUnwind = 0x4,
120e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier    kDexPcMoved = 0x8,
121e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier    kFieldRead = 0x10,
122e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier    kFieldWritten = 0x20,
123e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier    kExceptionCaught = 0x40,
124e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier    kBackwardBranch = 0x80,
1255550ca8bcc742b109d77e62f3a0877c667d894d3Nicolas Geoffray    kInvokeVirtualOrInterface = 0x100,
12662d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers  };
12762d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers
1280462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz  enum class InstrumentationLevel {
1290462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz    kInstrumentNothing,                   // execute without instrumentation
1300462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz    kInstrumentWithInstrumentationStubs,  // execute with instrumentation entry/exit stubs
1310462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz    kInstrumentWithInterpreter            // execute with interpreter
1320462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz  };
1330462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz
1343b05e9ba874449dbff65b01b8781001f7d93eea6Mathieu Chartier  Instrumentation();
13562d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers
13662d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers  // Add a listener to be notified of the masked together sent of instrumentation events. This
13762d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers  // suspend the runtime to install stubs. You are expected to hold the mutator lock as a proxy
13862d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers  // for saying you should have suspended all threads (installing stubs while threads are running
13962d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers  // will break).
14062d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers  void AddListener(InstrumentationListener* listener, uint32_t events)
14190443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier      REQUIRES(Locks::mutator_lock_, !Locks::thread_list_lock_, !Locks::classlinker_classes_lock_);
14262d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers
14362d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers  // Removes a listener possibly removing instrumentation stubs.
14462d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers  void RemoveListener(InstrumentationListener* listener, uint32_t events)
14590443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier      REQUIRES(Locks::mutator_lock_, !Locks::thread_list_lock_, !Locks::classlinker_classes_lock_);
14662d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers
147138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz  // Deoptimization.
148a76a6d4cb3dedec909bd927f20bc0ab23198a337Sebastien Hertz  void EnableDeoptimization()
149aa5168291c46f9b418d989bccf2d8e09338a83e6Mathieu Chartier      REQUIRES(Locks::mutator_lock_)
150aa5168291c46f9b418d989bccf2d8e09338a83e6Mathieu Chartier      REQUIRES(!deoptimized_methods_lock_);
151aa5168291c46f9b418d989bccf2d8e09338a83e6Mathieu Chartier  // Calls UndeoptimizeEverything which may visit class linker classes through ConfigureStubs.
1520462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz  void DisableDeoptimization(const char* key)
153aa5168291c46f9b418d989bccf2d8e09338a83e6Mathieu Chartier      REQUIRES(Locks::mutator_lock_, Roles::uninterruptible_)
154aa5168291c46f9b418d989bccf2d8e09338a83e6Mathieu Chartier      REQUIRES(!deoptimized_methods_lock_);
155aa5168291c46f9b418d989bccf2d8e09338a83e6Mathieu Chartier
156a76a6d4cb3dedec909bd927f20bc0ab23198a337Sebastien Hertz  bool AreAllMethodsDeoptimized() const {
157a76a6d4cb3dedec909bd927f20bc0ab23198a337Sebastien Hertz    return interpreter_stubs_installed_;
158a76a6d4cb3dedec909bd927f20bc0ab23198a337Sebastien Hertz  }
15990443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier  bool ShouldNotifyMethodEnterExitEvents() const SHARED_REQUIRES(Locks::mutator_lock_);
160138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz
161138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz  // Executes everything with interpreter.
1620462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz  void DeoptimizeEverything(const char* key)
163aa5168291c46f9b418d989bccf2d8e09338a83e6Mathieu Chartier      REQUIRES(Locks::mutator_lock_, Roles::uninterruptible_)
164aa5168291c46f9b418d989bccf2d8e09338a83e6Mathieu Chartier      REQUIRES(!Locks::thread_list_lock_,
165aa5168291c46f9b418d989bccf2d8e09338a83e6Mathieu Chartier               !Locks::classlinker_classes_lock_,
16690443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier               !deoptimized_methods_lock_);
167138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz
168aa5168291c46f9b418d989bccf2d8e09338a83e6Mathieu Chartier  // Executes everything with compiled code (or interpreter if there is no code). May visit class
169aa5168291c46f9b418d989bccf2d8e09338a83e6Mathieu Chartier  // linker classes through ConfigureStubs.
1700462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz  void UndeoptimizeEverything(const char* key)
171aa5168291c46f9b418d989bccf2d8e09338a83e6Mathieu Chartier      REQUIRES(Locks::mutator_lock_, Roles::uninterruptible_)
172aa5168291c46f9b418d989bccf2d8e09338a83e6Mathieu Chartier      REQUIRES(!Locks::thread_list_lock_,
173aa5168291c46f9b418d989bccf2d8e09338a83e6Mathieu Chartier               !Locks::classlinker_classes_lock_,
17490443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier               !deoptimized_methods_lock_);
175138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz
176138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz  // Deoptimize a method by forcing its execution with the interpreter. Nevertheless, a static
177138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz  // method (except a class initializer) set to the resolution trampoline will be deoptimized only
178138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz  // once its declaring class is initialized.
179e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier  void Deoptimize(ArtMethod* method)
18090443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier      REQUIRES(Locks::mutator_lock_, !Locks::thread_list_lock_, !deoptimized_methods_lock_);
181138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz
182138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz  // Undeoptimze the method by restoring its entrypoints. Nevertheless, a static method
183138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz  // (except a class initializer) set to the resolution trampoline will be updated only once its
184138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz  // declaring class is initialized.
185e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier  void Undeoptimize(ArtMethod* method)
18690443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier      REQUIRES(Locks::mutator_lock_, !Locks::thread_list_lock_, !deoptimized_methods_lock_);
187138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz
1880462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz  // Indicates whether the method has been deoptimized so it is executed with the interpreter.
189e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier  bool IsDeoptimized(ArtMethod* method)
19090443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier      REQUIRES(!deoptimized_methods_lock_) SHARED_REQUIRES(Locks::mutator_lock_);
191138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz
1920462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz  // Enable method tracing by installing instrumentation entry/exit stubs or interpreter.
1930462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz  void EnableMethodTracing(const char* key,
1940462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz                           bool needs_interpreter = kDeoptimizeForAccurateMethodEntryExitListeners)
195aa5168291c46f9b418d989bccf2d8e09338a83e6Mathieu Chartier      REQUIRES(Locks::mutator_lock_, Roles::uninterruptible_)
196aa5168291c46f9b418d989bccf2d8e09338a83e6Mathieu Chartier      REQUIRES(!Locks::thread_list_lock_,
197aa5168291c46f9b418d989bccf2d8e09338a83e6Mathieu Chartier               !Locks::classlinker_classes_lock_,
19890443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier               !deoptimized_methods_lock_);
199138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz
2000462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz  // Disable method tracing by uninstalling instrumentation entry/exit stubs or interpreter.
2010462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz  void DisableMethodTracing(const char* key)
202aa5168291c46f9b418d989bccf2d8e09338a83e6Mathieu Chartier      REQUIRES(Locks::mutator_lock_, Roles::uninterruptible_)
203aa5168291c46f9b418d989bccf2d8e09338a83e6Mathieu Chartier      REQUIRES(!Locks::thread_list_lock_,
204aa5168291c46f9b418d989bccf2d8e09338a83e6Mathieu Chartier               !Locks::classlinker_classes_lock_,
20590443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier               !deoptimized_methods_lock_);
206138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz
207ed2be1725fb79075892b1a9103487c9d9a95b350Sebastien Hertz  InterpreterHandlerTable GetInterpreterHandlerTable() const
20890443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier      SHARED_REQUIRES(Locks::mutator_lock_) {
209ee1997a3b83334985e757f369c09e111b121661bSebastien Hertz    return interpreter_handler_table_;
210ee1997a3b83334985e757f369c09e111b121661bSebastien Hertz  }
211ee1997a3b83334985e757f369c09e111b121661bSebastien Hertz
21290443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier  void InstrumentQuickAllocEntryPoints() REQUIRES(!Locks::instrument_entrypoints_lock_);
21390443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier  void UninstrumentQuickAllocEntryPoints() REQUIRES(!Locks::instrument_entrypoints_lock_);
2149ef78b59da51080882e47505896b420977fd79aeMathieu Chartier  void InstrumentQuickAllocEntryPointsLocked()
21590443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier      REQUIRES(Locks::instrument_entrypoints_lock_, !Locks::thread_list_lock_,
21690443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier               !Locks::runtime_shutdown_lock_);
2179ef78b59da51080882e47505896b420977fd79aeMathieu Chartier  void UninstrumentQuickAllocEntryPointsLocked()
21890443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier      REQUIRES(Locks::instrument_entrypoints_lock_, !Locks::thread_list_lock_,
21990443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier               !Locks::runtime_shutdown_lock_);
22090443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier  void ResetQuickAllocEntryPoints() REQUIRES(Locks::runtime_shutdown_lock_);
221fa82427c68b09f4aedbee319dc71579afbfc66f5Ian Rogers
22262d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers  // Update the code of a method respecting any installed stubs.
223e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier  void UpdateMethodsCode(ArtMethod* method, const void* quick_code)
22490443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier      SHARED_REQUIRES(Locks::mutator_lock_) REQUIRES(!deoptimized_methods_lock_);
22562d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers
22662d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers  // Get the quick code for the given method. More efficient than asking the class linker as it
22762d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers  // will short-cut to GetCode if instrumentation and static method resolution stubs aren't
22862d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers  // installed.
229e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier  const void* GetQuickCodeFor(ArtMethod* method, size_t pointer_size) const
23090443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier      SHARED_REQUIRES(Locks::mutator_lock_);
23162d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers
23262d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers  void ForceInterpretOnly() {
23362d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers    interpret_only_ = true;
23462d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers    forced_interpret_only_ = true;
23562d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers  }
23662d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers
237ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom  // Called by ArtMethod::Invoke to determine dispatch mechanism.
23862d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers  bool InterpretOnly() const {
23962d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers    return interpret_only_;
24062d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers  }
24162d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers
242563b47cc142e477da244539b1d63070425e7fd78Hiroshi Yamauchi  bool IsForcedInterpretOnly() const {
243563b47cc142e477da244539b1d63070425e7fd78Hiroshi Yamauchi    return forced_interpret_only_;
244563b47cc142e477da244539b1d63070425e7fd78Hiroshi Yamauchi  }
245563b47cc142e477da244539b1d63070425e7fd78Hiroshi Yamauchi
24662d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers  bool AreExitStubsInstalled() const {
24762d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers    return instrumentation_stubs_installed_;
24862d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers  }
24962d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers
25090443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier  bool HasMethodEntryListeners() const SHARED_REQUIRES(Locks::mutator_lock_) {
25174109f6683096de494b1457fa6d5b0ac33b4c98cSebastien Hertz    return have_method_entry_listeners_;
25274109f6683096de494b1457fa6d5b0ac33b4c98cSebastien Hertz  }
25374109f6683096de494b1457fa6d5b0ac33b4c98cSebastien Hertz
25490443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier  bool HasMethodExitListeners() const SHARED_REQUIRES(Locks::mutator_lock_) {
25574109f6683096de494b1457fa6d5b0ac33b4c98cSebastien Hertz    return have_method_exit_listeners_;
25674109f6683096de494b1457fa6d5b0ac33b4c98cSebastien Hertz  }
25774109f6683096de494b1457fa6d5b0ac33b4c98cSebastien Hertz
25890443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier  bool HasMethodUnwindListeners() const SHARED_REQUIRES(Locks::mutator_lock_) {
2590462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz    return have_method_unwind_listeners_;
2600462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz  }
2610462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz
26290443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier  bool HasDexPcListeners() const SHARED_REQUIRES(Locks::mutator_lock_) {
26374109f6683096de494b1457fa6d5b0ac33b4c98cSebastien Hertz    return have_dex_pc_listeners_;
26474109f6683096de494b1457fa6d5b0ac33b4c98cSebastien Hertz  }
26574109f6683096de494b1457fa6d5b0ac33b4c98cSebastien Hertz
26690443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier  bool HasFieldReadListeners() const SHARED_REQUIRES(Locks::mutator_lock_) {
2673f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertz    return have_field_read_listeners_;
2683f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertz  }
2693f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertz
27090443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier  bool HasFieldWriteListeners() const SHARED_REQUIRES(Locks::mutator_lock_) {
2713f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertz    return have_field_write_listeners_;
2723f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertz  }
2733f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertz
27490443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier  bool HasExceptionCaughtListeners() const SHARED_REQUIRES(Locks::mutator_lock_) {
2759f1020305292a21fd14a402b189c765a125226abSebastien Hertz    return have_exception_caught_listeners_;
2769f1020305292a21fd14a402b189c765a125226abSebastien Hertz  }
2779f1020305292a21fd14a402b189c765a125226abSebastien Hertz
27890443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier  bool HasBackwardBranchListeners() const SHARED_REQUIRES(Locks::mutator_lock_) {
279e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier    return have_backward_branch_listeners_;
280e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier  }
281e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier
2825550ca8bcc742b109d77e62f3a0877c667d894d3Nicolas Geoffray  bool HasInvokeVirtualOrInterfaceListeners() const SHARED_REQUIRES(Locks::mutator_lock_) {
2835550ca8bcc742b109d77e62f3a0877c667d894d3Nicolas Geoffray    return have_invoke_virtual_or_interface_listeners_;
2845550ca8bcc742b109d77e62f3a0877c667d894d3Nicolas Geoffray  }
2855550ca8bcc742b109d77e62f3a0877c667d894d3Nicolas Geoffray
28690443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier  bool IsActive() const SHARED_REQUIRES(Locks::mutator_lock_) {
287ee1997a3b83334985e757f369c09e111b121661bSebastien Hertz    return have_dex_pc_listeners_ || have_method_entry_listeners_ || have_method_exit_listeners_ ||
28842cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz        have_field_read_listeners_ || have_field_write_listeners_ ||
289ee1997a3b83334985e757f369c09e111b121661bSebastien Hertz        have_exception_caught_listeners_ || have_method_unwind_listeners_;
290ee1997a3b83334985e757f369c09e111b121661bSebastien Hertz  }
291ee1997a3b83334985e757f369c09e111b121661bSebastien Hertz
29262d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers  // Inform listeners that a method has been entered. A dex PC is provided as we may install
29362d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers  // listeners into executing code and get method enter events for methods already on the stack.
29462d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers  void MethodEnterEvent(Thread* thread, mirror::Object* this_object,
295e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier                        ArtMethod* method, uint32_t dex_pc) const
29690443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier      SHARED_REQUIRES(Locks::mutator_lock_) {
29774109f6683096de494b1457fa6d5b0ac33b4c98cSebastien Hertz    if (UNLIKELY(HasMethodEntryListeners())) {
29862d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers      MethodEnterEventImpl(thread, this_object, method, dex_pc);
29962d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers    }
30062d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers  }
30162d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers
30262d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers  // Inform listeners that a method has been exited.
30362d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers  void MethodExitEvent(Thread* thread, mirror::Object* this_object,
304e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier                       ArtMethod* method, uint32_t dex_pc,
30562d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers                       const JValue& return_value) const
30690443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier      SHARED_REQUIRES(Locks::mutator_lock_) {
30774109f6683096de494b1457fa6d5b0ac33b4c98cSebastien Hertz    if (UNLIKELY(HasMethodExitListeners())) {
30862d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers      MethodExitEventImpl(thread, this_object, method, dex_pc, return_value);
30962d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers    }
31062d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers  }
31162d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers
31262d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers  // Inform listeners that a method has been exited due to an exception.
31362d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers  void MethodUnwindEvent(Thread* thread, mirror::Object* this_object,
314e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier                         ArtMethod* method, uint32_t dex_pc) const
31590443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier      SHARED_REQUIRES(Locks::mutator_lock_);
31662d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers
31762d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers  // Inform listeners that the dex pc has moved (only supported by the interpreter).
31862d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers  void DexPcMovedEvent(Thread* thread, mirror::Object* this_object,
319e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier                       ArtMethod* method, uint32_t dex_pc) const
32090443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier      SHARED_REQUIRES(Locks::mutator_lock_) {
32174109f6683096de494b1457fa6d5b0ac33b4c98cSebastien Hertz    if (UNLIKELY(HasDexPcListeners())) {
32262d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers      DexPcMovedEventImpl(thread, this_object, method, dex_pc);
32362d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers    }
32462d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers  }
325725a957985171d712d5c048cc3d00ff14968784bjeffhao
326e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier  // Inform listeners that a backward branch has been taken (only supported by the interpreter).
327e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier  void BackwardBranch(Thread* thread, ArtMethod* method, int32_t offset) const
32890443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier      SHARED_REQUIRES(Locks::mutator_lock_) {
329e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier    if (UNLIKELY(HasBackwardBranchListeners())) {
330e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier      BackwardBranchImpl(thread, method, offset);
331e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier    }
332e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier  }
333e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier
3343f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertz  // Inform listeners that we read a field (only supported by the interpreter).
3353f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertz  void FieldReadEvent(Thread* thread, mirror::Object* this_object,
336e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier                      ArtMethod* method, uint32_t dex_pc,
337c785344b87221f5e4e6473e5b762e4e61fe65dcfMathieu Chartier                      ArtField* field) const
33890443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier      SHARED_REQUIRES(Locks::mutator_lock_) {
3393f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertz    if (UNLIKELY(HasFieldReadListeners())) {
3403f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertz      FieldReadEventImpl(thread, this_object, method, dex_pc, field);
3413f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertz    }
3423f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertz  }
3433f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertz
3443f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertz  // Inform listeners that we write a field (only supported by the interpreter).
3453f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertz  void FieldWriteEvent(Thread* thread, mirror::Object* this_object,
346e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier                       ArtMethod* method, uint32_t dex_pc,
347c785344b87221f5e4e6473e5b762e4e61fe65dcfMathieu Chartier                       ArtField* field, const JValue& field_value) const
34890443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier      SHARED_REQUIRES(Locks::mutator_lock_) {
3493f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertz    if (UNLIKELY(HasFieldWriteListeners())) {
3503f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertz      FieldWriteEventImpl(thread, this_object, method, dex_pc, field, field_value);
3513f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertz    }
3523f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertz  }
3533f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertz
3545550ca8bcc742b109d77e62f3a0877c667d894d3Nicolas Geoffray  void InvokeVirtualOrInterface(Thread* thread,
3555550ca8bcc742b109d77e62f3a0877c667d894d3Nicolas Geoffray                                mirror::Object* this_object,
3565550ca8bcc742b109d77e62f3a0877c667d894d3Nicolas Geoffray                                ArtMethod* caller,
3575550ca8bcc742b109d77e62f3a0877c667d894d3Nicolas Geoffray                                uint32_t dex_pc,
3585550ca8bcc742b109d77e62f3a0877c667d894d3Nicolas Geoffray                                ArtMethod* callee) const
3595550ca8bcc742b109d77e62f3a0877c667d894d3Nicolas Geoffray      SHARED_REQUIRES(Locks::mutator_lock_) {
3605550ca8bcc742b109d77e62f3a0877c667d894d3Nicolas Geoffray    if (UNLIKELY(HasInvokeVirtualOrInterfaceListeners())) {
3615550ca8bcc742b109d77e62f3a0877c667d894d3Nicolas Geoffray      InvokeVirtualOrInterfaceImpl(thread, this_object, caller, dex_pc, callee);
3625550ca8bcc742b109d77e62f3a0877c667d894d3Nicolas Geoffray    }
3635550ca8bcc742b109d77e62f3a0877c667d894d3Nicolas Geoffray  }
3645550ca8bcc742b109d77e62f3a0877c667d894d3Nicolas Geoffray
36562d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers  // Inform listeners that an exception was caught.
36614691c5e786e8c2c5734f687e4c96217340771beNicolas Geoffray  void ExceptionCaughtEvent(Thread* thread, mirror::Throwable* exception_object) const
36790443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier      SHARED_REQUIRES(Locks::mutator_lock_);
368725a957985171d712d5c048cc3d00ff14968784bjeffhao
36962d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers  // Called when an instrumented method is entered. The intended link register (lr) is saved so
37062d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers  // that returning causes a branch to the method exit stub. Generates method enter events.
37162d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers  void PushInstrumentationStackFrame(Thread* self, mirror::Object* this_object,
372e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier                                     ArtMethod* method, uintptr_t lr,
3739a916d3c0d0574d106c764e737c67b52988d6139Jeff Hao                                     bool interpreter_entry)
37490443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier      SHARED_REQUIRES(Locks::mutator_lock_);
375725a957985171d712d5c048cc3d00ff14968784bjeffhao
37662d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers  // Called when an instrumented method is exited. Removes the pushed instrumentation frame
37762d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers  // returning the intended link register. Generates method exit events.
378d58342caa97108ba413bad467c285c0377f138f5Andreas Gampe  TwoWordReturn PopInstrumentationStackFrame(Thread* self, uintptr_t* return_pc,
379d58342caa97108ba413bad467c285c0377f138f5Andreas Gampe                                             uint64_t gpr_result, uint64_t fpr_result)
38090443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier      SHARED_REQUIRES(Locks::mutator_lock_) REQUIRES(!deoptimized_methods_lock_);
381725a957985171d712d5c048cc3d00ff14968784bjeffhao
38262d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers  // Pops an instrumentation frame from the current thread and generate an unwind event.
38362d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers  void PopMethodForUnwind(Thread* self, bool is_deoptimization) const
38490443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier      SHARED_REQUIRES(Locks::mutator_lock_);
38562d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers
38662d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers  // Call back for configure stubs.
38790443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier  void InstallStubsForClass(mirror::Class* klass) SHARED_REQUIRES(Locks::mutator_lock_)
38890443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier      REQUIRES(!deoptimized_methods_lock_);
389725a957985171d712d5c048cc3d00ff14968784bjeffhao
390e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier  void InstallStubsForMethod(ArtMethod* method)
39190443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier      SHARED_REQUIRES(Locks::mutator_lock_) REQUIRES(!deoptimized_methods_lock_);
392138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz
39399170c636dfae4908b102347cfe9f92bad1881ccMingyao Yang  // Install instrumentation exit stub on every method of the stack of the given thread.
39499170c636dfae4908b102347cfe9f92bad1881ccMingyao Yang  // This is used by the debugger to cause a deoptimization of the thread's stack after updating
39599170c636dfae4908b102347cfe9f92bad1881ccMingyao Yang  // local variable(s).
39699170c636dfae4908b102347cfe9f92bad1881ccMingyao Yang  void InstrumentThreadStack(Thread* thread)
39799170c636dfae4908b102347cfe9f92bad1881ccMingyao Yang      SHARED_REQUIRES(Locks::mutator_lock_)
39899170c636dfae4908b102347cfe9f92bad1881ccMingyao Yang      REQUIRES(!Locks::thread_list_lock_);
39999170c636dfae4908b102347cfe9f92bad1881ccMingyao Yang
400b2feaafd89813af69c65da95e0b51b1a4cecaf0bSebastien Hertz  static size_t ComputeFrameId(Thread* self,
401b2feaafd89813af69c65da95e0b51b1a4cecaf0bSebastien Hertz                               size_t frame_depth,
402b2feaafd89813af69c65da95e0b51b1a4cecaf0bSebastien Hertz                               size_t inlined_frames_before_frame)
403b2feaafd89813af69c65da95e0b51b1a4cecaf0bSebastien Hertz      SHARED_REQUIRES(Locks::mutator_lock_);
404b2feaafd89813af69c65da95e0b51b1a4cecaf0bSebastien Hertz
405725a957985171d712d5c048cc3d00ff14968784bjeffhao private:
4060462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz  InstrumentationLevel GetCurrentInstrumentationLevel() const;
4070462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz
40862d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers  // Does the job of installing or removing instrumentation code within methods.
4090462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz  // In order to support multiple clients using instrumentation at the same time,
4100462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz  // the caller must pass a unique key (a string) identifying it so we remind which
4110462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz  // instrumentation level it needs. Therefore the current instrumentation level
4120462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz  // becomes the highest instrumentation level required by a client.
4130462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz  void ConfigureStubs(const char* key, InstrumentationLevel desired_instrumentation_level)
414aa5168291c46f9b418d989bccf2d8e09338a83e6Mathieu Chartier      REQUIRES(Locks::mutator_lock_, Roles::uninterruptible_)
415aa5168291c46f9b418d989bccf2d8e09338a83e6Mathieu Chartier      REQUIRES(!deoptimized_methods_lock_,
416aa5168291c46f9b418d989bccf2d8e09338a83e6Mathieu Chartier               !Locks::thread_list_lock_,
41790443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier               !Locks::classlinker_classes_lock_);
41862d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers
41990443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier  void UpdateInterpreterHandlerTable() REQUIRES(Locks::mutator_lock_) {
420ee1997a3b83334985e757f369c09e111b121661bSebastien Hertz    interpreter_handler_table_ = IsActive() ? kAlternativeHandlerTable : kMainHandlerTable;
421ee1997a3b83334985e757f369c09e111b121661bSebastien Hertz  }
422ee1997a3b83334985e757f369c09e111b121661bSebastien Hertz
423661974a5561e5ccdfbac8cb5d8df8b7e6f3483b8Mathieu Chartier  // No thread safety analysis to get around SetQuickAllocEntryPointsInstrumented requiring
424661974a5561e5ccdfbac8cb5d8df8b7e6f3483b8Mathieu Chartier  // exclusive access to mutator lock which you can't get if the runtime isn't started.
4259ef78b59da51080882e47505896b420977fd79aeMathieu Chartier  void SetEntrypointsInstrumented(bool instrumented) NO_THREAD_SAFETY_ANALYSIS;
426661974a5561e5ccdfbac8cb5d8df8b7e6f3483b8Mathieu Chartier
42762d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers  void MethodEnterEventImpl(Thread* thread, mirror::Object* this_object,
428e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier                            ArtMethod* method, uint32_t dex_pc) const
42990443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier      SHARED_REQUIRES(Locks::mutator_lock_);
43062d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers  void MethodExitEventImpl(Thread* thread, mirror::Object* this_object,
431e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier                           ArtMethod* method,
43262d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers                           uint32_t dex_pc, const JValue& return_value) const
43390443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier      SHARED_REQUIRES(Locks::mutator_lock_);
43462d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers  void DexPcMovedEventImpl(Thread* thread, mirror::Object* this_object,
435e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier                           ArtMethod* method, uint32_t dex_pc) const
43690443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier      SHARED_REQUIRES(Locks::mutator_lock_);
437e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier  void BackwardBranchImpl(Thread* thread, ArtMethod* method, int32_t offset) const
43890443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier      SHARED_REQUIRES(Locks::mutator_lock_);
4395550ca8bcc742b109d77e62f3a0877c667d894d3Nicolas Geoffray  void InvokeVirtualOrInterfaceImpl(Thread* thread,
4405550ca8bcc742b109d77e62f3a0877c667d894d3Nicolas Geoffray                                    mirror::Object* this_object,
4415550ca8bcc742b109d77e62f3a0877c667d894d3Nicolas Geoffray                                    ArtMethod* caller,
4425550ca8bcc742b109d77e62f3a0877c667d894d3Nicolas Geoffray                                    uint32_t dex_pc,
4435550ca8bcc742b109d77e62f3a0877c667d894d3Nicolas Geoffray                                    ArtMethod* callee) const
4445550ca8bcc742b109d77e62f3a0877c667d894d3Nicolas Geoffray      SHARED_REQUIRES(Locks::mutator_lock_);
4453f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertz  void FieldReadEventImpl(Thread* thread, mirror::Object* this_object,
446e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier                           ArtMethod* method, uint32_t dex_pc,
447c785344b87221f5e4e6473e5b762e4e61fe65dcfMathieu Chartier                           ArtField* field) const
44890443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier      SHARED_REQUIRES(Locks::mutator_lock_);
4493f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertz  void FieldWriteEventImpl(Thread* thread, mirror::Object* this_object,
450e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier                           ArtMethod* method, uint32_t dex_pc,
451c785344b87221f5e4e6473e5b762e4e61fe65dcfMathieu Chartier                           ArtField* field, const JValue& field_value) const
45290443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier      SHARED_REQUIRES(Locks::mutator_lock_);
45362d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers
454799eb3a5555254427db269921042419bc30d4d86Hiroshi Yamauchi  // Read barrier-aware utility functions for accessing deoptimized_methods_
455e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier  bool AddDeoptimizedMethod(ArtMethod* method)
45690443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier      SHARED_REQUIRES(Locks::mutator_lock_) REQUIRES(deoptimized_methods_lock_);
457e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier  bool IsDeoptimizedMethod(ArtMethod* method)
45890443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier      SHARED_REQUIRES(Locks::mutator_lock_, deoptimized_methods_lock_);
459e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier  bool RemoveDeoptimizedMethod(ArtMethod* method)
46090443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier      SHARED_REQUIRES(Locks::mutator_lock_) REQUIRES(deoptimized_methods_lock_);
461e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier  ArtMethod* BeginDeoptimizedMethod()
46290443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier      SHARED_REQUIRES(Locks::mutator_lock_, deoptimized_methods_lock_);
463799eb3a5555254427db269921042419bc30d4d86Hiroshi Yamauchi  bool IsDeoptimizedMethodsEmpty() const
46490443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier      SHARED_REQUIRES(Locks::mutator_lock_, deoptimized_methods_lock_);
465799eb3a5555254427db269921042419bc30d4d86Hiroshi Yamauchi
466ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom  // Have we hijacked ArtMethod::code_ so that it calls instrumentation/interpreter code?
46762d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers  bool instrumentation_stubs_installed_;
46862d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers
469ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom  // Have we hijacked ArtMethod::code_ to reference the enter/exit stubs?
47062d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers  bool entry_exit_stubs_installed_;
47162d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers
472ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom  // Have we hijacked ArtMethod::code_ to reference the enter interpreter stub?
47362d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers  bool interpreter_stubs_installed_;
47462d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers
47562d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers  // Do we need the fidelity of events that we only get from running within the interpreter?
47662d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers  bool interpret_only_;
477725a957985171d712d5c048cc3d00ff14968784bjeffhao
47862d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers  // Did the runtime request we only run in the interpreter? ie -Xint mode.
47962d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers  bool forced_interpret_only_;
480725a957985171d712d5c048cc3d00ff14968784bjeffhao
48162d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers  // Do we have any listeners for method entry events? Short-cut to avoid taking the
48262d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers  // instrumentation_lock_.
483ed2be1725fb79075892b1a9103487c9d9a95b350Sebastien Hertz  bool have_method_entry_listeners_ GUARDED_BY(Locks::mutator_lock_);
48462d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers
48562d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers  // Do we have any listeners for method exit events? Short-cut to avoid taking the
48662d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers  // instrumentation_lock_.
487ed2be1725fb79075892b1a9103487c9d9a95b350Sebastien Hertz  bool have_method_exit_listeners_ GUARDED_BY(Locks::mutator_lock_);
48862d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers
48962d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers  // Do we have any listeners for method unwind events? Short-cut to avoid taking the
49062d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers  // instrumentation_lock_.
491ed2be1725fb79075892b1a9103487c9d9a95b350Sebastien Hertz  bool have_method_unwind_listeners_ GUARDED_BY(Locks::mutator_lock_);
49262d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers
49362d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers  // Do we have any listeners for dex move events? Short-cut to avoid taking the
49462d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers  // instrumentation_lock_.
495ed2be1725fb79075892b1a9103487c9d9a95b350Sebastien Hertz  bool have_dex_pc_listeners_ GUARDED_BY(Locks::mutator_lock_);
49662d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers
4973f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertz  // Do we have any listeners for field read events? Short-cut to avoid taking the
4983f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertz  // instrumentation_lock_.
499ed2be1725fb79075892b1a9103487c9d9a95b350Sebastien Hertz  bool have_field_read_listeners_ GUARDED_BY(Locks::mutator_lock_);
5003f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertz
5013f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertz  // Do we have any listeners for field write events? Short-cut to avoid taking the
5023f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertz  // instrumentation_lock_.
503ed2be1725fb79075892b1a9103487c9d9a95b350Sebastien Hertz  bool have_field_write_listeners_ GUARDED_BY(Locks::mutator_lock_);
5043f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertz
50562d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers  // Do we have any exception caught listeners? Short-cut to avoid taking the instrumentation_lock_.
506ed2be1725fb79075892b1a9103487c9d9a95b350Sebastien Hertz  bool have_exception_caught_listeners_ GUARDED_BY(Locks::mutator_lock_);
50762d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers
508e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier  // Do we have any backward branch listeners? Short-cut to avoid taking the instrumentation_lock_.
509e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier  bool have_backward_branch_listeners_ GUARDED_BY(Locks::mutator_lock_);
510e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier
5115550ca8bcc742b109d77e62f3a0877c667d894d3Nicolas Geoffray  // Do we have any invoke listeners? Short-cut to avoid taking the instrumentation_lock_.
5125550ca8bcc742b109d77e62f3a0877c667d894d3Nicolas Geoffray  bool have_invoke_virtual_or_interface_listeners_ GUARDED_BY(Locks::mutator_lock_);
5135550ca8bcc742b109d77e62f3a0877c667d894d3Nicolas Geoffray
5140462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz  // Contains the instrumentation level required by each client of the instrumentation identified
5150462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz  // by a string key.
5160462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz  typedef SafeMap<const char*, InstrumentationLevel> InstrumentationLevelTable;
5170462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz  InstrumentationLevelTable requested_instrumentation_levels_ GUARDED_BY(Locks::mutator_lock_);
5180462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz
51962d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers  // The event listeners, written to with the mutator_lock_ exclusively held.
52062d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers  std::list<InstrumentationListener*> method_entry_listeners_ GUARDED_BY(Locks::mutator_lock_);
52162d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers  std::list<InstrumentationListener*> method_exit_listeners_ GUARDED_BY(Locks::mutator_lock_);
52262d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers  std::list<InstrumentationListener*> method_unwind_listeners_ GUARDED_BY(Locks::mutator_lock_);
523e5f13e57ff8fa36342beb33830b3ec5942a61ccaMathieu Chartier  std::list<InstrumentationListener*> backward_branch_listeners_ GUARDED_BY(Locks::mutator_lock_);
5245550ca8bcc742b109d77e62f3a0877c667d894d3Nicolas Geoffray  std::list<InstrumentationListener*> invoke_virtual_or_interface_listeners_
5255550ca8bcc742b109d77e62f3a0877c667d894d3Nicolas Geoffray      GUARDED_BY(Locks::mutator_lock_);
526ca1d06cfa2f2b8d2be4390644e126cb68cdbb5baDaniel Mihalyi  std::shared_ptr<std::list<InstrumentationListener*>> dex_pc_listeners_
527ca1d06cfa2f2b8d2be4390644e126cb68cdbb5baDaniel Mihalyi      GUARDED_BY(Locks::mutator_lock_);
528ca1d06cfa2f2b8d2be4390644e126cb68cdbb5baDaniel Mihalyi  std::shared_ptr<std::list<InstrumentationListener*>> field_read_listeners_
529ca1d06cfa2f2b8d2be4390644e126cb68cdbb5baDaniel Mihalyi      GUARDED_BY(Locks::mutator_lock_);
530ca1d06cfa2f2b8d2be4390644e126cb68cdbb5baDaniel Mihalyi  std::shared_ptr<std::list<InstrumentationListener*>> field_write_listeners_
531ca1d06cfa2f2b8d2be4390644e126cb68cdbb5baDaniel Mihalyi      GUARDED_BY(Locks::mutator_lock_);
532ca1d06cfa2f2b8d2be4390644e126cb68cdbb5baDaniel Mihalyi  std::shared_ptr<std::list<InstrumentationListener*>> exception_caught_listeners_
533ca1d06cfa2f2b8d2be4390644e126cb68cdbb5baDaniel Mihalyi      GUARDED_BY(Locks::mutator_lock_);
534725a957985171d712d5c048cc3d00ff14968784bjeffhao
535138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz  // The set of methods being deoptimized (by the debugger) which must be executed with interpreter
536138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz  // only.
5373b05e9ba874449dbff65b01b8781001f7d93eea6Mathieu Chartier  mutable ReaderWriterMutex deoptimized_methods_lock_ DEFAULT_MUTEX_ACQUIRED_AFTER;
538e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier  std::unordered_set<ArtMethod*> deoptimized_methods_ GUARDED_BY(deoptimized_methods_lock_);
53911d40c250ec86c784cf76b8c31e1cf9285d555dcSebastien Hertz  bool deoptimization_enabled_;
540138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz
541fa82427c68b09f4aedbee319dc71579afbfc66f5Ian Rogers  // Current interpreter handler table. This is updated each time the thread state flags are
542fa82427c68b09f4aedbee319dc71579afbfc66f5Ian Rogers  // modified.
543ed2be1725fb79075892b1a9103487c9d9a95b350Sebastien Hertz  InterpreterHandlerTable interpreter_handler_table_ GUARDED_BY(Locks::mutator_lock_);
544ee1997a3b83334985e757f369c09e111b121661bSebastien Hertz
545fa82427c68b09f4aedbee319dc71579afbfc66f5Ian Rogers  // Greater than 0 if quick alloc entry points instrumented.
5469ef78b59da51080882e47505896b420977fd79aeMathieu Chartier  size_t quick_alloc_entry_points_instrumentation_counter_
5479ef78b59da51080882e47505896b420977fd79aeMathieu Chartier      GUARDED_BY(Locks::instrument_entrypoints_lock_);
548fa82427c68b09f4aedbee319dc71579afbfc66f5Ian Rogers
5490462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz  friend class InstrumentationTest;  // For GetCurrentInstrumentationLevel and ConfigureStubs.
5500462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertz
551725a957985171d712d5c048cc3d00ff14968784bjeffhao  DISALLOW_COPY_AND_ASSIGN(Instrumentation);
552725a957985171d712d5c048cc3d00ff14968784bjeffhao};
5536a3c1fcb4ba42ad4d5d142c17a3712a6ddd3866fIan Rogersstd::ostream& operator<<(std::ostream& os, const Instrumentation::InstrumentationEvent& rhs);
5540462c4c87c39db6cfcd338f323844738109ac3c9Sebastien Hertzstd::ostream& operator<<(std::ostream& os, const Instrumentation::InstrumentationLevel& rhs);
555725a957985171d712d5c048cc3d00ff14968784bjeffhao
55662d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers// An element in the instrumentation side stack maintained in art::Thread.
55762d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogersstruct InstrumentationStackFrame {
558e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier  InstrumentationStackFrame(mirror::Object* this_object, ArtMethod* method,
5599a916d3c0d0574d106c764e737c67b52988d6139Jeff Hao                            uintptr_t return_pc, size_t frame_id, bool interpreter_entry)
5609a916d3c0d0574d106c764e737c67b52988d6139Jeff Hao      : this_object_(this_object), method_(method), return_pc_(return_pc), frame_id_(frame_id),
5619a916d3c0d0574d106c764e737c67b52988d6139Jeff Hao        interpreter_entry_(interpreter_entry) {
56262d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers  }
56362d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers
56490443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier  std::string Dump() const SHARED_REQUIRES(Locks::mutator_lock_);
56562d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers
56662d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers  mirror::Object* this_object_;
567e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier  ArtMethod* method_;
568138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz  uintptr_t return_pc_;
569138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz  size_t frame_id_;
570138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz  bool interpreter_entry_;
57162d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers};
57262d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers
57362d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers}  // namespace instrumentation
574725a957985171d712d5c048cc3d00ff14968784bjeffhao}  // namespace art
575725a957985171d712d5c048cc3d00ff14968784bjeffhao
576fc0e3219edc9a5bf81b166e82fd5db2796eb6a0dBrian Carlstrom#endif  // ART_RUNTIME_INSTRUMENTATION_H_
577