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

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

Issue 1582004: C++ profiles processor: wire up to VM. (Closed)
Patch Set: Created 10 years, 8 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
OLDNEW
1 // Copyright 2010 the V8 project authors. All rights reserved. 1 // Copyright 2010 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
11 // with the distribution. 11 // with the distribution.
12 // * Neither the name of Google Inc. nor the names of its 12 // * Neither the name of Google Inc. nor the names of its
13 // contributors may be used to endorse or promote products derived 13 // contributors may be used to endorse or promote products derived
14 // from this software without specific prior written permission. 14 // from this software without specific prior written permission.
15 // 15 //
16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 17 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 18 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 19 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 20 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 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. 26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 27
28 #ifdef ENABLE_CPP_PROFILES_PROCESSOR
29
30 #include "v8.h" 28 #include "v8.h"
31 29
32 #include "cpu-profiler-inl.h" 30 #include "cpu-profiler-inl.h"
33 31
32 #ifdef ENABLE_CPP_PROFILES_PROCESSOR
33
34 #include "log-inl.h"
35
34 namespace v8 { 36 namespace v8 {
35 namespace internal { 37 namespace internal {
36 38
37 static const int kEventsBufferSize = 256*KB; 39 static const int kEventsBufferSize = 256*KB;
38 static const int kTickSamplesBufferChunkSize = 64*KB; 40 static const int kTickSamplesBufferChunkSize = 64*KB;
39 static const int kTickSamplesBufferChunksCount = 16; 41 static const int kTickSamplesBufferChunksCount = 16;
40 42
41 43
42 ProfilerEventsProcessor::ProfilerEventsProcessor(ProfileGenerator* generator) 44 ProfilerEventsProcessor::ProfilerEventsProcessor(ProfileGenerator* generator)
43 : generator_(generator), 45 : generator_(generator),
44 running_(false), 46 running_(false),
45 events_buffer_(kEventsBufferSize), 47 events_buffer_(kEventsBufferSize),
46 ticks_buffer_(sizeof(TickSampleEventRecord), 48 ticks_buffer_(sizeof(TickSampleEventRecord),
47 kTickSamplesBufferChunkSize, 49 kTickSamplesBufferChunkSize,
48 kTickSamplesBufferChunksCount), 50 kTickSamplesBufferChunksCount),
49 enqueue_order_(0) { } 51 enqueue_order_(0) { }
50 52
51 53
54 void ProfilerEventsProcessor::CallbackCreateEvent(Logger::LogEventsAndTags tag,
55 const char* prefix,
56 String* name,
57 Address start) {
58 CodeEventsContainer evt_rec;
59 CodeCreateEventRecord* rec = &evt_rec.CodeCreateEventRecord_;
60 rec->type = CodeEventRecord::CODE_CREATION;
61 rec->order = ++enqueue_order_;
62 rec->start = start;
63 rec->entry = generator_->NewCodeEntry(tag, prefix, name);
64 rec->size = 1;
65 events_buffer_.Enqueue(evt_rec);
66 }
67
68
52 void ProfilerEventsProcessor::CodeCreateEvent(Logger::LogEventsAndTags tag, 69 void ProfilerEventsProcessor::CodeCreateEvent(Logger::LogEventsAndTags tag,
53 String* name, 70 String* name,
54 String* resource_name, 71 String* resource_name,
55 int line_number, 72 int line_number,
56 Address start, 73 Address start,
57 unsigned size) { 74 unsigned size) {
58 CodeEventsContainer evt_rec; 75 CodeEventsContainer evt_rec;
59 CodeCreateEventRecord* rec = &evt_rec.CodeCreateEventRecord_; 76 CodeCreateEventRecord* rec = &evt_rec.CodeCreateEventRecord_;
60 rec->type = CodeEventRecord::CODE_CREATION; 77 rec->type = CodeEventRecord::CODE_CREATION;
61 rec->order = ++enqueue_order_; 78 rec->order = ++enqueue_order_;
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after
189 } 206 }
190 YieldCPU(); 207 YieldCPU();
191 } 208 }
192 209
193 // Process remaining tick events. 210 // Process remaining tick events.
194 ticks_buffer_.FlushResidualRecords(); 211 ticks_buffer_.FlushResidualRecords();
195 // Perform processing until we have tick events, skip remaining code events. 212 // Perform processing until we have tick events, skip remaining code events.
196 while (ProcessTicks(dequeue_order) && ProcessCodeEvent(&dequeue_order)) { } 213 while (ProcessTicks(dequeue_order) && ProcessCodeEvent(&dequeue_order)) { }
197 } 214 }
198 215
216
217 CpuProfiler* CpuProfiler::singleton_ = NULL;
218
219 void CpuProfiler::StartProfiling(const char* title) {
220 ASSERT(singleton_ != NULL);
221 singleton_->StartCollectingProfile(title);
222 }
223
224
225 void CpuProfiler::StartProfiling(String* title) {
226 ASSERT(singleton_ != NULL);
227 singleton_->StartCollectingProfile(title);
228 }
229
230
231 CpuProfile* CpuProfiler::StopProfiling(const char* title) {
232 ASSERT(singleton_ != NULL);
233 return singleton_->StopCollectingProfile(title);
234 }
235
236
237 CpuProfile* CpuProfiler::StopProfiling(String* title) {
238 ASSERT(singleton_ != NULL);
239 return singleton_->StopCollectingProfile(title);
240 }
241
242
243 int CpuProfiler::GetProfilesCount() {
244 ASSERT(singleton_ != NULL);
245 return singleton_->profiles_->profiles()->length();
246 }
247
248
249 CpuProfile* CpuProfiler::GetProfile(int index) {
250 ASSERT(singleton_ != NULL);
251 return singleton_->profiles_->profiles()->at(index);
252 }
253
254
255 CpuProfile* CpuProfiler::FindProfile(unsigned uid) {
256 ASSERT(singleton_ != NULL);
257 return singleton_->profiles_->GetProfile(uid);
258 }
259
260
261 TickSample* CpuProfiler::TickSampleEvent() {
262 ASSERT(singleton_ != NULL);
263 if (singleton_->is_profiling()) {
264 return singleton_->processor_->TickSampleEvent();
265 } else {
266 return NULL;
267 }
268 }
269
270
271 void CpuProfiler::CallbackEvent(String* name, Address entry_point) {
272 singleton_->processor_->CallbackCreateEvent(
273 Logger::CALLBACK_TAG, CodeEntry::kEmptyNamePrefix, name, entry_point);
274 }
275
276
277 void CpuProfiler::CodeCreateEvent(Logger::LogEventsAndTags tag,
278 Code* code, const char* comment) {
279 singleton_->processor_->CodeCreateEvent(
280 tag, comment, code->address(), code->ExecutableSize());
281 }
282
283
284 void CpuProfiler::CodeCreateEvent(Logger::LogEventsAndTags tag,
285 Code* code, String* name) {
286 singleton_->processor_->CodeCreateEvent(
287 tag,
288 name,
289 Heap::empty_string(),
290 CodeEntry::kNoLineNumberInfo,
291 code->address(),
292 code->ExecutableSize());
293 }
294
295
296 void CpuProfiler::CodeCreateEvent(Logger::LogEventsAndTags tag,
297 Code* code, String* name,
298 String* source, int line) {
299 singleton_->processor_->CodeCreateEvent(
300 tag,
301 name,
302 source,
303 line,
304 code->address(),
305 code->ExecutableSize());
306 }
307
308
309 void CpuProfiler::CodeCreateEvent(Logger::LogEventsAndTags tag,
310 Code* code, int args_count) {
311 singleton_->processor_->CodeCreateEvent(
312 tag,
313 args_count,
314 code->address(),
315 code->ExecutableSize());
316 }
317
318
319 void CpuProfiler::CodeMoveEvent(Address from, Address to) {
320 singleton_->processor_->CodeMoveEvent(from, to);
321 }
322
323
324 void CpuProfiler::CodeDeleteEvent(Address from) {
325 singleton_->processor_->CodeDeleteEvent(from);
326 }
327
328
329 void CpuProfiler::FunctionCreateEvent(JSFunction* function) {
330 singleton_->processor_->FunctionCreateEvent(
331 function->address(), function->code()->address());
332 }
333
334
335 void CpuProfiler::FunctionMoveEvent(Address from, Address to) {
336 singleton_->processor_->FunctionMoveEvent(from, to);
337 }
338
339
340 void CpuProfiler::FunctionDeleteEvent(Address from) {
341 singleton_->processor_->FunctionDeleteEvent(from);
342 }
343
344
345 void CpuProfiler::GetterCallbackEvent(String* name, Address entry_point) {
346 singleton_->processor_->CallbackCreateEvent(
347 Logger::CALLBACK_TAG, "get ", name, entry_point);
348 }
349
350
351 void CpuProfiler::RegExpCodeCreateEvent(Code* code, String* source) {
352 singleton_->processor_->CodeCreateEvent(
353 Logger::REG_EXP_TAG,
354 source,
355 Heap::empty_string(),
356 CodeEntry::kNoLineNumberInfo,
357 code->address(),
358 code->ExecutableSize());
359 }
360
361
362 void CpuProfiler::SetterCallbackEvent(String* name, Address entry_point) {
363 singleton_->processor_->CallbackCreateEvent(
364 Logger::CALLBACK_TAG, "set ", name, entry_point);
365 }
366
367
368 CpuProfiler::CpuProfiler()
369 : profiles_(new CpuProfilesCollection()),
370 next_profile_uid_(1),
371 generator_(NULL),
372 processor_(NULL) {
373 }
374
375
376 CpuProfiler::~CpuProfiler() {
377 delete profiles_;
378 }
379
380
381 void CpuProfiler::StartCollectingProfile(const char* title) {
382 if (profiles_->StartProfiling(title, ++next_profile_uid_)) {
383 StartProcessorIfNotStarted();
384 }
385 }
386
387
388 void CpuProfiler::StartCollectingProfile(String* title) {
389 if (profiles_->StartProfiling(title, ++next_profile_uid_)) {
390 StartProcessorIfNotStarted();
391 }
392 }
393
394
395 void CpuProfiler::StartProcessorIfNotStarted() {
396 if (processor_ == NULL) {
397 generator_ = new ProfileGenerator(profiles_);
398 processor_ = new ProfilerEventsProcessor(generator_);
399 processor_->Start();
400 // Enumerate stuff we already have in the heap.
401 if (Heap::HasBeenSetup()) {
402 Logger::LogCodeObjects();
403 Logger::LogCompiledFunctions();
404 Logger::LogFunctionObjects();
405 Logger::LogAccessorCallbacks();
406 }
407 // Enable stack sampling.
408 Logger::ticker_->Start();
409 }
410 }
411
412
413 CpuProfile* CpuProfiler::StopCollectingProfile(const char* title) {
414 StopProcessorIfLastProfile();
415 CpuProfile* result = profiles_->StopProfiling(title);
416 if (result != NULL) {
417 result->Print();
418 }
419 return result;
420 }
421
422
423 CpuProfile* CpuProfiler::StopCollectingProfile(String* title) {
424 StopProcessorIfLastProfile();
425 return profiles_->StopProfiling(title);
426 }
427
428
429 void CpuProfiler::StopProcessorIfLastProfile() {
430 if (profiles_->is_last_profile()) {
431 Logger::ticker_->Stop();
432 processor_->Stop();
433 processor_->Join();
434 delete processor_;
435 delete generator_;
436 processor_ = NULL;
437 generator_ = NULL;
438 }
439 }
440
199 } } // namespace v8::internal 441 } } // namespace v8::internal
200 442
201 #endif // ENABLE_CPP_PROFILES_PROCESSOR 443 #endif // ENABLE_CPP_PROFILES_PROCESSOR
444
445 namespace v8 {
446 namespace internal {
447
448 void CpuProfiler::Setup() {
449 #ifdef ENABLE_CPP_PROFILES_PROCESSOR
450 if (singleton_ == NULL) {
451 singleton_ = new CpuProfiler();
452 }
453 #endif
454 }
455
456
457 void CpuProfiler::TearDown() {
458 #ifdef ENABLE_CPP_PROFILES_PROCESSOR
459 if (singleton_ != NULL) {
460 delete singleton_;
461 }
462 singleton_ = NULL;
463 #endif
464 }
465
466 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/cpu-profiler.h ('k') | src/cpu-profiler-inl.h » ('j') | src/platform-linux.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698