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