trace.h revision c5d824a20c225763761a6dff43294b229ff35469
12faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes/* 22faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * Copyright (C) 2011 The Android Open Source Project 32faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * 42faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * Licensed under the Apache License, Version 2.0 (the "License"); 52faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * you may not use this file except in compliance with the License. 62faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * You may obtain a copy of the License at 72faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * 82faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * http://www.apache.org/licenses/LICENSE-2.0 92faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * 102faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * Unless required by applicable law or agreed to in writing, software 112faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * distributed under the License is distributed on an "AS IS" BASIS, 122faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 132faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * See the License for the specific language governing permissions and 142faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * limitations under the License. 152faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes */ 16e343b76af81a005ef64f5e75a555389fd9147dabjeffhao 17fc0e3219edc9a5bf81b166e82fd5db2796eb6a0dBrian Carlstrom#ifndef ART_RUNTIME_TRACE_H_ 18fc0e3219edc9a5bf81b166e82fd5db2796eb6a0dBrian Carlstrom#define ART_RUNTIME_TRACE_H_ 19e343b76af81a005ef64f5e75a555389fd9147dabjeffhao 20700a402244a1a423da4f3ba8032459f4b65fa18fIan Rogers#include <memory> 21a9ef3fd82bebc6370fc3ddbb094988feb6c83022jeffhao#include <ostream> 22a9ef3fd82bebc6370fc3ddbb094988feb6c83022jeffhao#include <set> 23a9ef3fd82bebc6370fc3ddbb094988feb6c83022jeffhao#include <string> 240abc72ebe356c32354b575c48189965a0edc7890Jeff Hao#include <vector> 25e343b76af81a005ef64f5e75a555389fd9147dabjeffhao 268ab25ef11aed383bf7d3aa96e95f777972d1b58fIan Rogers#include "atomic.h" 27761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes#include "base/macros.h" 28e343b76af81a005ef64f5e75a555389fd9147dabjeffhao#include "globals.h" 2962d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers#include "instrumentation.h" 30761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes#include "os.h" 31a0e180632411f7fe0edf454e571c42209ee7b540Elliott Hughes#include "safe_map.h" 32e343b76af81a005ef64f5e75a555389fd9147dabjeffhao 33e343b76af81a005ef64f5e75a555389fd9147dabjeffhaonamespace art { 34e343b76af81a005ef64f5e75a555389fd9147dabjeffhao 352dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogersnamespace mirror { 363f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertz class ArtField; 37ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom class ArtMethod; 382dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers} // namespace mirror 39cfbe73d02a024800813f8f0fc4f6a4b4532195f3Elliott Hughes 40e63db27db913f1a88e2095a1ee8239b2bb9124e8Ian Rogersclass Thread; 41491ca9e75fad381468dd7f5fdbff56d1a9738dd7Brian Carlstrom 4264caa7dcf46ed6139b766dbe77fbd7353899417fJeff Haoenum TracingMode { 4364caa7dcf46ed6139b766dbe77fbd7353899417fJeff Hao kTracingInactive, 4464caa7dcf46ed6139b766dbe77fbd7353899417fJeff Hao kMethodTracingActive, 4564caa7dcf46ed6139b766dbe77fbd7353899417fJeff Hao kSampleProfilingActive, 4664caa7dcf46ed6139b766dbe77fbd7353899417fJeff Hao}; 4764caa7dcf46ed6139b766dbe77fbd7353899417fJeff Hao 483f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertzclass Trace FINAL : public instrumentation::InstrumentationListener { 49e343b76af81a005ef64f5e75a555389fd9147dabjeffhao public: 500791adc2249366c50684935a4c42ba5e58bc3746jeffhao enum TraceFlag { 510791adc2249366c50684935a4c42ba5e58bc3746jeffhao kTraceCountAllocs = 1, 520791adc2249366c50684935a4c42ba5e58bc3746jeffhao }; 530791adc2249366c50684935a4c42ba5e58bc3746jeffhao 54e63db27db913f1a88e2095a1ee8239b2bb9124e8Ian Rogers static void SetDefaultClockSource(TraceClockSource clock_source); 55cfbe73d02a024800813f8f0fc4f6a4b4532195f3Elliott Hughes 5662d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers static void Start(const char* trace_filename, int trace_fd, int buffer_size, int flags, 5723009dca63c1699e28bfeaa8b45ca48fa0e86aceJeff Hao bool direct_to_ddms, bool sampling_enabled, int interval_us) 58bae182cbc6adc8796154162a87fc54ae804e0469Sebastien Hertz LOCKS_EXCLUDED(Locks::mutator_lock_, 59bae182cbc6adc8796154162a87fc54ae804e0469Sebastien Hertz Locks::thread_list_lock_, 60bae182cbc6adc8796154162a87fc54ae804e0469Sebastien Hertz Locks::thread_suspend_count_lock_, 61bae182cbc6adc8796154162a87fc54ae804e0469Sebastien Hertz Locks::trace_lock_); 62bae182cbc6adc8796154162a87fc54ae804e0469Sebastien Hertz static void Stop() 63bae182cbc6adc8796154162a87fc54ae804e0469Sebastien Hertz LOCKS_EXCLUDED(Locks::mutator_lock_, 64bae182cbc6adc8796154162a87fc54ae804e0469Sebastien Hertz Locks::thread_list_lock_, 65bae182cbc6adc8796154162a87fc54ae804e0469Sebastien Hertz Locks::trace_lock_); 6662d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers static void Shutdown() LOCKS_EXCLUDED(Locks::trace_lock_); 6764caa7dcf46ed6139b766dbe77fbd7353899417fJeff Hao static TracingMode GetMethodTracingMode() LOCKS_EXCLUDED(Locks::trace_lock_); 68e343b76af81a005ef64f5e75a555389fd9147dabjeffhao 69cfbe73d02a024800813f8f0fc4f6a4b4532195f3Elliott Hughes bool UseWallClock(); 70cfbe73d02a024800813f8f0fc4f6a4b4532195f3Elliott Hughes bool UseThreadCpuClock(); 71c5d824a20c225763761a6dff43294b229ff35469Jeff Hao void MeasureClockOverhead(); 72c5d824a20c225763761a6dff43294b229ff35469Jeff Hao uint32_t GetClockOverheadNanoSeconds(); 73cfbe73d02a024800813f8f0fc4f6a4b4532195f3Elliott Hughes 74e2f77e7592842cad5a59e73535b8982c35e156caIan Rogers void CompareAndUpdateStackTrace(Thread* thread, std::vector<mirror::ArtMethod*>* stack_trace) 750abc72ebe356c32354b575c48189965a0edc7890Jeff Hao SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 760abc72ebe356c32354b575c48189965a0edc7890Jeff Hao 773f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertz // InstrumentationListener implementation. 783f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertz void MethodEntered(Thread* thread, mirror::Object* this_object, 793f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertz mirror::ArtMethod* method, uint32_t dex_pc) 803f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertz SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) OVERRIDE; 813f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertz void MethodExited(Thread* thread, mirror::Object* this_object, 823f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertz mirror::ArtMethod* method, uint32_t dex_pc, 833f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertz const JValue& return_value) 843f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertz SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) OVERRIDE; 853f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertz void MethodUnwind(Thread* thread, mirror::Object* this_object, 863f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertz mirror::ArtMethod* method, uint32_t dex_pc) 873f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertz SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) OVERRIDE; 883f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertz void DexPcMoved(Thread* thread, mirror::Object* this_object, 893f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertz mirror::ArtMethod* method, uint32_t new_dex_pc) 903f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertz SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) OVERRIDE; 913f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertz void FieldRead(Thread* thread, mirror::Object* this_object, 923f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertz mirror::ArtMethod* method, uint32_t dex_pc, mirror::ArtField* field) 933f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertz SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) OVERRIDE; 943f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertz void FieldWritten(Thread* thread, mirror::Object* this_object, 953f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertz mirror::ArtMethod* method, uint32_t dex_pc, mirror::ArtField* field, 963f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertz const JValue& field_value) 973f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertz SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) OVERRIDE; 983f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertz void ExceptionCaught(Thread* thread, const ThrowLocation& throw_location, 993f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertz mirror::ArtMethod* catch_method, uint32_t catch_dex_pc, 1003f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertz mirror::Throwable* exception_object) 1013f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertz SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) OVERRIDE; 1020cd7ec2dcd8d7ba30bf3ca420b40dac52849876cBrian Carlstrom 1035ce4b178d2483df679e7f718e379305e5d42a300Jeff Hao // Reuse an old stack trace if it exists, otherwise allocate a new one. 1045ce4b178d2483df679e7f718e379305e5d42a300Jeff Hao static std::vector<mirror::ArtMethod*>* AllocStackTrace(); 1055ce4b178d2483df679e7f718e379305e5d42a300Jeff Hao // Clear and store an old stack trace for later use. 1065ce4b178d2483df679e7f718e379305e5d42a300Jeff Hao static void FreeStackTrace(std::vector<mirror::ArtMethod*>* stack_trace); 1075ce4b178d2483df679e7f718e379305e5d42a300Jeff Hao 108e343b76af81a005ef64f5e75a555389fd9147dabjeffhao private: 10923009dca63c1699e28bfeaa8b45ca48fa0e86aceJeff Hao explicit Trace(File* trace_file, int buffer_size, int flags, bool sampling_enabled); 1102692b573a56cd63a3c8c8aa1636e3766b6d8c9c4jeffhao 11123009dca63c1699e28bfeaa8b45ca48fa0e86aceJeff Hao // The sampling interval in microseconds is passed as an argument. 1120abc72ebe356c32354b575c48189965a0edc7890Jeff Hao static void* RunSamplingThread(void* arg) LOCKS_EXCLUDED(Locks::trace_lock_); 1130abc72ebe356c32354b575c48189965a0edc7890Jeff Hao 114b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers void FinishTracing() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 1152692b573a56cd63a3c8c8aa1636e3766b6d8c9c4jeffhao 116c1ff4b79a5d81b849203cc1e1c4a91223e75cfd3Jeff Hao void ReadClocks(Thread* thread, uint32_t* thread_clock_diff, uint32_t* wall_clock_diff); 117c1ff4b79a5d81b849203cc1e1c4a91223e75cfd3Jeff Hao 118ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers void LogMethodTraceEvent(Thread* thread, mirror::ArtMethod* method, 119c1ff4b79a5d81b849203cc1e1c4a91223e75cfd3Jeff Hao instrumentation::Instrumentation::InstrumentationEvent event, 120c1ff4b79a5d81b849203cc1e1c4a91223e75cfd3Jeff Hao uint32_t thread_clock_diff, uint32_t wall_clock_diff); 12162d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers 122a9ef3fd82bebc6370fc3ddbb094988feb6c83022jeffhao // Methods to output traced methods and threads. 123ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom void GetVisitedMethods(size_t end_offset, std::set<mirror::ArtMethod*>* visited_methods); 124ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom void DumpMethodList(std::ostream& os, const std::set<mirror::ArtMethod*>& visited_methods) 12562d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 126b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers void DumpThreadList(std::ostream& os) LOCKS_EXCLUDED(Locks::thread_list_lock_); 1272692b573a56cd63a3c8c8aa1636e3766b6d8c9c4jeffhao 12862d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers // Singleton instance of the Trace or NULL when no method tracing is active. 1290abc72ebe356c32354b575c48189965a0edc7890Jeff Hao static Trace* volatile the_trace_ GUARDED_BY(Locks::trace_lock_); 13062d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers 13162d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers // The default profiler clock source. 132e63db27db913f1a88e2095a1ee8239b2bb9124e8Ian Rogers static TraceClockSource default_clock_source_; 1332692b573a56cd63a3c8c8aa1636e3766b6d8c9c4jeffhao 1340abc72ebe356c32354b575c48189965a0edc7890Jeff Hao // Sampling thread, non-zero when sampling. 1350abc72ebe356c32354b575c48189965a0edc7890Jeff Hao static pthread_t sampling_pthread_; 1360abc72ebe356c32354b575c48189965a0edc7890Jeff Hao 1375ce4b178d2483df679e7f718e379305e5d42a300Jeff Hao // Used to remember an unused stack trace to avoid re-allocation during sampling. 138700a402244a1a423da4f3ba8032459f4b65fa18fIan Rogers static std::unique_ptr<std::vector<mirror::ArtMethod*>> temp_stack_trace_; 1392692b573a56cd63a3c8c8aa1636e3766b6d8c9c4jeffhao 1402692b573a56cd63a3c8c8aa1636e3766b6d8c9c4jeffhao // File to write trace data out to, NULL if direct to ddms. 141700a402244a1a423da4f3ba8032459f4b65fa18fIan Rogers std::unique_ptr<File> trace_file_; 1422692b573a56cd63a3c8c8aa1636e3766b6d8c9c4jeffhao 1432692b573a56cd63a3c8c8aa1636e3766b6d8c9c4jeffhao // Buffer to store trace data. 144700a402244a1a423da4f3ba8032459f4b65fa18fIan Rogers std::unique_ptr<uint8_t> buf_; 1452692b573a56cd63a3c8c8aa1636e3766b6d8c9c4jeffhao 1460791adc2249366c50684935a4c42ba5e58bc3746jeffhao // Flags enabling extra tracing of things such as alloc counts. 14762d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers const int flags_; 1480791adc2249366c50684935a4c42ba5e58bc3746jeffhao 14923009dca63c1699e28bfeaa8b45ca48fa0e86aceJeff Hao // True if traceview should sample instead of instrumenting method entry/exit. 15023009dca63c1699e28bfeaa8b45ca48fa0e86aceJeff Hao const bool sampling_enabled_; 15123009dca63c1699e28bfeaa8b45ca48fa0e86aceJeff Hao 152e63db27db913f1a88e2095a1ee8239b2bb9124e8Ian Rogers const TraceClockSource clock_source_; 153cfbe73d02a024800813f8f0fc4f6a4b4532195f3Elliott Hughes 15462d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers // Size of buf_. 15562d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers const int buffer_size_; 15662d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers 15762d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers // Time trace was created. 15862d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers const uint64_t start_time_; 1592692b573a56cd63a3c8c8aa1636e3766b6d8c9c4jeffhao 160c5d824a20c225763761a6dff43294b229ff35469Jeff Hao // Clock overhead. 161c5d824a20c225763761a6dff43294b229ff35469Jeff Hao const uint32_t clock_overhead_ns_; 162c5d824a20c225763761a6dff43294b229ff35469Jeff Hao 16362d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers // Offset into buf_. 1648ab25ef11aed383bf7d3aa96e95f777972d1b58fIan Rogers AtomicInteger cur_offset_; 165a9ef3fd82bebc6370fc3ddbb094988feb6c83022jeffhao 16662d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers // Did we overflow the buffer recording traces? 16762d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers bool overflow_; 16862d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers 169e343b76af81a005ef64f5e75a555389fd9147dabjeffhao DISALLOW_COPY_AND_ASSIGN(Trace); 170e343b76af81a005ef64f5e75a555389fd9147dabjeffhao}; 171e343b76af81a005ef64f5e75a555389fd9147dabjeffhao 172e343b76af81a005ef64f5e75a555389fd9147dabjeffhao} // namespace art 173e343b76af81a005ef64f5e75a555389fd9147dabjeffhao 174fc0e3219edc9a5bf81b166e82fd5db2796eb6a0dBrian Carlstrom#endif // ART_RUNTIME_TRACE_H_ 175