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 298f4b056427a9d2321e3aa4f21ca8ffb18b3e5ae6David Sehr#include "base/atomic.h" 30761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes#include "base/macros.h" 318f4b056427a9d2321e3aa4f21ca8ffb18b3e5ae6David Sehr#include "base/os.h" 3267bf42e89592c3a1c648f927f2ce3ccb189a1161David Sehr#include "base/safe_map.h" 33e343b76af81a005ef64f5e75a555389fd9147dabjeffhao#include "globals.h" 3462d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers#include "instrumentation.h" 35e343b76af81a005ef64f5e75a555389fd9147dabjeffhao 36e343b76af81a005ef64f5e75a555389fd9147dabjeffhaonamespace art { 37e343b76af81a005ef64f5e75a555389fd9147dabjeffhao 38c785344b87221f5e4e6473e5b762e4e61fe65dcfMathieu Chartierclass ArtField; 39e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartierclass ArtMethod; 407526d783ab68ed1dd53c763c75895cb432532b0fAndreas Gampeclass DexFile; 4105f47743e604e9b3b1de9ec930c6af6d9780c440Alex Lightclass ShadowFrame; 42e63db27db913f1a88e2095a1ee8239b2bb9124e8Ian Rogersclass Thread; 43491ca9e75fad381468dd7f5fdbff56d1a9738dd7Brian Carlstrom 4440da286d3207d88ed8ff3f5caac4873874603428Andreas Gampeusing DexIndexBitSet = std::bitset<65536>; 45a344f6a153d84d9adc4f4d3c608538d7741168a9Alex Light 46a344f6a153d84d9adc4f4d3c608538d7741168a9Alex Lightconstexpr size_t kMaxThreadIdNumber = kIsTargetBuild ? 65536U : 1048576U; 47a344f6a153d84d9adc4f4d3c608538d7741168a9Alex Lightusing ThreadIDBitSet = std::bitset<kMaxThreadIdNumber>; 4840da286d3207d88ed8ff3f5caac4873874603428Andreas Gampe 4964caa7dcf46ed6139b766dbe77fbd7353899417fJeff Haoenum TracingMode { 5064caa7dcf46ed6139b766dbe77fbd7353899417fJeff Hao kTracingInactive, 5164caa7dcf46ed6139b766dbe77fbd7353899417fJeff Hao kMethodTracingActive, 5264caa7dcf46ed6139b766dbe77fbd7353899417fJeff Hao kSampleProfilingActive, 5364caa7dcf46ed6139b766dbe77fbd7353899417fJeff Hao}; 5464caa7dcf46ed6139b766dbe77fbd7353899417fJeff Hao 554d64cd45acc6a26742e8237eb65136998612820dMathieu Chartier// File format: 564d64cd45acc6a26742e8237eb65136998612820dMathieu Chartier// header 574d64cd45acc6a26742e8237eb65136998612820dMathieu Chartier// record 0 584d64cd45acc6a26742e8237eb65136998612820dMathieu Chartier// record 1 594d64cd45acc6a26742e8237eb65136998612820dMathieu Chartier// ... 604d64cd45acc6a26742e8237eb65136998612820dMathieu Chartier// 614d64cd45acc6a26742e8237eb65136998612820dMathieu Chartier// Header format: 624d64cd45acc6a26742e8237eb65136998612820dMathieu Chartier// u4 magic ('SLOW') 634d64cd45acc6a26742e8237eb65136998612820dMathieu Chartier// u2 version 644d64cd45acc6a26742e8237eb65136998612820dMathieu Chartier// u2 offset to data 654d64cd45acc6a26742e8237eb65136998612820dMathieu Chartier// u8 start date/time in usec 664d64cd45acc6a26742e8237eb65136998612820dMathieu Chartier// u2 record size in bytes (version >= 2 only) 674d64cd45acc6a26742e8237eb65136998612820dMathieu Chartier// ... padding to 32 bytes 684d64cd45acc6a26742e8237eb65136998612820dMathieu Chartier// 694d64cd45acc6a26742e8237eb65136998612820dMathieu Chartier// Record format v1: 704d64cd45acc6a26742e8237eb65136998612820dMathieu Chartier// u1 thread ID 714d64cd45acc6a26742e8237eb65136998612820dMathieu Chartier// u4 method ID | method action 724d64cd45acc6a26742e8237eb65136998612820dMathieu Chartier// u4 time delta since start, in usec 734d64cd45acc6a26742e8237eb65136998612820dMathieu Chartier// 744d64cd45acc6a26742e8237eb65136998612820dMathieu Chartier// Record format v2: 754d64cd45acc6a26742e8237eb65136998612820dMathieu Chartier// u2 thread ID 764d64cd45acc6a26742e8237eb65136998612820dMathieu Chartier// u4 method ID | method action 774d64cd45acc6a26742e8237eb65136998612820dMathieu Chartier// u4 time delta since start, in usec 784d64cd45acc6a26742e8237eb65136998612820dMathieu Chartier// 794d64cd45acc6a26742e8237eb65136998612820dMathieu Chartier// Record format v3: 804d64cd45acc6a26742e8237eb65136998612820dMathieu Chartier// u2 thread ID 814d64cd45acc6a26742e8237eb65136998612820dMathieu Chartier// u4 method ID | method action 824d64cd45acc6a26742e8237eb65136998612820dMathieu Chartier// u4 time delta since start, in usec 834d64cd45acc6a26742e8237eb65136998612820dMathieu Chartier// u4 wall time since start, in usec (when clock == "dual" only) 844d64cd45acc6a26742e8237eb65136998612820dMathieu Chartier// 854d64cd45acc6a26742e8237eb65136998612820dMathieu Chartier// 32 bits of microseconds is 70 minutes. 864d64cd45acc6a26742e8237eb65136998612820dMathieu Chartier// 874d64cd45acc6a26742e8237eb65136998612820dMathieu Chartier// All values are stored in little-endian order. 884d64cd45acc6a26742e8237eb65136998612820dMathieu Chartier 894d64cd45acc6a26742e8237eb65136998612820dMathieu Chartierenum TraceAction { 904d64cd45acc6a26742e8237eb65136998612820dMathieu Chartier kTraceMethodEnter = 0x00, // method entry 914d64cd45acc6a26742e8237eb65136998612820dMathieu Chartier kTraceMethodExit = 0x01, // method exit 924d64cd45acc6a26742e8237eb65136998612820dMathieu Chartier kTraceUnroll = 0x02, // method exited by exception unrolling 934d64cd45acc6a26742e8237eb65136998612820dMathieu Chartier // 0x03 currently unused 944d64cd45acc6a26742e8237eb65136998612820dMathieu Chartier kTraceMethodActionMask = 0x03, // two bits 954d64cd45acc6a26742e8237eb65136998612820dMathieu Chartier}; 964d64cd45acc6a26742e8237eb65136998612820dMathieu Chartier 973f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertzclass Trace FINAL : public instrumentation::InstrumentationListener { 98e343b76af81a005ef64f5e75a555389fd9147dabjeffhao public: 990791adc2249366c50684935a4c42ba5e58bc3746jeffhao enum TraceFlag { 1000791adc2249366c50684935a4c42ba5e58bc3746jeffhao kTraceCountAllocs = 1, 1010791adc2249366c50684935a4c42ba5e58bc3746jeffhao }; 1020791adc2249366c50684935a4c42ba5e58bc3746jeffhao 1037e7e0f47628fb358da70c5e2766545c4f0596235Andreas Gampe enum class TraceOutputMode { 1047e7e0f47628fb358da70c5e2766545c4f0596235Andreas Gampe kFile, 10540da286d3207d88ed8ff3f5caac4873874603428Andreas Gampe kDDMS, 10640da286d3207d88ed8ff3f5caac4873874603428Andreas Gampe kStreaming 1077e7e0f47628fb358da70c5e2766545c4f0596235Andreas Gampe }; 1087e7e0f47628fb358da70c5e2766545c4f0596235Andreas Gampe 1097e7e0f47628fb358da70c5e2766545c4f0596235Andreas Gampe enum class TraceMode { 1107e7e0f47628fb358da70c5e2766545c4f0596235Andreas Gampe kMethodTracing, 1117e7e0f47628fb358da70c5e2766545c4f0596235Andreas Gampe kSampling 1127e7e0f47628fb358da70c5e2766545c4f0596235Andreas Gampe }; 1137e7e0f47628fb358da70c5e2766545c4f0596235Andreas Gampe 11440da286d3207d88ed8ff3f5caac4873874603428Andreas Gampe ~Trace(); 11540da286d3207d88ed8ff3f5caac4873874603428Andreas Gampe 116e63db27db913f1a88e2095a1ee8239b2bb9124e8Ian Rogers static void SetDefaultClockSource(TraceClockSource clock_source); 117cfbe73d02a024800813f8f0fc4f6a4b4532195f3Elliott Hughes 118e34a42cd37b2b3b6b21280df14fa6f40917b5d6eAndreas Gampe static void Start(const char* trace_filename, int trace_fd, size_t buffer_size, int flags, 1197e7e0f47628fb358da70c5e2766545c4f0596235Andreas Gampe TraceOutputMode output_mode, TraceMode trace_mode, int interval_us) 12090443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier REQUIRES(!Locks::mutator_lock_, !Locks::thread_list_lock_, !Locks::thread_suspend_count_lock_, 12190443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier !Locks::trace_lock_); 12290443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier static void Pause() REQUIRES(!Locks::trace_lock_, !Locks::thread_list_lock_); 12390443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier static void Resume() REQUIRES(!Locks::trace_lock_); 12440da286d3207d88ed8ff3f5caac4873874603428Andreas Gampe 12540da286d3207d88ed8ff3f5caac4873874603428Andreas Gampe // Stop tracing. This will finish the trace and write it to file/send it via DDMS. 126bae182cbc6adc8796154162a87fc54ae804e0469Sebastien Hertz static void Stop() 12790443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier REQUIRES(!Locks::mutator_lock_, !Locks::thread_list_lock_, !Locks::trace_lock_); 12840da286d3207d88ed8ff3f5caac4873874603428Andreas Gampe // Abort tracing. This will just stop tracing and *not* write/send the collected data. 12940da286d3207d88ed8ff3f5caac4873874603428Andreas Gampe static void Abort() 13090443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier REQUIRES(!Locks::mutator_lock_, !Locks::thread_list_lock_, !Locks::trace_lock_); 1317526d783ab68ed1dd53c763c75895cb432532b0fAndreas Gampe static void Shutdown() 13290443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier REQUIRES(!Locks::mutator_lock_, !Locks::thread_list_lock_, !Locks::trace_lock_); 13390443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier static TracingMode GetMethodTracingMode() REQUIRES(!Locks::trace_lock_); 134e343b76af81a005ef64f5e75a555389fd9147dabjeffhao 135cfbe73d02a024800813f8f0fc4f6a4b4532195f3Elliott Hughes bool UseWallClock(); 136cfbe73d02a024800813f8f0fc4f6a4b4532195f3Elliott Hughes bool UseThreadCpuClock(); 137c5d824a20c225763761a6dff43294b229ff35469Jeff Hao void MeasureClockOverhead(); 138c5d824a20c225763761a6dff43294b229ff35469Jeff Hao uint32_t GetClockOverheadNanoSeconds(); 139cfbe73d02a024800813f8f0fc4f6a4b4532195f3Elliott Hughes 140e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier void CompareAndUpdateStackTrace(Thread* thread, std::vector<ArtMethod*>* stack_trace) 141bdf7f1c3ab65ccb70f62db5ab31dba060632d458Andreas Gampe REQUIRES_SHARED(Locks::mutator_lock_) REQUIRES(!*unique_methods_lock_, !*streaming_lock_); 1420abc72ebe356c32354b575c48189965a0edc7890Jeff Hao 1433f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertz // InstrumentationListener implementation. 144d76615851af31791c7b1549e8c4609152237b9ceAlex Light void MethodEntered(Thread* thread, 145d76615851af31791c7b1549e8c4609152237b9ceAlex Light Handle<mirror::Object> this_object, 146d76615851af31791c7b1549e8c4609152237b9ceAlex Light ArtMethod* method, 147d76615851af31791c7b1549e8c4609152237b9ceAlex Light uint32_t dex_pc) 148bdf7f1c3ab65ccb70f62db5ab31dba060632d458Andreas Gampe REQUIRES_SHARED(Locks::mutator_lock_) REQUIRES(!*unique_methods_lock_, !*streaming_lock_) 14990443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier OVERRIDE; 150d76615851af31791c7b1549e8c4609152237b9ceAlex Light void MethodExited(Thread* thread, 151d76615851af31791c7b1549e8c4609152237b9ceAlex Light Handle<mirror::Object> this_object, 152d76615851af31791c7b1549e8c4609152237b9ceAlex Light ArtMethod* method, 153d76615851af31791c7b1549e8c4609152237b9ceAlex Light uint32_t dex_pc, 1543f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertz const JValue& return_value) 155bdf7f1c3ab65ccb70f62db5ab31dba060632d458Andreas Gampe REQUIRES_SHARED(Locks::mutator_lock_) REQUIRES(!*unique_methods_lock_, !*streaming_lock_) 15690443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier OVERRIDE; 157d76615851af31791c7b1549e8c4609152237b9ceAlex Light void MethodUnwind(Thread* thread, 158d76615851af31791c7b1549e8c4609152237b9ceAlex Light Handle<mirror::Object> this_object, 159d76615851af31791c7b1549e8c4609152237b9ceAlex Light ArtMethod* method, 160d76615851af31791c7b1549e8c4609152237b9ceAlex Light uint32_t dex_pc) 161bdf7f1c3ab65ccb70f62db5ab31dba060632d458Andreas Gampe REQUIRES_SHARED(Locks::mutator_lock_) REQUIRES(!*unique_methods_lock_, !*streaming_lock_) 16290443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier OVERRIDE; 163d76615851af31791c7b1549e8c4609152237b9ceAlex Light void DexPcMoved(Thread* thread, 164d76615851af31791c7b1549e8c4609152237b9ceAlex Light Handle<mirror::Object> this_object, 165d76615851af31791c7b1549e8c4609152237b9ceAlex Light ArtMethod* method, 166d76615851af31791c7b1549e8c4609152237b9ceAlex Light uint32_t new_dex_pc) 167bdf7f1c3ab65ccb70f62db5ab31dba060632d458Andreas Gampe REQUIRES_SHARED(Locks::mutator_lock_) REQUIRES(!*unique_methods_lock_, !*streaming_lock_) 16890443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier OVERRIDE; 169d76615851af31791c7b1549e8c4609152237b9ceAlex Light void FieldRead(Thread* thread, 170d76615851af31791c7b1549e8c4609152237b9ceAlex Light Handle<mirror::Object> this_object, 171d76615851af31791c7b1549e8c4609152237b9ceAlex Light ArtMethod* method, 172d76615851af31791c7b1549e8c4609152237b9ceAlex Light uint32_t dex_pc, 173d76615851af31791c7b1549e8c4609152237b9ceAlex Light ArtField* field) 174bdf7f1c3ab65ccb70f62db5ab31dba060632d458Andreas Gampe REQUIRES_SHARED(Locks::mutator_lock_) REQUIRES(!*unique_methods_lock_) OVERRIDE; 175d76615851af31791c7b1549e8c4609152237b9ceAlex Light void FieldWritten(Thread* thread, 176d76615851af31791c7b1549e8c4609152237b9ceAlex Light Handle<mirror::Object> this_object, 177d76615851af31791c7b1549e8c4609152237b9ceAlex Light ArtMethod* method, 178d76615851af31791c7b1549e8c4609152237b9ceAlex Light uint32_t dex_pc, 179d76615851af31791c7b1549e8c4609152237b9ceAlex Light ArtField* field, 1803f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertz const JValue& field_value) 181bdf7f1c3ab65ccb70f62db5ab31dba060632d458Andreas Gampe REQUIRES_SHARED(Locks::mutator_lock_) REQUIRES(!*unique_methods_lock_) OVERRIDE; 1826e1607e247d979a1671a1fd5a98de3f1031fe719Alex Light void ExceptionThrown(Thread* thread, 183d76615851af31791c7b1549e8c4609152237b9ceAlex Light Handle<mirror::Throwable> exception_object) 184bdf7f1c3ab65ccb70f62db5ab31dba060632d458Andreas Gampe REQUIRES_SHARED(Locks::mutator_lock_) REQUIRES(!*unique_methods_lock_) OVERRIDE; 185798eab03120f6189e8f6aa804d67af1b1d9f00b0Alex Light void ExceptionHandled(Thread* thread, Handle<mirror::Throwable> exception_object) 186798eab03120f6189e8f6aa804d67af1b1d9f00b0Alex Light REQUIRES_SHARED(Locks::mutator_lock_) REQUIRES(!*unique_methods_lock_) OVERRIDE; 187d76615851af31791c7b1549e8c4609152237b9ceAlex Light void Branch(Thread* thread, 188d76615851af31791c7b1549e8c4609152237b9ceAlex Light ArtMethod* method, 189d76615851af31791c7b1549e8c4609152237b9ceAlex Light uint32_t dex_pc, 190d76615851af31791c7b1549e8c4609152237b9ceAlex Light int32_t dex_pc_offset) 191bdf7f1c3ab65ccb70f62db5ab31dba060632d458Andreas Gampe REQUIRES_SHARED(Locks::mutator_lock_) REQUIRES(!*unique_methods_lock_) OVERRIDE; 1925550ca8bcc742b109d77e62f3a0877c667d894d3Nicolas Geoffray void InvokeVirtualOrInterface(Thread* thread, 193d76615851af31791c7b1549e8c4609152237b9ceAlex Light Handle<mirror::Object> this_object, 1945550ca8bcc742b109d77e62f3a0877c667d894d3Nicolas Geoffray ArtMethod* caller, 1955550ca8bcc742b109d77e62f3a0877c667d894d3Nicolas Geoffray uint32_t dex_pc, 1965550ca8bcc742b109d77e62f3a0877c667d894d3Nicolas Geoffray ArtMethod* callee) 197bdf7f1c3ab65ccb70f62db5ab31dba060632d458Andreas Gampe REQUIRES_SHARED(Locks::mutator_lock_) REQUIRES(!*unique_methods_lock_) OVERRIDE; 19805f47743e604e9b3b1de9ec930c6af6d9780c440Alex Light void WatchedFramePop(Thread* thread, const ShadowFrame& frame) 19905f47743e604e9b3b1de9ec930c6af6d9780c440Alex Light REQUIRES_SHARED(Locks::mutator_lock_) OVERRIDE; 2005ce4b178d2483df679e7f718e379305e5d42a300Jeff Hao // Reuse an old stack trace if it exists, otherwise allocate a new one. 201e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier static std::vector<ArtMethod*>* AllocStackTrace(); 2025ce4b178d2483df679e7f718e379305e5d42a300Jeff Hao // Clear and store an old stack trace for later use. 203e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier static void FreeStackTrace(std::vector<ArtMethod*>* stack_trace); 204e094b87c6f6ea9ebf83aa56a3114ac59556aaf9fJeff Hao // Save id and name of a thread before it exits. 205e094b87c6f6ea9ebf83aa56a3114ac59556aaf9fJeff Hao static void StoreExitingThreadInfo(Thread* thread); 2065ce4b178d2483df679e7f718e379305e5d42a300Jeff Hao 20790443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier static TraceOutputMode GetOutputMode() REQUIRES(!Locks::trace_lock_); 20890443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier static TraceMode GetMode() REQUIRES(!Locks::trace_lock_); 20990443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier static size_t GetBufferSize() REQUIRES(!Locks::trace_lock_); 21040da286d3207d88ed8ff3f5caac4873874603428Andreas Gampe 2117778b880b9cf46fe7a303b11477bd92b5cf65316Mathieu Chartier // Used by class linker to prevent class unloading. 2127778b880b9cf46fe7a303b11477bd92b5cf65316Mathieu Chartier static bool IsTracingEnabled() REQUIRES(!Locks::trace_lock_); 2137778b880b9cf46fe7a303b11477bd92b5cf65316Mathieu Chartier 214e343b76af81a005ef64f5e75a555389fd9147dabjeffhao private: 215e34a42cd37b2b3b6b21280df14fa6f40917b5d6eAndreas Gampe Trace(File* trace_file, const char* trace_name, size_t buffer_size, int flags, 21640da286d3207d88ed8ff3f5caac4873874603428Andreas Gampe TraceOutputMode output_mode, TraceMode trace_mode); 2172692b573a56cd63a3c8c8aa1636e3766b6d8c9c4jeffhao 21823009dca63c1699e28bfeaa8b45ca48fa0e86aceJeff Hao // The sampling interval in microseconds is passed as an argument. 21990443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier static void* RunSamplingThread(void* arg) REQUIRES(!Locks::trace_lock_); 2200abc72ebe356c32354b575c48189965a0edc7890Jeff Hao 2217526d783ab68ed1dd53c763c75895cb432532b0fAndreas Gampe static void StopTracing(bool finish_tracing, bool flush_file) 22290443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier REQUIRES(!Locks::mutator_lock_, !Locks::thread_list_lock_, !Locks::trace_lock_) 22390443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier // There is an annoying issue with static functions that create a new object and call into 22490443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier // that object that causes them to not be able to tell that we don't currently hold the lock. 22590443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier // This causes the negative annotations to incorrectly have a false positive. TODO: Figure out 22690443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier // how to annotate this. 22790443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier NO_THREAD_SAFETY_ANALYSIS; 2288a5ab9102fe705b63eda6e6bcfe98ee1c03e5a6cShukang Zhou void FinishTracing() 2298a5ab9102fe705b63eda6e6bcfe98ee1c03e5a6cShukang Zhou REQUIRES_SHARED(Locks::mutator_lock_) REQUIRES(!*unique_methods_lock_, !*streaming_lock_); 2302692b573a56cd63a3c8c8aa1636e3766b6d8c9c4jeffhao 231c1ff4b79a5d81b849203cc1e1c4a91223e75cfd3Jeff Hao void ReadClocks(Thread* thread, uint32_t* thread_clock_diff, uint32_t* wall_clock_diff); 232c1ff4b79a5d81b849203cc1e1c4a91223e75cfd3Jeff Hao 233e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier void LogMethodTraceEvent(Thread* thread, ArtMethod* method, 234c1ff4b79a5d81b849203cc1e1c4a91223e75cfd3Jeff Hao instrumentation::Instrumentation::InstrumentationEvent event, 23540da286d3207d88ed8ff3f5caac4873874603428Andreas Gampe uint32_t thread_clock_diff, uint32_t wall_clock_diff) 236bdf7f1c3ab65ccb70f62db5ab31dba060632d458Andreas Gampe REQUIRES_SHARED(Locks::mutator_lock_) REQUIRES(!*unique_methods_lock_, !*streaming_lock_); 23762d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers 238a9ef3fd82bebc6370fc3ddbb094988feb6c83022jeffhao // Methods to output traced methods and threads. 23990443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier void GetVisitedMethods(size_t end_offset, std::set<ArtMethod*>* visited_methods) 24090443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier REQUIRES(!*unique_methods_lock_); 241e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier void DumpMethodList(std::ostream& os, const std::set<ArtMethod*>& visited_methods) 242bdf7f1c3ab65ccb70f62db5ab31dba060632d458Andreas Gampe REQUIRES_SHARED(Locks::mutator_lock_) REQUIRES(!*unique_methods_lock_); 24390443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier void DumpThreadList(std::ostream& os) REQUIRES(!Locks::thread_list_lock_); 2442692b573a56cd63a3c8c8aa1636e3766b6d8c9c4jeffhao 24540da286d3207d88ed8ff3f5caac4873874603428Andreas Gampe // Methods to register seen entitites in streaming mode. The methods return true if the entity 24640da286d3207d88ed8ff3f5caac4873874603428Andreas Gampe // is newly discovered. 247e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier bool RegisterMethod(ArtMethod* method) 248bdf7f1c3ab65ccb70f62db5ab31dba060632d458Andreas Gampe REQUIRES_SHARED(Locks::mutator_lock_) REQUIRES(streaming_lock_); 24940da286d3207d88ed8ff3f5caac4873874603428Andreas Gampe bool RegisterThread(Thread* thread) 25090443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier REQUIRES(streaming_lock_); 25140da286d3207d88ed8ff3f5caac4873874603428Andreas Gampe 25240da286d3207d88ed8ff3f5caac4873874603428Andreas Gampe // Copy a temporary buffer to the main buffer. Used for streaming. Exposed here for lock 25340da286d3207d88ed8ff3f5caac4873874603428Andreas Gampe // annotation. 25440da286d3207d88ed8ff3f5caac4873874603428Andreas Gampe void WriteToBuf(const uint8_t* src, size_t src_size) 25590443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier REQUIRES(streaming_lock_); 2568a5ab9102fe705b63eda6e6bcfe98ee1c03e5a6cShukang Zhou // Flush the main buffer to file. Used for streaming. Exposed here for lock annotation. 2578a5ab9102fe705b63eda6e6bcfe98ee1c03e5a6cShukang Zhou void FlushBuf() 2588a5ab9102fe705b63eda6e6bcfe98ee1c03e5a6cShukang Zhou REQUIRES(streaming_lock_); 25940da286d3207d88ed8ff3f5caac4873874603428Andreas Gampe 26090443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier uint32_t EncodeTraceMethod(ArtMethod* method) REQUIRES(!*unique_methods_lock_); 2614d64cd45acc6a26742e8237eb65136998612820dMathieu Chartier uint32_t EncodeTraceMethodAndAction(ArtMethod* method, TraceAction action) 26290443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier REQUIRES(!*unique_methods_lock_); 26390443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier ArtMethod* DecodeTraceMethod(uint32_t tmid) REQUIRES(!*unique_methods_lock_); 26490443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier std::string GetMethodLine(ArtMethod* method) REQUIRES(!*unique_methods_lock_) 265bdf7f1c3ab65ccb70f62db5ab31dba060632d458Andreas Gampe REQUIRES_SHARED(Locks::mutator_lock_); 2664d64cd45acc6a26742e8237eb65136998612820dMathieu Chartier 2674d64cd45acc6a26742e8237eb65136998612820dMathieu Chartier void DumpBuf(uint8_t* buf, size_t buf_size, TraceClockSource clock_source) 268bdf7f1c3ab65ccb70f62db5ab31dba060632d458Andreas Gampe REQUIRES_SHARED(Locks::mutator_lock_) REQUIRES(!*unique_methods_lock_); 2694d64cd45acc6a26742e8237eb65136998612820dMathieu Chartier 2702cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier // Singleton instance of the Trace or null when no method tracing is active. 2710abc72ebe356c32354b575c48189965a0edc7890Jeff Hao static Trace* volatile the_trace_ GUARDED_BY(Locks::trace_lock_); 27262d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers 27362d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers // The default profiler clock source. 274e63db27db913f1a88e2095a1ee8239b2bb9124e8Ian Rogers static TraceClockSource default_clock_source_; 2752692b573a56cd63a3c8c8aa1636e3766b6d8c9c4jeffhao 2760abc72ebe356c32354b575c48189965a0edc7890Jeff Hao // Sampling thread, non-zero when sampling. 2770abc72ebe356c32354b575c48189965a0edc7890Jeff Hao static pthread_t sampling_pthread_; 2780abc72ebe356c32354b575c48189965a0edc7890Jeff Hao 2795ce4b178d2483df679e7f718e379305e5d42a300Jeff Hao // Used to remember an unused stack trace to avoid re-allocation during sampling. 280e401d146407d61eeb99f8d6176b2ac13c4df1e33Mathieu Chartier static std::unique_ptr<std::vector<ArtMethod*>> temp_stack_trace_; 2812692b573a56cd63a3c8c8aa1636e3766b6d8c9c4jeffhao 2822cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier // File to write trace data out to, null if direct to ddms. 283700a402244a1a423da4f3ba8032459f4b65fa18fIan Rogers std::unique_ptr<File> trace_file_; 2842692b573a56cd63a3c8c8aa1636e3766b6d8c9c4jeffhao 2852692b573a56cd63a3c8c8aa1636e3766b6d8c9c4jeffhao // Buffer to store trace data. 286241a9588c6d7d0fcb4c92da40c7141863930083aChristopher Ferris std::unique_ptr<uint8_t[]> buf_; 2872692b573a56cd63a3c8c8aa1636e3766b6d8c9c4jeffhao 2880791adc2249366c50684935a4c42ba5e58bc3746jeffhao // Flags enabling extra tracing of things such as alloc counts. 28962d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers const int flags_; 2900791adc2249366c50684935a4c42ba5e58bc3746jeffhao 29140da286d3207d88ed8ff3f5caac4873874603428Andreas Gampe // The kind of output for this tracing. 29240da286d3207d88ed8ff3f5caac4873874603428Andreas Gampe const TraceOutputMode trace_output_mode_; 29340da286d3207d88ed8ff3f5caac4873874603428Andreas Gampe 29440da286d3207d88ed8ff3f5caac4873874603428Andreas Gampe // The tracing method. 2957e7e0f47628fb358da70c5e2766545c4f0596235Andreas Gampe const TraceMode trace_mode_; 29623009dca63c1699e28bfeaa8b45ca48fa0e86aceJeff Hao 297e63db27db913f1a88e2095a1ee8239b2bb9124e8Ian Rogers const TraceClockSource clock_source_; 298cfbe73d02a024800813f8f0fc4f6a4b4532195f3Elliott Hughes 29962d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers // Size of buf_. 300e34a42cd37b2b3b6b21280df14fa6f40917b5d6eAndreas Gampe const size_t buffer_size_; 30162d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers 30262d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers // Time trace was created. 30362d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers const uint64_t start_time_; 3042692b573a56cd63a3c8c8aa1636e3766b6d8c9c4jeffhao 305c5d824a20c225763761a6dff43294b229ff35469Jeff Hao // Clock overhead. 306c5d824a20c225763761a6dff43294b229ff35469Jeff Hao const uint32_t clock_overhead_ns_; 307c5d824a20c225763761a6dff43294b229ff35469Jeff Hao 30862d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers // Offset into buf_. 3098ab25ef11aed383bf7d3aa96e95f777972d1b58fIan Rogers AtomicInteger cur_offset_; 310a9ef3fd82bebc6370fc3ddbb094988feb6c83022jeffhao 31162d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers // Did we overflow the buffer recording traces? 31262d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers bool overflow_; 31362d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers 314e094b87c6f6ea9ebf83aa56a3114ac59556aaf9fJeff Hao // Map of thread ids and names that have already exited. 315e094b87c6f6ea9ebf83aa56a3114ac59556aaf9fJeff Hao SafeMap<pid_t, std::string> exited_threads_; 316e094b87c6f6ea9ebf83aa56a3114ac59556aaf9fJeff Hao 31740da286d3207d88ed8ff3f5caac4873874603428Andreas Gampe // Sampling profiler sampling interval. 31840da286d3207d88ed8ff3f5caac4873874603428Andreas Gampe int interval_us_; 31940da286d3207d88ed8ff3f5caac4873874603428Andreas Gampe 32040da286d3207d88ed8ff3f5caac4873874603428Andreas Gampe // Streaming mode data. 32140da286d3207d88ed8ff3f5caac4873874603428Andreas Gampe std::string streaming_file_name_; 32240da286d3207d88ed8ff3f5caac4873874603428Andreas Gampe Mutex* streaming_lock_; 3237526d783ab68ed1dd53c763c75895cb432532b0fAndreas Gampe std::map<const DexFile*, DexIndexBitSet*> seen_methods_; 32440da286d3207d88ed8ff3f5caac4873874603428Andreas Gampe std::unique_ptr<ThreadIDBitSet> seen_threads_; 32540da286d3207d88ed8ff3f5caac4873874603428Andreas Gampe 3264d64cd45acc6a26742e8237eb65136998612820dMathieu Chartier // Bijective map from ArtMethod* to index. 3274d64cd45acc6a26742e8237eb65136998612820dMathieu Chartier // Map from ArtMethod* to index in unique_methods_; 3287526d783ab68ed1dd53c763c75895cb432532b0fAndreas Gampe Mutex* unique_methods_lock_ ACQUIRED_AFTER(streaming_lock_); 3294d64cd45acc6a26742e8237eb65136998612820dMathieu Chartier std::unordered_map<ArtMethod*, uint32_t> art_method_id_map_ GUARDED_BY(unique_methods_lock_); 3304d64cd45acc6a26742e8237eb65136998612820dMathieu Chartier std::vector<ArtMethod*> unique_methods_ GUARDED_BY(unique_methods_lock_); 3314d64cd45acc6a26742e8237eb65136998612820dMathieu Chartier 332e343b76af81a005ef64f5e75a555389fd9147dabjeffhao DISALLOW_COPY_AND_ASSIGN(Trace); 333e343b76af81a005ef64f5e75a555389fd9147dabjeffhao}; 334e343b76af81a005ef64f5e75a555389fd9147dabjeffhao 335e343b76af81a005ef64f5e75a555389fd9147dabjeffhao} // namespace art 336e343b76af81a005ef64f5e75a555389fd9147dabjeffhao 337fc0e3219edc9a5bf81b166e82fd5db2796eb6a0dBrian Carlstrom#endif // ART_RUNTIME_TRACE_H_ 338