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 |