trace.h revision c1ff4b79a5d81b849203cc1e1c4a91223e75cfd3
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 20a9ef3fd82bebc6370fc3ddbb094988feb6c83022jeffhao#include <ostream> 21a9ef3fd82bebc6370fc3ddbb094988feb6c83022jeffhao#include <set> 22a9ef3fd82bebc6370fc3ddbb094988feb6c83022jeffhao#include <string> 230abc72ebe356c32354b575c48189965a0edc7890Jeff Hao#include <vector> 24e343b76af81a005ef64f5e75a555389fd9147dabjeffhao 25761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes#include "base/macros.h" 26e343b76af81a005ef64f5e75a555389fd9147dabjeffhao#include "globals.h" 2762d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers#include "instrumentation.h" 28761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes#include "os.h" 29a0e180632411f7fe0edf454e571c42209ee7b540Elliott Hughes#include "safe_map.h" 302692b573a56cd63a3c8c8aa1636e3766b6d8c9c4jeffhao#include "UniquePtr.h" 31e343b76af81a005ef64f5e75a555389fd9147dabjeffhao 32e343b76af81a005ef64f5e75a555389fd9147dabjeffhaonamespace art { 33e343b76af81a005ef64f5e75a555389fd9147dabjeffhao 342dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogersnamespace mirror { 35ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom class ArtMethod; 362dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers} // namespace mirror 37a9ef3fd82bebc6370fc3ddbb094988feb6c83022jeffhaoclass Thread; 38e343b76af81a005ef64f5e75a555389fd9147dabjeffhao 39cfbe73d02a024800813f8f0fc4f6a4b4532195f3Elliott Hughesenum ProfilerClockSource { 40cfbe73d02a024800813f8f0fc4f6a4b4532195f3Elliott Hughes kProfilerClockSourceThreadCpu, 41cfbe73d02a024800813f8f0fc4f6a4b4532195f3Elliott Hughes kProfilerClockSourceWall, 4262d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers kProfilerClockSourceDual, // Both wall and thread CPU clocks. 43cfbe73d02a024800813f8f0fc4f6a4b4532195f3Elliott Hughes}; 44cfbe73d02a024800813f8f0fc4f6a4b4532195f3Elliott Hughes 4562d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogersclass Trace : public instrumentation::InstrumentationListener { 46e343b76af81a005ef64f5e75a555389fd9147dabjeffhao public: 470791adc2249366c50684935a4c42ba5e58bc3746jeffhao enum TraceFlag { 480791adc2249366c50684935a4c42ba5e58bc3746jeffhao kTraceCountAllocs = 1, 490791adc2249366c50684935a4c42ba5e58bc3746jeffhao }; 500791adc2249366c50684935a4c42ba5e58bc3746jeffhao 51cfbe73d02a024800813f8f0fc4f6a4b4532195f3Elliott Hughes static void SetDefaultClockSource(ProfilerClockSource clock_source); 52cfbe73d02a024800813f8f0fc4f6a4b4532195f3Elliott Hughes 5362d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers static void Start(const char* trace_filename, int trace_fd, int buffer_size, int flags, 5462d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers bool direct_to_ddms) 5562d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers LOCKS_EXCLUDED(Locks::mutator_lock_, 5662d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers Locks::thread_list_lock_, 5762d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers Locks::thread_suspend_count_lock_, 5862d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers Locks::trace_lock_); 5962d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers static void Stop() LOCKS_EXCLUDED(Locks::trace_lock_); 6062d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers static void Shutdown() LOCKS_EXCLUDED(Locks::trace_lock_); 6162d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers static bool IsMethodTracingActive() LOCKS_EXCLUDED(Locks::trace_lock_); 62e343b76af81a005ef64f5e75a555389fd9147dabjeffhao 63cfbe73d02a024800813f8f0fc4f6a4b4532195f3Elliott Hughes bool UseWallClock(); 64cfbe73d02a024800813f8f0fc4f6a4b4532195f3Elliott Hughes bool UseThreadCpuClock(); 65cfbe73d02a024800813f8f0fc4f6a4b4532195f3Elliott Hughes 66e2f77e7592842cad5a59e73535b8982c35e156caIan Rogers void CompareAndUpdateStackTrace(Thread* thread, std::vector<mirror::ArtMethod*>* stack_trace) 670abc72ebe356c32354b575c48189965a0edc7890Jeff Hao SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 680abc72ebe356c32354b575c48189965a0edc7890Jeff Hao 6962d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers virtual void MethodEntered(Thread* thread, mirror::Object* this_object, 70ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom const mirror::ArtMethod* method, uint32_t dex_pc) 7162d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 7262d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers virtual void MethodExited(Thread* thread, mirror::Object* this_object, 73ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom const mirror::ArtMethod* method, uint32_t dex_pc, 7462d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers const JValue& return_value) 7562d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 76ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom virtual void MethodUnwind(Thread* thread, const mirror::ArtMethod* method, uint32_t dex_pc) 7762d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 7862d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers virtual void DexPcMoved(Thread* thread, mirror::Object* this_object, 79ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom const mirror::ArtMethod* method, uint32_t new_dex_pc) 8062d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 8162d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers virtual void ExceptionCaught(Thread* thread, const ThrowLocation& throw_location, 82ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom mirror::ArtMethod* catch_method, uint32_t catch_dex_pc, 8362d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers mirror::Throwable* exception_object) 8462d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 850cd7ec2dcd8d7ba30bf3ca420b40dac52849876cBrian Carlstrom 865ce4b178d2483df679e7f718e379305e5d42a300Jeff Hao // Reuse an old stack trace if it exists, otherwise allocate a new one. 875ce4b178d2483df679e7f718e379305e5d42a300Jeff Hao static std::vector<mirror::ArtMethod*>* AllocStackTrace(); 885ce4b178d2483df679e7f718e379305e5d42a300Jeff Hao // Clear and store an old stack trace for later use. 895ce4b178d2483df679e7f718e379305e5d42a300Jeff Hao static void FreeStackTrace(std::vector<mirror::ArtMethod*>* stack_trace); 905ce4b178d2483df679e7f718e379305e5d42a300Jeff Hao 910abc72ebe356c32354b575c48189965a0edc7890Jeff Hao ~Trace(); 920abc72ebe356c32354b575c48189965a0edc7890Jeff Hao 93e343b76af81a005ef64f5e75a555389fd9147dabjeffhao private: 94cfbe73d02a024800813f8f0fc4f6a4b4532195f3Elliott Hughes explicit Trace(File* trace_file, int buffer_size, int flags); 952692b573a56cd63a3c8c8aa1636e3766b6d8c9c4jeffhao 960abc72ebe356c32354b575c48189965a0edc7890Jeff Hao static void* RunSamplingThread(void* arg) LOCKS_EXCLUDED(Locks::trace_lock_); 970abc72ebe356c32354b575c48189965a0edc7890Jeff Hao 98b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers void FinishTracing() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 992692b573a56cd63a3c8c8aa1636e3766b6d8c9c4jeffhao 100c1ff4b79a5d81b849203cc1e1c4a91223e75cfd3Jeff Hao void ReadClocks(Thread* thread, uint32_t* thread_clock_diff, uint32_t* wall_clock_diff); 101c1ff4b79a5d81b849203cc1e1c4a91223e75cfd3Jeff Hao 102ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom void LogMethodTraceEvent(Thread* thread, const mirror::ArtMethod* method, 103c1ff4b79a5d81b849203cc1e1c4a91223e75cfd3Jeff Hao instrumentation::Instrumentation::InstrumentationEvent event, 104c1ff4b79a5d81b849203cc1e1c4a91223e75cfd3Jeff Hao uint32_t thread_clock_diff, uint32_t wall_clock_diff); 10562d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers 106a9ef3fd82bebc6370fc3ddbb094988feb6c83022jeffhao // Methods to output traced methods and threads. 107ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom void GetVisitedMethods(size_t end_offset, std::set<mirror::ArtMethod*>* visited_methods); 108ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom void DumpMethodList(std::ostream& os, const std::set<mirror::ArtMethod*>& visited_methods) 10962d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 110b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers void DumpThreadList(std::ostream& os) LOCKS_EXCLUDED(Locks::thread_list_lock_); 1112692b573a56cd63a3c8c8aa1636e3766b6d8c9c4jeffhao 11262d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers // Singleton instance of the Trace or NULL when no method tracing is active. 1130abc72ebe356c32354b575c48189965a0edc7890Jeff Hao static Trace* volatile the_trace_ GUARDED_BY(Locks::trace_lock_); 11462d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers 11562d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers // The default profiler clock source. 11662d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers static ProfilerClockSource default_clock_source_; 1172692b573a56cd63a3c8c8aa1636e3766b6d8c9c4jeffhao 1180abc72ebe356c32354b575c48189965a0edc7890Jeff Hao // True if traceview should sample instead of instrumenting method entry/exit. 1190abc72ebe356c32354b575c48189965a0edc7890Jeff Hao static bool sampling_enabled_; 1200abc72ebe356c32354b575c48189965a0edc7890Jeff Hao 1210abc72ebe356c32354b575c48189965a0edc7890Jeff Hao // Sampling interval in microseconds. 1220abc72ebe356c32354b575c48189965a0edc7890Jeff Hao static uint32_t sampling_interval_us_; 1230abc72ebe356c32354b575c48189965a0edc7890Jeff Hao 1240abc72ebe356c32354b575c48189965a0edc7890Jeff Hao // Sampling thread, non-zero when sampling. 1250abc72ebe356c32354b575c48189965a0edc7890Jeff Hao static pthread_t sampling_pthread_; 1260abc72ebe356c32354b575c48189965a0edc7890Jeff Hao 1275ce4b178d2483df679e7f718e379305e5d42a300Jeff Hao // Used to remember an unused stack trace to avoid re-allocation during sampling. 1285ce4b178d2483df679e7f718e379305e5d42a300Jeff Hao static UniquePtr<std::vector<mirror::ArtMethod*> > temp_stack_trace_; 1292692b573a56cd63a3c8c8aa1636e3766b6d8c9c4jeffhao 1302692b573a56cd63a3c8c8aa1636e3766b6d8c9c4jeffhao // File to write trace data out to, NULL if direct to ddms. 1312692b573a56cd63a3c8c8aa1636e3766b6d8c9c4jeffhao UniquePtr<File> trace_file_; 1322692b573a56cd63a3c8c8aa1636e3766b6d8c9c4jeffhao 1332692b573a56cd63a3c8c8aa1636e3766b6d8c9c4jeffhao // Buffer to store trace data. 1342692b573a56cd63a3c8c8aa1636e3766b6d8c9c4jeffhao UniquePtr<uint8_t> buf_; 1352692b573a56cd63a3c8c8aa1636e3766b6d8c9c4jeffhao 1360791adc2249366c50684935a4c42ba5e58bc3746jeffhao // Flags enabling extra tracing of things such as alloc counts. 13762d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers const int flags_; 1380791adc2249366c50684935a4c42ba5e58bc3746jeffhao 13962d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers const ProfilerClockSource clock_source_; 140cfbe73d02a024800813f8f0fc4f6a4b4532195f3Elliott Hughes 14162d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers // Size of buf_. 14262d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers const int buffer_size_; 14362d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers 14462d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers // Time trace was created. 14562d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers const uint64_t start_time_; 1462692b573a56cd63a3c8c8aa1636e3766b6d8c9c4jeffhao 14762d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers // Offset into buf_. 1482692b573a56cd63a3c8c8aa1636e3766b6d8c9c4jeffhao volatile int32_t cur_offset_; 149a9ef3fd82bebc6370fc3ddbb094988feb6c83022jeffhao 15062d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers // Did we overflow the buffer recording traces? 15162d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers bool overflow_; 15262d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers 153e343b76af81a005ef64f5e75a555389fd9147dabjeffhao DISALLOW_COPY_AND_ASSIGN(Trace); 154e343b76af81a005ef64f5e75a555389fd9147dabjeffhao}; 155e343b76af81a005ef64f5e75a555389fd9147dabjeffhao 156e343b76af81a005ef64f5e75a555389fd9147dabjeffhao} // namespace art 157e343b76af81a005ef64f5e75a555389fd9147dabjeffhao 158fc0e3219edc9a5bf81b166e82fd5db2796eb6a0dBrian Carlstrom#endif // ART_RUNTIME_TRACE_H_ 159