summaryrefslogtreecommitdiff
path: root/src/trace.h
blob: 43b0ff791fc3a5d7a190726ce6312e0176494674 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
/*
 * Copyright (C) 2011 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef ART_SRC_TRACE_H_
#define ART_SRC_TRACE_H_

#include <ostream>
#include <set>
#include <string>

#include "file.h"
#include "globals.h"
#include "macros.h"
#include "safe_map.h"
#include "UniquePtr.h"

namespace art {

class AbstractMethod;
class Thread;

uint32_t TraceMethodUnwindFromCode(Thread* self);

struct TraceStackFrame {
  TraceStackFrame(AbstractMethod* method, uintptr_t return_pc)
      : method_(method), return_pc_(return_pc) {
  }

  AbstractMethod* method_;
  uintptr_t return_pc_;
};

enum ProfilerClockSource {
  kProfilerClockSourceThreadCpu,
  kProfilerClockSourceWall,
  kProfilerClockSourceDual,
};

class Trace {
 public:
  enum TraceEvent {
    kMethodTraceEnter = 0,
    kMethodTraceExit = 1,
    kMethodTraceUnwind = 2,
  };

  enum TraceFlag {
    kTraceCountAllocs = 1,
  };

  static void SetDefaultClockSource(ProfilerClockSource clock_source);

  static void Start(const char* trace_filename, int trace_fd, int buffer_size, int flags, bool direct_to_ddms);
  static void Stop();
  static void Shutdown() NO_THREAD_SAFETY_ANALYSIS;  // TODO: implement appropriate locking.

  bool UseWallClock();
  bool UseThreadCpuClock();

  void LogMethodTraceEvent(Thread* self, const AbstractMethod* method, TraceEvent event);

  void AddSavedCodeToMap(const AbstractMethod* method, const void* code);
  void RemoveSavedCodeFromMap(const AbstractMethod* method);
  const void* GetSavedCodeFromMap(const AbstractMethod* method);

  void SaveAndUpdateCode(AbstractMethod* method);
  void ResetSavedCode(AbstractMethod* method);

 private:
  explicit Trace(File* trace_file, int buffer_size, int flags);

  void BeginTracing();
  void FinishTracing() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);

  // Replaces code of each method with a pointer to a stub for method tracing.
  void InstallStubs();

  // Restores original code for each method and fixes the return values of each thread's stack.
  void UninstallStubs() LOCKS_EXCLUDED(Locks::thread_list_lock_);

  // Methods to output traced methods and threads.
  void GetVisitedMethods(size_t end_offset);
  void DumpMethodList(std::ostream& os) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
  void DumpThreadList(std::ostream& os) LOCKS_EXCLUDED(Locks::thread_list_lock_);

  // Maps a method to its original code pointer.
  SafeMap<const AbstractMethod*, const void*> saved_code_map_;

  // Set of methods visited by the profiler.
  std::set<const AbstractMethod*> visited_methods_;

  // Maps a thread to its clock base.
  SafeMap<Thread*, uint64_t> thread_clock_base_map_;

  // File to write trace data out to, NULL if direct to ddms.
  UniquePtr<File> trace_file_;

  // Buffer to store trace data.
  UniquePtr<uint8_t> buf_;

  // Flags enabling extra tracing of things such as alloc counts.
  int flags_;

  ProfilerClockSource clock_source_;

  bool overflow_;
  int buffer_size_;
  uint64_t start_time_;
  uint16_t trace_version_;
  uint16_t record_size_;

  volatile int32_t cur_offset_;

  DISALLOW_COPY_AND_ASSIGN(Trace);
};

}  // namespace art

#endif  // ART_SRC_TRACE_H_