trace.h revision c5d824a20c225763761a6dff43294b229ff35469
12faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes/*
22faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * Copyright (C) 2011 The Android Open Source Project
32faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes *
42faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * Licensed under the Apache License, Version 2.0 (the "License");
52faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * you may not use this file except in compliance with the License.
62faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * You may obtain a copy of the License at
72faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes *
82faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes *      http://www.apache.org/licenses/LICENSE-2.0
92faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes *
102faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * Unless required by applicable law or agreed to in writing, software
112faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * distributed under the License is distributed on an "AS IS" BASIS,
122faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
132faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * See the License for the specific language governing permissions and
142faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes * limitations under the License.
152faa5f1271587cda765f26bcf2951065300a01ffElliott Hughes */
16e343b76af81a005ef64f5e75a555389fd9147dabjeffhao
17fc0e3219edc9a5bf81b166e82fd5db2796eb6a0dBrian Carlstrom#ifndef ART_RUNTIME_TRACE_H_
18fc0e3219edc9a5bf81b166e82fd5db2796eb6a0dBrian Carlstrom#define ART_RUNTIME_TRACE_H_
19e343b76af81a005ef64f5e75a555389fd9147dabjeffhao
20700a402244a1a423da4f3ba8032459f4b65fa18fIan Rogers#include <memory>
21a9ef3fd82bebc6370fc3ddbb094988feb6c83022jeffhao#include <ostream>
22a9ef3fd82bebc6370fc3ddbb094988feb6c83022jeffhao#include <set>
23a9ef3fd82bebc6370fc3ddbb094988feb6c83022jeffhao#include <string>
240abc72ebe356c32354b575c48189965a0edc7890Jeff Hao#include <vector>
25e343b76af81a005ef64f5e75a555389fd9147dabjeffhao
268ab25ef11aed383bf7d3aa96e95f777972d1b58fIan Rogers#include "atomic.h"
27761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes#include "base/macros.h"
28e343b76af81a005ef64f5e75a555389fd9147dabjeffhao#include "globals.h"
2962d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers#include "instrumentation.h"
30761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes#include "os.h"
31a0e180632411f7fe0edf454e571c42209ee7b540Elliott Hughes#include "safe_map.h"
32e343b76af81a005ef64f5e75a555389fd9147dabjeffhao
33e343b76af81a005ef64f5e75a555389fd9147dabjeffhaonamespace art {
34e343b76af81a005ef64f5e75a555389fd9147dabjeffhao
352dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogersnamespace mirror {
363f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertz  class ArtField;
37ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom  class ArtMethod;
382dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers}  // namespace mirror
39cfbe73d02a024800813f8f0fc4f6a4b4532195f3Elliott Hughes
40e63db27db913f1a88e2095a1ee8239b2bb9124e8Ian Rogersclass Thread;
41491ca9e75fad381468dd7f5fdbff56d1a9738dd7Brian Carlstrom
4264caa7dcf46ed6139b766dbe77fbd7353899417fJeff Haoenum TracingMode {
4364caa7dcf46ed6139b766dbe77fbd7353899417fJeff Hao  kTracingInactive,
4464caa7dcf46ed6139b766dbe77fbd7353899417fJeff Hao  kMethodTracingActive,
4564caa7dcf46ed6139b766dbe77fbd7353899417fJeff Hao  kSampleProfilingActive,
4664caa7dcf46ed6139b766dbe77fbd7353899417fJeff Hao};
4764caa7dcf46ed6139b766dbe77fbd7353899417fJeff Hao
483f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertzclass Trace FINAL : public instrumentation::InstrumentationListener {
49e343b76af81a005ef64f5e75a555389fd9147dabjeffhao public:
500791adc2249366c50684935a4c42ba5e58bc3746jeffhao  enum TraceFlag {
510791adc2249366c50684935a4c42ba5e58bc3746jeffhao    kTraceCountAllocs = 1,
520791adc2249366c50684935a4c42ba5e58bc3746jeffhao  };
530791adc2249366c50684935a4c42ba5e58bc3746jeffhao
54e63db27db913f1a88e2095a1ee8239b2bb9124e8Ian Rogers  static void SetDefaultClockSource(TraceClockSource clock_source);
55cfbe73d02a024800813f8f0fc4f6a4b4532195f3Elliott Hughes
5662d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers  static void Start(const char* trace_filename, int trace_fd, int buffer_size, int flags,
5723009dca63c1699e28bfeaa8b45ca48fa0e86aceJeff Hao                    bool direct_to_ddms, bool sampling_enabled, int interval_us)
58bae182cbc6adc8796154162a87fc54ae804e0469Sebastien Hertz      LOCKS_EXCLUDED(Locks::mutator_lock_,
59bae182cbc6adc8796154162a87fc54ae804e0469Sebastien Hertz                     Locks::thread_list_lock_,
60bae182cbc6adc8796154162a87fc54ae804e0469Sebastien Hertz                     Locks::thread_suspend_count_lock_,
61bae182cbc6adc8796154162a87fc54ae804e0469Sebastien Hertz                     Locks::trace_lock_);
62bae182cbc6adc8796154162a87fc54ae804e0469Sebastien Hertz  static void Stop()
63bae182cbc6adc8796154162a87fc54ae804e0469Sebastien Hertz      LOCKS_EXCLUDED(Locks::mutator_lock_,
64bae182cbc6adc8796154162a87fc54ae804e0469Sebastien Hertz                     Locks::thread_list_lock_,
65bae182cbc6adc8796154162a87fc54ae804e0469Sebastien Hertz                     Locks::trace_lock_);
6662d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers  static void Shutdown() LOCKS_EXCLUDED(Locks::trace_lock_);
6764caa7dcf46ed6139b766dbe77fbd7353899417fJeff Hao  static TracingMode GetMethodTracingMode() LOCKS_EXCLUDED(Locks::trace_lock_);
68e343b76af81a005ef64f5e75a555389fd9147dabjeffhao
69cfbe73d02a024800813f8f0fc4f6a4b4532195f3Elliott Hughes  bool UseWallClock();
70cfbe73d02a024800813f8f0fc4f6a4b4532195f3Elliott Hughes  bool UseThreadCpuClock();
71c5d824a20c225763761a6dff43294b229ff35469Jeff Hao  void MeasureClockOverhead();
72c5d824a20c225763761a6dff43294b229ff35469Jeff Hao  uint32_t GetClockOverheadNanoSeconds();
73cfbe73d02a024800813f8f0fc4f6a4b4532195f3Elliott Hughes
74e2f77e7592842cad5a59e73535b8982c35e156caIan Rogers  void CompareAndUpdateStackTrace(Thread* thread, std::vector<mirror::ArtMethod*>* stack_trace)
750abc72ebe356c32354b575c48189965a0edc7890Jeff Hao      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
760abc72ebe356c32354b575c48189965a0edc7890Jeff Hao
773f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertz  // InstrumentationListener implementation.
783f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertz  void MethodEntered(Thread* thread, mirror::Object* this_object,
793f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertz                     mirror::ArtMethod* method, uint32_t dex_pc)
803f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertz      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) OVERRIDE;
813f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertz  void MethodExited(Thread* thread, mirror::Object* this_object,
823f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertz                    mirror::ArtMethod* method, uint32_t dex_pc,
833f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertz                    const JValue& return_value)
843f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertz      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) OVERRIDE;
853f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertz  void MethodUnwind(Thread* thread, mirror::Object* this_object,
863f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertz                    mirror::ArtMethod* method, uint32_t dex_pc)
873f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertz      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) OVERRIDE;
883f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertz  void DexPcMoved(Thread* thread, mirror::Object* this_object,
893f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertz                  mirror::ArtMethod* method, uint32_t new_dex_pc)
903f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertz      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) OVERRIDE;
913f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertz  void FieldRead(Thread* thread, mirror::Object* this_object,
923f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertz                 mirror::ArtMethod* method, uint32_t dex_pc, mirror::ArtField* field)
933f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertz      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) OVERRIDE;
943f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertz  void FieldWritten(Thread* thread, mirror::Object* this_object,
953f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertz                    mirror::ArtMethod* method, uint32_t dex_pc, mirror::ArtField* field,
963f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertz                    const JValue& field_value)
973f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertz      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) OVERRIDE;
983f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertz  void ExceptionCaught(Thread* thread, const ThrowLocation& throw_location,
993f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertz                       mirror::ArtMethod* catch_method, uint32_t catch_dex_pc,
1003f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertz                       mirror::Throwable* exception_object)
1013f52eafe5577b8489f90dc8ed5981b3455206147Sebastien Hertz      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) OVERRIDE;
1020cd7ec2dcd8d7ba30bf3ca420b40dac52849876cBrian Carlstrom
1035ce4b178d2483df679e7f718e379305e5d42a300Jeff Hao  // Reuse an old stack trace if it exists, otherwise allocate a new one.
1045ce4b178d2483df679e7f718e379305e5d42a300Jeff Hao  static std::vector<mirror::ArtMethod*>* AllocStackTrace();
1055ce4b178d2483df679e7f718e379305e5d42a300Jeff Hao  // Clear and store an old stack trace for later use.
1065ce4b178d2483df679e7f718e379305e5d42a300Jeff Hao  static void FreeStackTrace(std::vector<mirror::ArtMethod*>* stack_trace);
1075ce4b178d2483df679e7f718e379305e5d42a300Jeff Hao
108e343b76af81a005ef64f5e75a555389fd9147dabjeffhao private:
10923009dca63c1699e28bfeaa8b45ca48fa0e86aceJeff Hao  explicit Trace(File* trace_file, int buffer_size, int flags, bool sampling_enabled);
1102692b573a56cd63a3c8c8aa1636e3766b6d8c9c4jeffhao
11123009dca63c1699e28bfeaa8b45ca48fa0e86aceJeff Hao  // The sampling interval in microseconds is passed as an argument.
1120abc72ebe356c32354b575c48189965a0edc7890Jeff Hao  static void* RunSamplingThread(void* arg) LOCKS_EXCLUDED(Locks::trace_lock_);
1130abc72ebe356c32354b575c48189965a0edc7890Jeff Hao
114b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers  void FinishTracing() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
1152692b573a56cd63a3c8c8aa1636e3766b6d8c9c4jeffhao
116c1ff4b79a5d81b849203cc1e1c4a91223e75cfd3Jeff Hao  void ReadClocks(Thread* thread, uint32_t* thread_clock_diff, uint32_t* wall_clock_diff);
117c1ff4b79a5d81b849203cc1e1c4a91223e75cfd3Jeff Hao
118ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers  void LogMethodTraceEvent(Thread* thread, mirror::ArtMethod* method,
119c1ff4b79a5d81b849203cc1e1c4a91223e75cfd3Jeff Hao                           instrumentation::Instrumentation::InstrumentationEvent event,
120c1ff4b79a5d81b849203cc1e1c4a91223e75cfd3Jeff Hao                           uint32_t thread_clock_diff, uint32_t wall_clock_diff);
12162d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers
122a9ef3fd82bebc6370fc3ddbb094988feb6c83022jeffhao  // Methods to output traced methods and threads.
123ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom  void GetVisitedMethods(size_t end_offset, std::set<mirror::ArtMethod*>* visited_methods);
124ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom  void DumpMethodList(std::ostream& os, const std::set<mirror::ArtMethod*>& visited_methods)
12562d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
126b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers  void DumpThreadList(std::ostream& os) LOCKS_EXCLUDED(Locks::thread_list_lock_);
1272692b573a56cd63a3c8c8aa1636e3766b6d8c9c4jeffhao
12862d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers  // Singleton instance of the Trace or NULL when no method tracing is active.
1290abc72ebe356c32354b575c48189965a0edc7890Jeff Hao  static Trace* volatile the_trace_ GUARDED_BY(Locks::trace_lock_);
13062d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers
13162d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers  // The default profiler clock source.
132e63db27db913f1a88e2095a1ee8239b2bb9124e8Ian Rogers  static TraceClockSource default_clock_source_;
1332692b573a56cd63a3c8c8aa1636e3766b6d8c9c4jeffhao
1340abc72ebe356c32354b575c48189965a0edc7890Jeff Hao  // Sampling thread, non-zero when sampling.
1350abc72ebe356c32354b575c48189965a0edc7890Jeff Hao  static pthread_t sampling_pthread_;
1360abc72ebe356c32354b575c48189965a0edc7890Jeff Hao
1375ce4b178d2483df679e7f718e379305e5d42a300Jeff Hao  // Used to remember an unused stack trace to avoid re-allocation during sampling.
138700a402244a1a423da4f3ba8032459f4b65fa18fIan Rogers  static std::unique_ptr<std::vector<mirror::ArtMethod*>> temp_stack_trace_;
1392692b573a56cd63a3c8c8aa1636e3766b6d8c9c4jeffhao
1402692b573a56cd63a3c8c8aa1636e3766b6d8c9c4jeffhao  // File to write trace data out to, NULL if direct to ddms.
141700a402244a1a423da4f3ba8032459f4b65fa18fIan Rogers  std::unique_ptr<File> trace_file_;
1422692b573a56cd63a3c8c8aa1636e3766b6d8c9c4jeffhao
1432692b573a56cd63a3c8c8aa1636e3766b6d8c9c4jeffhao  // Buffer to store trace data.
144700a402244a1a423da4f3ba8032459f4b65fa18fIan Rogers  std::unique_ptr<uint8_t> buf_;
1452692b573a56cd63a3c8c8aa1636e3766b6d8c9c4jeffhao
1460791adc2249366c50684935a4c42ba5e58bc3746jeffhao  // Flags enabling extra tracing of things such as alloc counts.
14762d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers  const int flags_;
1480791adc2249366c50684935a4c42ba5e58bc3746jeffhao
14923009dca63c1699e28bfeaa8b45ca48fa0e86aceJeff Hao  // True if traceview should sample instead of instrumenting method entry/exit.
15023009dca63c1699e28bfeaa8b45ca48fa0e86aceJeff Hao  const bool sampling_enabled_;
15123009dca63c1699e28bfeaa8b45ca48fa0e86aceJeff Hao
152e63db27db913f1a88e2095a1ee8239b2bb9124e8Ian Rogers  const TraceClockSource clock_source_;
153cfbe73d02a024800813f8f0fc4f6a4b4532195f3Elliott Hughes
15462d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers  // Size of buf_.
15562d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers  const int buffer_size_;
15662d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers
15762d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers  // Time trace was created.
15862d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers  const uint64_t start_time_;
1592692b573a56cd63a3c8c8aa1636e3766b6d8c9c4jeffhao
160c5d824a20c225763761a6dff43294b229ff35469Jeff Hao  // Clock overhead.
161c5d824a20c225763761a6dff43294b229ff35469Jeff Hao  const uint32_t clock_overhead_ns_;
162c5d824a20c225763761a6dff43294b229ff35469Jeff Hao
16362d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers  // Offset into buf_.
1648ab25ef11aed383bf7d3aa96e95f777972d1b58fIan Rogers  AtomicInteger cur_offset_;
165a9ef3fd82bebc6370fc3ddbb094988feb6c83022jeffhao
16662d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers  // Did we overflow the buffer recording traces?
16762d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers  bool overflow_;
16862d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers
169e343b76af81a005ef64f5e75a555389fd9147dabjeffhao  DISALLOW_COPY_AND_ASSIGN(Trace);
170e343b76af81a005ef64f5e75a555389fd9147dabjeffhao};
171e343b76af81a005ef64f5e75a555389fd9147dabjeffhao
172e343b76af81a005ef64f5e75a555389fd9147dabjeffhao}  // namespace art
173e343b76af81a005ef64f5e75a555389fd9147dabjeffhao
174fc0e3219edc9a5bf81b166e82fd5db2796eb6a0dBrian Carlstrom#endif  // ART_RUNTIME_TRACE_H_
175