| OLD | NEW |
| 1 // Copyright 2006-2009 the V8 project authors. All rights reserved. | 1 // Copyright 2006-2009 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 27 matching lines...) Expand all Loading... |
| 38 #include <ucontext.h> // walkstack(), getcontext() | 38 #include <ucontext.h> // walkstack(), getcontext() |
| 39 #include <dlfcn.h> // dladdr | 39 #include <dlfcn.h> // dladdr |
| 40 #include <pthread.h> | 40 #include <pthread.h> |
| 41 #include <sched.h> // for sched_yield | 41 #include <sched.h> // for sched_yield |
| 42 #include <semaphore.h> | 42 #include <semaphore.h> |
| 43 #include <time.h> | 43 #include <time.h> |
| 44 #include <sys/time.h> // gettimeofday(), timeradd() | 44 #include <sys/time.h> // gettimeofday(), timeradd() |
| 45 #include <errno.h> | 45 #include <errno.h> |
| 46 #include <ieeefp.h> // finite() | 46 #include <ieeefp.h> // finite() |
| 47 #include <signal.h> // sigemptyset(), etc | 47 #include <signal.h> // sigemptyset(), etc |
| 48 #include <sys/kdi_regs.h> |
| 48 | 49 |
| 49 | 50 |
| 50 #undef MAP_TYPE | 51 #undef MAP_TYPE |
| 51 | 52 |
| 52 #include "v8.h" | 53 #include "v8.h" |
| 53 | 54 |
| 54 #include "platform.h" | 55 #include "platform.h" |
| 55 #include "vm-state-inl.h" | 56 #include "vm-state-inl.h" |
| 56 | 57 |
| 57 | 58 |
| (...skipping 338 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 396 | 397 |
| 397 | 398 |
| 398 bool ThreadHandle::IsValid() const { | 399 bool ThreadHandle::IsValid() const { |
| 399 return data_->thread_ != kNoThread; | 400 return data_->thread_ != kNoThread; |
| 400 } | 401 } |
| 401 | 402 |
| 402 | 403 |
| 403 Thread::Thread(Isolate* isolate) | 404 Thread::Thread(Isolate* isolate) |
| 404 : ThreadHandle(ThreadHandle::INVALID), | 405 : ThreadHandle(ThreadHandle::INVALID), |
| 405 isolate_(isolate) { | 406 isolate_(isolate) { |
| 407 set_name("v8:<unknown>"); |
| 408 } |
| 409 |
| 410 |
| 411 Thread::Thread(Isolate* isolate, const char* name) |
| 412 : ThreadHandle(ThreadHandle::INVALID), |
| 413 isolate_(isolate) { |
| 414 set_name(name); |
| 406 } | 415 } |
| 407 | 416 |
| 408 | 417 |
| 409 Thread::~Thread() { | 418 Thread::~Thread() { |
| 410 } | 419 } |
| 411 | 420 |
| 412 | 421 |
| 413 static void* ThreadEntry(void* arg) { | 422 static void* ThreadEntry(void* arg) { |
| 414 Thread* thread = reinterpret_cast<Thread*>(arg); | 423 Thread* thread = reinterpret_cast<Thread*>(arg); |
| 415 // This is also initialized by the first argument to pthread_create() but we | 424 // This is also initialized by the first argument to pthread_create() but we |
| 416 // don't know which thread will run first (the original thread or the new | 425 // don't know which thread will run first (the original thread or the new |
| 417 // one) so we initialize it here too. | 426 // one) so we initialize it here too. |
| 418 thread->thread_handle_data()->thread_ = pthread_self(); | 427 thread->thread_handle_data()->thread_ = pthread_self(); |
| 419 ASSERT(thread->IsValid()); | 428 ASSERT(thread->IsValid()); |
| 420 Thread::SetThreadLocal(Isolate::isolate_key(), thread->isolate()); | 429 Thread::SetThreadLocal(Isolate::isolate_key(), thread->isolate()); |
| 421 thread->Run(); | 430 thread->Run(); |
| 422 return NULL; | 431 return NULL; |
| 423 } | 432 } |
| 424 | 433 |
| 425 | 434 |
| 435 void Thread::set_name(const char* name) { |
| 436 strncpy(name_, name, sizeof(name_)); |
| 437 name_[sizeof(name_) - 1] = '\0'; |
| 438 } |
| 439 |
| 440 |
| 426 void Thread::Start() { | 441 void Thread::Start() { |
| 427 pthread_create(&thread_handle_data()->thread_, NULL, ThreadEntry, this); | 442 pthread_create(&thread_handle_data()->thread_, NULL, ThreadEntry, this); |
| 428 ASSERT(IsValid()); | 443 ASSERT(IsValid()); |
| 429 } | 444 } |
| 430 | 445 |
| 431 | 446 |
| 432 void Thread::Join() { | 447 void Thread::Join() { |
| 433 pthread_join(thread_handle_data()->thread_, NULL); | 448 pthread_join(thread_handle_data()->thread_, NULL); |
| 434 } | 449 } |
| 435 | 450 |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 477 pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE); | 492 pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE); |
| 478 pthread_mutex_init(&mutex_, &attr); | 493 pthread_mutex_init(&mutex_, &attr); |
| 479 } | 494 } |
| 480 | 495 |
| 481 ~SolarisMutex() { pthread_mutex_destroy(&mutex_); } | 496 ~SolarisMutex() { pthread_mutex_destroy(&mutex_); } |
| 482 | 497 |
| 483 int Lock() { return pthread_mutex_lock(&mutex_); } | 498 int Lock() { return pthread_mutex_lock(&mutex_); } |
| 484 | 499 |
| 485 int Unlock() { return pthread_mutex_unlock(&mutex_); } | 500 int Unlock() { return pthread_mutex_unlock(&mutex_); } |
| 486 | 501 |
| 502 virtual bool TryLock() { |
| 503 int result = pthread_mutex_trylock(&mutex_); |
| 504 // Return false if the lock is busy and locking failed. |
| 505 if (result == EBUSY) { |
| 506 return false; |
| 507 } |
| 508 ASSERT(result == 0); // Verify no other errors. |
| 509 return true; |
| 510 } |
| 511 |
| 487 private: | 512 private: |
| 488 pthread_mutex_t mutex_; | 513 pthread_mutex_t mutex_; |
| 489 }; | 514 }; |
| 490 | 515 |
| 491 | 516 |
| 492 Mutex* OS::CreateMutex() { | 517 Mutex* OS::CreateMutex() { |
| 493 return new SolarisMutex(); | 518 return new SolarisMutex(); |
| 494 } | 519 } |
| 495 | 520 |
| 496 | 521 |
| (...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 568 | 593 |
| 569 | 594 |
| 570 Semaphore* OS::CreateSemaphore(int count) { | 595 Semaphore* OS::CreateSemaphore(int count) { |
| 571 return new SolarisSemaphore(count); | 596 return new SolarisSemaphore(count); |
| 572 } | 597 } |
| 573 | 598 |
| 574 | 599 |
| 575 #ifdef ENABLE_LOGGING_AND_PROFILING | 600 #ifdef ENABLE_LOGGING_AND_PROFILING |
| 576 | 601 |
| 577 static Sampler* active_sampler_ = NULL; | 602 static Sampler* active_sampler_ = NULL; |
| 603 static pthread_t vm_tid_ = 0; |
| 604 |
| 578 | 605 |
| 579 static void ProfilerSignalHandler(int signal, siginfo_t* info, void* context) { | 606 static void ProfilerSignalHandler(int signal, siginfo_t* info, void* context) { |
| 580 USE(info); | 607 USE(info); |
| 581 if (signal != SIGPROF) return; | 608 if (signal != SIGPROF) return; |
| 582 if (active_sampler_ == NULL) return; | 609 if (active_sampler_ == NULL || !active_sampler_->IsActive()) return; |
| 610 if (vm_tid_ != pthread_self()) return; |
| 583 | 611 |
| 584 TickSample sample; | 612 TickSample sample_obj; |
| 585 sample.pc = 0; | 613 TickSample* sample = CpuProfiler::TickSampleEvent(); |
| 586 sample.sp = 0; | 614 if (sample == NULL) sample = &sample_obj; |
| 587 sample.fp = 0; | |
| 588 | 615 |
| 589 // We always sample the VM state. | 616 // Extracting the sample from the context is extremely machine dependent. |
| 590 sample.state = VMState::current_state(); | 617 ucontext_t* ucontext = reinterpret_cast<ucontext_t*>(context); |
| 618 mcontext_t& mcontext = ucontext->uc_mcontext; |
| 619 sample->state = Top::current_vm_state(); |
| 591 | 620 |
| 592 active_sampler_->Tick(&sample); | 621 #if V8_HOST_ARCH_IA32 |
| 622 sample->pc = reinterpret_cast<Address>(mcontext.gregs[KDIREG_EIP]); |
| 623 sample->sp = reinterpret_cast<Address>(mcontext.gregs[KDIREG_ESP]); |
| 624 sample->fp = reinterpret_cast<Address>(mcontext.gregs[KDIREG_EBP]); |
| 625 #elif V8_HOST_ARCH_X64 |
| 626 sample->pc = reinterpret_cast<Address>(mcontext.gregs[KDIREG_RIP]); |
| 627 sample->sp = reinterpret_cast<Address>(mcontext.gregs[KDIREG_RSP]); |
| 628 sample->fp = reinterpret_cast<Address>(mcontext.gregs[KDIREG_RBP]); |
| 629 #else |
| 630 UNIMPLEMENTED(); |
| 631 #endif |
| 632 active_sampler_->SampleStack(sample); |
| 633 active_sampler_->Tick(sample); |
| 593 } | 634 } |
| 594 | 635 |
| 595 | 636 |
| 596 class Sampler::PlatformData : public Malloced { | 637 class Sampler::PlatformData : public Malloced { |
| 597 public: | 638 public: |
| 598 PlatformData() { | 639 PlatformData() { |
| 599 signal_handler_installed_ = false; | 640 signal_handler_installed_ = false; |
| 600 } | 641 } |
| 601 | 642 |
| 602 bool signal_handler_installed_; | 643 bool signal_handler_installed_; |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 656 } | 697 } |
| 657 | 698 |
| 658 // This sampler is no longer the active sampler. | 699 // This sampler is no longer the active sampler. |
| 659 active_sampler_ = NULL; | 700 active_sampler_ = NULL; |
| 660 active_ = false; | 701 active_ = false; |
| 661 } | 702 } |
| 662 | 703 |
| 663 #endif // ENABLE_LOGGING_AND_PROFILING | 704 #endif // ENABLE_LOGGING_AND_PROFILING |
| 664 | 705 |
| 665 } } // namespace v8::internal | 706 } } // namespace v8::internal |
| OLD | NEW |