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

Side by Side Diff: src/sampler.cc

Issue 578163002: Implemented GetSample. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Including win32-headers.h in v8.h for testing on trybots. Created 6 years, 3 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 | Annotate | Revision Log
OLDNEW
1 // Copyright 2013 the V8 project authors. All rights reserved. 1 // Copyright 2013 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "src/sampler.h" 5 #include "src/sampler.h"
6 6
7 #if V8_OS_POSIX && !V8_OS_CYGWIN 7 #if V8_OS_POSIX && !V8_OS_CYGWIN
8 8
9 #define USE_SIGNALS 9 #define USE_SIGNALS
10 10
(...skipping 214 matching lines...) Expand 10 before | Expand all | Expand 10 after
225 225
226 #if defined(USE_SIMULATOR) 226 #if defined(USE_SIMULATOR)
227 class SimulatorHelper { 227 class SimulatorHelper {
228 public: 228 public:
229 inline bool Init(Sampler* sampler, Isolate* isolate) { 229 inline bool Init(Sampler* sampler, Isolate* isolate) {
230 simulator_ = isolate->thread_local_top()->simulator_; 230 simulator_ = isolate->thread_local_top()->simulator_;
231 // Check if there is active simulator. 231 // Check if there is active simulator.
232 return simulator_ != NULL; 232 return simulator_ != NULL;
233 } 233 }
234 234
235 inline void FillRegisters(RegisterState* state) { 235 inline void FillRegisters(v8::RegisterState* state) {
236 #if V8_TARGET_ARCH_ARM 236 #if V8_TARGET_ARCH_ARM
237 state->pc = reinterpret_cast<Address>(simulator_->get_pc()); 237 state->pc = reinterpret_cast<Address>(simulator_->get_pc());
238 state->sp = reinterpret_cast<Address>(simulator_->get_register( 238 state->sp = reinterpret_cast<Address>(simulator_->get_register(
239 Simulator::sp)); 239 Simulator::sp));
240 state->fp = reinterpret_cast<Address>(simulator_->get_register( 240 state->fp = reinterpret_cast<Address>(simulator_->get_register(
241 Simulator::r11)); 241 Simulator::r11));
242 #elif V8_TARGET_ARCH_ARM64 242 #elif V8_TARGET_ARCH_ARM64
243 if (simulator_->sp() == 0 || simulator_->fp() == 0) { 243 if (simulator_->sp() == 0 || simulator_->fp() == 0) {
244 // It possible that the simulator is interrupted while it is updating 244 // It possible that the simulator is interrupted while it is updating
245 // the sp or fp register. ARM64 simulator does this in two steps: 245 // the sp or fp register. ARM64 simulator does this in two steps:
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after
346 return; 346 return;
347 } 347 }
348 if (v8::Locker::IsActive() && 348 if (v8::Locker::IsActive() &&
349 !isolate->thread_manager()->IsLockedByCurrentThread()) { 349 !isolate->thread_manager()->IsLockedByCurrentThread()) {
350 return; 350 return;
351 } 351 }
352 352
353 Sampler* sampler = isolate->logger()->sampler(); 353 Sampler* sampler = isolate->logger()->sampler();
354 if (sampler == NULL) return; 354 if (sampler == NULL) return;
355 355
356 RegisterState state;
357 356
358 #if defined(USE_SIMULATOR) 357 #if defined(USE_SIMULATOR)
358 v8::RegisterState state;
359 SimulatorHelper helper; 359 SimulatorHelper helper;
360 if (!helper.Init(sampler, isolate)) return; 360 if (!helper.Init(sampler, isolate)) return;
361 helper.FillRegisters(&state); 361 helper.FillRegisters(&state);
362 // It possible that the simulator is interrupted while it is updating 362 // It possible that the simulator is interrupted while it is updating
363 // the sp or fp register. ARM64 simulator does this in two steps: 363 // the sp or fp register. ARM64 simulator does this in two steps:
364 // first setting it to zero and then setting it to the new value. 364 // first setting it to zero and then setting it to the new value.
365 // Bailout if sp/fp doesn't contain the new value. 365 // Bailout if sp/fp doesn't contain the new value.
366 if (state.sp == 0 || state.fp == 0) return; 366 if (state.sp == 0 || state.fp == 0) return;
367 #else 367 #else
368 // Extracting the sample from the context is extremely machine dependent.
369 ucontext_t* ucontext = reinterpret_cast<ucontext_t*>(context); 368 ucontext_t* ucontext = reinterpret_cast<ucontext_t*>(context);
370 #if !V8_OS_OPENBSD 369 v8::RegisterState state(*ucontext);
371 mcontext_t& mcontext = ucontext->uc_mcontext;
372 #endif
373 #if V8_OS_LINUX
374 #if V8_HOST_ARCH_IA32
375 state.pc = reinterpret_cast<Address>(mcontext.gregs[REG_EIP]);
376 state.sp = reinterpret_cast<Address>(mcontext.gregs[REG_ESP]);
377 state.fp = reinterpret_cast<Address>(mcontext.gregs[REG_EBP]);
378 #elif V8_HOST_ARCH_X64
379 state.pc = reinterpret_cast<Address>(mcontext.gregs[REG_RIP]);
380 state.sp = reinterpret_cast<Address>(mcontext.gregs[REG_RSP]);
381 state.fp = reinterpret_cast<Address>(mcontext.gregs[REG_RBP]);
382 #elif V8_HOST_ARCH_ARM
383 #if defined(__GLIBC__) && !defined(__UCLIBC__) && \
384 (__GLIBC__ < 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ <= 3))
385 // Old GLibc ARM versions used a gregs[] array to access the register
386 // values from mcontext_t.
387 state.pc = reinterpret_cast<Address>(mcontext.gregs[R15]);
388 state.sp = reinterpret_cast<Address>(mcontext.gregs[R13]);
389 state.fp = reinterpret_cast<Address>(mcontext.gregs[R11]);
390 #else
391 state.pc = reinterpret_cast<Address>(mcontext.arm_pc);
392 state.sp = reinterpret_cast<Address>(mcontext.arm_sp);
393 state.fp = reinterpret_cast<Address>(mcontext.arm_fp);
394 #endif // defined(__GLIBC__) && !defined(__UCLIBC__) &&
395 // (__GLIBC__ < 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ <= 3))
396 #elif V8_HOST_ARCH_ARM64
397 state.pc = reinterpret_cast<Address>(mcontext.pc);
398 state.sp = reinterpret_cast<Address>(mcontext.sp);
399 // FP is an alias for x29.
400 state.fp = reinterpret_cast<Address>(mcontext.regs[29]);
401 #elif V8_HOST_ARCH_MIPS
402 state.pc = reinterpret_cast<Address>(mcontext.pc);
403 state.sp = reinterpret_cast<Address>(mcontext.gregs[29]);
404 state.fp = reinterpret_cast<Address>(mcontext.gregs[30]);
405 #elif V8_HOST_ARCH_MIPS64
406 state.pc = reinterpret_cast<Address>(mcontext.pc);
407 state.sp = reinterpret_cast<Address>(mcontext.gregs[29]);
408 state.fp = reinterpret_cast<Address>(mcontext.gregs[30]);
409 #endif // V8_HOST_ARCH_*
410 #elif V8_OS_MACOSX
411 #if V8_HOST_ARCH_X64
412 #if __DARWIN_UNIX03
413 state.pc = reinterpret_cast<Address>(mcontext->__ss.__rip);
414 state.sp = reinterpret_cast<Address>(mcontext->__ss.__rsp);
415 state.fp = reinterpret_cast<Address>(mcontext->__ss.__rbp);
416 #else // !__DARWIN_UNIX03
417 state.pc = reinterpret_cast<Address>(mcontext->ss.rip);
418 state.sp = reinterpret_cast<Address>(mcontext->ss.rsp);
419 state.fp = reinterpret_cast<Address>(mcontext->ss.rbp);
420 #endif // __DARWIN_UNIX03
421 #elif V8_HOST_ARCH_IA32
422 #if __DARWIN_UNIX03
423 state.pc = reinterpret_cast<Address>(mcontext->__ss.__eip);
424 state.sp = reinterpret_cast<Address>(mcontext->__ss.__esp);
425 state.fp = reinterpret_cast<Address>(mcontext->__ss.__ebp);
426 #else // !__DARWIN_UNIX03
427 state.pc = reinterpret_cast<Address>(mcontext->ss.eip);
428 state.sp = reinterpret_cast<Address>(mcontext->ss.esp);
429 state.fp = reinterpret_cast<Address>(mcontext->ss.ebp);
430 #endif // __DARWIN_UNIX03
431 #endif // V8_HOST_ARCH_IA32
432 #elif V8_OS_FREEBSD
433 #if V8_HOST_ARCH_IA32
434 state.pc = reinterpret_cast<Address>(mcontext.mc_eip);
435 state.sp = reinterpret_cast<Address>(mcontext.mc_esp);
436 state.fp = reinterpret_cast<Address>(mcontext.mc_ebp);
437 #elif V8_HOST_ARCH_X64
438 state.pc = reinterpret_cast<Address>(mcontext.mc_rip);
439 state.sp = reinterpret_cast<Address>(mcontext.mc_rsp);
440 state.fp = reinterpret_cast<Address>(mcontext.mc_rbp);
441 #elif V8_HOST_ARCH_ARM
442 state.pc = reinterpret_cast<Address>(mcontext.mc_r15);
443 state.sp = reinterpret_cast<Address>(mcontext.mc_r13);
444 state.fp = reinterpret_cast<Address>(mcontext.mc_r11);
445 #endif // V8_HOST_ARCH_*
446 #elif V8_OS_NETBSD
447 #if V8_HOST_ARCH_IA32
448 state.pc = reinterpret_cast<Address>(mcontext.__gregs[_REG_EIP]);
449 state.sp = reinterpret_cast<Address>(mcontext.__gregs[_REG_ESP]);
450 state.fp = reinterpret_cast<Address>(mcontext.__gregs[_REG_EBP]);
451 #elif V8_HOST_ARCH_X64
452 state.pc = reinterpret_cast<Address>(mcontext.__gregs[_REG_RIP]);
453 state.sp = reinterpret_cast<Address>(mcontext.__gregs[_REG_RSP]);
454 state.fp = reinterpret_cast<Address>(mcontext.__gregs[_REG_RBP]);
455 #endif // V8_HOST_ARCH_*
456 #elif V8_OS_OPENBSD
457 #if V8_HOST_ARCH_IA32
458 state.pc = reinterpret_cast<Address>(ucontext->sc_eip);
459 state.sp = reinterpret_cast<Address>(ucontext->sc_esp);
460 state.fp = reinterpret_cast<Address>(ucontext->sc_ebp);
461 #elif V8_HOST_ARCH_X64
462 state.pc = reinterpret_cast<Address>(ucontext->sc_rip);
463 state.sp = reinterpret_cast<Address>(ucontext->sc_rsp);
464 state.fp = reinterpret_cast<Address>(ucontext->sc_rbp);
465 #endif // V8_HOST_ARCH_*
466 #elif V8_OS_SOLARIS
467 state.pc = reinterpret_cast<Address>(mcontext.gregs[REG_PC]);
468 state.sp = reinterpret_cast<Address>(mcontext.gregs[REG_SP]);
469 state.fp = reinterpret_cast<Address>(mcontext.gregs[REG_FP]);
470 #elif V8_OS_QNX
471 #if V8_HOST_ARCH_IA32
472 state.pc = reinterpret_cast<Address>(mcontext.cpu.eip);
473 state.sp = reinterpret_cast<Address>(mcontext.cpu.esp);
474 state.fp = reinterpret_cast<Address>(mcontext.cpu.ebp);
475 #elif V8_HOST_ARCH_ARM
476 state.pc = reinterpret_cast<Address>(mcontext.cpu.gpr[ARM_REG_PC]);
477 state.sp = reinterpret_cast<Address>(mcontext.cpu.gpr[ARM_REG_SP]);
478 state.fp = reinterpret_cast<Address>(mcontext.cpu.gpr[ARM_REG_FP]);
479 #endif // V8_HOST_ARCH_*
480 #endif // V8_OS_QNX
481 #endif // USE_SIMULATOR 370 #endif // USE_SIMULATOR
482 sampler->SampleStack(state); 371 sampler->SampleStack(state);
483 } 372 }
484 #endif // V8_OS_NACL 373 #endif // V8_OS_NACL
485 374
486 #endif 375 #endif
487 376
488 377
489 class SamplerThread : public base::Thread { 378 class SamplerThread : public base::Thread {
490 public: 379 public:
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after
570 459
571 460
572 base::Mutex* SamplerThread::mutex_ = NULL; 461 base::Mutex* SamplerThread::mutex_ = NULL;
573 SamplerThread* SamplerThread::instance_ = NULL; 462 SamplerThread* SamplerThread::instance_ = NULL;
574 463
575 464
576 // 465 //
577 // StackTracer implementation 466 // StackTracer implementation
578 // 467 //
579 DISABLE_ASAN void TickSample::Init(Isolate* isolate, 468 DISABLE_ASAN void TickSample::Init(Isolate* isolate,
580 const RegisterState& regs) { 469 const v8::RegisterState& regs) {
581 DCHECK(isolate->IsInitialized()); 470 DCHECK(isolate->IsInitialized());
582 timestamp = base::TimeTicks::HighResolutionNow(); 471 timestamp = base::TimeTicks::HighResolutionNow();
583 pc = regs.pc; 472 pc = reinterpret_cast<Address>(regs.pc);
584 state = isolate->current_vm_state(); 473 state = isolate->current_vm_state();
585 474
586 // Avoid collecting traces while doing GC. 475 // Avoid collecting traces while doing GC.
587 if (state == GC) return; 476 if (state == GC) return;
588 477
589 Address js_entry_sp = isolate->js_entry_sp(); 478 Address js_entry_sp = isolate->js_entry_sp();
590 if (js_entry_sp == 0) { 479 if (js_entry_sp == 0) {
591 // Not executing JS now. 480 // Not executing JS now.
592 return; 481 return;
593 } 482 }
594 483
595 ExternalCallbackScope* scope = isolate->external_callback_scope(); 484 ExternalCallbackScope* scope = isolate->external_callback_scope();
596 Address handler = Isolate::handler(isolate->thread_local_top()); 485 Address handler = Isolate::handler(isolate->thread_local_top());
597 // If there is a handler on top of the external callback scope then 486 // If there is a handler on top of the external callback scope then
598 // we have already entrered JavaScript again and the external callback 487 // we have already entrered JavaScript again and the external callback
599 // is not the top function. 488 // is not the top function.
600 if (scope && scope->scope_address() < handler) { 489 if (scope && scope->scope_address() < handler) {
601 external_callback = scope->callback(); 490 external_callback = scope->callback();
602 has_external_callback = true; 491 has_external_callback = true;
603 } else { 492 } else {
604 // Sample potential return address value for frameless invocation of 493 // Sample potential return address value for frameless invocation of
605 // stubs (we'll figure out later, if this value makes sense). 494 // stubs (we'll figure out later, if this value makes sense).
606 tos = Memory::Address_at(regs.sp); 495 tos = Memory::Address_at(reinterpret_cast<Address>(regs.sp));
607 has_external_callback = false; 496 has_external_callback = false;
608 } 497 }
609 498
610 SafeStackFrameIterator it(isolate, regs.fp, regs.sp, js_entry_sp); 499 SafeStackFrameIterator it(isolate, reinterpret_cast<Address>(regs.fp),
500 reinterpret_cast<Address>(regs.sp), js_entry_sp);
611 top_frame_type = it.top_frame_type(); 501 top_frame_type = it.top_frame_type();
612 unsigned i = 0; 502 unsigned i = 0;
613 while (!it.done() && i < TickSample::kMaxFramesCount) { 503 while (!it.done() && i < TickSample::kMaxFramesCount) {
614 stack[i++] = it.frame()->pc(); 504 stack[i++] = it.frame()->pc();
615 it.Advance(); 505 it.Advance();
616 } 506 }
617 frames_count = i; 507 frames_count = i;
618 } 508 }
619 509
620 510
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
675 565
676 566
677 void Sampler::DecreaseProfilingDepth() { 567 void Sampler::DecreaseProfilingDepth() {
678 #if defined(USE_SIGNALS) 568 #if defined(USE_SIGNALS)
679 SignalHandler::DecreaseSamplerCount(); 569 SignalHandler::DecreaseSamplerCount();
680 #endif 570 #endif
681 base::NoBarrier_AtomicIncrement(&profiling_, -1); 571 base::NoBarrier_AtomicIncrement(&profiling_, -1);
682 } 572 }
683 573
684 574
685 void Sampler::SampleStack(const RegisterState& state) { 575 void Sampler::SampleStack(const v8::RegisterState& state) {
686 TickSample* sample = isolate_->cpu_profiler()->StartTickSample(); 576 TickSample* sample = isolate_->cpu_profiler()->StartTickSample();
687 TickSample sample_obj; 577 TickSample sample_obj;
688 if (sample == NULL) sample = &sample_obj; 578 if (sample == NULL) sample = &sample_obj;
689 sample->Init(isolate_, state); 579 sample->Init(isolate_, state);
690 if (is_counting_samples_) { 580 if (is_counting_samples_) {
691 if (sample->state == JS || sample->state == EXTERNAL) { 581 if (sample->state == JS || sample->state == EXTERNAL) {
692 ++js_and_external_sample_count_; 582 ++js_and_external_sample_count_;
693 } 583 }
694 } 584 }
695 Tick(sample); 585 Tick(sample);
(...skipping 22 matching lines...) Expand all
718 #endif 608 #endif
719 609
720 const DWORD kSuspendFailed = static_cast<DWORD>(-1); 610 const DWORD kSuspendFailed = static_cast<DWORD>(-1);
721 if (SuspendThread(profiled_thread) == kSuspendFailed) return; 611 if (SuspendThread(profiled_thread) == kSuspendFailed) return;
722 612
723 // Context used for sampling the register state of the profiled thread. 613 // Context used for sampling the register state of the profiled thread.
724 CONTEXT context; 614 CONTEXT context;
725 memset(&context, 0, sizeof(context)); 615 memset(&context, 0, sizeof(context));
726 context.ContextFlags = CONTEXT_FULL; 616 context.ContextFlags = CONTEXT_FULL;
727 if (GetThreadContext(profiled_thread, &context) != 0) { 617 if (GetThreadContext(profiled_thread, &context) != 0) {
728 RegisterState state;
729 #if defined(USE_SIMULATOR) 618 #if defined(USE_SIMULATOR)
619 v8::RegisterState state;
730 helper.FillRegisters(&state); 620 helper.FillRegisters(&state);
731 #else 621 #else
732 #if V8_HOST_ARCH_X64 622 v8::RegisterState state(context);
733 state.pc = reinterpret_cast<Address>(context.Rip);
734 state.sp = reinterpret_cast<Address>(context.Rsp);
735 state.fp = reinterpret_cast<Address>(context.Rbp);
736 #else
737 state.pc = reinterpret_cast<Address>(context.Eip);
738 state.sp = reinterpret_cast<Address>(context.Esp);
739 state.fp = reinterpret_cast<Address>(context.Ebp);
740 #endif 623 #endif
741 #endif // USE_SIMULATOR
742 SampleStack(state); 624 SampleStack(state);
743 } 625 }
744 ResumeThread(profiled_thread); 626 ResumeThread(profiled_thread);
745 } 627 }
746 628
747 #endif // USE_SIGNALS 629 #endif // USE_SIGNALS
748 630
749 631
750 } } // namespace v8::internal 632 } } // namespace v8::internal
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698