trace.h revision c1ff4b79a5d81b849203cc1e1c4a91223e75cfd3
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
20a9ef3fd82bebc6370fc3ddbb094988feb6c83022jeffhao#include <ostream>
21a9ef3fd82bebc6370fc3ddbb094988feb6c83022jeffhao#include <set>
22a9ef3fd82bebc6370fc3ddbb094988feb6c83022jeffhao#include <string>
230abc72ebe356c32354b575c48189965a0edc7890Jeff Hao#include <vector>
24e343b76af81a005ef64f5e75a555389fd9147dabjeffhao
25761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes#include "base/macros.h"
26e343b76af81a005ef64f5e75a555389fd9147dabjeffhao#include "globals.h"
2762d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers#include "instrumentation.h"
28761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes#include "os.h"
29a0e180632411f7fe0edf454e571c42209ee7b540Elliott Hughes#include "safe_map.h"
302692b573a56cd63a3c8c8aa1636e3766b6d8c9c4jeffhao#include "UniquePtr.h"
31e343b76af81a005ef64f5e75a555389fd9147dabjeffhao
32e343b76af81a005ef64f5e75a555389fd9147dabjeffhaonamespace art {
33e343b76af81a005ef64f5e75a555389fd9147dabjeffhao
342dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogersnamespace mirror {
35ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom  class ArtMethod;
362dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers}  // namespace mirror
37a9ef3fd82bebc6370fc3ddbb094988feb6c83022jeffhaoclass Thread;
38e343b76af81a005ef64f5e75a555389fd9147dabjeffhao
39cfbe73d02a024800813f8f0fc4f6a4b4532195f3Elliott Hughesenum ProfilerClockSource {
40cfbe73d02a024800813f8f0fc4f6a4b4532195f3Elliott Hughes  kProfilerClockSourceThreadCpu,
41cfbe73d02a024800813f8f0fc4f6a4b4532195f3Elliott Hughes  kProfilerClockSourceWall,
4262d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers  kProfilerClockSourceDual,  // Both wall and thread CPU clocks.
43cfbe73d02a024800813f8f0fc4f6a4b4532195f3Elliott Hughes};
44cfbe73d02a024800813f8f0fc4f6a4b4532195f3Elliott Hughes
4562d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogersclass Trace : public instrumentation::InstrumentationListener {
46e343b76af81a005ef64f5e75a555389fd9147dabjeffhao public:
470791adc2249366c50684935a4c42ba5e58bc3746jeffhao  enum TraceFlag {
480791adc2249366c50684935a4c42ba5e58bc3746jeffhao    kTraceCountAllocs = 1,
490791adc2249366c50684935a4c42ba5e58bc3746jeffhao  };
500791adc2249366c50684935a4c42ba5e58bc3746jeffhao
51cfbe73d02a024800813f8f0fc4f6a4b4532195f3Elliott Hughes  static void SetDefaultClockSource(ProfilerClockSource clock_source);
52cfbe73d02a024800813f8f0fc4f6a4b4532195f3Elliott Hughes
5362d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers  static void Start(const char* trace_filename, int trace_fd, int buffer_size, int flags,
5462d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers                    bool direct_to_ddms)
5562d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers  LOCKS_EXCLUDED(Locks::mutator_lock_,
5662d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers                 Locks::thread_list_lock_,
5762d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers                 Locks::thread_suspend_count_lock_,
5862d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers                 Locks::trace_lock_);
5962d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers  static void Stop() LOCKS_EXCLUDED(Locks::trace_lock_);
6062d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers  static void Shutdown() LOCKS_EXCLUDED(Locks::trace_lock_);
6162d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers  static bool IsMethodTracingActive() LOCKS_EXCLUDED(Locks::trace_lock_);
62e343b76af81a005ef64f5e75a555389fd9147dabjeffhao
63cfbe73d02a024800813f8f0fc4f6a4b4532195f3Elliott Hughes  bool UseWallClock();
64cfbe73d02a024800813f8f0fc4f6a4b4532195f3Elliott Hughes  bool UseThreadCpuClock();
65cfbe73d02a024800813f8f0fc4f6a4b4532195f3Elliott Hughes
66e2f77e7592842cad5a59e73535b8982c35e156caIan Rogers  void CompareAndUpdateStackTrace(Thread* thread, std::vector<mirror::ArtMethod*>* stack_trace)
670abc72ebe356c32354b575c48189965a0edc7890Jeff Hao      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
680abc72ebe356c32354b575c48189965a0edc7890Jeff Hao
6962d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers  virtual void MethodEntered(Thread* thread, mirror::Object* this_object,
70ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom                             const mirror::ArtMethod* method, uint32_t dex_pc)
7162d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
7262d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers  virtual void MethodExited(Thread* thread, mirror::Object* this_object,
73ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom                            const mirror::ArtMethod* method, uint32_t dex_pc,
7462d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers                            const JValue& return_value)
7562d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
76ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom  virtual void MethodUnwind(Thread* thread, const mirror::ArtMethod* method, uint32_t dex_pc)
7762d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
7862d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers  virtual void DexPcMoved(Thread* thread, mirror::Object* this_object,
79ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom                          const mirror::ArtMethod* method, uint32_t new_dex_pc)
8062d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
8162d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers  virtual void ExceptionCaught(Thread* thread, const ThrowLocation& throw_location,
82ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom                               mirror::ArtMethod* catch_method, uint32_t catch_dex_pc,
8362d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers                               mirror::Throwable* exception_object)
8462d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
850cd7ec2dcd8d7ba30bf3ca420b40dac52849876cBrian Carlstrom
865ce4b178d2483df679e7f718e379305e5d42a300Jeff Hao  // Reuse an old stack trace if it exists, otherwise allocate a new one.
875ce4b178d2483df679e7f718e379305e5d42a300Jeff Hao  static std::vector<mirror::ArtMethod*>* AllocStackTrace();
885ce4b178d2483df679e7f718e379305e5d42a300Jeff Hao  // Clear and store an old stack trace for later use.
895ce4b178d2483df679e7f718e379305e5d42a300Jeff Hao  static void FreeStackTrace(std::vector<mirror::ArtMethod*>* stack_trace);
905ce4b178d2483df679e7f718e379305e5d42a300Jeff Hao
910abc72ebe356c32354b575c48189965a0edc7890Jeff Hao  ~Trace();
920abc72ebe356c32354b575c48189965a0edc7890Jeff Hao
93e343b76af81a005ef64f5e75a555389fd9147dabjeffhao private:
94cfbe73d02a024800813f8f0fc4f6a4b4532195f3Elliott Hughes  explicit Trace(File* trace_file, int buffer_size, int flags);
952692b573a56cd63a3c8c8aa1636e3766b6d8c9c4jeffhao
960abc72ebe356c32354b575c48189965a0edc7890Jeff Hao  static void* RunSamplingThread(void* arg) LOCKS_EXCLUDED(Locks::trace_lock_);
970abc72ebe356c32354b575c48189965a0edc7890Jeff Hao
98b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers  void FinishTracing() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
992692b573a56cd63a3c8c8aa1636e3766b6d8c9c4jeffhao
100c1ff4b79a5d81b849203cc1e1c4a91223e75cfd3Jeff Hao  void ReadClocks(Thread* thread, uint32_t* thread_clock_diff, uint32_t* wall_clock_diff);
101c1ff4b79a5d81b849203cc1e1c4a91223e75cfd3Jeff Hao
102ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom  void LogMethodTraceEvent(Thread* thread, const mirror::ArtMethod* method,
103c1ff4b79a5d81b849203cc1e1c4a91223e75cfd3Jeff Hao                           instrumentation::Instrumentation::InstrumentationEvent event,
104c1ff4b79a5d81b849203cc1e1c4a91223e75cfd3Jeff Hao                           uint32_t thread_clock_diff, uint32_t wall_clock_diff);
10562d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers
106a9ef3fd82bebc6370fc3ddbb094988feb6c83022jeffhao  // Methods to output traced methods and threads.
107ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom  void GetVisitedMethods(size_t end_offset, std::set<mirror::ArtMethod*>* visited_methods);
108ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom  void DumpMethodList(std::ostream& os, const std::set<mirror::ArtMethod*>& visited_methods)
10962d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
110b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers  void DumpThreadList(std::ostream& os) LOCKS_EXCLUDED(Locks::thread_list_lock_);
1112692b573a56cd63a3c8c8aa1636e3766b6d8c9c4jeffhao
11262d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers  // Singleton instance of the Trace or NULL when no method tracing is active.
1130abc72ebe356c32354b575c48189965a0edc7890Jeff Hao  static Trace* volatile the_trace_ GUARDED_BY(Locks::trace_lock_);
11462d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers
11562d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers  // The default profiler clock source.
11662d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers  static ProfilerClockSource default_clock_source_;
1172692b573a56cd63a3c8c8aa1636e3766b6d8c9c4jeffhao
1180abc72ebe356c32354b575c48189965a0edc7890Jeff Hao  // True if traceview should sample instead of instrumenting method entry/exit.
1190abc72ebe356c32354b575c48189965a0edc7890Jeff Hao  static bool sampling_enabled_;
1200abc72ebe356c32354b575c48189965a0edc7890Jeff Hao
1210abc72ebe356c32354b575c48189965a0edc7890Jeff Hao  // Sampling interval in microseconds.
1220abc72ebe356c32354b575c48189965a0edc7890Jeff Hao  static uint32_t sampling_interval_us_;
1230abc72ebe356c32354b575c48189965a0edc7890Jeff Hao
1240abc72ebe356c32354b575c48189965a0edc7890Jeff Hao  // Sampling thread, non-zero when sampling.
1250abc72ebe356c32354b575c48189965a0edc7890Jeff Hao  static pthread_t sampling_pthread_;
1260abc72ebe356c32354b575c48189965a0edc7890Jeff Hao
1275ce4b178d2483df679e7f718e379305e5d42a300Jeff Hao  // Used to remember an unused stack trace to avoid re-allocation during sampling.
1285ce4b178d2483df679e7f718e379305e5d42a300Jeff Hao  static UniquePtr<std::vector<mirror::ArtMethod*> > temp_stack_trace_;
1292692b573a56cd63a3c8c8aa1636e3766b6d8c9c4jeffhao
1302692b573a56cd63a3c8c8aa1636e3766b6d8c9c4jeffhao  // File to write trace data out to, NULL if direct to ddms.
1312692b573a56cd63a3c8c8aa1636e3766b6d8c9c4jeffhao  UniquePtr<File> trace_file_;
1322692b573a56cd63a3c8c8aa1636e3766b6d8c9c4jeffhao
1332692b573a56cd63a3c8c8aa1636e3766b6d8c9c4jeffhao  // Buffer to store trace data.
1342692b573a56cd63a3c8c8aa1636e3766b6d8c9c4jeffhao  UniquePtr<uint8_t> buf_;
1352692b573a56cd63a3c8c8aa1636e3766b6d8c9c4jeffhao
1360791adc2249366c50684935a4c42ba5e58bc3746jeffhao  // Flags enabling extra tracing of things such as alloc counts.
13762d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers  const int flags_;
1380791adc2249366c50684935a4c42ba5e58bc3746jeffhao
13962d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers  const ProfilerClockSource clock_source_;
140cfbe73d02a024800813f8f0fc4f6a4b4532195f3Elliott Hughes
14162d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers  // Size of buf_.
14262d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers  const int buffer_size_;
14362d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers
14462d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers  // Time trace was created.
14562d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers  const uint64_t start_time_;
1462692b573a56cd63a3c8c8aa1636e3766b6d8c9c4jeffhao
14762d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers  // Offset into buf_.
1482692b573a56cd63a3c8c8aa1636e3766b6d8c9c4jeffhao  volatile int32_t cur_offset_;
149a9ef3fd82bebc6370fc3ddbb094988feb6c83022jeffhao
15062d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers  // Did we overflow the buffer recording traces?
15162d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers  bool overflow_;
15262d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers
153e343b76af81a005ef64f5e75a555389fd9147dabjeffhao  DISALLOW_COPY_AND_ASSIGN(Trace);
154e343b76af81a005ef64f5e75a555389fd9147dabjeffhao};
155e343b76af81a005ef64f5e75a555389fd9147dabjeffhao
156e343b76af81a005ef64f5e75a555389fd9147dabjeffhao}  // namespace art
157e343b76af81a005ef64f5e75a555389fd9147dabjeffhao
158fc0e3219edc9a5bf81b166e82fd5db2796eb6a0dBrian Carlstrom#endif  // ART_RUNTIME_TRACE_H_
159