trace.h revision 5550ca8bcc742b109d77e62f3a0877c667d894d3
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 2040da286d3207d88ed8ff3f5caac4873874603428Andreas Gampe#include <bitset> 2140da286d3207d88ed8ff3f5caac4873874603428Andreas Gampe#include <map> 22700a402244a1a423da4f3ba8032459f4b65fa18fIan Rogers#include <memory> 23a9ef3fd82bebc6370fc3ddbb094988feb6c83022jeffhao#include <ostream> 24a9ef3fd82bebc6370fc3ddbb094988feb6c83022jeffhao#include <set> 25a9ef3fd82bebc6370fc3ddbb094988feb6c83022jeffhao#include <string> 264d64cd45acc6a26742e8237eb65136998612820dMathieu Chartier#include <unordered_map> 270abc72ebe356c32354b575c48189965a0edc7890Jeff Hao#include <vector> 28e343b76af81a005ef64f5e75a555389fd9147dabjeffhao 298ab25ef11aed383bf7d3aa96e95f777972d1b58fIan Rogers#include "atomic.h" 30761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes#include "base/macros.h" 31e343b76af81a005ef64f5e75a555389fd9147dabjeffhao#include "globals.h" 3262d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers#include "instrumentation.h" 33761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes#include "os.h" 34a0e180632411f7fe0edf454e571c42209ee7b540Elliott Hughes#include "safe_map.h" 35e343b76af81a005ef64f5e75a555389fd9147dabjeffhao 36e343b76af81a005ef64f5e75a555389fd9147dabjeffhaonamespace art { 37e343b76af81a005ef64f5e75a555389fd9147dabjeffhao 38c785344b87221f5e4e6473e5b762e4e61fe65dcfMathieu Chartierclass ArtField; 39e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartierclass ArtMethod; 407526d783ab68ed1dd53c763c75895cb432532b0fAndreas Gampeclass DexFile; 41e63db27db913f1a88e2095a1ee8239b2bb9124e8Ian Rogersclass Thread; 42491ca9e75fad381468dd7f5fdbff56d1a9738dd7Brian Carlstrom 4340da286d3207d88ed8ff3f5caac4873874603428Andreas Gampeusing DexIndexBitSet = std::bitset<65536>; 4440da286d3207d88ed8ff3f5caac4873874603428Andreas Gampeusing ThreadIDBitSet = std::bitset<65536>; 4540da286d3207d88ed8ff3f5caac4873874603428Andreas Gampe 4664caa7dcf46ed6139b766dbe77fbd7353899417fJeff Haoenum TracingMode { 4764caa7dcf46ed6139b766dbe77fbd7353899417fJeff Hao kTracingInactive, 4864caa7dcf46ed6139b766dbe77fbd7353899417fJeff Hao kMethodTracingActive, 4964caa7dcf46ed6139b766dbe77fbd7353899417fJeff Hao kSampleProfilingActive, 5064caa7dcf46ed6139b766dbe77fbd7353899417fJeff Hao}; 5164caa7dcf46ed6139b766dbe77fbd7353899417fJeff Hao 524d64cd45acc6a26742e8237eb65136998612820dMathieu Chartier// File format: 534d64cd45acc6a26742e8237eb65136998612820dMathieu Chartier// header 544d64cd45acc6a26742e8237eb65136998612820dMathieu Chartier// record 0 554d64cd45acc6a26742e8237eb65136998612820dMathieu Chartier// record 1 564d64cd45acc6a26742e8237eb65136998612820dMathieu Chartier// ... 574d64cd45acc6a26742e8237eb65136998612820dMathieu Chartier// 584d64cd45acc6a26742e8237eb65136998612820dMathieu Chartier// Header format: 594d64cd45acc6a26742e8237eb65136998612820dMathieu Chartier// u4 magic ('SLOW') 604d64cd45acc6a26742e8237eb65136998612820dMathieu Chartier// u2 version 614d64cd45acc6a26742e8237eb65136998612820dMathieu Chartier// u2 offset to data 624d64cd45acc6a26742e8237eb65136998612820dMathieu Chartier// u8 start date/time in usec 634d64cd45acc6a26742e8237eb65136998612820dMathieu Chartier// u2 record size in bytes (version >= 2 only) 644d64cd45acc6a26742e8237eb65136998612820dMathieu Chartier// ... padding to 32 bytes 654d64cd45acc6a26742e8237eb65136998612820dMathieu Chartier// 664d64cd45acc6a26742e8237eb65136998612820dMathieu Chartier// Record format v1: 674d64cd45acc6a26742e8237eb65136998612820dMathieu Chartier// u1 thread ID 684d64cd45acc6a26742e8237eb65136998612820dMathieu Chartier// u4 method ID | method action 694d64cd45acc6a26742e8237eb65136998612820dMathieu Chartier// u4 time delta since start, in usec 704d64cd45acc6a26742e8237eb65136998612820dMathieu Chartier// 714d64cd45acc6a26742e8237eb65136998612820dMathieu Chartier// Record format v2: 724d64cd45acc6a26742e8237eb65136998612820dMathieu Chartier// u2 thread ID 734d64cd45acc6a26742e8237eb65136998612820dMathieu Chartier// u4 method ID | method action 744d64cd45acc6a26742e8237eb65136998612820dMathieu Chartier// u4 time delta since start, in usec 754d64cd45acc6a26742e8237eb65136998612820dMathieu Chartier// 764d64cd45acc6a26742e8237eb65136998612820dMathieu Chartier// Record format v3: 774d64cd45acc6a26742e8237eb65136998612820dMathieu Chartier// u2 thread ID 784d64cd45acc6a26742e8237eb65136998612820dMathieu Chartier// u4 method ID | method action 794d64cd45acc6a26742e8237eb65136998612820dMathieu Chartier// u4 time delta since start, in usec 804d64cd45acc6a26742e8237eb65136998612820dMathieu Chartier// u4 wall time since start, in usec (when clock == "dual" only) 814d64cd45acc6a26742e8237eb65136998612820dMathieu Chartier// 824d64cd45acc6a26742e8237eb65136998612820dMathieu Chartier// 32 bits of microseconds is 70 minutes. 834d64cd45acc6a26742e8237eb65136998612820dMathieu Chartier// 844d64cd45acc6a26742e8237eb65136998612820dMathieu Chartier// All values are stored in little-endian order. 854d64cd45acc6a26742e8237eb65136998612820dMathieu Chartier 864d64cd45acc6a26742e8237eb65136998612820dMathieu Chartierenum TraceAction { 874d64cd45acc6a26742e8237eb65136998612820dMathieu Chartier kTraceMethodEnter = 0x00, // method entry 884d64cd45acc6a26742e8237eb65136998612820dMathieu Chartier kTraceMethodExit = 0x01, // method exit 894d64cd45acc6a26742e8237eb65136998612820dMathieu Chartier kTraceUnroll = 0x02, // method exited by exception unrolling 904d64cd45acc6a26742e8237eb65136998612820dMathieu Chartier // 0x03 currently unused 914d64cd45acc6a26742e8237eb65136998612820dMathieu Chartier kTraceMethodActionMask = 0x03, // two bits 924d64cd45acc6a26742e8237eb65136998612820dMathieu Chartier}; 934d64cd45acc6a26742e8237eb65136998612820dMathieu Chartier 943f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertzclass Trace FINAL : public instrumentation::InstrumentationListener { 95e343b76af81a005ef64f5e75a555389fd9147dabjeffhao public: 960791adc2249366c50684935a4c42ba5e58bc3746jeffhao enum TraceFlag { 970791adc2249366c50684935a4c42ba5e58bc3746jeffhao kTraceCountAllocs = 1, 980791adc2249366c50684935a4c42ba5e58bc3746jeffhao }; 990791adc2249366c50684935a4c42ba5e58bc3746jeffhao 1007e7e0f47628fb358da70c5e2766545c4f0596235Andreas Gampe enum class TraceOutputMode { 1017e7e0f47628fb358da70c5e2766545c4f0596235Andreas Gampe kFile, 10240da286d3207d88ed8ff3f5caac4873874603428Andreas Gampe kDDMS, 10340da286d3207d88ed8ff3f5caac4873874603428Andreas Gampe kStreaming 1047e7e0f47628fb358da70c5e2766545c4f0596235Andreas Gampe }; 1057e7e0f47628fb358da70c5e2766545c4f0596235Andreas Gampe 1067e7e0f47628fb358da70c5e2766545c4f0596235Andreas Gampe enum class TraceMode { 1077e7e0f47628fb358da70c5e2766545c4f0596235Andreas Gampe kMethodTracing, 1087e7e0f47628fb358da70c5e2766545c4f0596235Andreas Gampe kSampling 1097e7e0f47628fb358da70c5e2766545c4f0596235Andreas Gampe }; 1107e7e0f47628fb358da70c5e2766545c4f0596235Andreas Gampe 11140da286d3207d88ed8ff3f5caac4873874603428Andreas Gampe ~Trace(); 11240da286d3207d88ed8ff3f5caac4873874603428Andreas Gampe 113e63db27db913f1a88e2095a1ee8239b2bb9124e8Ian Rogers static void SetDefaultClockSource(TraceClockSource clock_source); 114cfbe73d02a024800813f8f0fc4f6a4b4532195f3Elliott Hughes 115e34a42cd37b2b3b6b21280df14fa6f40917b5d6eAndreas Gampe static void Start(const char* trace_filename, int trace_fd, size_t buffer_size, int flags, 1167e7e0f47628fb358da70c5e2766545c4f0596235Andreas Gampe TraceOutputMode output_mode, TraceMode trace_mode, int interval_us) 11790443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier REQUIRES(!Locks::mutator_lock_, !Locks::thread_list_lock_, !Locks::thread_suspend_count_lock_, 11890443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier !Locks::trace_lock_); 11990443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier static void Pause() REQUIRES(!Locks::trace_lock_, !Locks::thread_list_lock_); 12090443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier static void Resume() REQUIRES(!Locks::trace_lock_); 12140da286d3207d88ed8ff3f5caac4873874603428Andreas Gampe 12240da286d3207d88ed8ff3f5caac4873874603428Andreas Gampe // Stop tracing. This will finish the trace and write it to file/send it via DDMS. 123bae182cbc6adc8796154162a87fc54ae804e0469Sebastien Hertz static void Stop() 12490443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier REQUIRES(!Locks::mutator_lock_, !Locks::thread_list_lock_, !Locks::trace_lock_); 12540da286d3207d88ed8ff3f5caac4873874603428Andreas Gampe // Abort tracing. This will just stop tracing and *not* write/send the collected data. 12640da286d3207d88ed8ff3f5caac4873874603428Andreas Gampe static void Abort() 12790443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier REQUIRES(!Locks::mutator_lock_, !Locks::thread_list_lock_, !Locks::trace_lock_); 1287526d783ab68ed1dd53c763c75895cb432532b0fAndreas Gampe static void Shutdown() 12990443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier REQUIRES(!Locks::mutator_lock_, !Locks::thread_list_lock_, !Locks::trace_lock_); 13090443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier static TracingMode GetMethodTracingMode() REQUIRES(!Locks::trace_lock_); 131e343b76af81a005ef64f5e75a555389fd9147dabjeffhao 132cfbe73d02a024800813f8f0fc4f6a4b4532195f3Elliott Hughes bool UseWallClock(); 133cfbe73d02a024800813f8f0fc4f6a4b4532195f3Elliott Hughes bool UseThreadCpuClock(); 134c5d824a20c225763761a6dff43294b229ff35469Jeff Hao void MeasureClockOverhead(); 135c5d824a20c225763761a6dff43294b229ff35469Jeff Hao uint32_t GetClockOverheadNanoSeconds(); 136cfbe73d02a024800813f8f0fc4f6a4b4532195f3Elliott Hughes 137e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier void CompareAndUpdateStackTrace(Thread* thread, std::vector<ArtMethod*>* stack_trace) 13890443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier SHARED_REQUIRES(Locks::mutator_lock_) REQUIRES(!*unique_methods_lock_, !*streaming_lock_); 1390abc72ebe356c32354b575c48189965a0edc7890Jeff Hao 1403f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertz // InstrumentationListener implementation. 1413f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertz void MethodEntered(Thread* thread, mirror::Object* this_object, 142e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier ArtMethod* method, uint32_t dex_pc) 14390443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier SHARED_REQUIRES(Locks::mutator_lock_) REQUIRES(!*unique_methods_lock_, !*streaming_lock_) 14490443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier OVERRIDE; 1453f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertz void MethodExited(Thread* thread, mirror::Object* this_object, 146e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier ArtMethod* method, uint32_t dex_pc, 1473f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertz const JValue& return_value) 14890443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier SHARED_REQUIRES(Locks::mutator_lock_) REQUIRES(!*unique_methods_lock_, !*streaming_lock_) 14990443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier OVERRIDE; 1503f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertz void MethodUnwind(Thread* thread, mirror::Object* this_object, 151e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier ArtMethod* method, uint32_t dex_pc) 15290443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier SHARED_REQUIRES(Locks::mutator_lock_) REQUIRES(!*unique_methods_lock_, !*streaming_lock_) 15390443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier OVERRIDE; 1543f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertz void DexPcMoved(Thread* thread, mirror::Object* this_object, 155e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier ArtMethod* method, uint32_t new_dex_pc) 15690443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier SHARED_REQUIRES(Locks::mutator_lock_) REQUIRES(!*unique_methods_lock_, !*streaming_lock_) 15790443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier OVERRIDE; 1583f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertz void FieldRead(Thread* thread, mirror::Object* this_object, 159e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier ArtMethod* method, uint32_t dex_pc, ArtField* field) 16090443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier SHARED_REQUIRES(Locks::mutator_lock_) REQUIRES(!*unique_methods_lock_) OVERRIDE; 1613f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertz void FieldWritten(Thread* thread, mirror::Object* this_object, 162e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier ArtMethod* method, uint32_t dex_pc, ArtField* field, 1633f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertz const JValue& field_value) 16490443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier SHARED_REQUIRES(Locks::mutator_lock_) REQUIRES(!*unique_methods_lock_) OVERRIDE; 16514691c5e786e8c2c5734f687e4c96217340771beNicolas Geoffray void ExceptionCaught(Thread* thread, mirror::Throwable* exception_object) 16690443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier SHARED_REQUIRES(Locks::mutator_lock_) REQUIRES(!*unique_methods_lock_) OVERRIDE; 167e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier void BackwardBranch(Thread* thread, ArtMethod* method, int32_t dex_pc_offset) 16890443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier SHARED_REQUIRES(Locks::mutator_lock_) REQUIRES(!*unique_methods_lock_) OVERRIDE; 1695550ca8bcc742b109d77e62f3a0877c667d894d3Nicolas Geoffray void InvokeVirtualOrInterface(Thread* thread, 1705550ca8bcc742b109d77e62f3a0877c667d894d3Nicolas Geoffray mirror::Object* this_object, 1715550ca8bcc742b109d77e62f3a0877c667d894d3Nicolas Geoffray ArtMethod* caller, 1725550ca8bcc742b109d77e62f3a0877c667d894d3Nicolas Geoffray uint32_t dex_pc, 1735550ca8bcc742b109d77e62f3a0877c667d894d3Nicolas Geoffray ArtMethod* callee) 1745550ca8bcc742b109d77e62f3a0877c667d894d3Nicolas Geoffray SHARED_REQUIRES(Locks::mutator_lock_) REQUIRES(!*unique_methods_lock_) OVERRIDE; 1755ce4b178d2483df679e7f718e379305e5d42a300Jeff Hao // Reuse an old stack trace if it exists, otherwise allocate a new one. 176e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier static std::vector<ArtMethod*>* AllocStackTrace(); 1775ce4b178d2483df679e7f718e379305e5d42a300Jeff Hao // Clear and store an old stack trace for later use. 178e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier static void FreeStackTrace(std::vector<ArtMethod*>* stack_trace); 179e094b87c6f6ea9ebf83aa56a3114ac59556aaf9fJeff Hao // Save id and name of a thread before it exits. 180e094b87c6f6ea9ebf83aa56a3114ac59556aaf9fJeff Hao static void StoreExitingThreadInfo(Thread* thread); 1815ce4b178d2483df679e7f718e379305e5d42a300Jeff Hao 18290443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier static TraceOutputMode GetOutputMode() REQUIRES(!Locks::trace_lock_); 18390443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier static TraceMode GetMode() REQUIRES(!Locks::trace_lock_); 18490443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier static size_t GetBufferSize() REQUIRES(!Locks::trace_lock_); 18540da286d3207d88ed8ff3f5caac4873874603428Andreas Gampe 186e343b76af81a005ef64f5e75a555389fd9147dabjeffhao private: 187e34a42cd37b2b3b6b21280df14fa6f40917b5d6eAndreas Gampe Trace(File* trace_file, const char* trace_name, size_t buffer_size, int flags, 18840da286d3207d88ed8ff3f5caac4873874603428Andreas Gampe TraceOutputMode output_mode, TraceMode trace_mode); 1892692b573a56cd63a3c8c8aa1636e3766b6d8c9c4jeffhao 19023009dca63c1699e28bfeaa8b45ca48fa0e86aceJeff Hao // The sampling interval in microseconds is passed as an argument. 19190443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier static void* RunSamplingThread(void* arg) REQUIRES(!Locks::trace_lock_); 1920abc72ebe356c32354b575c48189965a0edc7890Jeff Hao 1937526d783ab68ed1dd53c763c75895cb432532b0fAndreas Gampe static void StopTracing(bool finish_tracing, bool flush_file) 19490443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier REQUIRES(!Locks::mutator_lock_, !Locks::thread_list_lock_, !Locks::trace_lock_) 19590443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier // There is an annoying issue with static functions that create a new object and call into 19690443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier // that object that causes them to not be able to tell that we don't currently hold the lock. 19790443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier // This causes the negative annotations to incorrectly have a false positive. TODO: Figure out 19890443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier // how to annotate this. 19990443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier NO_THREAD_SAFETY_ANALYSIS; 20090443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier void FinishTracing() SHARED_REQUIRES(Locks::mutator_lock_) REQUIRES(!*unique_methods_lock_); 2012692b573a56cd63a3c8c8aa1636e3766b6d8c9c4jeffhao 202c1ff4b79a5d81b849203cc1e1c4a91223e75cfd3Jeff Hao void ReadClocks(Thread* thread, uint32_t* thread_clock_diff, uint32_t* wall_clock_diff); 203c1ff4b79a5d81b849203cc1e1c4a91223e75cfd3Jeff Hao 204e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier void LogMethodTraceEvent(Thread* thread, ArtMethod* method, 205c1ff4b79a5d81b849203cc1e1c4a91223e75cfd3Jeff Hao instrumentation::Instrumentation::InstrumentationEvent event, 20640da286d3207d88ed8ff3f5caac4873874603428Andreas Gampe uint32_t thread_clock_diff, uint32_t wall_clock_diff) 20790443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier SHARED_REQUIRES(Locks::mutator_lock_) REQUIRES(!*unique_methods_lock_, !*streaming_lock_); 20862d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers 209a9ef3fd82bebc6370fc3ddbb094988feb6c83022jeffhao // Methods to output traced methods and threads. 21090443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier void GetVisitedMethods(size_t end_offset, std::set<ArtMethod*>* visited_methods) 21190443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier REQUIRES(!*unique_methods_lock_); 212e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier void DumpMethodList(std::ostream& os, const std::set<ArtMethod*>& visited_methods) 21390443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier SHARED_REQUIRES(Locks::mutator_lock_) REQUIRES(!*unique_methods_lock_); 21490443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier void DumpThreadList(std::ostream& os) REQUIRES(!Locks::thread_list_lock_); 2152692b573a56cd63a3c8c8aa1636e3766b6d8c9c4jeffhao 21640da286d3207d88ed8ff3f5caac4873874603428Andreas Gampe // Methods to register seen entitites in streaming mode. The methods return true if the entity 21740da286d3207d88ed8ff3f5caac4873874603428Andreas Gampe // is newly discovered. 218e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier bool RegisterMethod(ArtMethod* method) 21990443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier SHARED_REQUIRES(Locks::mutator_lock_) REQUIRES(streaming_lock_); 22040da286d3207d88ed8ff3f5caac4873874603428Andreas Gampe bool RegisterThread(Thread* thread) 22190443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier REQUIRES(streaming_lock_); 22240da286d3207d88ed8ff3f5caac4873874603428Andreas Gampe 22340da286d3207d88ed8ff3f5caac4873874603428Andreas Gampe // Copy a temporary buffer to the main buffer. Used for streaming. Exposed here for lock 22440da286d3207d88ed8ff3f5caac4873874603428Andreas Gampe // annotation. 22540da286d3207d88ed8ff3f5caac4873874603428Andreas Gampe void WriteToBuf(const uint8_t* src, size_t src_size) 22690443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier REQUIRES(streaming_lock_); 22740da286d3207d88ed8ff3f5caac4873874603428Andreas Gampe 22890443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier uint32_t EncodeTraceMethod(ArtMethod* method) REQUIRES(!*unique_methods_lock_); 2294d64cd45acc6a26742e8237eb65136998612820dMathieu Chartier uint32_t EncodeTraceMethodAndAction(ArtMethod* method, TraceAction action) 23090443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier REQUIRES(!*unique_methods_lock_); 23190443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier ArtMethod* DecodeTraceMethod(uint32_t tmid) REQUIRES(!*unique_methods_lock_); 23290443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier std::string GetMethodLine(ArtMethod* method) REQUIRES(!*unique_methods_lock_) 23390443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier SHARED_REQUIRES(Locks::mutator_lock_); 2344d64cd45acc6a26742e8237eb65136998612820dMathieu Chartier 2354d64cd45acc6a26742e8237eb65136998612820dMathieu Chartier void DumpBuf(uint8_t* buf, size_t buf_size, TraceClockSource clock_source) 23690443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier SHARED_REQUIRES(Locks::mutator_lock_) REQUIRES(!*unique_methods_lock_); 2374d64cd45acc6a26742e8237eb65136998612820dMathieu Chartier 2382cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier // Singleton instance of the Trace or null when no method tracing is active. 2390abc72ebe356c32354b575c48189965a0edc7890Jeff Hao static Trace* volatile the_trace_ GUARDED_BY(Locks::trace_lock_); 24062d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers 24162d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers // The default profiler clock source. 242e63db27db913f1a88e2095a1ee8239b2bb9124e8Ian Rogers static TraceClockSource default_clock_source_; 2432692b573a56cd63a3c8c8aa1636e3766b6d8c9c4jeffhao 2440abc72ebe356c32354b575c48189965a0edc7890Jeff Hao // Sampling thread, non-zero when sampling. 2450abc72ebe356c32354b575c48189965a0edc7890Jeff Hao static pthread_t sampling_pthread_; 2460abc72ebe356c32354b575c48189965a0edc7890Jeff Hao 2475ce4b178d2483df679e7f718e379305e5d42a300Jeff Hao // Used to remember an unused stack trace to avoid re-allocation during sampling. 248e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier static std::unique_ptr<std::vector<ArtMethod*>> temp_stack_trace_; 2492692b573a56cd63a3c8c8aa1636e3766b6d8c9c4jeffhao 2502cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier // File to write trace data out to, null if direct to ddms. 251700a402244a1a423da4f3ba8032459f4b65fa18fIan Rogers std::unique_ptr<File> trace_file_; 2522692b573a56cd63a3c8c8aa1636e3766b6d8c9c4jeffhao 2532692b573a56cd63a3c8c8aa1636e3766b6d8c9c4jeffhao // Buffer to store trace data. 254241a9588c6d7d0fcb4c92da40c7141863930083aChristopher Ferris std::unique_ptr<uint8_t[]> buf_; 2552692b573a56cd63a3c8c8aa1636e3766b6d8c9c4jeffhao 2560791adc2249366c50684935a4c42ba5e58bc3746jeffhao // Flags enabling extra tracing of things such as alloc counts. 25762d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers const int flags_; 2580791adc2249366c50684935a4c42ba5e58bc3746jeffhao 25940da286d3207d88ed8ff3f5caac4873874603428Andreas Gampe // The kind of output for this tracing. 26040da286d3207d88ed8ff3f5caac4873874603428Andreas Gampe const TraceOutputMode trace_output_mode_; 26140da286d3207d88ed8ff3f5caac4873874603428Andreas Gampe 26240da286d3207d88ed8ff3f5caac4873874603428Andreas Gampe // The tracing method. 2637e7e0f47628fb358da70c5e2766545c4f0596235Andreas Gampe const TraceMode trace_mode_; 26423009dca63c1699e28bfeaa8b45ca48fa0e86aceJeff Hao 265e63db27db913f1a88e2095a1ee8239b2bb9124e8Ian Rogers const TraceClockSource clock_source_; 266cfbe73d02a024800813f8f0fc4f6a4b4532195f3Elliott Hughes 26762d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers // Size of buf_. 268e34a42cd37b2b3b6b21280df14fa6f40917b5d6eAndreas Gampe const size_t buffer_size_; 26962d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers 27062d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers // Time trace was created. 27162d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers const uint64_t start_time_; 2722692b573a56cd63a3c8c8aa1636e3766b6d8c9c4jeffhao 273c5d824a20c225763761a6dff43294b229ff35469Jeff Hao // Clock overhead. 274c5d824a20c225763761a6dff43294b229ff35469Jeff Hao const uint32_t clock_overhead_ns_; 275c5d824a20c225763761a6dff43294b229ff35469Jeff Hao 27662d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers // Offset into buf_. 2778ab25ef11aed383bf7d3aa96e95f777972d1b58fIan Rogers AtomicInteger cur_offset_; 278a9ef3fd82bebc6370fc3ddbb094988feb6c83022jeffhao 27962d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers // Did we overflow the buffer recording traces? 28062d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers bool overflow_; 28162d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers 282e094b87c6f6ea9ebf83aa56a3114ac59556aaf9fJeff Hao // Map of thread ids and names that have already exited. 283e094b87c6f6ea9ebf83aa56a3114ac59556aaf9fJeff Hao SafeMap<pid_t, std::string> exited_threads_; 284e094b87c6f6ea9ebf83aa56a3114ac59556aaf9fJeff Hao 28540da286d3207d88ed8ff3f5caac4873874603428Andreas Gampe // Sampling profiler sampling interval. 28640da286d3207d88ed8ff3f5caac4873874603428Andreas Gampe int interval_us_; 28740da286d3207d88ed8ff3f5caac4873874603428Andreas Gampe 28840da286d3207d88ed8ff3f5caac4873874603428Andreas Gampe // Streaming mode data. 28940da286d3207d88ed8ff3f5caac4873874603428Andreas Gampe std::string streaming_file_name_; 29040da286d3207d88ed8ff3f5caac4873874603428Andreas Gampe Mutex* streaming_lock_; 2917526d783ab68ed1dd53c763c75895cb432532b0fAndreas Gampe std::map<const DexFile*, DexIndexBitSet*> seen_methods_; 29240da286d3207d88ed8ff3f5caac4873874603428Andreas Gampe std::unique_ptr<ThreadIDBitSet> seen_threads_; 29340da286d3207d88ed8ff3f5caac4873874603428Andreas Gampe 2944d64cd45acc6a26742e8237eb65136998612820dMathieu Chartier // Bijective map from ArtMethod* to index. 2954d64cd45acc6a26742e8237eb65136998612820dMathieu Chartier // Map from ArtMethod* to index in unique_methods_; 2967526d783ab68ed1dd53c763c75895cb432532b0fAndreas Gampe Mutex* unique_methods_lock_ ACQUIRED_AFTER(streaming_lock_); 2974d64cd45acc6a26742e8237eb65136998612820dMathieu Chartier std::unordered_map<ArtMethod*, uint32_t> art_method_id_map_ GUARDED_BY(unique_methods_lock_); 2984d64cd45acc6a26742e8237eb65136998612820dMathieu Chartier std::vector<ArtMethod*> unique_methods_ GUARDED_BY(unique_methods_lock_); 2994d64cd45acc6a26742e8237eb65136998612820dMathieu Chartier 300e343b76af81a005ef64f5e75a555389fd9147dabjeffhao DISALLOW_COPY_AND_ASSIGN(Trace); 301e343b76af81a005ef64f5e75a555389fd9147dabjeffhao}; 302e343b76af81a005ef64f5e75a555389fd9147dabjeffhao 303e343b76af81a005ef64f5e75a555389fd9147dabjeffhao} // namespace art 304e343b76af81a005ef64f5e75a555389fd9147dabjeffhao 305fc0e3219edc9a5bf81b166e82fd5db2796eb6a0dBrian Carlstrom#endif // ART_RUNTIME_TRACE_H_ 306