trace.h revision 0cd7ec2dcd8d7ba30bf3ca420b40dac52849876c
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>
23e343b76af81a005ef64f5e75a555389fd9147dabjeffhao
24761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes#include "base/macros.h"
25e343b76af81a005ef64f5e75a555389fd9147dabjeffhao#include "globals.h"
2662d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers#include "instrumentation.h"
27761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes#include "os.h"
28a0e180632411f7fe0edf454e571c42209ee7b540Elliott Hughes#include "safe_map.h"
292692b573a56cd63a3c8c8aa1636e3766b6d8c9c4jeffhao#include "UniquePtr.h"
30e343b76af81a005ef64f5e75a555389fd9147dabjeffhao
31e343b76af81a005ef64f5e75a555389fd9147dabjeffhaonamespace art {
32e343b76af81a005ef64f5e75a555389fd9147dabjeffhao
332dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogersnamespace mirror {
3466f19258f9728d4ffe026074d8fd429d639802faMathieu Chartierclass AbstractMethod;
352dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers}  // namespace mirror
36a9ef3fd82bebc6370fc3ddbb094988feb6c83022jeffhaoclass Thread;
37e343b76af81a005ef64f5e75a555389fd9147dabjeffhao
38cfbe73d02a024800813f8f0fc4f6a4b4532195f3Elliott Hughesenum ProfilerClockSource {
39cfbe73d02a024800813f8f0fc4f6a4b4532195f3Elliott Hughes  kProfilerClockSourceThreadCpu,
40cfbe73d02a024800813f8f0fc4f6a4b4532195f3Elliott Hughes  kProfilerClockSourceWall,
4162d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers  kProfilerClockSourceDual,  // Both wall and thread CPU clocks.
42cfbe73d02a024800813f8f0fc4f6a4b4532195f3Elliott Hughes};
43cfbe73d02a024800813f8f0fc4f6a4b4532195f3Elliott Hughes
4462d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogersclass Trace : public instrumentation::InstrumentationListener {
45e343b76af81a005ef64f5e75a555389fd9147dabjeffhao public:
460791adc2249366c50684935a4c42ba5e58bc3746jeffhao  enum TraceFlag {
470791adc2249366c50684935a4c42ba5e58bc3746jeffhao    kTraceCountAllocs = 1,
480791adc2249366c50684935a4c42ba5e58bc3746jeffhao  };
490791adc2249366c50684935a4c42ba5e58bc3746jeffhao
50cfbe73d02a024800813f8f0fc4f6a4b4532195f3Elliott Hughes  static void SetDefaultClockSource(ProfilerClockSource clock_source);
51cfbe73d02a024800813f8f0fc4f6a4b4532195f3Elliott Hughes
5262d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers  static void Start(const char* trace_filename, int trace_fd, int buffer_size, int flags,
5362d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers                    bool direct_to_ddms)
5462d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers  LOCKS_EXCLUDED(Locks::mutator_lock_,
5562d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers                 Locks::thread_list_lock_,
5662d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers                 Locks::thread_suspend_count_lock_,
5762d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers                 Locks::trace_lock_);
5862d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers  static void Stop() LOCKS_EXCLUDED(Locks::trace_lock_);
5962d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers  static void Shutdown() LOCKS_EXCLUDED(Locks::trace_lock_);
6062d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers  static bool IsMethodTracingActive() LOCKS_EXCLUDED(Locks::trace_lock_);
61e343b76af81a005ef64f5e75a555389fd9147dabjeffhao
62cfbe73d02a024800813f8f0fc4f6a4b4532195f3Elliott Hughes  bool UseWallClock();
63cfbe73d02a024800813f8f0fc4f6a4b4532195f3Elliott Hughes  bool UseThreadCpuClock();
64cfbe73d02a024800813f8f0fc4f6a4b4532195f3Elliott Hughes
6562d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers  virtual void MethodEntered(Thread* thread, mirror::Object* this_object,
6662d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers                             const mirror::AbstractMethod* method, uint32_t dex_pc)
6762d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
6862d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers  virtual void MethodExited(Thread* thread, mirror::Object* this_object,
6962d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers                            const mirror::AbstractMethod* method, uint32_t dex_pc,
7062d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers                            const JValue& return_value)
7162d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
7262d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers  virtual void MethodUnwind(Thread* thread, const mirror::AbstractMethod* method, uint32_t dex_pc)
7362d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
7462d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers  virtual void DexPcMoved(Thread* thread, mirror::Object* this_object,
7562d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers                          const mirror::AbstractMethod* method, uint32_t new_dex_pc)
7662d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
7762d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers  virtual void ExceptionCaught(Thread* thread, const ThrowLocation& throw_location,
7862d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers                               mirror::AbstractMethod* catch_method, uint32_t catch_dex_pc,
7962d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers                               mirror::Throwable* exception_object)
8062d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
810cd7ec2dcd8d7ba30bf3ca420b40dac52849876cBrian Carlstrom
82e343b76af81a005ef64f5e75a555389fd9147dabjeffhao private:
83cfbe73d02a024800813f8f0fc4f6a4b4532195f3Elliott Hughes  explicit Trace(File* trace_file, int buffer_size, int flags);
842692b573a56cd63a3c8c8aa1636e3766b6d8c9c4jeffhao
85b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers  void FinishTracing() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
862692b573a56cd63a3c8c8aa1636e3766b6d8c9c4jeffhao
8762d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers  void LogMethodTraceEvent(Thread* thread, const mirror::AbstractMethod* method,
8862d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers                           instrumentation::Instrumentation::InstrumentationEvent event);
8962d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers
90a9ef3fd82bebc6370fc3ddbb094988feb6c83022jeffhao  // Methods to output traced methods and threads.
9162d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers  void GetVisitedMethods(size_t end_offset, std::set<mirror::AbstractMethod*>* visited_methods);
9262d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers  void DumpMethodList(std::ostream& os, const std::set<mirror::AbstractMethod*>& visited_methods)
9362d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
94b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers  void DumpThreadList(std::ostream& os) LOCKS_EXCLUDED(Locks::thread_list_lock_);
952692b573a56cd63a3c8c8aa1636e3766b6d8c9c4jeffhao
9662d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers  // Singleton instance of the Trace or NULL when no method tracing is active.
9762d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers  static Trace* the_trace_ GUARDED_BY(Locks::trace_lock_);
9862d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers
9962d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers  // The default profiler clock source.
10062d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers  static ProfilerClockSource default_clock_source_;
1012692b573a56cd63a3c8c8aa1636e3766b6d8c9c4jeffhao
1022692b573a56cd63a3c8c8aa1636e3766b6d8c9c4jeffhao  // Maps a thread to its clock base.
103a0e180632411f7fe0edf454e571c42209ee7b540Elliott Hughes  SafeMap<Thread*, uint64_t> thread_clock_base_map_;
1042692b573a56cd63a3c8c8aa1636e3766b6d8c9c4jeffhao
1052692b573a56cd63a3c8c8aa1636e3766b6d8c9c4jeffhao  // File to write trace data out to, NULL if direct to ddms.
1062692b573a56cd63a3c8c8aa1636e3766b6d8c9c4jeffhao  UniquePtr<File> trace_file_;
1072692b573a56cd63a3c8c8aa1636e3766b6d8c9c4jeffhao
1082692b573a56cd63a3c8c8aa1636e3766b6d8c9c4jeffhao  // Buffer to store trace data.
1092692b573a56cd63a3c8c8aa1636e3766b6d8c9c4jeffhao  UniquePtr<uint8_t> buf_;
1102692b573a56cd63a3c8c8aa1636e3766b6d8c9c4jeffhao
1110791adc2249366c50684935a4c42ba5e58bc3746jeffhao  // Flags enabling extra tracing of things such as alloc counts.
11262d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers  const int flags_;
1130791adc2249366c50684935a4c42ba5e58bc3746jeffhao
11462d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers  const ProfilerClockSource clock_source_;
115cfbe73d02a024800813f8f0fc4f6a4b4532195f3Elliott Hughes
11662d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers  // Size of buf_.
11762d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers  const int buffer_size_;
11862d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers
11962d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers  // Time trace was created.
12062d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers  const uint64_t start_time_;
1212692b573a56cd63a3c8c8aa1636e3766b6d8c9c4jeffhao
12262d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers  // Offset into buf_.
1232692b573a56cd63a3c8c8aa1636e3766b6d8c9c4jeffhao  volatile int32_t cur_offset_;
124a9ef3fd82bebc6370fc3ddbb094988feb6c83022jeffhao
12562d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers  // Did we overflow the buffer recording traces?
12662d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers  bool overflow_;
12762d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers
128e343b76af81a005ef64f5e75a555389fd9147dabjeffhao  DISALLOW_COPY_AND_ASSIGN(Trace);
129e343b76af81a005ef64f5e75a555389fd9147dabjeffhao};
130e343b76af81a005ef64f5e75a555389fd9147dabjeffhao
131e343b76af81a005ef64f5e75a555389fd9147dabjeffhao}  // namespace art
132e343b76af81a005ef64f5e75a555389fd9147dabjeffhao
133fc0e3219edc9a5bf81b166e82fd5db2796eb6a0dBrian Carlstrom#endif  // ART_RUNTIME_TRACE_H_
134