trace.h revision 700a402244a1a423da4f3ba8032459f4b65fa18f
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 "base/macros.h" 27#include "globals.h" 28#include "instrumentation.h" 29#include "os.h" 30#include "safe_map.h" 31 32namespace art { 33 34namespace mirror { 35 class ArtField; 36 class ArtMethod; 37} // namespace mirror 38class Thread; 39 40enum ProfilerClockSource { 41 kProfilerClockSourceThreadCpu, 42 kProfilerClockSourceWall, 43 kProfilerClockSourceDual, // Both wall and thread CPU clocks. 44}; 45 46#if defined(HAVE_POSIX_CLOCKS) 47const ProfilerClockSource kDefaultProfilerClockSource = kProfilerClockSourceDual; 48#else 49const ProfilerClockSource kDefaultProfilerClockSource = kProfilerClockSourceWall; 50#endif 51 52enum TracingMode { 53 kTracingInactive, 54 kMethodTracingActive, 55 kSampleProfilingActive, 56}; 57 58class Trace FINAL : public instrumentation::InstrumentationListener { 59 public: 60 enum TraceFlag { 61 kTraceCountAllocs = 1, 62 }; 63 64 static void SetDefaultClockSource(ProfilerClockSource clock_source); 65 66 static void Start(const char* trace_filename, int trace_fd, int buffer_size, int flags, 67 bool direct_to_ddms, bool sampling_enabled, int interval_us) 68 LOCKS_EXCLUDED(Locks::mutator_lock_, 69 Locks::thread_list_lock_, 70 Locks::thread_suspend_count_lock_, 71 Locks::trace_lock_); 72 static void Stop() LOCKS_EXCLUDED(Locks::trace_lock_); 73 static void Shutdown() LOCKS_EXCLUDED(Locks::trace_lock_); 74 static TracingMode GetMethodTracingMode() LOCKS_EXCLUDED(Locks::trace_lock_); 75 76 bool UseWallClock(); 77 bool UseThreadCpuClock(); 78 79 void CompareAndUpdateStackTrace(Thread* thread, std::vector<mirror::ArtMethod*>* stack_trace) 80 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 81 82 // InstrumentationListener implementation. 83 void MethodEntered(Thread* thread, mirror::Object* this_object, 84 mirror::ArtMethod* method, uint32_t dex_pc) 85 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) OVERRIDE; 86 void MethodExited(Thread* thread, mirror::Object* this_object, 87 mirror::ArtMethod* method, uint32_t dex_pc, 88 const JValue& return_value) 89 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) OVERRIDE; 90 void MethodUnwind(Thread* thread, mirror::Object* this_object, 91 mirror::ArtMethod* method, uint32_t dex_pc) 92 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) OVERRIDE; 93 void DexPcMoved(Thread* thread, mirror::Object* this_object, 94 mirror::ArtMethod* method, uint32_t new_dex_pc) 95 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) OVERRIDE; 96 void FieldRead(Thread* thread, mirror::Object* this_object, 97 mirror::ArtMethod* method, uint32_t dex_pc, mirror::ArtField* field) 98 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) OVERRIDE; 99 void FieldWritten(Thread* thread, mirror::Object* this_object, 100 mirror::ArtMethod* method, uint32_t dex_pc, mirror::ArtField* field, 101 const JValue& field_value) 102 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) OVERRIDE; 103 void ExceptionCaught(Thread* thread, const ThrowLocation& throw_location, 104 mirror::ArtMethod* catch_method, uint32_t catch_dex_pc, 105 mirror::Throwable* exception_object) 106 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) OVERRIDE; 107 108 // Reuse an old stack trace if it exists, otherwise allocate a new one. 109 static std::vector<mirror::ArtMethod*>* AllocStackTrace(); 110 // Clear and store an old stack trace for later use. 111 static void FreeStackTrace(std::vector<mirror::ArtMethod*>* stack_trace); 112 113 private: 114 explicit Trace(File* trace_file, int buffer_size, int flags, bool sampling_enabled); 115 116 // The sampling interval in microseconds is passed as an argument. 117 static void* RunSamplingThread(void* arg) LOCKS_EXCLUDED(Locks::trace_lock_); 118 119 void FinishTracing() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 120 121 void ReadClocks(Thread* thread, uint32_t* thread_clock_diff, uint32_t* wall_clock_diff); 122 123 void LogMethodTraceEvent(Thread* thread, mirror::ArtMethod* method, 124 instrumentation::Instrumentation::InstrumentationEvent event, 125 uint32_t thread_clock_diff, uint32_t wall_clock_diff); 126 127 // Methods to output traced methods and threads. 128 void GetVisitedMethods(size_t end_offset, std::set<mirror::ArtMethod*>* visited_methods); 129 void DumpMethodList(std::ostream& os, const std::set<mirror::ArtMethod*>& visited_methods) 130 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 131 void DumpThreadList(std::ostream& os) LOCKS_EXCLUDED(Locks::thread_list_lock_); 132 133 // Singleton instance of the Trace or NULL when no method tracing is active. 134 static Trace* volatile the_trace_ GUARDED_BY(Locks::trace_lock_); 135 136 // The default profiler clock source. 137 static ProfilerClockSource default_clock_source_; 138 139 // Sampling thread, non-zero when sampling. 140 static pthread_t sampling_pthread_; 141 142 // Used to remember an unused stack trace to avoid re-allocation during sampling. 143 static std::unique_ptr<std::vector<mirror::ArtMethod*>> temp_stack_trace_; 144 145 // File to write trace data out to, NULL if direct to ddms. 146 std::unique_ptr<File> trace_file_; 147 148 // Buffer to store trace data. 149 std::unique_ptr<uint8_t> buf_; 150 151 // Flags enabling extra tracing of things such as alloc counts. 152 const int flags_; 153 154 // True if traceview should sample instead of instrumenting method entry/exit. 155 const bool sampling_enabled_; 156 157 const ProfilerClockSource clock_source_; 158 159 // Size of buf_. 160 const int buffer_size_; 161 162 // Time trace was created. 163 const uint64_t start_time_; 164 165 // Offset into buf_. 166 volatile int32_t cur_offset_; 167 168 // Did we overflow the buffer recording traces? 169 bool overflow_; 170 171 DISALLOW_COPY_AND_ASSIGN(Trace); 172}; 173 174} // namespace art 175 176#endif // ART_RUNTIME_TRACE_H_ 177