trace.h revision 0791adc2249366c50684935a4c42ba5e58bc3746
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
17e343b76af81a005ef64f5e75a555389fd9147dabjeffhao#ifndef ART_SRC_TRACE_H_
18e343b76af81a005ef64f5e75a555389fd9147dabjeffhao#define ART_SRC_TRACE_H_
19e343b76af81a005ef64f5e75a555389fd9147dabjeffhao
20e343b76af81a005ef64f5e75a555389fd9147dabjeffhao#include <map>
21a9ef3fd82bebc6370fc3ddbb094988feb6c83022jeffhao#include <ostream>
22a9ef3fd82bebc6370fc3ddbb094988feb6c83022jeffhao#include <set>
23a9ef3fd82bebc6370fc3ddbb094988feb6c83022jeffhao#include <string>
24e343b76af81a005ef64f5e75a555389fd9147dabjeffhao
25a9ef3fd82bebc6370fc3ddbb094988feb6c83022jeffhao#include "file.h"
26e343b76af81a005ef64f5e75a555389fd9147dabjeffhao#include "globals.h"
27e343b76af81a005ef64f5e75a555389fd9147dabjeffhao#include "macros.h"
282692b573a56cd63a3c8c8aa1636e3766b6d8c9c4jeffhao#include "UniquePtr.h"
29e343b76af81a005ef64f5e75a555389fd9147dabjeffhao
30e343b76af81a005ef64f5e75a555389fd9147dabjeffhaonamespace art {
31e343b76af81a005ef64f5e75a555389fd9147dabjeffhao
32e343b76af81a005ef64f5e75a555389fd9147dabjeffhaoclass Method;
33a9ef3fd82bebc6370fc3ddbb094988feb6c83022jeffhaoclass Thread;
34e343b76af81a005ef64f5e75a555389fd9147dabjeffhao
3557b86d47b66322693a070185fadfb43cb9c12eabIan Rogersuint32_t TraceMethodUnwindFromCode(Thread* self);
3657b86d47b66322693a070185fadfb43cb9c12eabIan Rogers
37e343b76af81a005ef64f5e75a555389fd9147dabjeffhaostruct TraceStackFrame {
38e343b76af81a005ef64f5e75a555389fd9147dabjeffhao  TraceStackFrame(Method* method, uintptr_t return_pc)
39e343b76af81a005ef64f5e75a555389fd9147dabjeffhao      : method_(method), return_pc_(return_pc) {
40e343b76af81a005ef64f5e75a555389fd9147dabjeffhao  }
41e343b76af81a005ef64f5e75a555389fd9147dabjeffhao
42e343b76af81a005ef64f5e75a555389fd9147dabjeffhao  Method* method_;
43e343b76af81a005ef64f5e75a555389fd9147dabjeffhao  uintptr_t return_pc_;
44e343b76af81a005ef64f5e75a555389fd9147dabjeffhao};
45e343b76af81a005ef64f5e75a555389fd9147dabjeffhao
46e343b76af81a005ef64f5e75a555389fd9147dabjeffhaoclass Trace {
47e343b76af81a005ef64f5e75a555389fd9147dabjeffhao public:
48a9ef3fd82bebc6370fc3ddbb094988feb6c83022jeffhao
49a9ef3fd82bebc6370fc3ddbb094988feb6c83022jeffhao  enum TraceEvent {
50a9ef3fd82bebc6370fc3ddbb094988feb6c83022jeffhao    kMethodTraceEnter = 0,
51a9ef3fd82bebc6370fc3ddbb094988feb6c83022jeffhao    kMethodTraceExit = 1,
52a9ef3fd82bebc6370fc3ddbb094988feb6c83022jeffhao    kMethodTraceUnwind = 2,
53a9ef3fd82bebc6370fc3ddbb094988feb6c83022jeffhao  };
54a9ef3fd82bebc6370fc3ddbb094988feb6c83022jeffhao
550791adc2249366c50684935a4c42ba5e58bc3746jeffhao  enum TraceFlag {
560791adc2249366c50684935a4c42ba5e58bc3746jeffhao    kTraceCountAllocs = 1,
570791adc2249366c50684935a4c42ba5e58bc3746jeffhao  };
580791adc2249366c50684935a4c42ba5e58bc3746jeffhao
59e343b76af81a005ef64f5e75a555389fd9147dabjeffhao  static void Start(const char* trace_filename, int trace_fd, int buffer_size, int flags, bool direct_to_ddms);
60e343b76af81a005ef64f5e75a555389fd9147dabjeffhao  static void Stop();
61b5e81858a47dd7ed051135f6982fbc4e13d0f309jeffhao  static void Shutdown();
62e343b76af81a005ef64f5e75a555389fd9147dabjeffhao
632692b573a56cd63a3c8c8aa1636e3766b6d8c9c4jeffhao  void LogMethodTraceEvent(Thread* self, const Method* method, TraceEvent event);
64a9ef3fd82bebc6370fc3ddbb094988feb6c83022jeffhao
652692b573a56cd63a3c8c8aa1636e3766b6d8c9c4jeffhao  void AddSavedCodeToMap(const Method* method, const void* code);
662692b573a56cd63a3c8c8aa1636e3766b6d8c9c4jeffhao  void RemoveSavedCodeFromMap(const Method* method);
672692b573a56cd63a3c8c8aa1636e3766b6d8c9c4jeffhao  const void* GetSavedCodeFromMap(const Method* method);
68e343b76af81a005ef64f5e75a555389fd9147dabjeffhao
69b5e81858a47dd7ed051135f6982fbc4e13d0f309jeffhao  void SaveAndUpdateCode(Method* method);
702692b573a56cd63a3c8c8aa1636e3766b6d8c9c4jeffhao  void ResetSavedCode(Method* method);
71e343b76af81a005ef64f5e75a555389fd9147dabjeffhao
72e343b76af81a005ef64f5e75a555389fd9147dabjeffhao private:
730791adc2249366c50684935a4c42ba5e58bc3746jeffhao  explicit Trace(File* trace_file, int buffer_size, int flags)
740791adc2249366c50684935a4c42ba5e58bc3746jeffhao      : trace_file_(trace_file), buf_(new uint8_t[buffer_size]()), flags_(flags), overflow_(false),
750791adc2249366c50684935a4c42ba5e58bc3746jeffhao        buffer_size_(buffer_size), start_time_(0), trace_version_(0), record_size_(0), cur_offset_(0) {
762692b573a56cd63a3c8c8aa1636e3766b6d8c9c4jeffhao  }
772692b573a56cd63a3c8c8aa1636e3766b6d8c9c4jeffhao
782692b573a56cd63a3c8c8aa1636e3766b6d8c9c4jeffhao  void BeginTracing();
792692b573a56cd63a3c8c8aa1636e3766b6d8c9c4jeffhao  void FinishTracing();
802692b573a56cd63a3c8c8aa1636e3766b6d8c9c4jeffhao
81e343b76af81a005ef64f5e75a555389fd9147dabjeffhao  // Replaces code of each method with a pointer to a stub for method tracing.
822692b573a56cd63a3c8c8aa1636e3766b6d8c9c4jeffhao  void InstallStubs();
83e343b76af81a005ef64f5e75a555389fd9147dabjeffhao
84e343b76af81a005ef64f5e75a555389fd9147dabjeffhao  // Restores original code for each method and fixes the return values of each thread's stack.
852692b573a56cd63a3c8c8aa1636e3766b6d8c9c4jeffhao  void UninstallStubs();
86e343b76af81a005ef64f5e75a555389fd9147dabjeffhao
87a9ef3fd82bebc6370fc3ddbb094988feb6c83022jeffhao  // Methods to output traced methods and threads.
882692b573a56cd63a3c8c8aa1636e3766b6d8c9c4jeffhao  void GetVisitedMethods(size_t end_offset);
892692b573a56cd63a3c8c8aa1636e3766b6d8c9c4jeffhao  void DumpMethodList(std::ostream& os);
902692b573a56cd63a3c8c8aa1636e3766b6d8c9c4jeffhao  void DumpThreadList(std::ostream& os);
912692b573a56cd63a3c8c8aa1636e3766b6d8c9c4jeffhao
922692b573a56cd63a3c8c8aa1636e3766b6d8c9c4jeffhao  // Maps a method to its original code pointer.
932692b573a56cd63a3c8c8aa1636e3766b6d8c9c4jeffhao  std::map<const Method*, const void*> saved_code_map_;
942692b573a56cd63a3c8c8aa1636e3766b6d8c9c4jeffhao
952692b573a56cd63a3c8c8aa1636e3766b6d8c9c4jeffhao  // Set of methods visited by the profiler.
962692b573a56cd63a3c8c8aa1636e3766b6d8c9c4jeffhao  std::set<const Method*> visited_methods_;
972692b573a56cd63a3c8c8aa1636e3766b6d8c9c4jeffhao
982692b573a56cd63a3c8c8aa1636e3766b6d8c9c4jeffhao  // Maps a thread to its clock base.
992692b573a56cd63a3c8c8aa1636e3766b6d8c9c4jeffhao  std::map<Thread*, uint64_t> thread_clock_base_map_;
1002692b573a56cd63a3c8c8aa1636e3766b6d8c9c4jeffhao
1012692b573a56cd63a3c8c8aa1636e3766b6d8c9c4jeffhao  // File to write trace data out to, NULL if direct to ddms.
1022692b573a56cd63a3c8c8aa1636e3766b6d8c9c4jeffhao  UniquePtr<File> trace_file_;
1032692b573a56cd63a3c8c8aa1636e3766b6d8c9c4jeffhao
1042692b573a56cd63a3c8c8aa1636e3766b6d8c9c4jeffhao  // Buffer to store trace data.
1052692b573a56cd63a3c8c8aa1636e3766b6d8c9c4jeffhao  UniquePtr<uint8_t> buf_;
1062692b573a56cd63a3c8c8aa1636e3766b6d8c9c4jeffhao
1070791adc2249366c50684935a4c42ba5e58bc3746jeffhao  // Flags enabling extra tracing of things such as alloc counts.
1080791adc2249366c50684935a4c42ba5e58bc3746jeffhao  int flags_;
1090791adc2249366c50684935a4c42ba5e58bc3746jeffhao
1102692b573a56cd63a3c8c8aa1636e3766b6d8c9c4jeffhao  bool overflow_;
1112692b573a56cd63a3c8c8aa1636e3766b6d8c9c4jeffhao  int buffer_size_;
1122692b573a56cd63a3c8c8aa1636e3766b6d8c9c4jeffhao  uint64_t start_time_;
1132692b573a56cd63a3c8c8aa1636e3766b6d8c9c4jeffhao  uint16_t trace_version_;
1142692b573a56cd63a3c8c8aa1636e3766b6d8c9c4jeffhao  uint16_t record_size_;
1152692b573a56cd63a3c8c8aa1636e3766b6d8c9c4jeffhao
1162692b573a56cd63a3c8c8aa1636e3766b6d8c9c4jeffhao  volatile int32_t cur_offset_;
117a9ef3fd82bebc6370fc3ddbb094988feb6c83022jeffhao
118e343b76af81a005ef64f5e75a555389fd9147dabjeffhao  DISALLOW_COPY_AND_ASSIGN(Trace);
119e343b76af81a005ef64f5e75a555389fd9147dabjeffhao};
120e343b76af81a005ef64f5e75a555389fd9147dabjeffhao
121e343b76af81a005ef64f5e75a555389fd9147dabjeffhao}  // namespace art
122e343b76af81a005ef64f5e75a555389fd9147dabjeffhao
123e343b76af81a005ef64f5e75a555389fd9147dabjeffhao#endif  // ART_SRC_TRACE_H_
124