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

Side by Side Diff: src/profiler/sampler.cc

Issue 1926863003: Make Isolate::GetStackSample API support simulator (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 4 years, 7 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/profiler/sampler.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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/profiler/sampler.h" 5 #include "src/profiler/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 314 matching lines...) Expand 10 before | Expand all | Expand 10 after
325 325
326 HANDLE profiled_thread() { return profiled_thread_; } 326 HANDLE profiled_thread() { return profiled_thread_; }
327 327
328 private: 328 private:
329 HANDLE profiled_thread_; 329 HANDLE profiled_thread_;
330 }; 330 };
331 #endif 331 #endif
332 332
333 333
334 #if defined(USE_SIMULATOR) 334 #if defined(USE_SIMULATOR)
335 class SimulatorHelper { 335 bool SimulatorHelper::FillRegisters(Isolate* isolate,
336 public: 336 v8::RegisterState* state) {
337 inline bool Init(Isolate* isolate) { 337 Simulator *simulator = isolate->thread_local_top()->simulator_;
338 simulator_ = isolate->thread_local_top()->simulator_; 338 // Check if there is active simulator.
339 // Check if there is active simulator. 339 if (simulator == NULL) return false;
340 return simulator_ != NULL; 340 #if V8_TARGET_ARCH_ARM
341 if (!simulator->has_bad_pc()) {
342 state->pc = reinterpret_cast<Address>(simulator->get_pc());
341 } 343 }
342 344 state->sp = reinterpret_cast<Address>(simulator->get_register(Simulator::sp));
343 inline void FillRegisters(v8::RegisterState* state) { 345 state->fp = reinterpret_cast<Address>(simulator->get_register(
344 #if V8_TARGET_ARCH_ARM 346 Simulator::r11));
345 if (!simulator_->has_bad_pc()) {
346 state->pc = reinterpret_cast<Address>(simulator_->get_pc());
347 }
348 state->sp = reinterpret_cast<Address>(simulator_->get_register(
349 Simulator::sp));
350 state->fp = reinterpret_cast<Address>(simulator_->get_register(
351 Simulator::r11));
352 #elif V8_TARGET_ARCH_ARM64 347 #elif V8_TARGET_ARCH_ARM64
353 if (simulator_->sp() == 0 || simulator_->fp() == 0) { 348 state->pc = reinterpret_cast<Address>(simulator->pc());
354 // It's possible that the simulator is interrupted while it is updating 349 state->sp = reinterpret_cast<Address>(simulator->sp());
355 // the sp or fp register. ARM64 simulator does this in two steps: 350 state->fp = reinterpret_cast<Address>(simulator->fp());
356 // first setting it to zero and then setting it to a new value.
357 // Bailout if sp/fp doesn't contain the new value.
358 //
359 // FIXME: The above doesn't really solve the issue.
360 // If a 64-bit target is executed on a 32-bit host even the final
361 // write is non-atomic, so it might obtain a half of the result.
362 // Moreover as long as the register set code uses memcpy (as of now),
363 // it is not guaranteed to be atomic even when both host and target
364 // are of same bitness.
365 return;
366 }
367 state->pc = reinterpret_cast<Address>(simulator_->pc());
368 state->sp = reinterpret_cast<Address>(simulator_->sp());
369 state->fp = reinterpret_cast<Address>(simulator_->fp());
370 #elif V8_TARGET_ARCH_MIPS || V8_TARGET_ARCH_MIPS64 351 #elif V8_TARGET_ARCH_MIPS || V8_TARGET_ARCH_MIPS64
371 if (!simulator_->has_bad_pc()) { 352 if (!simulator->has_bad_pc()) {
372 state->pc = reinterpret_cast<Address>(simulator_->get_pc()); 353 state->pc = reinterpret_cast<Address>(simulator->get_pc());
373 } 354 }
374 state->sp = reinterpret_cast<Address>(simulator_->get_register( 355 state->sp = reinterpret_cast<Address>(simulator->get_register(Simulator::sp));
375 Simulator::sp)); 356 state->fp = reinterpret_cast<Address>(simulator->get_register(Simulator::fp));
376 state->fp = reinterpret_cast<Address>(simulator_->get_register(
377 Simulator::fp));
378 #elif V8_TARGET_ARCH_PPC 357 #elif V8_TARGET_ARCH_PPC
379 if (!simulator_->has_bad_pc()) { 358 if (!simulator->has_bad_pc()) {
380 state->pc = reinterpret_cast<Address>(simulator_->get_pc()); 359 state->pc = reinterpret_cast<Address>(simulator->get_pc());
381 } 360 }
382 state->sp = 361 state->sp = reinterpret_cast<Address>(simulator->get_register(Simulator::sp));
383 reinterpret_cast<Address>(simulator_->get_register(Simulator::sp)); 362 state->fp = reinterpret_cast<Address>(simulator->get_register(Simulator::fp));
384 state->fp =
385 reinterpret_cast<Address>(simulator_->get_register(Simulator::fp));
386 #elif V8_TARGET_ARCH_S390 363 #elif V8_TARGET_ARCH_S390
387 if (!simulator_->has_bad_pc()) { 364 if (!simulator->has_bad_pc()) {
388 state->pc = reinterpret_cast<Address>(simulator_->get_pc()); 365 state->pc = reinterpret_cast<Address>(simulator->get_pc());
389 } 366 }
390 state->sp = 367 state->sp = reinterpret_cast<Address>(simulator->get_register(Simulator::sp));
391 reinterpret_cast<Address>(simulator_->get_register(Simulator::sp)); 368 state->fp = reinterpret_cast<Address>(simulator->get_register(Simulator::fp));
392 state->fp =
393 reinterpret_cast<Address>(simulator_->get_register(Simulator::fp));
394 #endif 369 #endif
370 if (state->sp == 0 || state->fp == 0) {
371 // It possible that the simulator is interrupted while it is updating
372 // the sp or fp register. ARM64 simulator does this in two steps:
373 // first setting it to zero and then setting it to the new value.
374 // Bailout if sp/fp doesn't contain the new value.
375 //
376 // FIXME: The above doesn't really solve the issue.
377 // If a 64-bit target is executed on a 32-bit host even the final
378 // write is non-atomic, so it might obtain a half of the result.
379 // Moreover as long as the register set code uses memcpy (as of now),
380 // it is not guaranteed to be atomic even when both host and target
381 // are of same bitness.
382 return false;
395 } 383 }
396 384 return true;
397 private: 385 }
398 Simulator* simulator_;
399 };
400 #endif // USE_SIMULATOR 386 #endif // USE_SIMULATOR
401 387
402 388
403 #if defined(USE_SIGNALS) 389 #if defined(USE_SIGNALS)
404 390
405 class SignalHandler : public AllStatic { 391 class SignalHandler : public AllStatic {
406 public: 392 public:
407 static void SetUp() { if (!mutex_) mutex_ = new base::Mutex(); } 393 static void SetUp() { if (!mutex_) mutex_ = new base::Mutex(); }
408 static void TearDown() { delete mutex_; mutex_ = NULL; } 394 static void TearDown() { delete mutex_; mutex_ = NULL; }
409 395
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
480 if (isolate == NULL || !isolate->IsInUse()) return; 466 if (isolate == NULL || !isolate->IsInUse()) return;
481 467
482 if (v8::Locker::IsActive() && 468 if (v8::Locker::IsActive() &&
483 !isolate->thread_manager()->IsLockedByCurrentThread()) { 469 !isolate->thread_manager()->IsLockedByCurrentThread()) {
484 return; 470 return;
485 } 471 }
486 472
487 v8::RegisterState state; 473 v8::RegisterState state;
488 474
489 #if defined(USE_SIMULATOR) 475 #if defined(USE_SIMULATOR)
490 SimulatorHelper helper; 476 if (!SimulatorHelper::FillRegisters(isolate, &state)) return;
491 if (!helper.Init(isolate)) return;
492 helper.FillRegisters(&state);
493 // It possible that the simulator is interrupted while it is updating
494 // the sp or fp register. ARM64 simulator does this in two steps:
495 // first setting it to zero and then setting it to the new value.
496 // Bailout if sp/fp doesn't contain the new value.
497 if (state.sp == 0 || state.fp == 0) return;
498 #else 477 #else
499 // Extracting the sample from the context is extremely machine dependent. 478 // Extracting the sample from the context is extremely machine dependent.
500 ucontext_t* ucontext = reinterpret_cast<ucontext_t*>(context); 479 ucontext_t* ucontext = reinterpret_cast<ucontext_t*>(context);
501 #if !(V8_OS_OPENBSD || (V8_OS_LINUX && (V8_HOST_ARCH_PPC || V8_HOST_ARCH_S390))) 480 #if !(V8_OS_OPENBSD || (V8_OS_LINUX && (V8_HOST_ARCH_PPC || V8_HOST_ARCH_S390)))
502 mcontext_t& mcontext = ucontext->uc_mcontext; 481 mcontext_t& mcontext = ucontext->uc_mcontext;
503 #endif 482 #endif
504 #if V8_OS_LINUX 483 #if V8_OS_LINUX
505 #if V8_HOST_ARCH_IA32 484 #if V8_HOST_ARCH_IA32
506 state.pc = reinterpret_cast<Address>(mcontext.gregs[REG_EIP]); 485 state.pc = reinterpret_cast<Address>(mcontext.gregs[REG_EIP]);
507 state.sp = reinterpret_cast<Address>(mcontext.gregs[REG_ESP]); 486 state.sp = reinterpret_cast<Address>(mcontext.gregs[REG_ESP]);
(...skipping 508 matching lines...) Expand 10 before | Expand all | Expand 10 after
1016 } 995 }
1017 pthread_kill(platform_data()->vm_tid(), SIGPROF); 996 pthread_kill(platform_data()->vm_tid(), SIGPROF);
1018 } 997 }
1019 998
1020 #elif V8_OS_WIN || V8_OS_CYGWIN 999 #elif V8_OS_WIN || V8_OS_CYGWIN
1021 1000
1022 void Sampler::DoSample() { 1001 void Sampler::DoSample() {
1023 HANDLE profiled_thread = platform_data()->profiled_thread(); 1002 HANDLE profiled_thread = platform_data()->profiled_thread();
1024 if (profiled_thread == NULL) return; 1003 if (profiled_thread == NULL) return;
1025 1004
1026 #if defined(USE_SIMULATOR)
1027 SimulatorHelper helper;
1028 if (!helper.Init(isolate())) return;
1029 #endif
1030
1031 const DWORD kSuspendFailed = static_cast<DWORD>(-1); 1005 const DWORD kSuspendFailed = static_cast<DWORD>(-1);
1032 if (SuspendThread(profiled_thread) == kSuspendFailed) return; 1006 if (SuspendThread(profiled_thread) == kSuspendFailed) return;
1033 1007
1034 // Context used for sampling the register state of the profiled thread. 1008 // Context used for sampling the register state of the profiled thread.
1035 CONTEXT context; 1009 CONTEXT context;
1036 memset(&context, 0, sizeof(context)); 1010 memset(&context, 0, sizeof(context));
1037 context.ContextFlags = CONTEXT_FULL; 1011 context.ContextFlags = CONTEXT_FULL;
1038 if (GetThreadContext(profiled_thread, &context) != 0) { 1012 if (GetThreadContext(profiled_thread, &context) != 0) {
1039 v8::RegisterState state; 1013 v8::RegisterState state;
1040 #if defined(USE_SIMULATOR) 1014 #if defined(USE_SIMULATOR)
1041 helper.FillRegisters(&state); 1015 if (!SimulatorHelper::FillRegisters(isolate(), &state)) {
1016 ResumeThread(profiled_thread);
1017 return;
1018 }
1042 #else 1019 #else
1043 #if V8_HOST_ARCH_X64 1020 #if V8_HOST_ARCH_X64
1044 state.pc = reinterpret_cast<Address>(context.Rip); 1021 state.pc = reinterpret_cast<Address>(context.Rip);
1045 state.sp = reinterpret_cast<Address>(context.Rsp); 1022 state.sp = reinterpret_cast<Address>(context.Rsp);
1046 state.fp = reinterpret_cast<Address>(context.Rbp); 1023 state.fp = reinterpret_cast<Address>(context.Rbp);
1047 #else 1024 #else
1048 state.pc = reinterpret_cast<Address>(context.Eip); 1025 state.pc = reinterpret_cast<Address>(context.Eip);
1049 state.sp = reinterpret_cast<Address>(context.Esp); 1026 state.sp = reinterpret_cast<Address>(context.Esp);
1050 state.fp = reinterpret_cast<Address>(context.Ebp); 1027 state.fp = reinterpret_cast<Address>(context.Ebp);
1051 #endif 1028 #endif
1052 #endif // USE_SIMULATOR 1029 #endif // USE_SIMULATOR
1053 SampleStack(state); 1030 SampleStack(state);
1054 } 1031 }
1055 ResumeThread(profiled_thread); 1032 ResumeThread(profiled_thread);
1056 } 1033 }
1057 1034
1058 #endif // USE_SIGNALS 1035 #endif // USE_SIGNALS
1059 1036
1060 1037
1061 } // namespace internal 1038 } // namespace internal
1062 } // namespace v8 1039 } // namespace v8
OLDNEW
« no previous file with comments | « src/profiler/sampler.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698