instrumentation.h revision ed2be1725fb79075892b1a9103487c9d9a95b350
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> 22799eb3a5555254427db269921042419bc30d4d86Hiroshi Yamauchi#include <map> 23576ca0cd692c0b6ae70e776de91015b8ff000a08Ian Rogers 24ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers#include "atomic.h" 25d58342caa97108ba413bad467c285c0377f138f5Andreas Gampe#include "instruction_set.h" 26761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes#include "base/macros.h" 27719d1a33f6569864f529e5a3fff59e7bca97aad0Ian Rogers#include "base/mutex.h" 2894f7b49578b6aaa80de8ffed230648d601393905Hiroshi Yamauchi#include "gc_root.h" 293b05e9ba874449dbff65b01b8781001f7d93eea6Mathieu Chartier#include "object_callbacks.h" 302dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 31725a957985171d712d5c048cc3d00ff14968784bjeffhaonamespace art { 322dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogersnamespace mirror { 333f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertz class ArtField; 34ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom class ArtMethod; 35ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom class Class; 36ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom class Object; 37ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom class Throwable; 3862d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers} // namespace mirror 3962d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogersunion JValue; 40725a957985171d712d5c048cc3d00ff14968784bjeffhaoclass Thread; 4162d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogersclass ThrowLocation; 42725a957985171d712d5c048cc3d00ff14968784bjeffhao 4362d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogersnamespace instrumentation { 44725a957985171d712d5c048cc3d00ff14968784bjeffhao 45ee1997a3b83334985e757f369c09e111b121661bSebastien Hertz// Interpreter handler tables. 46ee1997a3b83334985e757f369c09e111b121661bSebastien Hertzenum InterpreterHandlerTable { 47ee1997a3b83334985e757f369c09e111b121661bSebastien Hertz kMainHandlerTable = 0, // Main handler table: no suspend check, no instrumentation. 48ee1997a3b83334985e757f369c09e111b121661bSebastien Hertz kAlternativeHandlerTable = 1, // Alternative handler table: suspend check and/or instrumentation 49ee1997a3b83334985e757f369c09e111b121661bSebastien Hertz // enabled. 50ee1997a3b83334985e757f369c09e111b121661bSebastien Hertz kNumHandlerTables 51ee1997a3b83334985e757f369c09e111b121661bSebastien Hertz}; 52ee1997a3b83334985e757f369c09e111b121661bSebastien Hertz 5362d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers// Instrumentation event listener API. Registered listeners will get the appropriate call back for 5462d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers// the events they are listening for. The call backs supply the thread, method and dex_pc the event 5562d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers// occurred upon. The thread may or may not be Thread::Current(). 5662d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogersstruct InstrumentationListener { 5762d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers InstrumentationListener() {} 5862d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers virtual ~InstrumentationListener() {} 5962d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers 6062d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers // Call-back for when a method is entered. 6162d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers virtual void MethodEntered(Thread* thread, mirror::Object* this_object, 62ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers mirror::ArtMethod* method, 6362d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers uint32_t dex_pc) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) = 0; 6462d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers 6562d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers // Call-back for when a method is exited. 6662d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers // TODO: its likely passing the return value would be useful, however, we may need to get and 6762d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers // parse the shorty to determine what kind of register holds the result. 6862d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers virtual void MethodExited(Thread* thread, mirror::Object* this_object, 69ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers mirror::ArtMethod* method, uint32_t dex_pc, 7062d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers const JValue& return_value) 7162d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) = 0; 7262d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers 7362d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers // Call-back for when a method is popped due to an exception throw. A method will either cause a 7462d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers // MethodExited call-back or a MethodUnwind call-back when its activation is removed. 7551db44a194bafc3810a41164a8b39614f10e79dfSebastien Hertz virtual void MethodUnwind(Thread* thread, mirror::Object* this_object, 76ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers mirror::ArtMethod* method, uint32_t dex_pc) 7751db44a194bafc3810a41164a8b39614f10e79dfSebastien Hertz SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) = 0; 7862d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers 7962d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers // Call-back for when the dex pc moves in a method. 8062d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers virtual void DexPcMoved(Thread* thread, mirror::Object* this_object, 81ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers mirror::ArtMethod* method, uint32_t new_dex_pc) 8262d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) = 0; 8362d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers 843f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertz // Call-back for when we read from a field. 853f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertz virtual void FieldRead(Thread* thread, mirror::Object* this_object, mirror::ArtMethod* method, 863f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertz uint32_t dex_pc, mirror::ArtField* field) = 0; 873f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertz 883f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertz // Call-back for when we write into a field. 893f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertz virtual void FieldWritten(Thread* thread, mirror::Object* this_object, mirror::ArtMethod* method, 903f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertz uint32_t dex_pc, mirror::ArtField* field, const JValue& field_value) = 0; 913f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertz 9262d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers // Call-back when an exception is caught. 9362d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers virtual void ExceptionCaught(Thread* thread, const ThrowLocation& throw_location, 94ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom mirror::ArtMethod* catch_method, uint32_t catch_dex_pc, 9562d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers mirror::Throwable* exception_object) 9662d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) = 0; 97725a957985171d712d5c048cc3d00ff14968784bjeffhao}; 98725a957985171d712d5c048cc3d00ff14968784bjeffhao 9962d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers// Instrumentation is a catch-all for when extra information is required from the runtime. The 10062d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers// typical use for instrumentation is for profiling and debugging. Instrumentation may add stubs 10162d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers// to method entry and exit, it may also force execution to be switched to the interpreter and 10262d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers// trigger deoptimization. 103725a957985171d712d5c048cc3d00ff14968784bjeffhaoclass Instrumentation { 104725a957985171d712d5c048cc3d00ff14968784bjeffhao public: 10562d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers enum InstrumentationEvent { 1063f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertz kMethodEntered = 1 << 0, 1073f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertz kMethodExited = 1 << 1, 1083f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertz kMethodUnwind = 1 << 2, 1093f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertz kDexPcMoved = 1 << 3, 1103f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertz kFieldRead = 1 << 4, 1113f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertz kFieldWritten = 1 << 5, 1123f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertz kExceptionCaught = 1 << 6, 11362d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers }; 11462d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers 1153b05e9ba874449dbff65b01b8781001f7d93eea6Mathieu Chartier Instrumentation(); 11662d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers 11762d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers // Add a listener to be notified of the masked together sent of instrumentation events. This 11862d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers // suspend the runtime to install stubs. You are expected to hold the mutator lock as a proxy 11962d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers // for saying you should have suspended all threads (installing stubs while threads are running 12062d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers // will break). 12162d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers void AddListener(InstrumentationListener* listener, uint32_t events) 12262d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers EXCLUSIVE_LOCKS_REQUIRED(Locks::mutator_lock_) 12362d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers LOCKS_EXCLUDED(Locks::thread_list_lock_, Locks::classlinker_classes_lock_); 12462d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers 12562d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers // Removes a listener possibly removing instrumentation stubs. 12662d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers void RemoveListener(InstrumentationListener* listener, uint32_t events) 12762d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers EXCLUSIVE_LOCKS_REQUIRED(Locks::mutator_lock_) 12862d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers LOCKS_EXCLUDED(Locks::thread_list_lock_, Locks::classlinker_classes_lock_); 12962d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers 130138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz // Deoptimization. 131a76a6d4cb3dedec909bd927f20bc0ab23198a337Sebastien Hertz void EnableDeoptimization() 132a76a6d4cb3dedec909bd927f20bc0ab23198a337Sebastien Hertz EXCLUSIVE_LOCKS_REQUIRED(Locks::mutator_lock_) 1333b05e9ba874449dbff65b01b8781001f7d93eea6Mathieu Chartier LOCKS_EXCLUDED(deoptimized_methods_lock_); 134a76a6d4cb3dedec909bd927f20bc0ab23198a337Sebastien Hertz void DisableDeoptimization() 135a76a6d4cb3dedec909bd927f20bc0ab23198a337Sebastien Hertz EXCLUSIVE_LOCKS_REQUIRED(Locks::mutator_lock_) 1364d25df3f76f864b7629ac8c0046d46997f293d8dSebastien Hertz LOCKS_EXCLUDED(deoptimized_methods_lock_); 137a76a6d4cb3dedec909bd927f20bc0ab23198a337Sebastien Hertz bool AreAllMethodsDeoptimized() const { 138a76a6d4cb3dedec909bd927f20bc0ab23198a337Sebastien Hertz return interpreter_stubs_installed_; 139a76a6d4cb3dedec909bd927f20bc0ab23198a337Sebastien Hertz } 14011d40c250ec86c784cf76b8c31e1cf9285d555dcSebastien Hertz bool ShouldNotifyMethodEnterExitEvents() const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 141138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz 142138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz // Executes everything with interpreter. 143138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz void DeoptimizeEverything() 144138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz EXCLUSIVE_LOCKS_REQUIRED(Locks::mutator_lock_) 145138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz LOCKS_EXCLUDED(Locks::thread_list_lock_, Locks::classlinker_classes_lock_); 146138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz 147138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz // Executes everything with compiled code (or interpreter if there is no code). 148138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz void UndeoptimizeEverything() 149138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz EXCLUSIVE_LOCKS_REQUIRED(Locks::mutator_lock_) 150138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz LOCKS_EXCLUDED(Locks::thread_list_lock_, Locks::classlinker_classes_lock_); 151138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz 152138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz // Deoptimize a method by forcing its execution with the interpreter. Nevertheless, a static 153138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz // method (except a class initializer) set to the resolution trampoline will be deoptimized only 154138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz // once its declaring class is initialized. 155138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz void Deoptimize(mirror::ArtMethod* method) 1563b05e9ba874449dbff65b01b8781001f7d93eea6Mathieu Chartier LOCKS_EXCLUDED(Locks::thread_list_lock_, deoptimized_methods_lock_) 157138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz EXCLUSIVE_LOCKS_REQUIRED(Locks::mutator_lock_); 158138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz 159138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz // Undeoptimze the method by restoring its entrypoints. Nevertheless, a static method 160138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz // (except a class initializer) set to the resolution trampoline will be updated only once its 161138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz // declaring class is initialized. 162138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz void Undeoptimize(mirror::ArtMethod* method) 1634d25df3f76f864b7629ac8c0046d46997f293d8dSebastien Hertz LOCKS_EXCLUDED(Locks::thread_list_lock_, deoptimized_methods_lock_) 164138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz EXCLUSIVE_LOCKS_REQUIRED(Locks::mutator_lock_); 165138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz 166799eb3a5555254427db269921042419bc30d4d86Hiroshi Yamauchi bool IsDeoptimized(mirror::ArtMethod* method) 167799eb3a5555254427db269921042419bc30d4d86Hiroshi Yamauchi LOCKS_EXCLUDED(deoptimized_methods_lock_) 168799eb3a5555254427db269921042419bc30d4d86Hiroshi Yamauchi SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 169138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz 170138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz // Enable method tracing by installing instrumentation entry/exit stubs. 171138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz void EnableMethodTracing() 172138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz EXCLUSIVE_LOCKS_REQUIRED(Locks::mutator_lock_) 173138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz LOCKS_EXCLUDED(Locks::thread_list_lock_, Locks::classlinker_classes_lock_); 174138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz 175138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz // Disable method tracing by uninstalling instrumentation entry/exit stubs. 176138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz void DisableMethodTracing() 177138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz EXCLUSIVE_LOCKS_REQUIRED(Locks::mutator_lock_) 178138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz LOCKS_EXCLUDED(Locks::thread_list_lock_, Locks::classlinker_classes_lock_); 179138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz 180ed2be1725fb79075892b1a9103487c9d9a95b350Sebastien Hertz InterpreterHandlerTable GetInterpreterHandlerTable() const 181ed2be1725fb79075892b1a9103487c9d9a95b350Sebastien Hertz SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 182ee1997a3b83334985e757f369c09e111b121661bSebastien Hertz return interpreter_handler_table_; 183ee1997a3b83334985e757f369c09e111b121661bSebastien Hertz } 184ee1997a3b83334985e757f369c09e111b121661bSebastien Hertz 185d889178ec78930538d9d6a66c3df9ee9afaffbb4Mathieu Chartier void InstrumentQuickAllocEntryPoints() LOCKS_EXCLUDED(Locks::thread_list_lock_, 186d889178ec78930538d9d6a66c3df9ee9afaffbb4Mathieu Chartier Locks::runtime_shutdown_lock_); 187d889178ec78930538d9d6a66c3df9ee9afaffbb4Mathieu Chartier void UninstrumentQuickAllocEntryPoints() LOCKS_EXCLUDED(Locks::thread_list_lock_, 188d889178ec78930538d9d6a66c3df9ee9afaffbb4Mathieu Chartier Locks::runtime_shutdown_lock_); 189d889178ec78930538d9d6a66c3df9ee9afaffbb4Mathieu Chartier void ResetQuickAllocEntryPoints() EXCLUSIVE_LOCKS_REQUIRED(Locks::runtime_shutdown_lock_); 190fa82427c68b09f4aedbee319dc71579afbfc66f5Ian Rogers 19162d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers // Update the code of a method respecting any installed stubs. 192ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers void UpdateMethodsCode(mirror::ArtMethod* method, const void* quick_code, 193799eb3a5555254427db269921042419bc30d4d86Hiroshi Yamauchi const void* portable_code, bool have_portable_code) 194138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 19562d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers 19662d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers // Get the quick code for the given method. More efficient than asking the class linker as it 19762d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers // will short-cut to GetCode if instrumentation and static method resolution stubs aren't 19862d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers // installed. 199ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers const void* GetQuickCodeFor(mirror::ArtMethod* method) const 20062d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 20162d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers 20262d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers void ForceInterpretOnly() { 20362d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers interpret_only_ = true; 20462d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers forced_interpret_only_ = true; 20562d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers } 20662d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers 207ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom // Called by ArtMethod::Invoke to determine dispatch mechanism. 20862d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers bool InterpretOnly() const { 20962d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers return interpret_only_; 21062d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers } 21162d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers 212563b47cc142e477da244539b1d63070425e7fd78Hiroshi Yamauchi bool IsForcedInterpretOnly() const { 213563b47cc142e477da244539b1d63070425e7fd78Hiroshi Yamauchi return forced_interpret_only_; 214563b47cc142e477da244539b1d63070425e7fd78Hiroshi Yamauchi } 215563b47cc142e477da244539b1d63070425e7fd78Hiroshi Yamauchi 21662d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers bool ShouldPortableCodeDeoptimize() const { 21762d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers return instrumentation_stubs_installed_; 21862d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers } 21962d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers 22062d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers bool AreExitStubsInstalled() const { 22162d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers return instrumentation_stubs_installed_; 22262d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers } 22362d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers 224ed2be1725fb79075892b1a9103487c9d9a95b350Sebastien Hertz bool HasMethodEntryListeners() const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 22574109f6683096de494b1457fa6d5b0ac33b4c98cSebastien Hertz return have_method_entry_listeners_; 22674109f6683096de494b1457fa6d5b0ac33b4c98cSebastien Hertz } 22774109f6683096de494b1457fa6d5b0ac33b4c98cSebastien Hertz 228ed2be1725fb79075892b1a9103487c9d9a95b350Sebastien Hertz bool HasMethodExitListeners() const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 22974109f6683096de494b1457fa6d5b0ac33b4c98cSebastien Hertz return have_method_exit_listeners_; 23074109f6683096de494b1457fa6d5b0ac33b4c98cSebastien Hertz } 23174109f6683096de494b1457fa6d5b0ac33b4c98cSebastien Hertz 232ed2be1725fb79075892b1a9103487c9d9a95b350Sebastien Hertz bool HasDexPcListeners() const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 23374109f6683096de494b1457fa6d5b0ac33b4c98cSebastien Hertz return have_dex_pc_listeners_; 23474109f6683096de494b1457fa6d5b0ac33b4c98cSebastien Hertz } 23574109f6683096de494b1457fa6d5b0ac33b4c98cSebastien Hertz 236ed2be1725fb79075892b1a9103487c9d9a95b350Sebastien Hertz bool HasFieldReadListeners() const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 2373f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertz return have_field_read_listeners_; 2383f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertz } 2393f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertz 240ed2be1725fb79075892b1a9103487c9d9a95b350Sebastien Hertz bool HasFieldWriteListeners() const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 2413f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertz return have_field_write_listeners_; 2423f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertz } 2433f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertz 244ed2be1725fb79075892b1a9103487c9d9a95b350Sebastien Hertz bool HasExceptionCaughtListeners() const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 2459f1020305292a21fd14a402b189c765a125226abSebastien Hertz return have_exception_caught_listeners_; 2469f1020305292a21fd14a402b189c765a125226abSebastien Hertz } 2479f1020305292a21fd14a402b189c765a125226abSebastien Hertz 248ed2be1725fb79075892b1a9103487c9d9a95b350Sebastien Hertz bool IsActive() const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 249ee1997a3b83334985e757f369c09e111b121661bSebastien Hertz return have_dex_pc_listeners_ || have_method_entry_listeners_ || have_method_exit_listeners_ || 25042cd43fa593e8f0427eb0ec158bef08814a6180bSebastien Hertz have_field_read_listeners_ || have_field_write_listeners_ || 251ee1997a3b83334985e757f369c09e111b121661bSebastien Hertz have_exception_caught_listeners_ || have_method_unwind_listeners_; 252ee1997a3b83334985e757f369c09e111b121661bSebastien Hertz } 253ee1997a3b83334985e757f369c09e111b121661bSebastien Hertz 25462d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers // Inform listeners that a method has been entered. A dex PC is provided as we may install 25562d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers // listeners into executing code and get method enter events for methods already on the stack. 25662d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers void MethodEnterEvent(Thread* thread, mirror::Object* this_object, 257ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers mirror::ArtMethod* method, uint32_t dex_pc) const 25862d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 25974109f6683096de494b1457fa6d5b0ac33b4c98cSebastien Hertz if (UNLIKELY(HasMethodEntryListeners())) { 26062d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers MethodEnterEventImpl(thread, this_object, method, dex_pc); 26162d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers } 26262d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers } 26362d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers 26462d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers // Inform listeners that a method has been exited. 26562d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers void MethodExitEvent(Thread* thread, mirror::Object* this_object, 266ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers mirror::ArtMethod* method, uint32_t dex_pc, 26762d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers const JValue& return_value) const 26862d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 26974109f6683096de494b1457fa6d5b0ac33b4c98cSebastien Hertz if (UNLIKELY(HasMethodExitListeners())) { 27062d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers MethodExitEventImpl(thread, this_object, method, dex_pc, return_value); 27162d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers } 27262d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers } 27362d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers 27462d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers // Inform listeners that a method has been exited due to an exception. 27562d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers void MethodUnwindEvent(Thread* thread, mirror::Object* this_object, 276ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers mirror::ArtMethod* method, uint32_t dex_pc) const 27762d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 27862d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers 27962d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers // Inform listeners that the dex pc has moved (only supported by the interpreter). 28062d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers void DexPcMovedEvent(Thread* thread, mirror::Object* this_object, 281ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers mirror::ArtMethod* method, uint32_t dex_pc) const 28262d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 28374109f6683096de494b1457fa6d5b0ac33b4c98cSebastien Hertz if (UNLIKELY(HasDexPcListeners())) { 28462d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers DexPcMovedEventImpl(thread, this_object, method, dex_pc); 28562d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers } 28662d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers } 287725a957985171d712d5c048cc3d00ff14968784bjeffhao 2883f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertz // Inform listeners that we read a field (only supported by the interpreter). 2893f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertz void FieldReadEvent(Thread* thread, mirror::Object* this_object, 2903f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertz mirror::ArtMethod* method, uint32_t dex_pc, 2913f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertz mirror::ArtField* field) const 2923f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertz SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 2933f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertz if (UNLIKELY(HasFieldReadListeners())) { 2943f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertz FieldReadEventImpl(thread, this_object, method, dex_pc, field); 2953f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertz } 2963f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertz } 2973f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertz 2983f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertz // Inform listeners that we write a field (only supported by the interpreter). 2993f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertz void FieldWriteEvent(Thread* thread, mirror::Object* this_object, 3003f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertz mirror::ArtMethod* method, uint32_t dex_pc, 3013f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertz mirror::ArtField* field, const JValue& field_value) const 3023f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertz SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 3033f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertz if (UNLIKELY(HasFieldWriteListeners())) { 3043f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertz FieldWriteEventImpl(thread, this_object, method, dex_pc, field, field_value); 3053f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertz } 3063f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertz } 3073f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertz 30862d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers // Inform listeners that an exception was caught. 30962d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers void ExceptionCaughtEvent(Thread* thread, const ThrowLocation& throw_location, 310ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom mirror::ArtMethod* catch_method, uint32_t catch_dex_pc, 311947ff080753c786a74f1cd7aeb09f717bb7074bdSebastien Hertz mirror::Throwable* exception_object) const 31262d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 313725a957985171d712d5c048cc3d00ff14968784bjeffhao 31462d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers // Called when an instrumented method is entered. The intended link register (lr) is saved so 31562d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers // that returning causes a branch to the method exit stub. Generates method enter events. 31662d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers void PushInstrumentationStackFrame(Thread* self, mirror::Object* this_object, 317ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom mirror::ArtMethod* method, uintptr_t lr, 3189a916d3c0d0574d106c764e737c67b52988d6139Jeff Hao bool interpreter_entry) 31962d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 320725a957985171d712d5c048cc3d00ff14968784bjeffhao 32162d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers // Called when an instrumented method is exited. Removes the pushed instrumentation frame 32262d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers // returning the intended link register. Generates method exit events. 323d58342caa97108ba413bad467c285c0377f138f5Andreas Gampe TwoWordReturn PopInstrumentationStackFrame(Thread* self, uintptr_t* return_pc, 324d58342caa97108ba413bad467c285c0377f138f5Andreas Gampe uint64_t gpr_result, uint64_t fpr_result) 32562d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 326725a957985171d712d5c048cc3d00ff14968784bjeffhao 32762d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers // Pops an instrumentation frame from the current thread and generate an unwind event. 32862d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers void PopMethodForUnwind(Thread* self, bool is_deoptimization) const 32962d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 33062d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers 33162d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers // Call back for configure stubs. 33262d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers bool InstallStubsForClass(mirror::Class* klass) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 333725a957985171d712d5c048cc3d00ff14968784bjeffhao 334138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz void InstallStubsForMethod(mirror::ArtMethod* method) 335138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 336138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz 3373b05e9ba874449dbff65b01b8781001f7d93eea6Mathieu Chartier void VisitRoots(RootCallback* callback, void* arg) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) 3383b05e9ba874449dbff65b01b8781001f7d93eea6Mathieu Chartier LOCKS_EXCLUDED(deoptimized_methods_lock_); 3393b05e9ba874449dbff65b01b8781001f7d93eea6Mathieu Chartier 340725a957985171d712d5c048cc3d00ff14968784bjeffhao private: 34162d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers // Does the job of installing or removing instrumentation code within methods. 34262d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers void ConfigureStubs(bool require_entry_exit_stubs, bool require_interpreter) 34362d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers EXCLUSIVE_LOCKS_REQUIRED(Locks::mutator_lock_) 3443b05e9ba874449dbff65b01b8781001f7d93eea6Mathieu Chartier LOCKS_EXCLUDED(Locks::thread_list_lock_, Locks::classlinker_classes_lock_, 3453b05e9ba874449dbff65b01b8781001f7d93eea6Mathieu Chartier deoptimized_methods_lock_); 34662d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers 347ed2be1725fb79075892b1a9103487c9d9a95b350Sebastien Hertz void UpdateInterpreterHandlerTable() EXCLUSIVE_LOCKS_REQUIRED(Locks::mutator_lock_) { 348ee1997a3b83334985e757f369c09e111b121661bSebastien Hertz interpreter_handler_table_ = IsActive() ? kAlternativeHandlerTable : kMainHandlerTable; 349ee1997a3b83334985e757f369c09e111b121661bSebastien Hertz } 350ee1997a3b83334985e757f369c09e111b121661bSebastien Hertz 351661974a5561e5ccdfbac8cb5d8df8b7e6f3483b8Mathieu Chartier // No thread safety analysis to get around SetQuickAllocEntryPointsInstrumented requiring 352661974a5561e5ccdfbac8cb5d8df8b7e6f3483b8Mathieu Chartier // exclusive access to mutator lock which you can't get if the runtime isn't started. 353661974a5561e5ccdfbac8cb5d8df8b7e6f3483b8Mathieu Chartier void SetEntrypointsInstrumented(bool instrumented) NO_THREAD_SAFETY_ANALYSIS; 354661974a5561e5ccdfbac8cb5d8df8b7e6f3483b8Mathieu Chartier 35562d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers void MethodEnterEventImpl(Thread* thread, mirror::Object* this_object, 356ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers mirror::ArtMethod* method, uint32_t dex_pc) const 35762d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 35862d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers void MethodExitEventImpl(Thread* thread, mirror::Object* this_object, 359ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers mirror::ArtMethod* method, 36062d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers uint32_t dex_pc, const JValue& return_value) const 36162d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 36262d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers void DexPcMovedEventImpl(Thread* thread, mirror::Object* this_object, 363ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers mirror::ArtMethod* method, uint32_t dex_pc) const 36462d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 3653f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertz void FieldReadEventImpl(Thread* thread, mirror::Object* this_object, 3663f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertz mirror::ArtMethod* method, uint32_t dex_pc, 3673f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertz mirror::ArtField* field) const 3683f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertz SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 3693f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertz void FieldWriteEventImpl(Thread* thread, mirror::Object* this_object, 3703f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertz mirror::ArtMethod* method, uint32_t dex_pc, 3713f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertz mirror::ArtField* field, const JValue& field_value) const 3723f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertz SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 37362d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers 374799eb3a5555254427db269921042419bc30d4d86Hiroshi Yamauchi // Read barrier-aware utility functions for accessing deoptimized_methods_ 375799eb3a5555254427db269921042419bc30d4d86Hiroshi Yamauchi bool AddDeoptimizedMethod(mirror::ArtMethod* method) 376799eb3a5555254427db269921042419bc30d4d86Hiroshi Yamauchi SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) 377799eb3a5555254427db269921042419bc30d4d86Hiroshi Yamauchi EXCLUSIVE_LOCKS_REQUIRED(deoptimized_methods_lock_); 378799eb3a5555254427db269921042419bc30d4d86Hiroshi Yamauchi bool FindDeoptimizedMethod(mirror::ArtMethod* method) 379799eb3a5555254427db269921042419bc30d4d86Hiroshi Yamauchi SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) 380799eb3a5555254427db269921042419bc30d4d86Hiroshi Yamauchi SHARED_LOCKS_REQUIRED(deoptimized_methods_lock_); 381799eb3a5555254427db269921042419bc30d4d86Hiroshi Yamauchi bool RemoveDeoptimizedMethod(mirror::ArtMethod* method) 382799eb3a5555254427db269921042419bc30d4d86Hiroshi Yamauchi SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) 383799eb3a5555254427db269921042419bc30d4d86Hiroshi Yamauchi EXCLUSIVE_LOCKS_REQUIRED(deoptimized_methods_lock_); 384799eb3a5555254427db269921042419bc30d4d86Hiroshi Yamauchi mirror::ArtMethod* BeginDeoptimizedMethod() 385799eb3a5555254427db269921042419bc30d4d86Hiroshi Yamauchi SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) 386799eb3a5555254427db269921042419bc30d4d86Hiroshi Yamauchi SHARED_LOCKS_REQUIRED(deoptimized_methods_lock_); 387799eb3a5555254427db269921042419bc30d4d86Hiroshi Yamauchi bool IsDeoptimizedMethodsEmpty() const 388799eb3a5555254427db269921042419bc30d4d86Hiroshi Yamauchi SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) 389799eb3a5555254427db269921042419bc30d4d86Hiroshi Yamauchi SHARED_LOCKS_REQUIRED(deoptimized_methods_lock_); 390799eb3a5555254427db269921042419bc30d4d86Hiroshi Yamauchi 391ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom // Have we hijacked ArtMethod::code_ so that it calls instrumentation/interpreter code? 39262d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers bool instrumentation_stubs_installed_; 39362d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers 394ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom // Have we hijacked ArtMethod::code_ to reference the enter/exit stubs? 39562d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers bool entry_exit_stubs_installed_; 39662d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers 397ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom // Have we hijacked ArtMethod::code_ to reference the enter interpreter stub? 39862d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers bool interpreter_stubs_installed_; 39962d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers 40062d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers // Do we need the fidelity of events that we only get from running within the interpreter? 40162d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers bool interpret_only_; 402725a957985171d712d5c048cc3d00ff14968784bjeffhao 40362d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers // Did the runtime request we only run in the interpreter? ie -Xint mode. 40462d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers bool forced_interpret_only_; 405725a957985171d712d5c048cc3d00ff14968784bjeffhao 40662d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers // Do we have any listeners for method entry events? Short-cut to avoid taking the 40762d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers // instrumentation_lock_. 408ed2be1725fb79075892b1a9103487c9d9a95b350Sebastien Hertz bool have_method_entry_listeners_ GUARDED_BY(Locks::mutator_lock_); 40962d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers 41062d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers // Do we have any listeners for method exit events? Short-cut to avoid taking the 41162d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers // instrumentation_lock_. 412ed2be1725fb79075892b1a9103487c9d9a95b350Sebastien Hertz bool have_method_exit_listeners_ GUARDED_BY(Locks::mutator_lock_); 41362d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers 41462d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers // Do we have any listeners for method unwind events? Short-cut to avoid taking the 41562d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers // instrumentation_lock_. 416ed2be1725fb79075892b1a9103487c9d9a95b350Sebastien Hertz bool have_method_unwind_listeners_ GUARDED_BY(Locks::mutator_lock_); 41762d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers 41862d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers // Do we have any listeners for dex move events? Short-cut to avoid taking the 41962d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers // instrumentation_lock_. 420ed2be1725fb79075892b1a9103487c9d9a95b350Sebastien Hertz bool have_dex_pc_listeners_ GUARDED_BY(Locks::mutator_lock_); 42162d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers 4223f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertz // Do we have any listeners for field read events? Short-cut to avoid taking the 4233f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertz // instrumentation_lock_. 424ed2be1725fb79075892b1a9103487c9d9a95b350Sebastien Hertz bool have_field_read_listeners_ GUARDED_BY(Locks::mutator_lock_); 4253f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertz 4263f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertz // Do we have any listeners for field write events? Short-cut to avoid taking the 4273f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertz // instrumentation_lock_. 428ed2be1725fb79075892b1a9103487c9d9a95b350Sebastien Hertz bool have_field_write_listeners_ GUARDED_BY(Locks::mutator_lock_); 4293f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertz 43062d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers // Do we have any exception caught listeners? Short-cut to avoid taking the instrumentation_lock_. 431ed2be1725fb79075892b1a9103487c9d9a95b350Sebastien Hertz bool have_exception_caught_listeners_ GUARDED_BY(Locks::mutator_lock_); 43262d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers 43362d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers // The event listeners, written to with the mutator_lock_ exclusively held. 43462d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers std::list<InstrumentationListener*> method_entry_listeners_ GUARDED_BY(Locks::mutator_lock_); 43562d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers std::list<InstrumentationListener*> method_exit_listeners_ GUARDED_BY(Locks::mutator_lock_); 43662d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers std::list<InstrumentationListener*> method_unwind_listeners_ GUARDED_BY(Locks::mutator_lock_); 437ca1d06cfa2f2b8d2be4390644e126cb68cdbb5baDaniel Mihalyi std::shared_ptr<std::list<InstrumentationListener*>> dex_pc_listeners_ 438ca1d06cfa2f2b8d2be4390644e126cb68cdbb5baDaniel Mihalyi GUARDED_BY(Locks::mutator_lock_); 439ca1d06cfa2f2b8d2be4390644e126cb68cdbb5baDaniel Mihalyi std::shared_ptr<std::list<InstrumentationListener*>> field_read_listeners_ 440ca1d06cfa2f2b8d2be4390644e126cb68cdbb5baDaniel Mihalyi GUARDED_BY(Locks::mutator_lock_); 441ca1d06cfa2f2b8d2be4390644e126cb68cdbb5baDaniel Mihalyi std::shared_ptr<std::list<InstrumentationListener*>> field_write_listeners_ 442ca1d06cfa2f2b8d2be4390644e126cb68cdbb5baDaniel Mihalyi GUARDED_BY(Locks::mutator_lock_); 443ca1d06cfa2f2b8d2be4390644e126cb68cdbb5baDaniel Mihalyi std::shared_ptr<std::list<InstrumentationListener*>> exception_caught_listeners_ 444ca1d06cfa2f2b8d2be4390644e126cb68cdbb5baDaniel Mihalyi GUARDED_BY(Locks::mutator_lock_); 445725a957985171d712d5c048cc3d00ff14968784bjeffhao 446138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz // The set of methods being deoptimized (by the debugger) which must be executed with interpreter 447138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz // only. 4483b05e9ba874449dbff65b01b8781001f7d93eea6Mathieu Chartier mutable ReaderWriterMutex deoptimized_methods_lock_ DEFAULT_MUTEX_ACQUIRED_AFTER; 44994f7b49578b6aaa80de8ffed230648d601393905Hiroshi Yamauchi std::multimap<int32_t, GcRoot<mirror::ArtMethod>> deoptimized_methods_ 45094f7b49578b6aaa80de8ffed230648d601393905Hiroshi Yamauchi GUARDED_BY(deoptimized_methods_lock_); 45111d40c250ec86c784cf76b8c31e1cf9285d555dcSebastien Hertz bool deoptimization_enabled_; 452138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz 453fa82427c68b09f4aedbee319dc71579afbfc66f5Ian Rogers // Current interpreter handler table. This is updated each time the thread state flags are 454fa82427c68b09f4aedbee319dc71579afbfc66f5Ian Rogers // modified. 455ed2be1725fb79075892b1a9103487c9d9a95b350Sebastien Hertz InterpreterHandlerTable interpreter_handler_table_ GUARDED_BY(Locks::mutator_lock_); 456ee1997a3b83334985e757f369c09e111b121661bSebastien Hertz 457fa82427c68b09f4aedbee319dc71579afbfc66f5Ian Rogers // Greater than 0 if quick alloc entry points instrumented. 458fa82427c68b09f4aedbee319dc71579afbfc66f5Ian Rogers // TODO: The access and changes to this is racy and should be guarded by a lock. 459cbb2d20bea2861f244da2e2318d8c088300a3710Mathieu Chartier AtomicInteger quick_alloc_entry_points_instrumentation_counter_; 460fa82427c68b09f4aedbee319dc71579afbfc66f5Ian Rogers 461725a957985171d712d5c048cc3d00ff14968784bjeffhao DISALLOW_COPY_AND_ASSIGN(Instrumentation); 462725a957985171d712d5c048cc3d00ff14968784bjeffhao}; 463725a957985171d712d5c048cc3d00ff14968784bjeffhao 46462d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers// An element in the instrumentation side stack maintained in art::Thread. 46562d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogersstruct InstrumentationStackFrame { 466ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom InstrumentationStackFrame(mirror::Object* this_object, mirror::ArtMethod* method, 4679a916d3c0d0574d106c764e737c67b52988d6139Jeff Hao uintptr_t return_pc, size_t frame_id, bool interpreter_entry) 4689a916d3c0d0574d106c764e737c67b52988d6139Jeff Hao : this_object_(this_object), method_(method), return_pc_(return_pc), frame_id_(frame_id), 4699a916d3c0d0574d106c764e737c67b52988d6139Jeff Hao interpreter_entry_(interpreter_entry) { 47062d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers } 47162d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers 47262d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers std::string Dump() const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 47362d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers 47462d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers mirror::Object* this_object_; 475ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom mirror::ArtMethod* method_; 476138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz uintptr_t return_pc_; 477138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz size_t frame_id_; 478138dbfc3336e379d74d157086f69a0fbe830089bSebastien Hertz bool interpreter_entry_; 47962d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers}; 48062d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers 48162d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers} // namespace instrumentation 482725a957985171d712d5c048cc3d00ff14968784bjeffhao} // namespace art 483725a957985171d712d5c048cc3d00ff14968784bjeffhao 484fc0e3219edc9a5bf81b166e82fd5db2796eb6a0dBrian Carlstrom#endif // ART_RUNTIME_INSTRUMENTATION_H_ 485