| OLD | NEW |
| 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 127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 138 } ucontext_t; | 138 } ucontext_t; |
| 139 enum { REG_EBP = 6, REG_ESP = 7, REG_EIP = 14 }; | 139 enum { REG_EBP = 6, REG_ESP = 7, REG_EIP = 14 }; |
| 140 #endif | 140 #endif |
| 141 | 141 |
| 142 #endif // __ANDROID__ && !defined(__BIONIC_HAVE_UCONTEXT_T) | 142 #endif // __ANDROID__ && !defined(__BIONIC_HAVE_UCONTEXT_T) |
| 143 | 143 |
| 144 | 144 |
| 145 namespace v8 { | 145 namespace v8 { |
| 146 namespace internal { | 146 namespace internal { |
| 147 | 147 |
| 148 namespace { |
| 149 |
| 150 class PlatformDataCommon : public Malloced { |
| 151 public: |
| 152 PlatformDataCommon() : profiled_thread_id_(ThreadId::Current()) {} |
| 153 ThreadId profiled_thread_id() { return profiled_thread_id_; } |
| 154 |
| 155 protected: |
| 156 ~PlatformDataCommon() {} |
| 157 |
| 158 private: |
| 159 ThreadId profiled_thread_id_; |
| 160 }; |
| 161 |
| 162 } // namespace |
| 163 |
| 148 #if defined(USE_SIGNALS) | 164 #if defined(USE_SIGNALS) |
| 149 | 165 |
| 150 class Sampler::PlatformData : public Malloced { | 166 class Sampler::PlatformData : public PlatformDataCommon { |
| 151 public: | 167 public: |
| 152 PlatformData() | 168 PlatformData() : vm_tid_(pthread_self()) {} |
| 153 : vm_tid_(pthread_self()), | |
| 154 profiled_thread_id_(ThreadId::Current()) {} | |
| 155 | |
| 156 pthread_t vm_tid() const { return vm_tid_; } | 169 pthread_t vm_tid() const { return vm_tid_; } |
| 157 ThreadId profiled_thread_id() { return profiled_thread_id_; } | |
| 158 | 170 |
| 159 private: | 171 private: |
| 160 pthread_t vm_tid_; | 172 pthread_t vm_tid_; |
| 161 ThreadId profiled_thread_id_; | |
| 162 }; | 173 }; |
| 163 | 174 |
| 175 #elif defined(__MACH__) |
| 176 |
| 177 class Sampler::PlatformData : public PlatformDataCommon { |
| 178 public: |
| 179 PlatformData() : profiled_thread_(mach_thread_self()) {} |
| 180 |
| 181 ~PlatformData() { |
| 182 // Deallocate Mach port for thread. |
| 183 mach_port_deallocate(mach_task_self(), profiled_thread_); |
| 184 } |
| 185 |
| 186 thread_act_t profiled_thread() { return profiled_thread_; } |
| 187 |
| 188 private: |
| 189 // Note: for profiled_thread_ Mach primitives are used instead of PThread's |
| 190 // because the latter doesn't provide thread manipulation primitives required. |
| 191 // For details, consult "Mac OS X Internals" book, Section 7.3. |
| 192 thread_act_t profiled_thread_; |
| 193 }; |
| 194 |
| 195 #elif defined(_WIN32) || defined(_WIN64) || defined(__CYGWIN__) |
| 196 |
| 197 // ---------------------------------------------------------------------------- |
| 198 // Win32 profiler support. On Cygwin we use the same sampler implementation as |
| 199 // on Win32. |
| 200 |
| 201 class Sampler::PlatformData : public PlatformDataCommon { |
| 202 public: |
| 203 // Get a handle to the calling thread. This is the thread that we are |
| 204 // going to profile. We need to make a copy of the handle because we are |
| 205 // going to use it in the sampler thread. Using GetThreadHandle() will |
| 206 // not work in this case. We're using OpenThread because DuplicateHandle |
| 207 // for some reason doesn't work in Chrome's sandbox. |
| 208 PlatformData() |
| 209 : profiled_thread_(OpenThread(THREAD_GET_CONTEXT | |
| 210 THREAD_SUSPEND_RESUME | |
| 211 THREAD_QUERY_INFORMATION, |
| 212 false, |
| 213 GetCurrentThreadId())) {} |
| 214 |
| 215 ~PlatformData() { |
| 216 if (profiled_thread_ != NULL) { |
| 217 CloseHandle(profiled_thread_); |
| 218 profiled_thread_ = NULL; |
| 219 } |
| 220 } |
| 221 |
| 222 HANDLE profiled_thread() { return profiled_thread_; } |
| 223 |
| 224 private: |
| 225 HANDLE profiled_thread_; |
| 226 }; |
| 227 #endif |
| 228 |
| 229 |
| 230 class SampleHelper { |
| 231 public: |
| 232 inline TickSample* Init(Sampler* sampler, Isolate* isolate) { |
| 233 #if defined(USE_SIMULATOR) |
| 234 ThreadId thread_id = sampler->platform_data()->profiled_thread_id(); |
| 235 Isolate::PerIsolateThreadData* per_thread_data = isolate-> |
| 236 FindPerThreadDataForThread(thread_id); |
| 237 if (!per_thread_data) return NULL; |
| 238 simulator_ = per_thread_data->simulator(); |
| 239 // Check if there is active simulator before allocating TickSample. |
| 240 if (!simulator_) return NULL; |
| 241 #endif // USE_SIMULATOR |
| 242 TickSample* sample = isolate->cpu_profiler()->TickSampleEvent(); |
| 243 if (sample == NULL) sample = &sample_obj; |
| 244 return sample; |
| 245 } |
| 246 |
| 247 #if defined(USE_SIMULATOR) |
| 248 inline void FillRegisters(TickSample* sample) { |
| 249 sample->pc = reinterpret_cast<Address>(simulator_->get_pc()); |
| 250 sample->sp = reinterpret_cast<Address>(simulator_->get_register( |
| 251 Simulator::sp)); |
| 252 #if V8_TARGET_ARCH_ARM |
| 253 sample->fp = reinterpret_cast<Address>(simulator_->get_register( |
| 254 Simulator::r11)); |
| 255 #elif V8_TARGET_ARCH_MIPS |
| 256 sample->fp = reinterpret_cast<Address>(simulator_->get_register( |
| 257 Simulator::fp)); |
| 258 #endif |
| 259 } |
| 260 #endif // USE_SIMULATOR |
| 261 |
| 262 private: |
| 263 #if defined(USE_SIMULATOR) |
| 264 Simulator* simulator_; |
| 265 #endif |
| 266 TickSample sample_obj; |
| 267 }; |
| 268 |
| 269 |
| 270 #if defined(USE_SIGNALS) |
| 164 | 271 |
| 165 class SignalHandler : public AllStatic { | 272 class SignalHandler : public AllStatic { |
| 166 public: | 273 public: |
| 167 static inline void EnsureInstalled() { | 274 static inline void EnsureInstalled() { |
| 168 if (signal_handler_installed_) return; | 275 if (signal_handler_installed_) return; |
| 169 struct sigaction sa; | 276 struct sigaction sa; |
| 170 sa.sa_sigaction = &HandleProfilerSignal; | 277 sa.sa_sigaction = &HandleProfilerSignal; |
| 171 sigemptyset(&sa.sa_mask); | 278 sigemptyset(&sa.sa_mask); |
| 172 sa.sa_flags = SA_RESTART | SA_SIGINFO; | 279 sa.sa_flags = SA_RESTART | SA_SIGINFO; |
| 173 signal_handler_installed_ = | 280 signal_handler_installed_ = |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 210 return; | 317 return; |
| 211 } | 318 } |
| 212 if (v8::Locker::IsActive() && | 319 if (v8::Locker::IsActive() && |
| 213 !isolate->thread_manager()->IsLockedByCurrentThread()) { | 320 !isolate->thread_manager()->IsLockedByCurrentThread()) { |
| 214 return; | 321 return; |
| 215 } | 322 } |
| 216 | 323 |
| 217 Sampler* sampler = isolate->logger()->sampler(); | 324 Sampler* sampler = isolate->logger()->sampler(); |
| 218 if (sampler == NULL || !sampler->IsActive()) return; | 325 if (sampler == NULL || !sampler->IsActive()) return; |
| 219 | 326 |
| 220 #if defined(USE_SIMULATOR) | 327 SampleHelper helper; |
| 221 #if V8_TARGET_ARCH_ARM || V8_TARGET_ARCH_MIPS | 328 TickSample* sample = helper.Init(sampler, isolate); |
| 222 ThreadId thread_id = sampler->platform_data()->profiled_thread_id(); | 329 if (sample == NULL) return; |
| 223 Isolate::PerIsolateThreadData* per_thread_data = isolate-> | |
| 224 FindPerThreadDataForThread(thread_id); | |
| 225 if (!per_thread_data) return; | |
| 226 Simulator* sim = per_thread_data->simulator(); | |
| 227 // Check if there is active simulator before allocating TickSample. | |
| 228 if (!sim) return; | |
| 229 #endif | |
| 230 #endif // USE_SIMULATOR | |
| 231 | |
| 232 TickSample sample_obj; | |
| 233 TickSample* sample = isolate->cpu_profiler()->TickSampleEvent(); | |
| 234 if (sample == NULL) sample = &sample_obj; | |
| 235 | 330 |
| 236 #if defined(USE_SIMULATOR) | 331 #if defined(USE_SIMULATOR) |
| 237 sample->pc = reinterpret_cast<Address>(sim->get_pc()); | 332 helper.FillRegisters(sample); |
| 238 sample->sp = reinterpret_cast<Address>(sim->get_register(Simulator::sp)); | |
| 239 #if V8_TARGET_ARCH_ARM | |
| 240 sample->fp = reinterpret_cast<Address>(sim->get_register(Simulator::r11)); | |
| 241 #elif V8_TARGET_ARCH_MIPS | |
| 242 sample->fp = reinterpret_cast<Address>(sim->get_register(Simulator::fp)); | |
| 243 #endif // V8_TARGET_ARCH_* | |
| 244 #else | 333 #else |
| 245 // Extracting the sample from the context is extremely machine dependent. | 334 // Extracting the sample from the context is extremely machine dependent. |
| 246 ucontext_t* ucontext = reinterpret_cast<ucontext_t*>(context); | 335 ucontext_t* ucontext = reinterpret_cast<ucontext_t*>(context); |
| 247 mcontext_t& mcontext = ucontext->uc_mcontext; | 336 mcontext_t& mcontext = ucontext->uc_mcontext; |
| 248 sample->state = isolate->current_vm_state(); | 337 sample->state = isolate->current_vm_state(); |
| 249 #if defined(__linux__) || defined(__ANDROID__) | 338 #if defined(__linux__) || defined(__ANDROID__) |
| 250 #if V8_HOST_ARCH_IA32 | 339 #if V8_HOST_ARCH_IA32 |
| 251 sample->pc = reinterpret_cast<Address>(mcontext.gregs[REG_EIP]); | 340 sample->pc = reinterpret_cast<Address>(mcontext.gregs[REG_EIP]); |
| 252 sample->sp = reinterpret_cast<Address>(mcontext.gregs[REG_ESP]); | 341 sample->sp = reinterpret_cast<Address>(mcontext.gregs[REG_ESP]); |
| 253 sample->fp = reinterpret_cast<Address>(mcontext.gregs[REG_EBP]); | 342 sample->fp = reinterpret_cast<Address>(mcontext.gregs[REG_EBP]); |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 314 sample->sp = reinterpret_cast<Address>(mcontext.gregs[REG_SP]); | 403 sample->sp = reinterpret_cast<Address>(mcontext.gregs[REG_SP]); |
| 315 sample->fp = reinterpret_cast<Address>(mcontext.gregs[REG_FP]); | 404 sample->fp = reinterpret_cast<Address>(mcontext.gregs[REG_FP]); |
| 316 #endif // __sun | 405 #endif // __sun |
| 317 #endif // USE_SIMULATOR | 406 #endif // USE_SIMULATOR |
| 318 | 407 |
| 319 sampler->SampleStack(sample); | 408 sampler->SampleStack(sample); |
| 320 sampler->Tick(sample); | 409 sampler->Tick(sample); |
| 321 #endif // __native_client__ | 410 #endif // __native_client__ |
| 322 } | 411 } |
| 323 | 412 |
| 324 #elif defined(__MACH__) | |
| 325 class Sampler::PlatformData : public Malloced { | |
| 326 public: | |
| 327 PlatformData() | |
| 328 : profiled_thread_(mach_thread_self()), | |
| 329 profiled_thread_id_(ThreadId::Current()) {} | |
| 330 | |
| 331 ~PlatformData() { | |
| 332 // Deallocate Mach port for thread. | |
| 333 mach_port_deallocate(mach_task_self(), profiled_thread_); | |
| 334 } | |
| 335 | |
| 336 thread_act_t profiled_thread() { return profiled_thread_; } | |
| 337 ThreadId profiled_thread_id() { return profiled_thread_id_; } | |
| 338 | |
| 339 private: | |
| 340 // Note: for profiled_thread_ Mach primitives are used instead of PThread's | |
| 341 // because the latter doesn't provide thread manipulation primitives required. | |
| 342 // For details, consult "Mac OS X Internals" book, Section 7.3. | |
| 343 thread_act_t profiled_thread_; | |
| 344 ThreadId profiled_thread_id_; | |
| 345 }; | |
| 346 | |
| 347 #elif defined(_WIN32) || defined(_WIN64) || defined(__CYGWIN__) | |
| 348 | |
| 349 // ---------------------------------------------------------------------------- | |
| 350 // Win32 profiler support. On Cygwin we use the same sampler implementation as | |
| 351 // on Win32. | |
| 352 | |
| 353 class Sampler::PlatformData : public Malloced { | |
| 354 public: | |
| 355 // Get a handle to the calling thread. This is the thread that we are | |
| 356 // going to profile. We need to make a copy of the handle because we are | |
| 357 // going to use it in the sampler thread. Using GetThreadHandle() will | |
| 358 // not work in this case. We're using OpenThread because DuplicateHandle | |
| 359 // for some reason doesn't work in Chrome's sandbox. | |
| 360 PlatformData() | |
| 361 : profiled_thread_(OpenThread(THREAD_GET_CONTEXT | | |
| 362 THREAD_SUSPEND_RESUME | | |
| 363 THREAD_QUERY_INFORMATION, | |
| 364 false, | |
| 365 GetCurrentThreadId())), | |
| 366 profiled_thread_id_(ThreadId::Current()) {} | |
| 367 | |
| 368 ~PlatformData() { | |
| 369 if (profiled_thread_ != NULL) { | |
| 370 CloseHandle(profiled_thread_); | |
| 371 profiled_thread_ = NULL; | |
| 372 } | |
| 373 } | |
| 374 | |
| 375 HANDLE profiled_thread() { return profiled_thread_; } | |
| 376 ThreadId profiled_thread_id() { return profiled_thread_id_; } | |
| 377 | |
| 378 private: | |
| 379 HANDLE profiled_thread_; | |
| 380 ThreadId profiled_thread_id_; | |
| 381 }; | |
| 382 | |
| 383 #endif | 413 #endif |
| 384 | 414 |
| 385 | 415 |
| 386 class SamplerThread : public Thread { | 416 class SamplerThread : public Thread { |
| 387 public: | 417 public: |
| 388 static const int kSamplerThreadStackSize = 64 * KB; | 418 static const int kSamplerThreadStackSize = 64 * KB; |
| 389 | 419 |
| 390 explicit SamplerThread(int interval) | 420 explicit SamplerThread(int interval) |
| 391 : Thread(Thread::Options("SamplerThread", kSamplerThreadStackSize)), | 421 : Thread(Thread::Options("SamplerThread", kSamplerThreadStackSize)), |
| 392 interval_(interval) {} | 422 interval_(interval) {} |
| (...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 469 int result = pthread_kill(tid, SIGPROF); | 499 int result = pthread_kill(tid, SIGPROF); |
| 470 USE(result); | 500 USE(result); |
| 471 ASSERT(result == 0); | 501 ASSERT(result == 0); |
| 472 } | 502 } |
| 473 | 503 |
| 474 #elif defined(__MACH__) | 504 #elif defined(__MACH__) |
| 475 | 505 |
| 476 void SampleContext(Sampler* sampler) { | 506 void SampleContext(Sampler* sampler) { |
| 477 thread_act_t profiled_thread = sampler->platform_data()->profiled_thread(); | 507 thread_act_t profiled_thread = sampler->platform_data()->profiled_thread(); |
| 478 Isolate* isolate = sampler->isolate(); | 508 Isolate* isolate = sampler->isolate(); |
| 479 #if defined(USE_SIMULATOR) | 509 |
| 480 #if V8_TARGET_ARCH_ARM || V8_TARGET_ARCH_MIPS | 510 SampleHelper helper; |
| 481 ThreadId thread_id = sampler->platform_data()->profiled_thread_id(); | 511 TickSample* sample = helper.Init(sampler, isolate); |
| 482 Isolate::PerIsolateThreadData* per_thread_data = isolate-> | 512 if (sample == NULL) return; |
| 483 FindPerThreadDataForThread(thread_id); | |
| 484 if (!per_thread_data) return; | |
| 485 Simulator* sim = per_thread_data->simulator(); | |
| 486 // Check if there is active simulator before allocating TickSample. | |
| 487 if (!sim) return; | |
| 488 #endif | |
| 489 #endif // USE_SIMULATOR | |
| 490 TickSample sample_obj; | |
| 491 TickSample* sample = isolate->cpu_profiler()->TickSampleEvent(); | |
| 492 if (sample == NULL) sample = &sample_obj; | |
| 493 | 513 |
| 494 if (KERN_SUCCESS != thread_suspend(profiled_thread)) return; | 514 if (KERN_SUCCESS != thread_suspend(profiled_thread)) return; |
| 495 | 515 |
| 496 #if V8_HOST_ARCH_X64 | 516 #if V8_HOST_ARCH_X64 |
| 497 thread_state_flavor_t flavor = x86_THREAD_STATE64; | 517 thread_state_flavor_t flavor = x86_THREAD_STATE64; |
| 498 x86_thread_state64_t state; | 518 x86_thread_state64_t state; |
| 499 mach_msg_type_number_t count = x86_THREAD_STATE64_COUNT; | 519 mach_msg_type_number_t count = x86_THREAD_STATE64_COUNT; |
| 500 #if __DARWIN_UNIX03 | 520 #if __DARWIN_UNIX03 |
| 501 #define REGISTER_FIELD(name) __r ## name | 521 #define REGISTER_FIELD(name) __r ## name |
| 502 #else | 522 #else |
| (...skipping 11 matching lines...) Expand all Loading... |
| 514 #else | 534 #else |
| 515 #error Unsupported Mac OS X host architecture. | 535 #error Unsupported Mac OS X host architecture. |
| 516 #endif // V8_HOST_ARCH | 536 #endif // V8_HOST_ARCH |
| 517 | 537 |
| 518 if (thread_get_state(profiled_thread, | 538 if (thread_get_state(profiled_thread, |
| 519 flavor, | 539 flavor, |
| 520 reinterpret_cast<natural_t*>(&state), | 540 reinterpret_cast<natural_t*>(&state), |
| 521 &count) == KERN_SUCCESS) { | 541 &count) == KERN_SUCCESS) { |
| 522 sample->state = isolate->current_vm_state(); | 542 sample->state = isolate->current_vm_state(); |
| 523 #if defined(USE_SIMULATOR) | 543 #if defined(USE_SIMULATOR) |
| 524 sample->pc = reinterpret_cast<Address>(sim->get_pc()); | 544 helper.FillRegisters(sample); |
| 525 sample->sp = reinterpret_cast<Address>(sim->get_register(Simulator::sp)); | |
| 526 #if V8_TARGET_ARCH_ARM | |
| 527 sample->fp = reinterpret_cast<Address>(sim->get_register(Simulator::r11)); | |
| 528 #elif V8_TARGET_ARCH_MIPS | |
| 529 sample->fp = reinterpret_cast<Address>(sim->get_register(Simulator::fp)); | |
| 530 #endif | |
| 531 #else | 545 #else |
| 532 sample->pc = reinterpret_cast<Address>(state.REGISTER_FIELD(ip)); | 546 sample->pc = reinterpret_cast<Address>(state.REGISTER_FIELD(ip)); |
| 533 sample->sp = reinterpret_cast<Address>(state.REGISTER_FIELD(sp)); | 547 sample->sp = reinterpret_cast<Address>(state.REGISTER_FIELD(sp)); |
| 534 sample->fp = reinterpret_cast<Address>(state.REGISTER_FIELD(bp)); | 548 sample->fp = reinterpret_cast<Address>(state.REGISTER_FIELD(bp)); |
| 535 #endif // USE_SIMULATOR | 549 #endif // USE_SIMULATOR |
| 536 #undef REGISTER_FIELD | 550 #undef REGISTER_FIELD |
| 537 sampler->SampleStack(sample); | 551 sampler->SampleStack(sample); |
| 538 sampler->Tick(sample); | 552 sampler->Tick(sample); |
| 539 } | 553 } |
| 540 thread_resume(profiled_thread); | 554 thread_resume(profiled_thread); |
| 541 } | 555 } |
| 542 | 556 |
| 543 #elif defined(_WIN32) || defined(_WIN64) || defined(__CYGWIN__) | 557 #elif defined(_WIN32) || defined(_WIN64) || defined(__CYGWIN__) |
| 544 | 558 |
| 545 void SampleContext(Sampler* sampler) { | 559 void SampleContext(Sampler* sampler) { |
| 546 HANDLE profiled_thread = sampler->platform_data()->profiled_thread(); | 560 HANDLE profiled_thread = sampler->platform_data()->profiled_thread(); |
| 547 if (profiled_thread == NULL) return; | 561 if (profiled_thread == NULL) return; |
| 548 | 562 |
| 563 Isolate* isolate = sampler->isolate(); |
| 564 SampleHelper helper; |
| 565 TickSample* sample = helper.Init(sampler, isolate); |
| 566 if (sample == NULL) return; |
| 567 |
| 568 const DWORD kSuspendFailed = static_cast<DWORD>(-1); |
| 569 if (SuspendThread(profiled_thread) == kSuspendFailed) return; |
| 570 sample->state = isolate->current_vm_state(); |
| 571 |
| 549 // Context used for sampling the register state of the profiled thread. | 572 // Context used for sampling the register state of the profiled thread. |
| 550 CONTEXT context; | 573 CONTEXT context; |
| 551 memset(&context, 0, sizeof(context)); | 574 memset(&context, 0, sizeof(context)); |
| 552 | |
| 553 Isolate* isolate = sampler->isolate(); | |
| 554 #if defined(USE_SIMULATOR) | |
| 555 #if V8_TARGET_ARCH_ARM || V8_TARGET_ARCH_MIPS | |
| 556 ThreadId thread_id = sampler->platform_data()->profiled_thread_id(); | |
| 557 Isolate::PerIsolateThreadData* per_thread_data = isolate-> | |
| 558 FindPerThreadDataForThread(thread_id); | |
| 559 if (!per_thread_data) return; | |
| 560 Simulator* sim = per_thread_data->simulator(); | |
| 561 // Check if there is active simulator before allocating TickSample. | |
| 562 if (!sim) return; | |
| 563 #endif | |
| 564 #endif // USE_SIMULATOR | |
| 565 TickSample sample_obj; | |
| 566 TickSample* sample = isolate->cpu_profiler()->TickSampleEvent(); | |
| 567 if (sample == NULL) sample = &sample_obj; | |
| 568 | |
| 569 static const DWORD kSuspendFailed = static_cast<DWORD>(-1); | |
| 570 if (SuspendThread(profiled_thread) == kSuspendFailed) return; | |
| 571 sample->state = isolate->current_vm_state(); | |
| 572 | |
| 573 context.ContextFlags = CONTEXT_FULL; | 575 context.ContextFlags = CONTEXT_FULL; |
| 574 if (GetThreadContext(profiled_thread, &context) != 0) { | 576 if (GetThreadContext(profiled_thread, &context) != 0) { |
| 575 #if defined(USE_SIMULATOR) | 577 #if defined(USE_SIMULATOR) |
| 576 sample->pc = reinterpret_cast<Address>(sim->get_pc()); | 578 helper.FillRegisters(sample); |
| 577 sample->sp = reinterpret_cast<Address>(sim->get_register(Simulator::sp)); | |
| 578 #if V8_TARGET_ARCH_ARM | |
| 579 sample->fp = reinterpret_cast<Address>(sim->get_register(Simulator::r11)); | |
| 580 #elif V8_TARGET_ARCH_MIPS | |
| 581 sample->fp = reinterpret_cast<Address>(sim->get_register(Simulator::fp)); | |
| 582 #endif | |
| 583 #else | 579 #else |
| 584 #if V8_HOST_ARCH_X64 | 580 #if V8_HOST_ARCH_X64 |
| 585 sample->pc = reinterpret_cast<Address>(context.Rip); | 581 sample->pc = reinterpret_cast<Address>(context.Rip); |
| 586 sample->sp = reinterpret_cast<Address>(context.Rsp); | 582 sample->sp = reinterpret_cast<Address>(context.Rsp); |
| 587 sample->fp = reinterpret_cast<Address>(context.Rbp); | 583 sample->fp = reinterpret_cast<Address>(context.Rbp); |
| 588 #else | 584 #else |
| 589 sample->pc = reinterpret_cast<Address>(context.Eip); | 585 sample->pc = reinterpret_cast<Address>(context.Eip); |
| 590 sample->sp = reinterpret_cast<Address>(context.Esp); | 586 sample->sp = reinterpret_cast<Address>(context.Esp); |
| 591 sample->fp = reinterpret_cast<Address>(context.Ebp); | 587 sample->fp = reinterpret_cast<Address>(context.Ebp); |
| 592 #endif | 588 #endif |
| (...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 689 SamplerThread::RemoveActiveSampler(this); | 685 SamplerThread::RemoveActiveSampler(this); |
| 690 SetActive(false); | 686 SetActive(false); |
| 691 } | 687 } |
| 692 | 688 |
| 693 void Sampler::SampleStack(TickSample* sample) { | 689 void Sampler::SampleStack(TickSample* sample) { |
| 694 sample->Trace(isolate_); | 690 sample->Trace(isolate_); |
| 695 if (++samples_taken_ < 0) samples_taken_ = 0; | 691 if (++samples_taken_ < 0) samples_taken_ = 0; |
| 696 } | 692 } |
| 697 | 693 |
| 698 } } // namespace v8::internal | 694 } } // namespace v8::internal |
| OLD | NEW |