• 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 <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