trace.h revision c7c6d18a90079b67a7592d3f2cb3d4c6f0081512
1/* 2 * Copyright (C) 2011 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17#ifndef ART_RUNTIME_TRACE_H_ 18#define ART_RUNTIME_TRACE_H_ 19 20#include <memory> 21#include <ostream> 22#include <set> 23#include <string> 24#include <vector> 25 26#include "atomic.h" 27#include "base/macros.h" 28#include "globals.h" 29#include "instrumentation.h" 30#include "os.h" 31#include "safe_map.h" 32 33namespace art { 34 35namespace mirror { 36 class ArtField; 37 class ArtMethod; 38} // namespace mirror 39class Thread; 40 41enum ProfilerClockSource { 42 kProfilerClockSourceThreadCpu, 43 kProfilerClockSourceWall, 44 kProfilerClockSourceDual, // Both wall and thread CPU clocks. 45}; 46 47#if defined(HAVE_POSIX_CLOCKS) 48const ProfilerClockSource kDefaultProfilerClockSource = kProfilerClockSourceDual; 49#else 50const ProfilerClockSource kDefaultProfilerClockSource = kProfilerClockSourceWall; 51#endif 52 53enum TracingMode { 54 kTracingInactive, 55 kMethodTracingActive, 56 kSampleProfilingActive, 57}; 58 59class Trace FINAL : public instrumentation::InstrumentationListener { 60 public: 61 enum TraceFlag { 62 kTraceCountAllocs = 1, 63 }; 64 65 static void SetDefaultClockSource(ProfilerClockSource clock_source); 66 67 static void Start(const char* trace_filename, int trace_fd, int buffer_size, int flags, 68 bool direct_to_ddms, bool sampling_enabled, int interval_us) 69 LOCKS_EXCLUDED(Locks::mutator_lock_, 70 Locks::thread_list_lock_, 71 Locks::thread_suspend_count_lock_, 72 Locks::trace_lock_); 73 static void Stop() 74 LOCKS_EXCLUDED(Locks::mutator_lock_, 75 Locks::thread_list_lock_, 76 Locks::trace_lock_); 77 static void Shutdown() LOCKS_EXCLUDED(Locks::trace_lock_); 78 static TracingMode GetMethodTracingMode() LOCKS_EXCLUDED(Locks::trace_lock_); 79 80 bool UseWallClock(); 81 bool UseThreadCpuClock(); 82 void MeasureClockOverhead(); 83 uint32_t GetClockOverheadNanoSeconds(); 84 85 void CompareAndUpdateStackTrace(Thread* thread, std::vector<mirror::ArtMethod*>* stack_trace) 86 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 87 88 // InstrumentationListener implementation. 89 void MethodEntered(Thread* thread, mirror::Object* this_object, 90 mirror::ArtMethod* method, uint32_t dex_pc) 91 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) OVERRIDE; 92 void MethodExited(Thread* thread, mirror::Object* this_object, 93 mirror::ArtMethod* method, uint32_t dex_pc, 94 const JValue& return_value) 95 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) OVERRIDE; 96 void MethodUnwind(Thread* thread, mirror::Object* this_object, 97 mirror::ArtMethod* method, uint32_t dex_pc) 98 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) OVERRIDE; 99 void DexPcMoved(Thread* thread, mirror::Object* this_object, 100 mirror::ArtMethod* method, uint32_t new_dex_pc) 101 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) OVERRIDE; 102 void FieldRead(Thread* thread, mirror::Object* this_object, 103 mirror::ArtMethod* method, uint32_t dex_pc, mirror::ArtField* field) 104 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) OVERRIDE; 105 void FieldWritten(Thread* thread, mirror::Object* this_object, 106 mirror::ArtMethod* method, uint32_t dex_pc, mirror::ArtField* field, 107 const JValue& field_value) 108 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) OVERRIDE; 109 void ExceptionCaught(Thread* thread, const ThrowLocation& throw_location, 110 mirror::ArtMethod* catch_method, uint32_t catch_dex_pc, 111 mirror::Throwable* exception_object) 112 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) OVERRIDE; 113 114 // Reuse an old stack trace if it exists, otherwise allocate a new one. 115 static std::vector<mirror::ArtMethod*>* AllocStackTrace(); 116 // Clear and store an old stack trace for later use. 117 static void FreeStackTrace(std::vector<mirror::ArtMethod*>* stack_trace); 118 119 private: 120 explicit Trace(File* trace_file, int buffer_size, int flags, bool sampling_enabled); 121 122 // The sampling interval in microseconds is passed as an argument. 123 static void* RunSamplingThread(void* arg) LOCKS_EXCLUDED(Locks::trace_lock_); 124 125 void FinishTracing() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 126 127 void ReadClocks(Thread* thread, uint32_t* thread_clock_diff, uint32_t* wall_clock_diff); 128 129 void LogMethodTraceEvent(Thread* thread, mirror::ArtMethod* method, 130 instrumentation::Instrumentation::InstrumentationEvent event, 131 uint32_t thread_clock_diff, uint32_t wall_clock_diff); 132 133 // Methods to output traced methods and threads. 134 void GetVisitedMethods(size_t end_offset, std::set<mirror::ArtMethod*>* visited_methods); 135 void DumpMethodList(std::ostream& os, const std::set<mirror::ArtMethod*>& visited_methods) 136 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 137 void DumpThreadList(std::ostream& os) LOCKS_EXCLUDED(Locks::thread_list_lock_); 138 139 // Singleton instance of the Trace or NULL when no method tracing is active. 140 static Trace* volatile the_trace_ GUARDED_BY(Locks::trace_lock_); 141 142 // The default profiler clock source. 143 static ProfilerClockSource default_clock_source_; 144 145 // Sampling thread, non-zero when sampling. 146 static pthread_t sampling_pthread_; 147 148 // Used to remember an unused stack trace to avoid re-allocation during sampling. 149 static std::unique_ptr<std::vector<mirror::ArtMethod*>> temp_stack_trace_; 150 151 // File to write trace data out to, NULL if direct to ddms. 152 std::unique_ptr<File> trace_file_; 153 154 // Buffer to store trace data. 155 std::unique_ptr<uint8_t> buf_; 156 157 // Flags enabling extra tracing of things such as alloc counts. 158 const int flags_; 159 160 // True if traceview should sample instead of instrumenting method entry/exit. 161 const bool sampling_enabled_; 162 163 const ProfilerClockSource clock_source_; 164 165 // Size of buf_. 166 const int buffer_size_; 167 168 // Time trace was created. 169 const uint64_t start_time_; 170 171 // Clock overhead. 172 const uint32_t clock_overhead_ns_; 173 174 // Offset into buf_. 175 AtomicInteger cur_offset_; 176 177 // Did we overflow the buffer recording traces? 178 bool overflow_; 179 180 DISALLOW_COPY_AND_ASSIGN(Trace); 181}; 182 183} // namespace art 184 185#endif // ART_RUNTIME_TRACE_H_ 186