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

Side by Side Diff: src/sampler.cc

Issue 148503002: A64: Synchronize with r15545. (Closed) Base URL: https://v8.googlecode.com/svn/branches/experimental/a64
Patch Set: Created 6 years, 10 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
« no previous file with comments | « src/sampler.h ('k') | src/scanner-character-streams.cc » ('j') | 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 // 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
11 // with the distribution. 11 // with the distribution.
12 // * Neither the name of Google Inc. nor the names of its 12 // * Neither the name of Google Inc. nor the names of its
13 // contributors may be used to endorse or promote products derived 13 // contributors may be used to endorse or promote products derived
14 // from this software without specific prior written permission. 14 // from this software without specific prior written permission.
15 // 15 //
16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 17 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 18 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 19 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 20 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 27
28 #include "sampler.h"
29
28 #if defined(__linux__) || defined(__FreeBSD__) || defined(__OpenBSD__) \ 30 #if defined(__linux__) || defined(__FreeBSD__) || defined(__OpenBSD__) \
29 || defined(__NetBSD__) || defined(__sun) || defined(__ANDROID__) \ 31 || defined(__NetBSD__) || defined(__sun) || defined(__ANDROID__) \
30 || defined(__native_client__) 32 || defined(__native_client__)
31 33
32 #define USE_SIGNALS 34 #define USE_SIGNALS
33 35
34 #include <errno.h> 36 #include <errno.h>
35 #include <pthread.h> 37 #include <pthread.h>
36 #include <signal.h> 38 #include <signal.h>
37 #include <sys/time.h> 39 #include <sys/time.h>
(...skipping 15 matching lines...) Expand all
53 #include <mach/mach.h> 55 #include <mach/mach.h>
54 56
55 #elif defined(_WIN32) || defined(_WIN64) || defined(__CYGWIN__) 57 #elif defined(_WIN32) || defined(_WIN64) || defined(__CYGWIN__)
56 58
57 #include "win32-headers.h" 59 #include "win32-headers.h"
58 60
59 #endif 61 #endif
60 62
61 #include "v8.h" 63 #include "v8.h"
62 64
65 #include "cpu-profiler.h"
66 #include "flags.h"
63 #include "frames-inl.h" 67 #include "frames-inl.h"
64 #include "log.h" 68 #include "log.h"
65 #include "platform.h" 69 #include "platform.h"
66 #include "simulator.h" 70 #include "simulator.h"
67 #include "v8threads.h" 71 #include "v8threads.h"
68 72
69 73
70 #if defined(__ANDROID__) && !defined(__BIONIC_HAVE_UCONTEXT_T) 74 #if defined(__ANDROID__) && !defined(__BIONIC_HAVE_UCONTEXT_T)
71 75
72 // Not all versions of Android's C library provide ucontext_t. 76 // Not all versions of Android's C library provide ucontext_t.
(...skipping 150 matching lines...) Expand 10 before | Expand all | Expand 10 after
223 } 227 }
224 228
225 HANDLE profiled_thread() { return profiled_thread_; } 229 HANDLE profiled_thread() { return profiled_thread_; }
226 230
227 private: 231 private:
228 HANDLE profiled_thread_; 232 HANDLE profiled_thread_;
229 }; 233 };
230 #endif 234 #endif
231 235
232 236
233 class SampleHelper { 237 #if defined(USE_SIMULATOR)
238 class SimulatorHelper {
234 public: 239 public:
235 inline TickSample* Init(Sampler* sampler, Isolate* isolate) { 240 inline bool Init(Sampler* sampler, Isolate* isolate) {
236 #if defined(USE_SIMULATOR)
237 ThreadId thread_id = sampler->platform_data()->profiled_thread_id(); 241 ThreadId thread_id = sampler->platform_data()->profiled_thread_id();
238 Isolate::PerIsolateThreadData* per_thread_data = isolate-> 242 Isolate::PerIsolateThreadData* per_thread_data = isolate->
239 FindPerThreadDataForThread(thread_id); 243 FindPerThreadDataForThread(thread_id);
240 if (!per_thread_data) return NULL; 244 if (!per_thread_data) return false;
241 simulator_ = per_thread_data->simulator(); 245 simulator_ = per_thread_data->simulator();
242 // Check if there is active simulator before allocating TickSample. 246 // Check if there is active simulator.
243 if (!simulator_) return NULL; 247 return simulator_ != NULL;
244 #endif // USE_SIMULATOR
245 TickSample* sample = isolate->cpu_profiler()->TickSampleEvent();
246 if (sample == NULL) sample = &sample_obj;
247 return sample;
248 } 248 }
249 249
250 #if defined(USE_SIMULATOR) 250 inline void FillRegisters(RegisterState* state) {
251 inline void FillRegisters(TickSample* sample) {
252 #if V8_TARGET_ARCH_ARM 251 #if V8_TARGET_ARCH_ARM
253 sample->pc = reinterpret_cast<Address>(simulator_->get_pc()); 252 state->pc = reinterpret_cast<Address>(simulator_->get_pc());
254 sample->sp = reinterpret_cast<Address>(simulator_->get_register( 253 state->sp = reinterpret_cast<Address>(simulator_->get_register(
255 Simulator::sp)); 254 Simulator::sp));
256 sample->fp = reinterpret_cast<Address>(simulator_->get_register( 255 state->fp = reinterpret_cast<Address>(simulator_->get_register(
257 Simulator::r11)); 256 Simulator::r11));
258 #elif V8_TARGET_ARCH_A64 257 #elif V8_TARGET_ARCH_A64
259 if (simulator_->sp() == 0 || simulator_->fp() == 0) { 258 if (simulator_->sp() == 0 || simulator_->fp() == 0) {
260 // It possible that the simulator is interrupted while it is updating 259 // It possible that the simulator is interrupted while it is updating
261 // the sp or fp register. A64 simulator does this in two steps: 260 // the sp or fp register. A64 simulator does this in two steps:
262 // first setting it to zero and then setting it to the new value. 261 // first setting it to zero and then setting it to the new value.
263 // Bailout if sp/fp doesn't contain the new value. 262 // Bailout if sp/fp doesn't contain the new value.
264 return; 263 return;
265 } 264 }
266 sample->pc = reinterpret_cast<Address>(simulator_->pc()); 265 state->pc = reinterpret_cast<Address>(simulator_->pc());
267 sample->sp = reinterpret_cast<Address>(simulator_->sp()); 266 state->sp = reinterpret_cast<Address>(simulator_->sp());
268 sample->fp = reinterpret_cast<Address>(simulator_->fp()); 267 state->fp = reinterpret_cast<Address>(simulator_->fp());
269 #elif V8_TARGET_ARCH_MIPS 268 #elif V8_TARGET_ARCH_MIPS
270 sample->pc = reinterpret_cast<Address>(simulator_->get_pc()); 269 state->pc = reinterpret_cast<Address>(simulator_->get_pc());
271 sample->sp = reinterpret_cast<Address>(simulator_->get_register( 270 state->sp = reinterpret_cast<Address>(simulator_->get_register(
272 Simulator::sp)); 271 Simulator::sp));
273 sample->fp = reinterpret_cast<Address>(simulator_->get_register( 272 state->fp = reinterpret_cast<Address>(simulator_->get_register(
274 Simulator::fp)); 273 Simulator::fp));
275 #endif 274 #endif
276 } 275 }
277 #endif // USE_SIMULATOR
278 276
279 private: 277 private:
280 #if defined(USE_SIMULATOR)
281 Simulator* simulator_; 278 Simulator* simulator_;
282 #endif
283 TickSample sample_obj;
284 }; 279 };
280 #endif // USE_SIMULATOR
285 281
286 282
287 #if defined(USE_SIGNALS) 283 #if defined(USE_SIGNALS)
288 284
289 class SignalHandler : public AllStatic { 285 class SignalHandler : public AllStatic {
290 public: 286 public:
291 static inline void EnsureInstalled() { 287 static inline void EnsureInstalled() {
292 if (signal_handler_installed_) return; 288 if (signal_handler_installed_) return;
293 struct sigaction sa; 289 struct sigaction sa;
294 sa.sa_sigaction = &HandleProfilerSignal; 290 sa.sa_sigaction = &HandleProfilerSignal;
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
334 return; 330 return;
335 } 331 }
336 if (v8::Locker::IsActive() && 332 if (v8::Locker::IsActive() &&
337 !isolate->thread_manager()->IsLockedByCurrentThread()) { 333 !isolate->thread_manager()->IsLockedByCurrentThread()) {
338 return; 334 return;
339 } 335 }
340 336
341 Sampler* sampler = isolate->logger()->sampler(); 337 Sampler* sampler = isolate->logger()->sampler();
342 if (sampler == NULL || !sampler->IsActive()) return; 338 if (sampler == NULL || !sampler->IsActive()) return;
343 339
344 SampleHelper helper; 340 RegisterState state;
345 TickSample* sample = helper.Init(sampler, isolate);
346 if (sample == NULL) return;
347 341
348 #if defined(USE_SIMULATOR) 342 #if defined(USE_SIMULATOR)
349 helper.FillRegisters(sample); 343 SimulatorHelper helper;
344 if (!helper.Init(sampler, isolate)) return;
345 helper.FillRegisters(&state);
350 // It possible that the simulator is interrupted while it is updating 346 // It possible that the simulator is interrupted while it is updating
351 // the sp or fp register. A64 simulator does this in two steps: 347 // the sp or fp register. A64 simulator does this in two steps:
352 // first setting it to zero and then setting it to the new value. 348 // first setting it to zero and then setting it to the new value.
353 // Bailout if sp/fp doesn't contain the new value. 349 // Bailout if sp/fp doesn't contain the new value.
354 if (sample->sp == 0 || sample->fp == 0) return; 350 if (state.sp == 0 || state.fp == 0) return;
355 #else 351 #else
356 // Extracting the sample from the context is extremely machine dependent. 352 // Extracting the sample from the context is extremely machine dependent.
357 ucontext_t* ucontext = reinterpret_cast<ucontext_t*>(context); 353 ucontext_t* ucontext = reinterpret_cast<ucontext_t*>(context);
358 mcontext_t& mcontext = ucontext->uc_mcontext; 354 mcontext_t& mcontext = ucontext->uc_mcontext;
359 sample->state = isolate->current_vm_state();
360 #if defined(__linux__) || defined(__ANDROID__) 355 #if defined(__linux__) || defined(__ANDROID__)
361 #if V8_HOST_ARCH_IA32 356 #if V8_HOST_ARCH_IA32
362 sample->pc = reinterpret_cast<Address>(mcontext.gregs[REG_EIP]); 357 state.pc = reinterpret_cast<Address>(mcontext.gregs[REG_EIP]);
363 sample->sp = reinterpret_cast<Address>(mcontext.gregs[REG_ESP]); 358 state.sp = reinterpret_cast<Address>(mcontext.gregs[REG_ESP]);
364 sample->fp = reinterpret_cast<Address>(mcontext.gregs[REG_EBP]); 359 state.fp = reinterpret_cast<Address>(mcontext.gregs[REG_EBP]);
365 #elif V8_HOST_ARCH_X64 360 #elif V8_HOST_ARCH_X64
366 sample->pc = reinterpret_cast<Address>(mcontext.gregs[REG_RIP]); 361 state.pc = reinterpret_cast<Address>(mcontext.gregs[REG_RIP]);
367 sample->sp = reinterpret_cast<Address>(mcontext.gregs[REG_RSP]); 362 state.sp = reinterpret_cast<Address>(mcontext.gregs[REG_RSP]);
368 sample->fp = reinterpret_cast<Address>(mcontext.gregs[REG_RBP]); 363 state.fp = reinterpret_cast<Address>(mcontext.gregs[REG_RBP]);
369 #elif V8_HOST_ARCH_ARM 364 #elif V8_HOST_ARCH_ARM
370 #if defined(__GLIBC__) && !defined(__UCLIBC__) && \ 365 #if defined(__GLIBC__) && !defined(__UCLIBC__) && \
371 (__GLIBC__ < 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ <= 3)) 366 (__GLIBC__ < 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ <= 3))
372 // Old GLibc ARM versions used a gregs[] array to access the register 367 // Old GLibc ARM versions used a gregs[] array to access the register
373 // values from mcontext_t. 368 // values from mcontext_t.
374 sample->pc = reinterpret_cast<Address>(mcontext.gregs[R15]); 369 state.pc = reinterpret_cast<Address>(mcontext.gregs[R15]);
375 sample->sp = reinterpret_cast<Address>(mcontext.gregs[R13]); 370 state.sp = reinterpret_cast<Address>(mcontext.gregs[R13]);
376 sample->fp = reinterpret_cast<Address>(mcontext.gregs[R11]); 371 state.fp = reinterpret_cast<Address>(mcontext.gregs[R11]);
377 #else 372 #else
378 sample->pc = reinterpret_cast<Address>(mcontext.arm_pc); 373 state.pc = reinterpret_cast<Address>(mcontext.arm_pc);
379 sample->sp = reinterpret_cast<Address>(mcontext.arm_sp); 374 state.sp = reinterpret_cast<Address>(mcontext.arm_sp);
380 sample->fp = reinterpret_cast<Address>(mcontext.arm_fp); 375 state.fp = reinterpret_cast<Address>(mcontext.arm_fp);
381 #endif // defined(__GLIBC__) && !defined(__UCLIBC__) && 376 #endif // defined(__GLIBC__) && !defined(__UCLIBC__) &&
382 // (__GLIBC__ < 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ <= 3)) 377 // (__GLIBC__ < 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ <= 3))
383 #elif V8_HOST_ARCH_A64 378 #elif V8_HOST_ARCH_A64
384 sample->pc = reinterpret_cast<Address>(mcontext.pc); 379 sample->pc = reinterpret_cast<Address>(mcontext.pc);
385 sample->sp = reinterpret_cast<Address>(mcontext.sp); 380 sample->sp = reinterpret_cast<Address>(mcontext.sp);
386 // FP is an alias for x29. 381 // FP is an alias for x29.
387 sample->fp = reinterpret_cast<Address>(mcontext.regs[29]); 382 sample->fp = reinterpret_cast<Address>(mcontext.regs[29]);
388 #elif V8_HOST_ARCH_MIPS 383 #elif V8_HOST_ARCH_MIPS
389 sample->pc = reinterpret_cast<Address>(mcontext.pc); 384 state.pc = reinterpret_cast<Address>(mcontext.pc);
390 sample->sp = reinterpret_cast<Address>(mcontext.gregs[29]); 385 state.sp = reinterpret_cast<Address>(mcontext.gregs[29]);
391 sample->fp = reinterpret_cast<Address>(mcontext.gregs[30]); 386 state.fp = reinterpret_cast<Address>(mcontext.gregs[30]);
392 #endif // V8_HOST_ARCH_* 387 #endif // V8_HOST_ARCH_*
393 #elif defined(__FreeBSD__) 388 #elif defined(__FreeBSD__)
394 #if V8_HOST_ARCH_IA32 389 #if V8_HOST_ARCH_IA32
395 sample->pc = reinterpret_cast<Address>(mcontext.mc_eip); 390 state.pc = reinterpret_cast<Address>(mcontext.mc_eip);
396 sample->sp = reinterpret_cast<Address>(mcontext.mc_esp); 391 state.sp = reinterpret_cast<Address>(mcontext.mc_esp);
397 sample->fp = reinterpret_cast<Address>(mcontext.mc_ebp); 392 state.fp = reinterpret_cast<Address>(mcontext.mc_ebp);
398 #elif V8_HOST_ARCH_X64 393 #elif V8_HOST_ARCH_X64
399 sample->pc = reinterpret_cast<Address>(mcontext.mc_rip); 394 state.pc = reinterpret_cast<Address>(mcontext.mc_rip);
400 sample->sp = reinterpret_cast<Address>(mcontext.mc_rsp); 395 state.sp = reinterpret_cast<Address>(mcontext.mc_rsp);
401 sample->fp = reinterpret_cast<Address>(mcontext.mc_rbp); 396 state.fp = reinterpret_cast<Address>(mcontext.mc_rbp);
402 #elif V8_HOST_ARCH_ARM 397 #elif V8_HOST_ARCH_ARM
403 sample->pc = reinterpret_cast<Address>(mcontext.mc_r15); 398 state.pc = reinterpret_cast<Address>(mcontext.mc_r15);
404 sample->sp = reinterpret_cast<Address>(mcontext.mc_r13); 399 state.sp = reinterpret_cast<Address>(mcontext.mc_r13);
405 sample->fp = reinterpret_cast<Address>(mcontext.mc_r11); 400 state.fp = reinterpret_cast<Address>(mcontext.mc_r11);
406 #endif // V8_HOST_ARCH_* 401 #endif // V8_HOST_ARCH_*
407 #elif defined(__NetBSD__) 402 #elif defined(__NetBSD__)
408 #if V8_HOST_ARCH_IA32 403 #if V8_HOST_ARCH_IA32
409 sample->pc = reinterpret_cast<Address>(mcontext.__gregs[_REG_EIP]); 404 state.pc = reinterpret_cast<Address>(mcontext.__gregs[_REG_EIP]);
410 sample->sp = reinterpret_cast<Address>(mcontext.__gregs[_REG_ESP]); 405 state.sp = reinterpret_cast<Address>(mcontext.__gregs[_REG_ESP]);
411 sample->fp = reinterpret_cast<Address>(mcontext.__gregs[_REG_EBP]); 406 state.fp = reinterpret_cast<Address>(mcontext.__gregs[_REG_EBP]);
412 #elif V8_HOST_ARCH_X64 407 #elif V8_HOST_ARCH_X64
413 sample->pc = reinterpret_cast<Address>(mcontext.__gregs[_REG_RIP]); 408 state.pc = reinterpret_cast<Address>(mcontext.__gregs[_REG_RIP]);
414 sample->sp = reinterpret_cast<Address>(mcontext.__gregs[_REG_RSP]); 409 state.sp = reinterpret_cast<Address>(mcontext.__gregs[_REG_RSP]);
415 sample->fp = reinterpret_cast<Address>(mcontext.__gregs[_REG_RBP]); 410 state.fp = reinterpret_cast<Address>(mcontext.__gregs[_REG_RBP]);
416 #endif // V8_HOST_ARCH_* 411 #endif // V8_HOST_ARCH_*
417 #elif defined(__OpenBSD__) 412 #elif defined(__OpenBSD__)
418 USE(mcontext); 413 USE(mcontext);
419 #if V8_HOST_ARCH_IA32 414 #if V8_HOST_ARCH_IA32
420 sample->pc = reinterpret_cast<Address>(ucontext->sc_eip); 415 state.pc = reinterpret_cast<Address>(ucontext->sc_eip);
421 sample->sp = reinterpret_cast<Address>(ucontext->sc_esp); 416 state.sp = reinterpret_cast<Address>(ucontext->sc_esp);
422 sample->fp = reinterpret_cast<Address>(ucontext->sc_ebp); 417 state.fp = reinterpret_cast<Address>(ucontext->sc_ebp);
423 #elif V8_HOST_ARCH_X64 418 #elif V8_HOST_ARCH_X64
424 sample->pc = reinterpret_cast<Address>(ucontext->sc_rip); 419 state.pc = reinterpret_cast<Address>(ucontext->sc_rip);
425 sample->sp = reinterpret_cast<Address>(ucontext->sc_rsp); 420 state.sp = reinterpret_cast<Address>(ucontext->sc_rsp);
426 sample->fp = reinterpret_cast<Address>(ucontext->sc_rbp); 421 state.fp = reinterpret_cast<Address>(ucontext->sc_rbp);
427 #endif // V8_HOST_ARCH_* 422 #endif // V8_HOST_ARCH_*
428 #elif defined(__sun) 423 #elif defined(__sun)
429 sample->pc = reinterpret_cast<Address>(mcontext.gregs[REG_PC]); 424 state.pc = reinterpret_cast<Address>(mcontext.gregs[REG_PC]);
430 sample->sp = reinterpret_cast<Address>(mcontext.gregs[REG_SP]); 425 state.sp = reinterpret_cast<Address>(mcontext.gregs[REG_SP]);
431 sample->fp = reinterpret_cast<Address>(mcontext.gregs[REG_FP]); 426 state.fp = reinterpret_cast<Address>(mcontext.gregs[REG_FP]);
432 #endif // __sun 427 #endif // __sun
433 #endif // USE_SIMULATOR 428 #endif // USE_SIMULATOR
434 429 sampler->SampleStack(state);
435 sampler->SampleStack(sample);
436 sampler->Tick(sample);
437 #endif // __native_client__ 430 #endif // __native_client__
438 } 431 }
439 432
440 #endif 433 #endif
441 434
442 435
443 class SamplerThread : public Thread { 436 class SamplerThread : public Thread {
444 public: 437 public:
445 static const int kSamplerThreadStackSize = 64 * KB; 438 static const int kSamplerThreadStackSize = 64 * KB;
446 439
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after
523 void SampleContext(Sampler* sampler) { 516 void SampleContext(Sampler* sampler) {
524 if (!SignalHandler::Installed()) return; 517 if (!SignalHandler::Installed()) return;
525 pthread_t tid = sampler->platform_data()->vm_tid(); 518 pthread_t tid = sampler->platform_data()->vm_tid();
526 pthread_kill(tid, SIGPROF); 519 pthread_kill(tid, SIGPROF);
527 } 520 }
528 521
529 #elif defined(__MACH__) 522 #elif defined(__MACH__)
530 523
531 void SampleContext(Sampler* sampler) { 524 void SampleContext(Sampler* sampler) {
532 thread_act_t profiled_thread = sampler->platform_data()->profiled_thread(); 525 thread_act_t profiled_thread = sampler->platform_data()->profiled_thread();
526
527 #if defined(USE_SIMULATOR)
528 SimulatorHelper helper;
533 Isolate* isolate = sampler->isolate(); 529 Isolate* isolate = sampler->isolate();
534 530 if (!helper.Init(sampler, isolate)) return;
535 SampleHelper helper; 531 #endif
536 TickSample* sample = helper.Init(sampler, isolate);
537 if (sample == NULL) return;
538 532
539 if (KERN_SUCCESS != thread_suspend(profiled_thread)) return; 533 if (KERN_SUCCESS != thread_suspend(profiled_thread)) return;
540 534
541 #if V8_HOST_ARCH_X64 535 #if V8_HOST_ARCH_X64
542 thread_state_flavor_t flavor = x86_THREAD_STATE64; 536 thread_state_flavor_t flavor = x86_THREAD_STATE64;
543 x86_thread_state64_t state; 537 x86_thread_state64_t thread_state;
544 mach_msg_type_number_t count = x86_THREAD_STATE64_COUNT; 538 mach_msg_type_number_t count = x86_THREAD_STATE64_COUNT;
545 #if __DARWIN_UNIX03 539 #if __DARWIN_UNIX03
546 #define REGISTER_FIELD(name) __r ## name 540 #define REGISTER_FIELD(name) __r ## name
547 #else 541 #else
548 #define REGISTER_FIELD(name) r ## name 542 #define REGISTER_FIELD(name) r ## name
549 #endif // __DARWIN_UNIX03 543 #endif // __DARWIN_UNIX03
550 #elif V8_HOST_ARCH_IA32 544 #elif V8_HOST_ARCH_IA32
551 thread_state_flavor_t flavor = i386_THREAD_STATE; 545 thread_state_flavor_t flavor = i386_THREAD_STATE;
552 i386_thread_state_t state; 546 i386_thread_state_t thread_state;
553 mach_msg_type_number_t count = i386_THREAD_STATE_COUNT; 547 mach_msg_type_number_t count = i386_THREAD_STATE_COUNT;
554 #if __DARWIN_UNIX03 548 #if __DARWIN_UNIX03
555 #define REGISTER_FIELD(name) __e ## name 549 #define REGISTER_FIELD(name) __e ## name
556 #else 550 #else
557 #define REGISTER_FIELD(name) e ## name 551 #define REGISTER_FIELD(name) e ## name
558 #endif // __DARWIN_UNIX03 552 #endif // __DARWIN_UNIX03
559 #else 553 #else
560 #error Unsupported Mac OS X host architecture. 554 #error Unsupported Mac OS X host architecture.
561 #endif // V8_HOST_ARCH 555 #endif // V8_HOST_ARCH
562 556
563 if (thread_get_state(profiled_thread, 557 if (thread_get_state(profiled_thread,
564 flavor, 558 flavor,
565 reinterpret_cast<natural_t*>(&state), 559 reinterpret_cast<natural_t*>(&thread_state),
566 &count) == KERN_SUCCESS) { 560 &count) == KERN_SUCCESS) {
567 sample->state = isolate->current_vm_state(); 561 RegisterState state;
568 #if defined(USE_SIMULATOR) 562 #if defined(USE_SIMULATOR)
569 helper.FillRegisters(sample); 563 helper.FillRegisters(&state);
570 #else 564 #else
571 sample->pc = reinterpret_cast<Address>(state.REGISTER_FIELD(ip)); 565 state.pc = reinterpret_cast<Address>(thread_state.REGISTER_FIELD(ip));
572 sample->sp = reinterpret_cast<Address>(state.REGISTER_FIELD(sp)); 566 state.sp = reinterpret_cast<Address>(thread_state.REGISTER_FIELD(sp));
573 sample->fp = reinterpret_cast<Address>(state.REGISTER_FIELD(bp)); 567 state.fp = reinterpret_cast<Address>(thread_state.REGISTER_FIELD(bp));
574 #endif // USE_SIMULATOR 568 #endif // USE_SIMULATOR
575 #undef REGISTER_FIELD 569 #undef REGISTER_FIELD
576 sampler->SampleStack(sample); 570 sampler->SampleStack(state);
577 sampler->Tick(sample);
578 } 571 }
579 thread_resume(profiled_thread); 572 thread_resume(profiled_thread);
580 } 573 }
581 574
582 #elif defined(_WIN32) || defined(_WIN64) || defined(__CYGWIN__) 575 #elif defined(_WIN32) || defined(_WIN64) || defined(__CYGWIN__)
583 576
584 void SampleContext(Sampler* sampler) { 577 void SampleContext(Sampler* sampler) {
585 HANDLE profiled_thread = sampler->platform_data()->profiled_thread(); 578 HANDLE profiled_thread = sampler->platform_data()->profiled_thread();
586 if (profiled_thread == NULL) return; 579 if (profiled_thread == NULL) return;
587 580
588 Isolate* isolate = sampler->isolate(); 581 Isolate* isolate = sampler->isolate();
589 SampleHelper helper; 582 #if defined(USE_SIMULATOR)
590 TickSample* sample = helper.Init(sampler, isolate); 583 SimulatorHelper helper;
591 if (sample == NULL) return; 584 if (!helper.Init(sampler, isolate)) return;
585 #endif
592 586
593 const DWORD kSuspendFailed = static_cast<DWORD>(-1); 587 const DWORD kSuspendFailed = static_cast<DWORD>(-1);
594 if (SuspendThread(profiled_thread) == kSuspendFailed) return; 588 if (SuspendThread(profiled_thread) == kSuspendFailed) return;
595 sample->state = isolate->current_vm_state();
596 589
597 // Context used for sampling the register state of the profiled thread. 590 // Context used for sampling the register state of the profiled thread.
598 CONTEXT context; 591 CONTEXT context;
599 memset(&context, 0, sizeof(context)); 592 memset(&context, 0, sizeof(context));
600 context.ContextFlags = CONTEXT_FULL; 593 context.ContextFlags = CONTEXT_FULL;
601 if (GetThreadContext(profiled_thread, &context) != 0) { 594 if (GetThreadContext(profiled_thread, &context) != 0) {
595 RegisterState state;
602 #if defined(USE_SIMULATOR) 596 #if defined(USE_SIMULATOR)
603 helper.FillRegisters(sample); 597 helper.FillRegisters(&state);
604 #else 598 #else
605 #if V8_HOST_ARCH_X64 599 #if V8_HOST_ARCH_X64
606 sample->pc = reinterpret_cast<Address>(context.Rip); 600 state.pc = reinterpret_cast<Address>(context.Rip);
607 sample->sp = reinterpret_cast<Address>(context.Rsp); 601 state.sp = reinterpret_cast<Address>(context.Rsp);
608 sample->fp = reinterpret_cast<Address>(context.Rbp); 602 state.fp = reinterpret_cast<Address>(context.Rbp);
609 #else 603 #else
610 sample->pc = reinterpret_cast<Address>(context.Eip); 604 state.pc = reinterpret_cast<Address>(context.Eip);
611 sample->sp = reinterpret_cast<Address>(context.Esp); 605 state.sp = reinterpret_cast<Address>(context.Esp);
612 sample->fp = reinterpret_cast<Address>(context.Ebp); 606 state.fp = reinterpret_cast<Address>(context.Ebp);
613 #endif 607 #endif
614 #endif // USE_SIMULATOR 608 #endif // USE_SIMULATOR
615 sampler->SampleStack(sample); 609 sampler->SampleStack(state);
616 sampler->Tick(sample);
617 } 610 }
618 ResumeThread(profiled_thread); 611 ResumeThread(profiled_thread);
619 } 612 }
620 613
621 #endif // USE_SIGNALS 614 #endif // USE_SIGNALS
622 615
623 616
624 // Protects the process wide state below. 617 // Protects the process wide state below.
625 static Mutex* mutex_; 618 static Mutex* mutex_;
626 static SamplerThread* instance_; 619 static SamplerThread* instance_;
627 620
628 const int interval_; 621 const int interval_;
629 List<Sampler*> active_samplers_; 622 List<Sampler*> active_samplers_;
630 623
631 DISALLOW_COPY_AND_ASSIGN(SamplerThread); 624 DISALLOW_COPY_AND_ASSIGN(SamplerThread);
632 }; 625 };
633 626
634 627
635 Mutex* SamplerThread::mutex_ = NULL; 628 Mutex* SamplerThread::mutex_ = NULL;
636 SamplerThread* SamplerThread::instance_ = NULL; 629 SamplerThread* SamplerThread::instance_ = NULL;
637 630
638 631
639 // 632 //
640 // StackTracer implementation 633 // StackTracer implementation
641 // 634 //
642 DISABLE_ASAN void TickSample::Trace(Isolate* isolate) { 635 DISABLE_ASAN void TickSample::Init(Isolate* isolate,
636 const RegisterState& regs) {
643 ASSERT(isolate->IsInitialized()); 637 ASSERT(isolate->IsInitialized());
638 pc = regs.pc;
639 state = isolate->current_vm_state();
644 640
645 // Avoid collecting traces while doing GC. 641 // Avoid collecting traces while doing GC.
646 if (state == GC) return; 642 if (state == GC) return;
647 643
648 const Address js_entry_sp = 644 const Address js_entry_sp =
649 Isolate::js_entry_sp(isolate->thread_local_top()); 645 Isolate::js_entry_sp(isolate->thread_local_top());
650 if (js_entry_sp == 0) { 646 if (js_entry_sp == 0) {
651 // Not executing JS now. 647 // Not executing JS now.
652 return; 648 return;
653 } 649 }
654 650
655 const Address callback = isolate->external_callback(); 651 const Address callback = isolate->external_callback();
656 if (callback != NULL) { 652 if (callback != NULL) {
657 external_callback = callback; 653 external_callback = callback;
658 has_external_callback = true; 654 has_external_callback = true;
659 } else { 655 } else {
660 // Sample potential return address value for frameless invocation of 656 // Sample potential return address value for frameless invocation of
661 // stubs (we'll figure out later, if this value makes sense). 657 // stubs (we'll figure out later, if this value makes sense).
662 tos = Memory::Address_at(sp); 658 tos = Memory::Address_at(regs.sp);
663 has_external_callback = false; 659 has_external_callback = false;
664 } 660 }
665 661
666 SafeStackFrameIterator it(isolate, fp, sp, sp, js_entry_sp); 662 SafeStackFrameIterator it(isolate, regs.fp, regs.sp, js_entry_sp);
663 top_frame_type = it.top_frame_type();
667 int i = 0; 664 int i = 0;
668 while (!it.done() && i < TickSample::kMaxFramesCount) { 665 while (!it.done() && i < TickSample::kMaxFramesCount) {
669 stack[i++] = it.frame()->pc(); 666 stack[i++] = it.frame()->pc();
670 it.Advance(); 667 it.Advance();
671 } 668 }
672 frames_count = i; 669 frames_count = i;
673 } 670 }
674 671
675 672
676 void Sampler::SetUp() { 673 void Sampler::SetUp() {
(...skipping 14 matching lines...) Expand all
691 samples_taken_(0) { 688 samples_taken_(0) {
692 data_ = new PlatformData; 689 data_ = new PlatformData;
693 } 690 }
694 691
695 692
696 Sampler::~Sampler() { 693 Sampler::~Sampler() {
697 ASSERT(!IsActive()); 694 ASSERT(!IsActive());
698 delete data_; 695 delete data_;
699 } 696 }
700 697
698
701 void Sampler::Start() { 699 void Sampler::Start() {
702 ASSERT(!IsActive()); 700 ASSERT(!IsActive());
703 SetActive(true); 701 SetActive(true);
704 SamplerThread::AddActiveSampler(this); 702 SamplerThread::AddActiveSampler(this);
705 } 703 }
706 704
707 705
708 void Sampler::Stop() { 706 void Sampler::Stop() {
709 ASSERT(IsActive()); 707 ASSERT(IsActive());
710 SamplerThread::RemoveActiveSampler(this); 708 SamplerThread::RemoveActiveSampler(this);
711 SetActive(false); 709 SetActive(false);
712 } 710 }
713 711
714 void Sampler::SampleStack(TickSample* sample) { 712
715 sample->Trace(isolate_); 713 void Sampler::SampleStack(const RegisterState& state) {
714 TickSample* sample = isolate_->cpu_profiler()->TickSampleEvent();
715 TickSample sample_obj;
716 if (sample == NULL) sample = &sample_obj;
717 sample->Init(isolate_, state);
716 if (++samples_taken_ < 0) samples_taken_ = 0; 718 if (++samples_taken_ < 0) samples_taken_ = 0;
719 Tick(sample);
717 } 720 }
718 721
719 } } // namespace v8::internal 722 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/sampler.h ('k') | src/scanner-character-streams.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698