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 108 private: 109 explicit Trace(File* trace_file, int buffer_size, int flags, bool sampling_enabled); 110 111 // The sampling interval in microseconds is passed as an argument. 112 static void* RunSamplingThread(void* arg) LOCKS_EXCLUDED(Locks::trace_lock_); 113 114 void FinishTracing() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 115 116 void ReadClocks(Thread* thread, uint32_t* thread_clock_diff, uint32_t* wall_clock_diff); 117 118 void LogMethodTraceEvent(Thread* thread, mirror::ArtMethod* method, 119 instrumentation::Instrumentation::InstrumentationEvent event, 120 uint32_t thread_clock_diff, uint32_t wall_clock_diff); 121 122 // Methods to output traced methods and threads. 123 void GetVisitedMethods(size_t end_offset, std::set<mirror::ArtMethod*>* visited_methods); 124 void DumpMethodList(std::ostream& os, const std::set<mirror::ArtMethod*>& visited_methods) 125 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 126 void DumpThreadList(std::ostream& os) LOCKS_EXCLUDED(Locks::thread_list_lock_); 127 128 // Singleton instance of the Trace or NULL when no method tracing is active. 129 static Trace* volatile the_trace_ GUARDED_BY(Locks::trace_lock_); 130 131 // The default profiler clock source. 132 static TraceClockSource default_clock_source_; 133 134 // Sampling thread, non-zero when sampling. 135 static pthread_t sampling_pthread_; 136 137 // Used to remember an unused stack trace to avoid re-allocation during sampling. 138 static std::unique_ptr<std::vector<mirror::ArtMethod*>> temp_stack_trace_; 139 140 // File to write trace data out to, NULL if direct to ddms. 141 std::unique_ptr<File> trace_file_; 142 143 // Buffer to store trace data. 144 std::unique_ptr<uint8_t> buf_; 145 146 // Flags enabling extra tracing of things such as alloc counts. 147 const int flags_; 148 149 // True if traceview should sample instead of instrumenting method entry/exit. 150 const bool sampling_enabled_; 151 152 const TraceClockSource clock_source_; 153 154 // Size of buf_. 155 const int buffer_size_; 156 157 // Time trace was created. 158 const uint64_t start_time_; 159 160 // Clock overhead. 161 const uint32_t clock_overhead_ns_; 162 163 // Offset into buf_. 164 AtomicInteger cur_offset_; 165 166 // Did we overflow the buffer recording traces? 167 bool overflow_; 168 169 DISALLOW_COPY_AND_ASSIGN(Trace); 170 }; 171 172 } // namespace art 173 174 #endif // ART_RUNTIME_TRACE_H_ 175