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