The data contained in this repository can be downloaded to your computer using one of several clients.
Please see the documentation of your version control software client for more information.

Please select the desired protocol below to get the URL.

This URL has Read-Only access.

Statistics
| Branch: | Revision:

main_repo / deps / v8 / src / cpu-profiler.h @ f230a1cf

History | View | Annotate | Download (9.23 KB)

1
// Copyright 2012 the V8 project authors. All rights reserved.
2
// Redistribution and use in source and binary forms, with or without
3
// modification, are permitted provided that the following conditions are
4
// met:
5
//
6
//     * Redistributions of source code must retain the above copyright
7
//       notice, this list of conditions and the following disclaimer.
8
//     * Redistributions in binary form must reproduce the above
9
//       copyright notice, this list of conditions and the following
10
//       disclaimer in the documentation and/or other materials provided
11
//       with the distribution.
12
//     * Neither the name of Google Inc. nor the names of its
13
//       contributors may be used to endorse or promote products derived
14
//       from this software without specific prior written permission.
15
//
16
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27

    
28
#ifndef V8_CPU_PROFILER_H_
29
#define V8_CPU_PROFILER_H_
30

    
31
#include "allocation.h"
32
#include "atomicops.h"
33
#include "circular-queue.h"
34
#include "platform/time.h"
35
#include "sampler.h"
36
#include "unbound-queue.h"
37

    
38
namespace v8 {
39
namespace internal {
40

    
41
// Forward declarations.
42
class CodeEntry;
43
class CodeMap;
44
class CompilationInfo;
45
class CpuProfile;
46
class CpuProfilesCollection;
47
class ProfileGenerator;
48

    
49
#define CODE_EVENTS_TYPE_LIST(V)                                   \
50
  V(CODE_CREATION,    CodeCreateEventRecord)                       \
51
  V(CODE_MOVE,        CodeMoveEventRecord)                         \
52
  V(SHARED_FUNC_MOVE, SharedFunctionInfoMoveEventRecord)           \
53
  V(REPORT_BUILTIN,   ReportBuiltinEventRecord)
54

    
55

    
56
class CodeEventRecord {
57
 public:
58
#define DECLARE_TYPE(type, ignore) type,
59
  enum Type {
60
    NONE = 0,
61
    CODE_EVENTS_TYPE_LIST(DECLARE_TYPE)
62
    NUMBER_OF_TYPES
63
  };
64
#undef DECLARE_TYPE
65

    
66
  Type type;
67
  mutable unsigned order;
68
};
69

    
70

    
71
class CodeCreateEventRecord : public CodeEventRecord {
72
 public:
73
  Address start;
74
  CodeEntry* entry;
75
  unsigned size;
76
  Address shared;
77

    
78
  INLINE(void UpdateCodeMap(CodeMap* code_map));
79
};
80

    
81

    
82
class CodeMoveEventRecord : public CodeEventRecord {
83
 public:
84
  Address from;
85
  Address to;
86

    
87
  INLINE(void UpdateCodeMap(CodeMap* code_map));
88
};
89

    
90

    
91
class SharedFunctionInfoMoveEventRecord : public CodeEventRecord {
92
 public:
93
  Address from;
94
  Address to;
95

    
96
  INLINE(void UpdateCodeMap(CodeMap* code_map));
97
};
98

    
99

    
100
class ReportBuiltinEventRecord : public CodeEventRecord {
101
 public:
102
  Address start;
103
  Builtins::Name builtin_id;
104

    
105
  INLINE(void UpdateCodeMap(CodeMap* code_map));
106
};
107

    
108

    
109
class TickSampleEventRecord {
110
 public:
111
  // The parameterless constructor is used when we dequeue data from
112
  // the ticks buffer.
113
  TickSampleEventRecord() { }
114
  explicit TickSampleEventRecord(unsigned order) : order(order) { }
115

    
116
  unsigned order;
117
  TickSample sample;
118
};
119

    
120

    
121
class CodeEventsContainer {
122
 public:
123
  explicit CodeEventsContainer(
124
      CodeEventRecord::Type type = CodeEventRecord::NONE) {
125
    generic.type = type;
126
  }
127
  union  {
128
    CodeEventRecord generic;
129
#define DECLARE_CLASS(ignore, type) type type##_;
130
    CODE_EVENTS_TYPE_LIST(DECLARE_CLASS)
131
#undef DECLARE_TYPE
132
  };
133
};
134

    
135

    
136
// This class implements both the profile events processor thread and
137
// methods called by event producers: VM and stack sampler threads.
138
class ProfilerEventsProcessor : public Thread {
139
 public:
140
  ProfilerEventsProcessor(ProfileGenerator* generator,
141
                          Sampler* sampler,
142
                          TimeDelta period);
143
  virtual ~ProfilerEventsProcessor() {}
144

    
145
  // Thread control.
146
  virtual void Run();
147
  void StopSynchronously();
148
  INLINE(bool running()) { return running_; }
149
  void Enqueue(const CodeEventsContainer& event);
150

    
151
  // Puts current stack into tick sample events buffer.
152
  void AddCurrentStack(Isolate* isolate);
153

    
154
  // Tick sample events are filled directly in the buffer of the circular
155
  // queue (because the structure is of fixed width, but usually not all
156
  // stack frame entries are filled.) This method returns a pointer to the
157
  // next record of the buffer.
158
  inline TickSample* StartTickSample();
159
  inline void FinishTickSample();
160

    
161
 private:
162
  // Called from events processing thread (Run() method.)
163
  bool ProcessCodeEvent();
164

    
165
  enum SampleProcessingResult {
166
    OneSampleProcessed,
167
    FoundSampleForNextCodeEvent,
168
    NoSamplesInQueue
169
  };
170
  SampleProcessingResult ProcessOneSample();
171

    
172
  ProfileGenerator* generator_;
173
  Sampler* sampler_;
174
  bool running_;
175
  // Sampling period in microseconds.
176
  const TimeDelta period_;
177
  UnboundQueue<CodeEventsContainer> events_buffer_;
178
  static const size_t kTickSampleBufferSize = 1 * MB;
179
  static const size_t kTickSampleQueueLength =
180
      kTickSampleBufferSize / sizeof(TickSampleEventRecord);
181
  SamplingCircularQueue<TickSampleEventRecord,
182
                        kTickSampleQueueLength> ticks_buffer_;
183
  UnboundQueue<TickSampleEventRecord> ticks_from_vm_buffer_;
184
  unsigned last_code_event_id_;
185
  unsigned last_processed_code_event_id_;
186
};
187

    
188

    
189
#define PROFILE(IsolateGetter, Call)                                        \
190
  do {                                                                      \
191
    Isolate* cpu_profiler_isolate = (IsolateGetter);                        \
192
    v8::internal::Logger* logger = cpu_profiler_isolate->logger();          \
193
    CpuProfiler* cpu_profiler = cpu_profiler_isolate->cpu_profiler();       \
194
    if (logger->is_logging_code_events() || cpu_profiler->is_profiling()) { \
195
      logger->Call;                                                         \
196
    }                                                                       \
197
  } while (false)
198

    
199

    
200
class CpuProfiler : public CodeEventListener {
201
 public:
202
  explicit CpuProfiler(Isolate* isolate);
203

    
204
  CpuProfiler(Isolate* isolate,
205
              CpuProfilesCollection* test_collection,
206
              ProfileGenerator* test_generator,
207
              ProfilerEventsProcessor* test_processor);
208

    
209
  virtual ~CpuProfiler();
210

    
211
  void set_sampling_interval(TimeDelta value);
212
  void StartProfiling(const char* title, bool record_samples = false);
213
  void StartProfiling(String* title, bool record_samples);
214
  CpuProfile* StopProfiling(const char* title);
215
  CpuProfile* StopProfiling(String* title);
216
  int GetProfilesCount();
217
  CpuProfile* GetProfile(int index);
218
  void DeleteAllProfiles();
219
  void DeleteProfile(CpuProfile* profile);
220

    
221
  // Invoked from stack sampler (thread or signal handler.)
222
  inline TickSample* StartTickSample();
223
  inline void FinishTickSample();
224

    
225
  // Must be called via PROFILE macro, otherwise will crash when
226
  // profiling is not enabled.
227
  virtual void CallbackEvent(Name* name, Address entry_point);
228
  virtual void CodeCreateEvent(Logger::LogEventsAndTags tag,
229
                               Code* code, const char* comment);
230
  virtual void CodeCreateEvent(Logger::LogEventsAndTags tag,
231
                               Code* code, Name* name);
232
  virtual void CodeCreateEvent(Logger::LogEventsAndTags tag,
233
                               Code* code,
234
                               SharedFunctionInfo* shared,
235
                               CompilationInfo* info,
236
                               Name* name);
237
  virtual void CodeCreateEvent(Logger::LogEventsAndTags tag,
238
                               Code* code,
239
                               SharedFunctionInfo* shared,
240
                               CompilationInfo* info,
241
                               Name* source, int line, int column);
242
  virtual void CodeCreateEvent(Logger::LogEventsAndTags tag,
243
                               Code* code, int args_count);
244
  virtual void CodeMovingGCEvent() {}
245
  virtual void CodeMoveEvent(Address from, Address to);
246
  virtual void CodeDeleteEvent(Address from);
247
  virtual void GetterCallbackEvent(Name* name, Address entry_point);
248
  virtual void RegExpCodeCreateEvent(Code* code, String* source);
249
  virtual void SetterCallbackEvent(Name* name, Address entry_point);
250
  virtual void SharedFunctionInfoMoveEvent(Address from, Address to);
251

    
252
  INLINE(bool is_profiling() const) { return is_profiling_; }
253
  bool* is_profiling_address() {
254
    return &is_profiling_;
255
  }
256

    
257
  ProfileGenerator* generator() const { return generator_; }
258
  ProfilerEventsProcessor* processor() const { return processor_; }
259
  Isolate* isolate() const { return isolate_; }
260

    
261
 private:
262
  void StartProcessorIfNotStarted();
263
  void StopProcessorIfLastProfile(const char* title);
264
  void StopProcessor();
265
  void ResetProfiles();
266
  void LogBuiltins();
267

    
268
  Isolate* isolate_;
269
  TimeDelta sampling_interval_;
270
  CpuProfilesCollection* profiles_;
271
  unsigned next_profile_uid_;
272
  ProfileGenerator* generator_;
273
  ProfilerEventsProcessor* processor_;
274
  bool saved_is_logging_;
275
  bool is_profiling_;
276

    
277
  DISALLOW_COPY_AND_ASSIGN(CpuProfiler);
278
};
279

    
280
} }  // namespace v8::internal
281

    
282

    
283
#endif  // V8_CPU_PROFILER_H_