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   // Save id and name of a thread before it exits.
    108   static void StoreExitingThreadInfo(Thread* thread);
    109 
    110  private:
    111   explicit Trace(File* trace_file, int buffer_size, int flags, bool sampling_enabled);
    112 
    113   // The sampling interval in microseconds is passed as an argument.
    114   static void* RunSamplingThread(void* arg) LOCKS_EXCLUDED(Locks::trace_lock_);
    115 
    116   void FinishTracing() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
    117 
    118   void ReadClocks(Thread* thread, uint32_t* thread_clock_diff, uint32_t* wall_clock_diff);
    119 
    120   void LogMethodTraceEvent(Thread* thread, mirror::ArtMethod* method,
    121                            instrumentation::Instrumentation::InstrumentationEvent event,
    122                            uint32_t thread_clock_diff, uint32_t wall_clock_diff);
    123 
    124   // Methods to output traced methods and threads.
    125   void GetVisitedMethods(size_t end_offset, std::set<mirror::ArtMethod*>* visited_methods);
    126   void DumpMethodList(std::ostream& os, const std::set<mirror::ArtMethod*>& visited_methods)
    127       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
    128   void DumpThreadList(std::ostream& os) LOCKS_EXCLUDED(Locks::thread_list_lock_);
    129 
    130   // Singleton instance of the Trace or NULL when no method tracing is active.
    131   static Trace* volatile the_trace_ GUARDED_BY(Locks::trace_lock_);
    132 
    133   // The default profiler clock source.
    134   static TraceClockSource default_clock_source_;
    135 
    136   // Sampling thread, non-zero when sampling.
    137   static pthread_t sampling_pthread_;
    138 
    139   // Used to remember an unused stack trace to avoid re-allocation during sampling.
    140   static std::unique_ptr<std::vector<mirror::ArtMethod*>> temp_stack_trace_;
    141 
    142   // File to write trace data out to, NULL if direct to ddms.
    143   std::unique_ptr<File> trace_file_;
    144 
    145   // Buffer to store trace data.
    146   std::unique_ptr<uint8_t> buf_;
    147 
    148   // Flags enabling extra tracing of things such as alloc counts.
    149   const int flags_;
    150 
    151   // True if traceview should sample instead of instrumenting method entry/exit.
    152   const bool sampling_enabled_;
    153 
    154   const TraceClockSource clock_source_;
    155 
    156   // Size of buf_.
    157   const int buffer_size_;
    158 
    159   // Time trace was created.
    160   const uint64_t start_time_;
    161 
    162   // Clock overhead.
    163   const uint32_t clock_overhead_ns_;
    164 
    165   // Offset into buf_.
    166   AtomicInteger cur_offset_;
    167 
    168   // Did we overflow the buffer recording traces?
    169   bool overflow_;
    170 
    171   // Map of thread ids and names that have already exited.
    172   SafeMap<pid_t, std::string> exited_threads_;
    173 
    174   DISALLOW_COPY_AND_ASSIGN(Trace);
    175 };
    176 
    177 }  // namespace art
    178 
    179 #endif  // ART_RUNTIME_TRACE_H_
    180