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