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