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

Side by Side Diff: src/sampler.cc

Issue 18620002: Do not store fp and sp values in TickSample (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Removed fp Created 7 years, 5 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 // 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
(...skipping 209 matching lines...) Expand 10 before | Expand all | Expand 10 after
220 } 220 }
221 221
222 HANDLE profiled_thread() { return profiled_thread_; } 222 HANDLE profiled_thread() { return profiled_thread_; }
223 223
224 private: 224 private:
225 HANDLE profiled_thread_; 225 HANDLE profiled_thread_;
226 }; 226 };
227 #endif 227 #endif
228 228
229 229
230 class SampleHelper { 230 #if defined(USE_SIMULATOR)
231 class SimulatorHelper {
231 public: 232 public:
232 inline TickSample* Init(Sampler* sampler, Isolate* isolate) { 233 inline bool Init(Sampler* sampler, Isolate* isolate) {
233 #if defined(USE_SIMULATOR)
234 ThreadId thread_id = sampler->platform_data()->profiled_thread_id(); 234 ThreadId thread_id = sampler->platform_data()->profiled_thread_id();
235 Isolate::PerIsolateThreadData* per_thread_data = isolate-> 235 Isolate::PerIsolateThreadData* per_thread_data = isolate->
236 FindPerThreadDataForThread(thread_id); 236 FindPerThreadDataForThread(thread_id);
237 if (!per_thread_data) return NULL; 237 if (!per_thread_data) return false;
238 simulator_ = per_thread_data->simulator(); 238 simulator_ = per_thread_data->simulator();
239 // Check if there is active simulator before allocating TickSample. 239 // Check if there is active simulator.
240 if (!simulator_) return NULL; 240 return simulator_ != NULL;
241 #endif // USE_SIMULATOR
242 TickSample* sample = isolate->cpu_profiler()->TickSampleEvent();
243 if (sample == NULL) sample = &sample_obj;
244 return sample;
245 } 241 }
246 242
247 #if defined(USE_SIMULATOR) 243 inline void FillRegisters(Sampler::RegisterState* state) {
248 inline void FillRegisters(TickSample* sample) { 244 state->pc = reinterpret_cast<Address>(simulator_->get_pc());
249 sample->pc = reinterpret_cast<Address>(simulator_->get_pc()); 245 state->sp = reinterpret_cast<Address>(simulator_->get_register(
250 sample->sp = reinterpret_cast<Address>(simulator_->get_register(
251 Simulator::sp)); 246 Simulator::sp));
252 #if V8_TARGET_ARCH_ARM 247 #if V8_TARGET_ARCH_ARM
253 sample->fp = reinterpret_cast<Address>(simulator_->get_register( 248 state->fp = reinterpret_cast<Address>(simulator_->get_register(
254 Simulator::r11)); 249 Simulator::r11));
255 #elif V8_TARGET_ARCH_MIPS 250 #elif V8_TARGET_ARCH_MIPS
256 sample->fp = reinterpret_cast<Address>(simulator_->get_register( 251 state->fp = reinterpret_cast<Address>(simulator_->get_register(
257 Simulator::fp)); 252 Simulator::fp));
258 #endif 253 #endif
259 } 254 }
260 #endif // USE_SIMULATOR
261 255
262 private: 256 private:
263 #if defined(USE_SIMULATOR)
264 Simulator* simulator_; 257 Simulator* simulator_;
265 #endif
266 TickSample sample_obj;
267 }; 258 };
259 #endif // USE_SIMULATOR
268 260
269 261
270 #if defined(USE_SIGNALS) 262 #if defined(USE_SIGNALS)
271 263
272 class SignalHandler : public AllStatic { 264 class SignalHandler : public AllStatic {
273 public: 265 public:
274 static inline void EnsureInstalled() { 266 static inline void EnsureInstalled() {
275 if (signal_handler_installed_) return; 267 if (signal_handler_installed_) return;
276 struct sigaction sa; 268 struct sigaction sa;
277 sa.sa_sigaction = &HandleProfilerSignal; 269 sa.sa_sigaction = &HandleProfilerSignal;
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
317 return; 309 return;
318 } 310 }
319 if (v8::Locker::IsActive() && 311 if (v8::Locker::IsActive() &&
320 !isolate->thread_manager()->IsLockedByCurrentThread()) { 312 !isolate->thread_manager()->IsLockedByCurrentThread()) {
321 return; 313 return;
322 } 314 }
323 315
324 Sampler* sampler = isolate->logger()->sampler(); 316 Sampler* sampler = isolate->logger()->sampler();
325 if (sampler == NULL || !sampler->IsActive()) return; 317 if (sampler == NULL || !sampler->IsActive()) return;
326 318
327 SampleHelper helper; 319 RegisterState state;
328 TickSample* sample = helper.Init(sampler, isolate);
329 if (sample == NULL) return;
330 320
331 #if defined(USE_SIMULATOR) 321 #if defined(USE_SIMULATOR)
332 helper.FillRegisters(sample); 322 SimulatorHelper helper;
323 if (!helper.Init(sampler, isolate)) return;
324 helper.FillRegisters(&state);
333 #else 325 #else
334 // Extracting the sample from the context is extremely machine dependent. 326 // Extracting the sample from the context is extremely machine dependent.
335 ucontext_t* ucontext = reinterpret_cast<ucontext_t*>(context); 327 ucontext_t* ucontext = reinterpret_cast<ucontext_t*>(context);
336 mcontext_t& mcontext = ucontext->uc_mcontext; 328 mcontext_t& mcontext = ucontext->uc_mcontext;
337 sample->state = isolate->current_vm_state();
338 #if defined(__linux__) || defined(__ANDROID__) 329 #if defined(__linux__) || defined(__ANDROID__)
339 #if V8_HOST_ARCH_IA32 330 #if V8_HOST_ARCH_IA32
340 sample->pc = reinterpret_cast<Address>(mcontext.gregs[REG_EIP]); 331 state.pc = reinterpret_cast<Address>(mcontext.gregs[REG_EIP]);
341 sample->sp = reinterpret_cast<Address>(mcontext.gregs[REG_ESP]); 332 state.sp = reinterpret_cast<Address>(mcontext.gregs[REG_ESP]);
342 sample->fp = reinterpret_cast<Address>(mcontext.gregs[REG_EBP]); 333 state.fp = reinterpret_cast<Address>(mcontext.gregs[REG_EBP]);
343 #elif V8_HOST_ARCH_X64 334 #elif V8_HOST_ARCH_X64
344 sample->pc = reinterpret_cast<Address>(mcontext.gregs[REG_RIP]); 335 state.pc = reinterpret_cast<Address>(mcontext.gregs[REG_RIP]);
345 sample->sp = reinterpret_cast<Address>(mcontext.gregs[REG_RSP]); 336 state.sp = reinterpret_cast<Address>(mcontext.gregs[REG_RSP]);
346 sample->fp = reinterpret_cast<Address>(mcontext.gregs[REG_RBP]); 337 state.fp = reinterpret_cast<Address>(mcontext.gregs[REG_RBP]);
347 #elif V8_HOST_ARCH_ARM 338 #elif V8_HOST_ARCH_ARM
348 #if defined(__GLIBC__) && !defined(__UCLIBC__) && \ 339 #if defined(__GLIBC__) && !defined(__UCLIBC__) && \
349 (__GLIBC__ < 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ <= 3)) 340 (__GLIBC__ < 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ <= 3))
350 // Old GLibc ARM versions used a gregs[] array to access the register 341 // Old GLibc ARM versions used a gregs[] array to access the register
351 // values from mcontext_t. 342 // values from mcontext_t.
352 sample->pc = reinterpret_cast<Address>(mcontext.gregs[R15]); 343 state.pc = reinterpret_cast<Address>(mcontext.gregs[R15]);
353 sample->sp = reinterpret_cast<Address>(mcontext.gregs[R13]); 344 state.sp = reinterpret_cast<Address>(mcontext.gregs[R13]);
354 sample->fp = reinterpret_cast<Address>(mcontext.gregs[R11]); 345 state.fp = reinterpret_cast<Address>(mcontext.gregs[R11]);
355 #else 346 #else
356 sample->pc = reinterpret_cast<Address>(mcontext.arm_pc); 347 state.pc = reinterpret_cast<Address>(mcontext.arm_pc);
357 sample->sp = reinterpret_cast<Address>(mcontext.arm_sp); 348 state.sp = reinterpret_cast<Address>(mcontext.arm_sp);
358 sample->fp = reinterpret_cast<Address>(mcontext.arm_fp); 349 state.fp = reinterpret_cast<Address>(mcontext.arm_fp);
359 #endif // defined(__GLIBC__) && !defined(__UCLIBC__) && 350 #endif // defined(__GLIBC__) && !defined(__UCLIBC__) &&
360 // (__GLIBC__ < 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ <= 3)) 351 // (__GLIBC__ < 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ <= 3))
361 #elif V8_HOST_ARCH_MIPS 352 #elif V8_HOST_ARCH_MIPS
362 sample->pc = reinterpret_cast<Address>(mcontext.pc); 353 state.pc = reinterpret_cast<Address>(mcontext.pc);
363 sample->sp = reinterpret_cast<Address>(mcontext.gregs[29]); 354 state.sp = reinterpret_cast<Address>(mcontext.gregs[29]);
364 sample->fp = reinterpret_cast<Address>(mcontext.gregs[30]); 355 state.fp = reinterpret_cast<Address>(mcontext.gregs[30]);
365 #endif // V8_HOST_ARCH_* 356 #endif // V8_HOST_ARCH_*
366 #elif defined(__FreeBSD__) 357 #elif defined(__FreeBSD__)
367 #if V8_HOST_ARCH_IA32 358 #if V8_HOST_ARCH_IA32
368 sample->pc = reinterpret_cast<Address>(mcontext.mc_eip); 359 state.pc = reinterpret_cast<Address>(mcontext.mc_eip);
369 sample->sp = reinterpret_cast<Address>(mcontext.mc_esp); 360 state.sp = reinterpret_cast<Address>(mcontext.mc_esp);
370 sample->fp = reinterpret_cast<Address>(mcontext.mc_ebp); 361 state.fp = reinterpret_cast<Address>(mcontext.mc_ebp);
371 #elif V8_HOST_ARCH_X64 362 #elif V8_HOST_ARCH_X64
372 sample->pc = reinterpret_cast<Address>(mcontext.mc_rip); 363 state.pc = reinterpret_cast<Address>(mcontext.mc_rip);
373 sample->sp = reinterpret_cast<Address>(mcontext.mc_rsp); 364 state.sp = reinterpret_cast<Address>(mcontext.mc_rsp);
374 sample->fp = reinterpret_cast<Address>(mcontext.mc_rbp); 365 state.fp = reinterpret_cast<Address>(mcontext.mc_rbp);
375 #elif V8_HOST_ARCH_ARM 366 #elif V8_HOST_ARCH_ARM
376 sample->pc = reinterpret_cast<Address>(mcontext.mc_r15); 367 state.pc = reinterpret_cast<Address>(mcontext.mc_r15);
377 sample->sp = reinterpret_cast<Address>(mcontext.mc_r13); 368 state.sp = reinterpret_cast<Address>(mcontext.mc_r13);
378 sample->fp = reinterpret_cast<Address>(mcontext.mc_r11); 369 state.fp = reinterpret_cast<Address>(mcontext.mc_r11);
379 #endif // V8_HOST_ARCH_* 370 #endif // V8_HOST_ARCH_*
380 #elif defined(__NetBSD__) 371 #elif defined(__NetBSD__)
381 #if V8_HOST_ARCH_IA32 372 #if V8_HOST_ARCH_IA32
382 sample->pc = reinterpret_cast<Address>(mcontext.__gregs[_REG_EIP]); 373 state.pc = reinterpret_cast<Address>(mcontext.__gregs[_REG_EIP]);
383 sample->sp = reinterpret_cast<Address>(mcontext.__gregs[_REG_ESP]); 374 state.sp = reinterpret_cast<Address>(mcontext.__gregs[_REG_ESP]);
384 sample->fp = reinterpret_cast<Address>(mcontext.__gregs[_REG_EBP]); 375 state.fp = reinterpret_cast<Address>(mcontext.__gregs[_REG_EBP]);
385 #elif V8_HOST_ARCH_X64 376 #elif V8_HOST_ARCH_X64
386 sample->pc = reinterpret_cast<Address>(mcontext.__gregs[_REG_RIP]); 377 state.pc = reinterpret_cast<Address>(mcontext.__gregs[_REG_RIP]);
387 sample->sp = reinterpret_cast<Address>(mcontext.__gregs[_REG_RSP]); 378 state.sp = reinterpret_cast<Address>(mcontext.__gregs[_REG_RSP]);
388 sample->fp = reinterpret_cast<Address>(mcontext.__gregs[_REG_RBP]); 379 state.fp = reinterpret_cast<Address>(mcontext.__gregs[_REG_RBP]);
389 #endif // V8_HOST_ARCH_* 380 #endif // V8_HOST_ARCH_*
390 #elif defined(__OpenBSD__) 381 #elif defined(__OpenBSD__)
391 USE(mcontext); 382 USE(mcontext);
392 #if V8_HOST_ARCH_IA32 383 #if V8_HOST_ARCH_IA32
393 sample->pc = reinterpret_cast<Address>(ucontext->sc_eip); 384 state.pc = reinterpret_cast<Address>(ucontext->sc_eip);
394 sample->sp = reinterpret_cast<Address>(ucontext->sc_esp); 385 state.sp = reinterpret_cast<Address>(ucontext->sc_esp);
395 sample->fp = reinterpret_cast<Address>(ucontext->sc_ebp); 386 state.fp = reinterpret_cast<Address>(ucontext->sc_ebp);
396 #elif V8_HOST_ARCH_X64 387 #elif V8_HOST_ARCH_X64
397 sample->pc = reinterpret_cast<Address>(ucontext->sc_rip); 388 state.pc = reinterpret_cast<Address>(ucontext->sc_rip);
398 sample->sp = reinterpret_cast<Address>(ucontext->sc_rsp); 389 state.sp = reinterpret_cast<Address>(ucontext->sc_rsp);
399 sample->fp = reinterpret_cast<Address>(ucontext->sc_rbp); 390 state.fp = reinterpret_cast<Address>(ucontext->sc_rbp);
400 #endif // V8_HOST_ARCH_* 391 #endif // V8_HOST_ARCH_*
401 #elif defined(__sun) 392 #elif defined(__sun)
402 sample->pc = reinterpret_cast<Address>(mcontext.gregs[REG_PC]); 393 state.pc = reinterpret_cast<Address>(mcontext.gregs[REG_PC]);
403 sample->sp = reinterpret_cast<Address>(mcontext.gregs[REG_SP]); 394 state.sp = reinterpret_cast<Address>(mcontext.gregs[REG_SP]);
404 sample->fp = reinterpret_cast<Address>(mcontext.gregs[REG_FP]); 395 state.fp = reinterpret_cast<Address>(mcontext.gregs[REG_FP]);
405 #endif // __sun 396 #endif // __sun
406 #endif // USE_SIMULATOR 397 #endif // USE_SIMULATOR
407 398 sampler->SampleStack(state);
408 sampler->SampleStack(sample);
409 sampler->Tick(sample);
410 #endif // __native_client__ 399 #endif // __native_client__
411 } 400 }
412 401
413 #endif 402 #endif
414 403
415 404
416 class SamplerThread : public Thread { 405 class SamplerThread : public Thread {
417 public: 406 public:
418 static const int kSamplerThreadStackSize = 64 * KB; 407 static const int kSamplerThreadStackSize = 64 * KB;
419 408
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after
498 pthread_t tid = sampler->platform_data()->vm_tid(); 487 pthread_t tid = sampler->platform_data()->vm_tid();
499 pthread_kill(tid, SIGPROF); 488 pthread_kill(tid, SIGPROF);
500 } 489 }
501 490
502 #elif defined(__MACH__) 491 #elif defined(__MACH__)
503 492
504 void SampleContext(Sampler* sampler) { 493 void SampleContext(Sampler* sampler) {
505 thread_act_t profiled_thread = sampler->platform_data()->profiled_thread(); 494 thread_act_t profiled_thread = sampler->platform_data()->profiled_thread();
506 Isolate* isolate = sampler->isolate(); 495 Isolate* isolate = sampler->isolate();
507 496
508 SampleHelper helper; 497 #if defined(USE_SIMULATOR)
509 TickSample* sample = helper.Init(sampler, isolate); 498 SimulatorHelper helper;
510 if (sample == NULL) return; 499 if (!helper.Init(sampler, isolate)) return;
500 #endif
511 501
512 if (KERN_SUCCESS != thread_suspend(profiled_thread)) return; 502 if (KERN_SUCCESS != thread_suspend(profiled_thread)) return;
513 503
514 #if V8_HOST_ARCH_X64 504 #if V8_HOST_ARCH_X64
515 thread_state_flavor_t flavor = x86_THREAD_STATE64; 505 thread_state_flavor_t flavor = x86_THREAD_STATE64;
516 x86_thread_state64_t state; 506 x86_thread_state64_t state;
517 mach_msg_type_number_t count = x86_THREAD_STATE64_COUNT; 507 mach_msg_type_number_t count = x86_THREAD_STATE64_COUNT;
518 #if __DARWIN_UNIX03 508 #if __DARWIN_UNIX03
519 #define REGISTER_FIELD(name) __r ## name 509 #define REGISTER_FIELD(name) __r ## name
520 #else 510 #else
521 #define REGISTER_FIELD(name) r ## name 511 #define REGISTER_FIELD(name) r ## name
522 #endif // __DARWIN_UNIX03 512 #endif // __DARWIN_UNIX03
523 #elif V8_HOST_ARCH_IA32 513 #elif V8_HOST_ARCH_IA32
524 thread_state_flavor_t flavor = i386_THREAD_STATE; 514 thread_state_flavor_t flavor = i386_THREAD_STATE;
525 i386_thread_state_t state; 515 i386_thread_state_t state;
526 mach_msg_type_number_t count = i386_THREAD_STATE_COUNT; 516 mach_msg_type_number_t count = i386_THREAD_STATE_COUNT;
527 #if __DARWIN_UNIX03 517 #if __DARWIN_UNIX03
528 #define REGISTER_FIELD(name) __e ## name 518 #define REGISTER_FIELD(name) __e ## name
529 #else 519 #else
530 #define REGISTER_FIELD(name) e ## name 520 #define REGISTER_FIELD(name) e ## name
531 #endif // __DARWIN_UNIX03 521 #endif // __DARWIN_UNIX03
532 #else 522 #else
533 #error Unsupported Mac OS X host architecture. 523 #error Unsupported Mac OS X host architecture.
534 #endif // V8_HOST_ARCH 524 #endif // V8_HOST_ARCH
535 525
536 if (thread_get_state(profiled_thread, 526 if (thread_get_state(profiled_thread,
537 flavor, 527 flavor,
538 reinterpret_cast<natural_t*>(&state), 528 reinterpret_cast<natural_t*>(&state),
539 &count) == KERN_SUCCESS) { 529 &count) == KERN_SUCCESS) {
540 sample->state = isolate->current_vm_state(); 530 RegisterState state;
541 #if defined(USE_SIMULATOR) 531 #if defined(USE_SIMULATOR)
542 helper.FillRegisters(sample); 532 helper.FillRegisters(&state);
543 #else 533 #else
544 sample->pc = reinterpret_cast<Address>(state.REGISTER_FIELD(ip)); 534 state.pc = reinterpret_cast<Address>(state.REGISTER_FIELD(ip));
545 sample->sp = reinterpret_cast<Address>(state.REGISTER_FIELD(sp)); 535 state.sp = reinterpret_cast<Address>(state.REGISTER_FIELD(sp));
546 sample->fp = reinterpret_cast<Address>(state.REGISTER_FIELD(bp)); 536 state.fp = reinterpret_cast<Address>(state.REGISTER_FIELD(bp));
547 #endif // USE_SIMULATOR 537 #endif // USE_SIMULATOR
548 #undef REGISTER_FIELD 538 #undef REGISTER_FIELD
549 sampler->SampleStack(sample); 539 sampler->SampleStack(state);
550 sampler->Tick(sample);
551 } 540 }
552 thread_resume(profiled_thread); 541 thread_resume(profiled_thread);
553 } 542 }
554 543
555 #elif defined(_WIN32) || defined(_WIN64) || defined(__CYGWIN__) 544 #elif defined(_WIN32) || defined(_WIN64) || defined(__CYGWIN__)
556 545
557 void SampleContext(Sampler* sampler) { 546 void SampleContext(Sampler* sampler) {
558 HANDLE profiled_thread = sampler->platform_data()->profiled_thread(); 547 HANDLE profiled_thread = sampler->platform_data()->profiled_thread();
559 if (profiled_thread == NULL) return; 548 if (profiled_thread == NULL) return;
560 549
561 Isolate* isolate = sampler->isolate(); 550 Isolate* isolate = sampler->isolate();
562 SampleHelper helper; 551 #if defined(USE_SIMULATOR)
563 TickSample* sample = helper.Init(sampler, isolate); 552 SimulatorHelper helper;
564 if (sample == NULL) return; 553 if (!helper.Init(sampler, isolate)) return;
554 #endif
565 555
566 const DWORD kSuspendFailed = static_cast<DWORD>(-1); 556 const DWORD kSuspendFailed = static_cast<DWORD>(-1);
567 if (SuspendThread(profiled_thread) == kSuspendFailed) return; 557 if (SuspendThread(profiled_thread) == kSuspendFailed) return;
568 sample->state = isolate->current_vm_state();
569 558
570 // Context used for sampling the register state of the profiled thread. 559 // Context used for sampling the register state of the profiled thread.
571 CONTEXT context; 560 CONTEXT context;
572 memset(&context, 0, sizeof(context)); 561 memset(&context, 0, sizeof(context));
573 context.ContextFlags = CONTEXT_FULL; 562 context.ContextFlags = CONTEXT_FULL;
574 if (GetThreadContext(profiled_thread, &context) != 0) { 563 if (GetThreadContext(profiled_thread, &context) != 0) {
564 RegisterState state;
575 #if defined(USE_SIMULATOR) 565 #if defined(USE_SIMULATOR)
576 helper.FillRegisters(sample); 566 helper.FillRegisters(&state);
577 #else 567 #else
578 #if V8_HOST_ARCH_X64 568 #if V8_HOST_ARCH_X64
579 sample->pc = reinterpret_cast<Address>(context.Rip); 569 state.pc = reinterpret_cast<Address>(context.Rip);
580 sample->sp = reinterpret_cast<Address>(context.Rsp); 570 state.sp = reinterpret_cast<Address>(context.Rsp);
581 sample->fp = reinterpret_cast<Address>(context.Rbp); 571 state.fp = reinterpret_cast<Address>(context.Rbp);
582 #else 572 #else
583 sample->pc = reinterpret_cast<Address>(context.Eip); 573 state.pc = reinterpret_cast<Address>(context.Eip);
584 sample->sp = reinterpret_cast<Address>(context.Esp); 574 state.sp = reinterpret_cast<Address>(context.Esp);
585 sample->fp = reinterpret_cast<Address>(context.Ebp); 575 state.fp = reinterpret_cast<Address>(context.Ebp);
586 #endif 576 #endif
587 #endif // USE_SIMULATOR 577 #endif // USE_SIMULATOR
588 sampler->SampleStack(sample); 578 sampler->SampleStack(state);
589 sampler->Tick(sample);
590 } 579 }
591 ResumeThread(profiled_thread); 580 ResumeThread(profiled_thread);
592 } 581 }
593 582
594 #endif // USE_SIGNALS 583 #endif // USE_SIGNALS
595 584
596 585
597 // Protects the process wide state below. 586 // Protects the process wide state below.
598 static Mutex* mutex_; 587 static Mutex* mutex_;
599 static SamplerThread* instance_; 588 static SamplerThread* instance_;
600 589
601 const int interval_; 590 const int interval_;
602 List<Sampler*> active_samplers_; 591 List<Sampler*> active_samplers_;
603 592
604 DISALLOW_COPY_AND_ASSIGN(SamplerThread); 593 DISALLOW_COPY_AND_ASSIGN(SamplerThread);
605 }; 594 };
606 595
607 596
608 Mutex* SamplerThread::mutex_ = NULL; 597 Mutex* SamplerThread::mutex_ = NULL;
609 SamplerThread* SamplerThread::instance_ = NULL; 598 SamplerThread* SamplerThread::instance_ = NULL;
610 599
611 600
612 // 601 //
613 // StackTracer implementation 602 // StackTracer implementation
614 // 603 //
615 DISABLE_ASAN void TickSample::Trace(Isolate* isolate) { 604 DISABLE_ASAN void TickSample::Init(Isolate* isolate,
605 const RegisterState& regs) {
616 ASSERT(isolate->IsInitialized()); 606 ASSERT(isolate->IsInitialized());
607 pc = regs.pc;
608 state = isolate->current_vm_state();
617 609
618 // Avoid collecting traces while doing GC. 610 // Avoid collecting traces while doing GC.
619 if (state == GC) return; 611 if (state == GC) return;
620 612
621 const Address js_entry_sp = 613 const Address js_entry_sp =
622 Isolate::js_entry_sp(isolate->thread_local_top()); 614 Isolate::js_entry_sp(isolate->thread_local_top());
623 if (js_entry_sp == 0) { 615 if (js_entry_sp == 0) {
624 // Not executing JS now. 616 // Not executing JS now.
625 return; 617 return;
626 } 618 }
627 619
628 const Address callback = isolate->external_callback(); 620 const Address callback = isolate->external_callback();
629 if (callback != NULL) { 621 if (callback != NULL) {
630 external_callback = callback; 622 external_callback = callback;
631 has_external_callback = true; 623 has_external_callback = true;
632 } else { 624 } else {
633 // Sample potential return address value for frameless invocation of 625 // Sample potential return address value for frameless invocation of
634 // stubs (we'll figure out later, if this value makes sense). 626 // stubs (we'll figure out later, if this value makes sense).
635 tos = Memory::Address_at(sp); 627 tos = Memory::Address_at(regs.sp);
636 has_external_callback = false; 628 has_external_callback = false;
637 } 629 }
638 630
639 SafeStackFrameIterator it(isolate, fp, sp, sp, js_entry_sp); 631 SafeStackFrameIterator it(isolate, regs.fp, regs.sp, js_entry_sp);
640 top_frame_type = it.top_frame_type(); 632 top_frame_type = it.top_frame_type();
641 int i = 0; 633 int i = 0;
642 while (!it.done() && i < TickSample::kMaxFramesCount) { 634 while (!it.done() && i < TickSample::kMaxFramesCount) {
643 stack[i++] = it.frame()->pc(); 635 stack[i++] = it.frame()->pc();
644 it.Advance(); 636 it.Advance();
645 } 637 }
646 frames_count = i; 638 frames_count = i;
647 } 639 }
648 640
649 641
(...skipping 28 matching lines...) Expand all
678 SamplerThread::AddActiveSampler(this); 670 SamplerThread::AddActiveSampler(this);
679 } 671 }
680 672
681 673
682 void Sampler::Stop() { 674 void Sampler::Stop() {
683 ASSERT(IsActive()); 675 ASSERT(IsActive());
684 SamplerThread::RemoveActiveSampler(this); 676 SamplerThread::RemoveActiveSampler(this);
685 SetActive(false); 677 SetActive(false);
686 } 678 }
687 679
688 void Sampler::SampleStack(TickSample* sample) { 680 void Sampler::SampleStack(const RegisterState& state) {
689 sample->Trace(isolate_); 681 TickSample* sample = isolate_->cpu_profiler()->TickSampleEvent();
682 TickSample sample_obj;
683 if (sample == NULL) sample = &sample_obj;
684 sample->Init(isolate_, state);
690 if (++samples_taken_ < 0) samples_taken_ = 0; 685 if (++samples_taken_ < 0) samples_taken_ = 0;
686 Tick(sample);
691 } 687 }
692 688
693 } } // namespace v8::internal 689 } } // namespace v8::internal
OLDNEW
« src/frames.cc ('K') | « src/sampler.h ('k') | test/cctest/test-log-stack-tracer.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698