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

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
« src/profiler/sampler.h ('K') | « 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 30 matching lines...) Expand all
41 #include "src/base/win32-headers.h" 41 #include "src/base/win32-headers.h"
42 42
43 #endif 43 #endif
44 44
45 #include "src/atomic-utils.h" 45 #include "src/atomic-utils.h"
46 #include "src/base/platform/platform.h" 46 #include "src/base/platform/platform.h"
47 #include "src/flags.h" 47 #include "src/flags.h"
48 #include "src/frames-inl.h" 48 #include "src/frames-inl.h"
49 #include "src/log.h" 49 #include "src/log.h"
50 #include "src/profiler/cpu-profiler-inl.h" 50 #include "src/profiler/cpu-profiler-inl.h"
51 #include "src/simulator.h"
52 #include "src/v8threads.h" 51 #include "src/v8threads.h"
53 #include "src/vm-state-inl.h" 52 #include "src/vm-state-inl.h"
54 53
55 54
56 #if V8_OS_ANDROID && !defined(__BIONIC_HAVE_UCONTEXT_T) 55 #if V8_OS_ANDROID && !defined(__BIONIC_HAVE_UCONTEXT_T)
57 56
58 // Not all versions of Android's C library provide ucontext_t. 57 // Not all versions of Android's C library provide ucontext_t.
59 // Detect this and provide custom but compatible definitions. Note that these 58 // Detect this and provide custom but compatible definitions. Note that these
60 // follow the GLibc naming convention to access register values from 59 // follow the GLibc naming convention to access register values from
61 // mcontext_t. 60 // mcontext_t.
(...skipping 262 matching lines...) Expand 10 before | Expand all | Expand 10 after
324 } 323 }
325 324
326 HANDLE profiled_thread() { return profiled_thread_; } 325 HANDLE profiled_thread() { return profiled_thread_; }
327 326
328 private: 327 private:
329 HANDLE profiled_thread_; 328 HANDLE profiled_thread_;
330 }; 329 };
331 #endif 330 #endif
332 331
333 332
334 #if defined(USE_SIMULATOR)
335 class SimulatorHelper {
336 public:
337 inline bool Init(Isolate* isolate) {
338 simulator_ = isolate->thread_local_top()->simulator_;
339 // Check if there is active simulator.
340 return simulator_ != NULL;
341 }
342
343 inline void FillRegisters(v8::RegisterState* state) {
344 #if V8_TARGET_ARCH_ARM
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
353 if (simulator_->sp() == 0 || simulator_->fp() == 0) {
354 // It's possible that the simulator is interrupted while it is updating
355 // the sp or fp register. ARM64 simulator does this in two steps:
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
371 if (!simulator_->has_bad_pc()) {
372 state->pc = reinterpret_cast<Address>(simulator_->get_pc());
373 }
374 state->sp = reinterpret_cast<Address>(simulator_->get_register(
375 Simulator::sp));
376 state->fp = reinterpret_cast<Address>(simulator_->get_register(
377 Simulator::fp));
378 #elif V8_TARGET_ARCH_PPC
379 if (!simulator_->has_bad_pc()) {
380 state->pc = reinterpret_cast<Address>(simulator_->get_pc());
381 }
382 state->sp =
383 reinterpret_cast<Address>(simulator_->get_register(Simulator::sp));
384 state->fp =
385 reinterpret_cast<Address>(simulator_->get_register(Simulator::fp));
386 #elif V8_TARGET_ARCH_S390
387 if (!simulator_->has_bad_pc()) {
388 state->pc = reinterpret_cast<Address>(simulator_->get_pc());
389 }
390 state->sp =
391 reinterpret_cast<Address>(simulator_->get_register(Simulator::sp));
392 state->fp =
393 reinterpret_cast<Address>(simulator_->get_register(Simulator::fp));
394 #endif
395 }
396
397 private:
398 Simulator* simulator_;
399 };
400 #endif // USE_SIMULATOR
401
402
403 #if defined(USE_SIGNALS) 333 #if defined(USE_SIGNALS)
404 334
405 class SignalHandler : public AllStatic { 335 class SignalHandler : public AllStatic {
406 public: 336 public:
407 static void SetUp() { if (!mutex_) mutex_ = new base::Mutex(); } 337 static void SetUp() { if (!mutex_) mutex_ = new base::Mutex(); }
408 static void TearDown() { delete mutex_; mutex_ = NULL; } 338 static void TearDown() { delete mutex_; mutex_ = NULL; }
409 339
410 static void IncreaseSamplerCount() { 340 static void IncreaseSamplerCount() {
411 base::LockGuard<base::Mutex> lock_guard(mutex_); 341 base::LockGuard<base::Mutex> lock_guard(mutex_);
412 if (++client_count_ == 1) Install(); 342 if (++client_count_ == 1) Install();
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
480 if (isolate == NULL || !isolate->IsInUse()) return; 410 if (isolate == NULL || !isolate->IsInUse()) return;
481 411
482 if (v8::Locker::IsActive() && 412 if (v8::Locker::IsActive() &&
483 !isolate->thread_manager()->IsLockedByCurrentThread()) { 413 !isolate->thread_manager()->IsLockedByCurrentThread()) {
484 return; 414 return;
485 } 415 }
486 416
487 v8::RegisterState state; 417 v8::RegisterState state;
488 418
489 #if defined(USE_SIMULATOR) 419 #if defined(USE_SIMULATOR)
490 SimulatorHelper helper; 420 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 421 // It possible that the simulator is interrupted while it is updating
494 // the sp or fp register. ARM64 simulator does this in two steps: 422 // 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. 423 // first setting it to zero and then setting it to the new value.
496 // Bailout if sp/fp doesn't contain the new value. 424 // Bailout if sp/fp doesn't contain the new value.
497 if (state.sp == 0 || state.fp == 0) return; 425 if (state.sp == 0 || state.fp == 0) return;
alph 2016/04/29 18:55:06 you can move this part into FillRegisters.
lpy 2016/04/29 19:51:58 Done.
498 #else 426 #else
499 // Extracting the sample from the context is extremely machine dependent. 427 // Extracting the sample from the context is extremely machine dependent.
500 ucontext_t* ucontext = reinterpret_cast<ucontext_t*>(context); 428 ucontext_t* ucontext = reinterpret_cast<ucontext_t*>(context);
501 #if !(V8_OS_OPENBSD || (V8_OS_LINUX && (V8_HOST_ARCH_PPC || V8_HOST_ARCH_S390))) 429 #if !(V8_OS_OPENBSD || (V8_OS_LINUX && (V8_HOST_ARCH_PPC || V8_HOST_ARCH_S390)))
502 mcontext_t& mcontext = ucontext->uc_mcontext; 430 mcontext_t& mcontext = ucontext->uc_mcontext;
503 #endif 431 #endif
504 #if V8_OS_LINUX 432 #if V8_OS_LINUX
505 #if V8_HOST_ARCH_IA32 433 #if V8_HOST_ARCH_IA32
506 state.pc = reinterpret_cast<Address>(mcontext.gregs[REG_EIP]); 434 state.pc = reinterpret_cast<Address>(mcontext.gregs[REG_EIP]);
507 state.sp = reinterpret_cast<Address>(mcontext.gregs[REG_ESP]); 435 state.sp = reinterpret_cast<Address>(mcontext.gregs[REG_ESP]);
(...skipping 508 matching lines...) Expand 10 before | Expand all | Expand 10 after
1016 } 944 }
1017 pthread_kill(platform_data()->vm_tid(), SIGPROF); 945 pthread_kill(platform_data()->vm_tid(), SIGPROF);
1018 } 946 }
1019 947
1020 #elif V8_OS_WIN || V8_OS_CYGWIN 948 #elif V8_OS_WIN || V8_OS_CYGWIN
1021 949
1022 void Sampler::DoSample() { 950 void Sampler::DoSample() {
1023 HANDLE profiled_thread = platform_data()->profiled_thread(); 951 HANDLE profiled_thread = platform_data()->profiled_thread();
1024 if (profiled_thread == NULL) return; 952 if (profiled_thread == NULL) return;
1025 953
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); 954 const DWORD kSuspendFailed = static_cast<DWORD>(-1);
1032 if (SuspendThread(profiled_thread) == kSuspendFailed) return; 955 if (SuspendThread(profiled_thread) == kSuspendFailed) return;
1033 956
1034 // Context used for sampling the register state of the profiled thread. 957 // Context used for sampling the register state of the profiled thread.
1035 CONTEXT context; 958 CONTEXT context;
1036 memset(&context, 0, sizeof(context)); 959 memset(&context, 0, sizeof(context));
1037 context.ContextFlags = CONTEXT_FULL; 960 context.ContextFlags = CONTEXT_FULL;
1038 if (GetThreadContext(profiled_thread, &context) != 0) { 961 if (GetThreadContext(profiled_thread, &context) != 0) {
1039 v8::RegisterState state; 962 v8::RegisterState state;
1040 #if defined(USE_SIMULATOR) 963 #if defined(USE_SIMULATOR)
1041 helper.FillRegisters(&state); 964 if (!SimulatorHelper::FillRegisters(isolate(), &state)) return;
1042 #else 965 #else
1043 #if V8_HOST_ARCH_X64 966 #if V8_HOST_ARCH_X64
1044 state.pc = reinterpret_cast<Address>(context.Rip); 967 state.pc = reinterpret_cast<Address>(context.Rip);
1045 state.sp = reinterpret_cast<Address>(context.Rsp); 968 state.sp = reinterpret_cast<Address>(context.Rsp);
1046 state.fp = reinterpret_cast<Address>(context.Rbp); 969 state.fp = reinterpret_cast<Address>(context.Rbp);
1047 #else 970 #else
1048 state.pc = reinterpret_cast<Address>(context.Eip); 971 state.pc = reinterpret_cast<Address>(context.Eip);
1049 state.sp = reinterpret_cast<Address>(context.Esp); 972 state.sp = reinterpret_cast<Address>(context.Esp);
1050 state.fp = reinterpret_cast<Address>(context.Ebp); 973 state.fp = reinterpret_cast<Address>(context.Ebp);
1051 #endif 974 #endif
1052 #endif // USE_SIMULATOR 975 #endif // USE_SIMULATOR
1053 SampleStack(state); 976 SampleStack(state);
1054 } 977 }
1055 ResumeThread(profiled_thread); 978 ResumeThread(profiled_thread);
1056 } 979 }
1057 980
1058 #endif // USE_SIGNALS 981 #endif // USE_SIGNALS
1059 982
1060 983
1061 } // namespace internal 984 } // namespace internal
1062 } // namespace v8 985 } // namespace v8
OLDNEW
« src/profiler/sampler.h ('K') | « src/profiler/sampler.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698