Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(44)

Side by Side Diff: src/cpu-profiler.h

Issue 1356223004: Move heap and CPU profilers into a dedicated directory. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: rebaseline Created 5 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/compiler.cc ('k') | src/cpu-profiler.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #ifndef V8_CPU_PROFILER_H_
6 #define V8_CPU_PROFILER_H_
7
8 #include "src/allocation.h"
9 #include "src/base/atomicops.h"
10 #include "src/base/platform/time.h"
11 #include "src/circular-queue.h"
12 #include "src/compiler.h"
13 #include "src/sampler.h"
14 #include "src/unbound-queue.h"
15
16 namespace v8 {
17 namespace internal {
18
19 // Forward declarations.
20 class CodeEntry;
21 class CodeMap;
22 class CompilationInfo;
23 class CpuProfile;
24 class CpuProfilesCollection;
25 class ProfileGenerator;
26
27 #define CODE_EVENTS_TYPE_LIST(V) \
28 V(CODE_CREATION, CodeCreateEventRecord) \
29 V(CODE_MOVE, CodeMoveEventRecord) \
30 V(CODE_DISABLE_OPT, CodeDisableOptEventRecord) \
31 V(CODE_DEOPT, CodeDeoptEventRecord) \
32 V(REPORT_BUILTIN, ReportBuiltinEventRecord)
33
34
35 class CodeEventRecord {
36 public:
37 #define DECLARE_TYPE(type, ignore) type,
38 enum Type {
39 NONE = 0,
40 CODE_EVENTS_TYPE_LIST(DECLARE_TYPE)
41 NUMBER_OF_TYPES
42 };
43 #undef DECLARE_TYPE
44
45 Type type;
46 mutable unsigned order;
47 };
48
49
50 class CodeCreateEventRecord : public CodeEventRecord {
51 public:
52 Address start;
53 CodeEntry* entry;
54 unsigned size;
55
56 INLINE(void UpdateCodeMap(CodeMap* code_map));
57 };
58
59
60 class CodeMoveEventRecord : public CodeEventRecord {
61 public:
62 Address from;
63 Address to;
64
65 INLINE(void UpdateCodeMap(CodeMap* code_map));
66 };
67
68
69 class CodeDisableOptEventRecord : public CodeEventRecord {
70 public:
71 Address start;
72 const char* bailout_reason;
73
74 INLINE(void UpdateCodeMap(CodeMap* code_map));
75 };
76
77
78 class CodeDeoptEventRecord : public CodeEventRecord {
79 public:
80 Address start;
81 const char* deopt_reason;
82 SourcePosition position;
83 size_t pc_offset;
84
85 INLINE(void UpdateCodeMap(CodeMap* code_map));
86 };
87
88
89 class ReportBuiltinEventRecord : public CodeEventRecord {
90 public:
91 Address start;
92 Builtins::Name builtin_id;
93
94 INLINE(void UpdateCodeMap(CodeMap* code_map));
95 };
96
97
98 class TickSampleEventRecord {
99 public:
100 // The parameterless constructor is used when we dequeue data from
101 // the ticks buffer.
102 TickSampleEventRecord() { }
103 explicit TickSampleEventRecord(unsigned order) : order(order) { }
104
105 unsigned order;
106 TickSample sample;
107 };
108
109
110 class CodeEventsContainer {
111 public:
112 explicit CodeEventsContainer(
113 CodeEventRecord::Type type = CodeEventRecord::NONE) {
114 generic.type = type;
115 }
116 union {
117 CodeEventRecord generic;
118 #define DECLARE_CLASS(ignore, type) type type##_;
119 CODE_EVENTS_TYPE_LIST(DECLARE_CLASS)
120 #undef DECLARE_TYPE
121 };
122 };
123
124
125 // This class implements both the profile events processor thread and
126 // methods called by event producers: VM and stack sampler threads.
127 class ProfilerEventsProcessor : public base::Thread {
128 public:
129 ProfilerEventsProcessor(ProfileGenerator* generator,
130 Sampler* sampler,
131 base::TimeDelta period);
132 virtual ~ProfilerEventsProcessor();
133
134 // Thread control.
135 virtual void Run();
136 void StopSynchronously();
137 INLINE(bool running()) { return !!base::NoBarrier_Load(&running_); }
138 void Enqueue(const CodeEventsContainer& event);
139
140 // Puts current stack into tick sample events buffer.
141 void AddCurrentStack(Isolate* isolate);
142 void AddDeoptStack(Isolate* isolate, Address from, int fp_to_sp_delta);
143
144 // Tick sample events are filled directly in the buffer of the circular
145 // queue (because the structure is of fixed width, but usually not all
146 // stack frame entries are filled.) This method returns a pointer to the
147 // next record of the buffer.
148 inline TickSample* StartTickSample();
149 inline void FinishTickSample();
150
151 // SamplingCircularQueue has stricter alignment requirements than a normal new
152 // can fulfil, so we need to provide our own new/delete here.
153 void* operator new(size_t size);
154 void operator delete(void* ptr);
155
156 private:
157 // Called from events processing thread (Run() method.)
158 bool ProcessCodeEvent();
159
160 enum SampleProcessingResult {
161 OneSampleProcessed,
162 FoundSampleForNextCodeEvent,
163 NoSamplesInQueue
164 };
165 SampleProcessingResult ProcessOneSample();
166
167 ProfileGenerator* generator_;
168 Sampler* sampler_;
169 base::Atomic32 running_;
170 // Sampling period in microseconds.
171 const base::TimeDelta period_;
172 UnboundQueue<CodeEventsContainer> events_buffer_;
173 static const size_t kTickSampleBufferSize = 1 * MB;
174 static const size_t kTickSampleQueueLength =
175 kTickSampleBufferSize / sizeof(TickSampleEventRecord);
176 SamplingCircularQueue<TickSampleEventRecord,
177 kTickSampleQueueLength> ticks_buffer_;
178 UnboundQueue<TickSampleEventRecord> ticks_from_vm_buffer_;
179 unsigned last_code_event_id_;
180 unsigned last_processed_code_event_id_;
181 };
182
183
184 #define PROFILE(IsolateGetter, Call) \
185 do { \
186 Isolate* cpu_profiler_isolate = (IsolateGetter); \
187 v8::internal::Logger* logger = cpu_profiler_isolate->logger(); \
188 CpuProfiler* cpu_profiler = cpu_profiler_isolate->cpu_profiler(); \
189 if (logger->is_logging_code_events() || cpu_profiler->is_profiling()) { \
190 logger->Call; \
191 } \
192 } while (false)
193
194
195 class CpuProfiler : public CodeEventListener {
196 public:
197 explicit CpuProfiler(Isolate* isolate);
198
199 CpuProfiler(Isolate* isolate,
200 CpuProfilesCollection* test_collection,
201 ProfileGenerator* test_generator,
202 ProfilerEventsProcessor* test_processor);
203
204 virtual ~CpuProfiler();
205
206 void set_sampling_interval(base::TimeDelta value);
207 void StartProfiling(const char* title, bool record_samples = false);
208 void StartProfiling(String* title, bool record_samples);
209 CpuProfile* StopProfiling(const char* title);
210 CpuProfile* StopProfiling(String* title);
211 int GetProfilesCount();
212 CpuProfile* GetProfile(int index);
213 void DeleteAllProfiles();
214 void DeleteProfile(CpuProfile* profile);
215
216 // Invoked from stack sampler (thread or signal handler.)
217 inline TickSample* StartTickSample();
218 inline void FinishTickSample();
219
220 // Must be called via PROFILE macro, otherwise will crash when
221 // profiling is not enabled.
222 virtual void CallbackEvent(Name* name, Address entry_point);
223 virtual void CodeCreateEvent(Logger::LogEventsAndTags tag,
224 Code* code, const char* comment);
225 virtual void CodeCreateEvent(Logger::LogEventsAndTags tag,
226 Code* code, Name* name);
227 virtual void CodeCreateEvent(Logger::LogEventsAndTags tag, Code* code,
228 SharedFunctionInfo* shared,
229 CompilationInfo* info, Name* script_name);
230 virtual void CodeCreateEvent(Logger::LogEventsAndTags tag, Code* code,
231 SharedFunctionInfo* shared,
232 CompilationInfo* info, Name* script_name,
233 int line, int column);
234 virtual void CodeCreateEvent(Logger::LogEventsAndTags tag,
235 Code* code, int args_count);
236 virtual void CodeMovingGCEvent() {}
237 virtual void CodeMoveEvent(Address from, Address to);
238 virtual void CodeDisableOptEvent(Code* code, SharedFunctionInfo* shared);
239 virtual void CodeDeoptEvent(Code* code, Address pc, int fp_to_sp_delta);
240 virtual void CodeDeleteEvent(Address from);
241 virtual void GetterCallbackEvent(Name* name, Address entry_point);
242 virtual void RegExpCodeCreateEvent(Code* code, String* source);
243 virtual void SetterCallbackEvent(Name* name, Address entry_point);
244 virtual void SharedFunctionInfoMoveEvent(Address from, Address to) {}
245
246 INLINE(bool is_profiling() const) { return is_profiling_; }
247 bool* is_profiling_address() {
248 return &is_profiling_;
249 }
250
251 ProfileGenerator* generator() const { return generator_; }
252 ProfilerEventsProcessor* processor() const { return processor_; }
253 Isolate* isolate() const { return isolate_; }
254
255 private:
256 void StartProcessorIfNotStarted();
257 void StopProcessorIfLastProfile(const char* title);
258 void StopProcessor();
259 void ResetProfiles();
260 void LogBuiltins();
261
262 Isolate* isolate_;
263 base::TimeDelta sampling_interval_;
264 CpuProfilesCollection* profiles_;
265 ProfileGenerator* generator_;
266 ProfilerEventsProcessor* processor_;
267 bool saved_is_logging_;
268 bool is_profiling_;
269
270 DISALLOW_COPY_AND_ASSIGN(CpuProfiler);
271 };
272
273 } } // namespace v8::internal
274
275
276 #endif // V8_CPU_PROFILER_H_
OLDNEW
« no previous file with comments | « src/compiler.cc ('k') | src/cpu-profiler.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698