Home | History | Annotate | Download | only in runtime
      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