• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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