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

Side by Side Diff: src/platform-win32.cc

Issue 6685088: Merge isolates to bleeding_edge. (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: '' Created 9 years, 9 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/platform-solaris.cc ('k') | src/preparse-data.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 2006-2008 the V8 project authors. All rights reserved. 1 // Copyright 2006-2008 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 155 matching lines...) Expand 10 before | Expand all | Expand 10 after
166 } 166 }
167 167
168 168
169 namespace v8 { 169 namespace v8 {
170 namespace internal { 170 namespace internal {
171 171
172 double ceiling(double x) { 172 double ceiling(double x) {
173 return ceil(x); 173 return ceil(x);
174 } 174 }
175 175
176
177 static Mutex* limit_mutex = NULL;
178
179
176 #ifdef _WIN64 180 #ifdef _WIN64
177 typedef double (*ModuloFunction)(double, double); 181 typedef double (*ModuloFunction)(double, double);
178 182
179 // Defined in codegen-x64.cc. 183 // Defined in codegen-x64.cc.
180 ModuloFunction CreateModuloFunction(); 184 ModuloFunction CreateModuloFunction();
181 185
182 double modulo(double x, double y) { 186 double modulo(double x, double y) {
183 static ModuloFunction function = CreateModuloFunction(); 187 static ModuloFunction function = CreateModuloFunction();
184 return function(x, y); 188 return function(x, y);
185 } 189 }
(...skipping 347 matching lines...) Expand 10 before | Expand all | Expand 10 after
533 537
534 538
535 void OS::Setup() { 539 void OS::Setup() {
536 // Seed the random number generator. 540 // Seed the random number generator.
537 // Convert the current time to a 64-bit integer first, before converting it 541 // Convert the current time to a 64-bit integer first, before converting it
538 // to an unsigned. Going directly can cause an overflow and the seed to be 542 // to an unsigned. Going directly can cause an overflow and the seed to be
539 // set to all ones. The seed will be identical for different instances that 543 // set to all ones. The seed will be identical for different instances that
540 // call this setup code within the same millisecond. 544 // call this setup code within the same millisecond.
541 uint64_t seed = static_cast<uint64_t>(TimeCurrentMillis()); 545 uint64_t seed = static_cast<uint64_t>(TimeCurrentMillis());
542 srand(static_cast<unsigned int>(seed)); 546 srand(static_cast<unsigned int>(seed));
547 limit_mutex = CreateMutex();
543 } 548 }
544 549
545 550
546 // Returns the accumulated user time for thread. 551 // Returns the accumulated user time for thread.
547 int OS::GetUserTime(uint32_t* secs, uint32_t* usecs) { 552 int OS::GetUserTime(uint32_t* secs, uint32_t* usecs) {
548 FILETIME dummy; 553 FILETIME dummy;
549 uint64_t usertime; 554 uint64_t usertime;
550 555
551 // Get the amount of time that the thread has executed in user mode. 556 // Get the amount of time that the thread has executed in user mode.
552 if (!GetThreadTimes(GetCurrentThread(), &dummy, &dummy, &dummy, 557 if (!GetThreadTimes(GetCurrentThread(), &dummy, &dummy, &dummy,
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after
669 } 674 }
670 } 675 }
671 676
672 677
673 bool OS::Remove(const char* path) { 678 bool OS::Remove(const char* path) {
674 return (DeleteFileA(path) != 0); 679 return (DeleteFileA(path) != 0);
675 } 680 }
676 681
677 682
678 // Open log file in binary mode to avoid /n -> /r/n conversion. 683 // Open log file in binary mode to avoid /n -> /r/n conversion.
679 const char* OS::LogFileOpenMode = "wb"; 684 const char* const OS::LogFileOpenMode = "wb";
680 685
681 686
682 // Print (debug) message to console. 687 // Print (debug) message to console.
683 void OS::Print(const char* format, ...) { 688 void OS::Print(const char* format, ...) {
684 va_list args; 689 va_list args;
685 va_start(args, format); 690 va_start(args, format);
686 VPrint(format, args); 691 VPrint(format, args);
687 va_end(args); 692 va_end(args);
688 } 693 }
689 694
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
758 // We keep the lowest and highest addresses mapped as a quick way of 763 // We keep the lowest and highest addresses mapped as a quick way of
759 // determining that pointers are outside the heap (used mostly in assertions 764 // determining that pointers are outside the heap (used mostly in assertions
760 // and verification). The estimate is conservative, ie, not all addresses in 765 // and verification). The estimate is conservative, ie, not all addresses in
761 // 'allocated' space are actually allocated to our heap. The range is 766 // 'allocated' space are actually allocated to our heap. The range is
762 // [lowest, highest), inclusive on the low and and exclusive on the high end. 767 // [lowest, highest), inclusive on the low and and exclusive on the high end.
763 static void* lowest_ever_allocated = reinterpret_cast<void*>(-1); 768 static void* lowest_ever_allocated = reinterpret_cast<void*>(-1);
764 static void* highest_ever_allocated = reinterpret_cast<void*>(0); 769 static void* highest_ever_allocated = reinterpret_cast<void*>(0);
765 770
766 771
767 static void UpdateAllocatedSpaceLimits(void* address, int size) { 772 static void UpdateAllocatedSpaceLimits(void* address, int size) {
773 ASSERT(limit_mutex != NULL);
774 ScopedLock lock(limit_mutex);
775
768 lowest_ever_allocated = Min(lowest_ever_allocated, address); 776 lowest_ever_allocated = Min(lowest_ever_allocated, address);
769 highest_ever_allocated = 777 highest_ever_allocated =
770 Max(highest_ever_allocated, 778 Max(highest_ever_allocated,
771 reinterpret_cast<void*>(reinterpret_cast<char*>(address) + size)); 779 reinterpret_cast<void*>(reinterpret_cast<char*>(address) + size));
772 } 780 }
773 781
774 782
775 bool OS::IsOutsideAllocatedSpace(void* pointer) { 783 bool OS::IsOutsideAllocatedSpace(void* pointer) {
776 if (pointer < lowest_ever_allocated || pointer >= highest_ever_allocated) 784 if (pointer < lowest_ever_allocated || pointer >= highest_ever_allocated)
777 return true; 785 return true;
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
828 // VirtualAlloc rounds allocated size to page size automatically. 836 // VirtualAlloc rounds allocated size to page size automatically.
829 size_t msize = RoundUp(requested, static_cast<int>(GetPageSize())); 837 size_t msize = RoundUp(requested, static_cast<int>(GetPageSize()));
830 intptr_t address = 0; 838 intptr_t address = 0;
831 839
832 // Windows XP SP2 allows Data Excution Prevention (DEP). 840 // Windows XP SP2 allows Data Excution Prevention (DEP).
833 int prot = is_executable ? PAGE_EXECUTE_READWRITE : PAGE_READWRITE; 841 int prot = is_executable ? PAGE_EXECUTE_READWRITE : PAGE_READWRITE;
834 842
835 // For exectutable pages try and randomize the allocation address 843 // For exectutable pages try and randomize the allocation address
836 if (prot == PAGE_EXECUTE_READWRITE && 844 if (prot == PAGE_EXECUTE_READWRITE &&
837 msize >= static_cast<size_t>(Page::kPageSize)) { 845 msize >= static_cast<size_t>(Page::kPageSize)) {
838 address = (V8::RandomPrivate() << kPageSizeBits) 846 address = (V8::RandomPrivate(Isolate::Current()) << kPageSizeBits)
839 | kAllocationRandomAddressMin; 847 | kAllocationRandomAddressMin;
840 address &= kAllocationRandomAddressMax; 848 address &= kAllocationRandomAddressMax;
841 } 849 }
842 850
843 LPVOID mbase = VirtualAlloc(reinterpret_cast<void *>(address), 851 LPVOID mbase = VirtualAlloc(reinterpret_cast<void *>(address),
844 msize, 852 msize,
845 MEM_COMMIT | MEM_RESERVE, 853 MEM_COMMIT | MEM_RESERVE,
846 prot); 854 prot);
847 if (mbase == NULL && address != 0) 855 if (mbase == NULL && address != 0)
848 mbase = VirtualAlloc(NULL, msize, MEM_COMMIT | MEM_RESERVE, prot); 856 mbase = VirtualAlloc(NULL, msize, MEM_COMMIT | MEM_RESERVE, prot);
849 857
850 if (mbase == NULL) { 858 if (mbase == NULL) {
851 LOG(StringEvent("OS::Allocate", "VirtualAlloc failed")); 859 LOG(ISOLATE, StringEvent("OS::Allocate", "VirtualAlloc failed"));
852 return NULL; 860 return NULL;
853 } 861 }
854 862
855 ASSERT(IsAligned(reinterpret_cast<size_t>(mbase), OS::AllocateAlignment())); 863 ASSERT(IsAligned(reinterpret_cast<size_t>(mbase), OS::AllocateAlignment()));
856 864
857 *allocated = msize; 865 *allocated = msize;
858 UpdateAllocatedSpaceLimits(mbase, static_cast<int>(msize)); 866 UpdateAllocatedSpaceLimits(mbase, static_cast<int>(msize));
859 return mbase; 867 return mbase;
860 } 868 }
861 869
(...skipping 322 matching lines...) Expand 10 before | Expand all | Expand 10 after
1184 0, // hFile 1192 0, // hFile
1185 reinterpret_cast<PSTR>(module_entry.szExePath), // ImageName 1193 reinterpret_cast<PSTR>(module_entry.szExePath), // ImageName
1186 reinterpret_cast<PSTR>(module_entry.szModule), // ModuleName 1194 reinterpret_cast<PSTR>(module_entry.szModule), // ModuleName
1187 reinterpret_cast<DWORD64>(module_entry.modBaseAddr), // BaseOfDll 1195 reinterpret_cast<DWORD64>(module_entry.modBaseAddr), // BaseOfDll
1188 module_entry.modBaseSize); // SizeOfDll 1196 module_entry.modBaseSize); // SizeOfDll
1189 if (base == 0) { 1197 if (base == 0) {
1190 int err = GetLastError(); 1198 int err = GetLastError();
1191 if (err != ERROR_MOD_NOT_FOUND && 1199 if (err != ERROR_MOD_NOT_FOUND &&
1192 err != ERROR_INVALID_HANDLE) return false; 1200 err != ERROR_INVALID_HANDLE) return false;
1193 } 1201 }
1194 LOG(SharedLibraryEvent( 1202 LOG(i::Isolate::Current(),
1203 SharedLibraryEvent(
1195 module_entry.szExePath, 1204 module_entry.szExePath,
1196 reinterpret_cast<unsigned int>(module_entry.modBaseAddr), 1205 reinterpret_cast<unsigned int>(module_entry.modBaseAddr),
1197 reinterpret_cast<unsigned int>(module_entry.modBaseAddr + 1206 reinterpret_cast<unsigned int>(module_entry.modBaseAddr +
1198 module_entry.modBaseSize))); 1207 module_entry.modBaseSize)));
1199 cont = _Module32NextW(snapshot, &module_entry); 1208 cont = _Module32NextW(snapshot, &module_entry);
1200 } 1209 }
1201 CloseHandle(snapshot); 1210 CloseHandle(snapshot);
1202 1211
1203 symbols_loaded = true; 1212 symbols_loaded = true;
1204 return true; 1213 return true;
(...skipping 238 matching lines...) Expand 10 before | Expand all | Expand 10 after
1443 // Entry point for threads. The supplied argument is a pointer to the thread 1452 // Entry point for threads. The supplied argument is a pointer to the thread
1444 // object. The entry function dispatches to the run method in the thread 1453 // object. The entry function dispatches to the run method in the thread
1445 // object. It is important that this function has __stdcall calling 1454 // object. It is important that this function has __stdcall calling
1446 // convention. 1455 // convention.
1447 static unsigned int __stdcall ThreadEntry(void* arg) { 1456 static unsigned int __stdcall ThreadEntry(void* arg) {
1448 Thread* thread = reinterpret_cast<Thread*>(arg); 1457 Thread* thread = reinterpret_cast<Thread*>(arg);
1449 // This is also initialized by the last parameter to _beginthreadex() but we 1458 // This is also initialized by the last parameter to _beginthreadex() but we
1450 // don't know which thread will run first (the original thread or the new 1459 // don't know which thread will run first (the original thread or the new
1451 // one) so we initialize it here too. 1460 // one) so we initialize it here too.
1452 thread->thread_handle_data()->tid_ = GetCurrentThreadId(); 1461 thread->thread_handle_data()->tid_ = GetCurrentThreadId();
1462 Thread::SetThreadLocal(Isolate::isolate_key(), thread->isolate());
1453 thread->Run(); 1463 thread->Run();
1454 return 0; 1464 return 0;
1455 } 1465 }
1456 1466
1457 1467
1458 // Initialize thread handle to invalid handle. 1468 // Initialize thread handle to invalid handle.
1459 ThreadHandle::ThreadHandle(ThreadHandle::Kind kind) { 1469 ThreadHandle::ThreadHandle(ThreadHandle::Kind kind) {
1460 data_ = new PlatformData(kind); 1470 data_ = new PlatformData(kind);
1461 } 1471 }
1462 1472
(...skipping 23 matching lines...) Expand all
1486 class Thread::PlatformData : public Malloced { 1496 class Thread::PlatformData : public Malloced {
1487 public: 1497 public:
1488 explicit PlatformData(HANDLE thread) : thread_(thread) {} 1498 explicit PlatformData(HANDLE thread) : thread_(thread) {}
1489 HANDLE thread_; 1499 HANDLE thread_;
1490 }; 1500 };
1491 1501
1492 1502
1493 // Initialize a Win32 thread object. The thread has an invalid thread 1503 // Initialize a Win32 thread object. The thread has an invalid thread
1494 // handle until it is started. 1504 // handle until it is started.
1495 1505
1496 Thread::Thread() : ThreadHandle(ThreadHandle::INVALID) { 1506 Thread::Thread(Isolate* isolate)
1507 : ThreadHandle(ThreadHandle::INVALID),
1508 isolate_(isolate) {
1497 data_ = new PlatformData(kNoThread); 1509 data_ = new PlatformData(kNoThread);
1498 set_name("v8:<unknown>"); 1510 set_name("v8:<unknown>");
1499 } 1511 }
1500 1512
1501 1513
1502 Thread::Thread(const char* name) : ThreadHandle(ThreadHandle::INVALID) { 1514 Thread::Thread(Isolate* isolate, const char* name)
1515 : ThreadHandle(ThreadHandle::INVALID),
1516 isolate_(isolate) {
1503 data_ = new PlatformData(kNoThread); 1517 data_ = new PlatformData(kNoThread);
1504 set_name(name); 1518 set_name(name);
1505 } 1519 }
1506 1520
1507 1521
1508 void Thread::set_name(const char* name) { 1522 void Thread::set_name(const char* name) {
1509 OS::StrNCpy(Vector<char>(name_, sizeof(name_)), name, strlen(name)); 1523 OS::StrNCpy(Vector<char>(name_, sizeof(name_)), name, strlen(name));
1510 name_[sizeof(name_) - 1] = '\0'; 1524 name_[sizeof(name_) - 1] = '\0';
1511 } 1525 }
1512 1526
(...skipping 320 matching lines...) Expand 10 before | Expand all | Expand 10 after
1833 1847
1834 Socket* OS::CreateSocket() { 1848 Socket* OS::CreateSocket() {
1835 return new Win32Socket(); 1849 return new Win32Socket();
1836 } 1850 }
1837 1851
1838 1852
1839 #ifdef ENABLE_LOGGING_AND_PROFILING 1853 #ifdef ENABLE_LOGGING_AND_PROFILING
1840 1854
1841 // ---------------------------------------------------------------------------- 1855 // ----------------------------------------------------------------------------
1842 // Win32 profiler support. 1856 // Win32 profiler support.
1843 //
1844 // On win32 we use a sampler thread with high priority to sample the program
1845 // counter for the profiled thread.
1846 1857
1847 class Sampler::PlatformData : public Malloced { 1858 class Sampler::PlatformData : public Malloced {
1848 public: 1859 public:
1849 explicit PlatformData(Sampler* sampler) {
1850 sampler_ = sampler;
1851 sampler_thread_ = INVALID_HANDLE_VALUE;
1852 profiled_thread_ = INVALID_HANDLE_VALUE;
1853 }
1854
1855 Sampler* sampler_;
1856 HANDLE sampler_thread_;
1857 HANDLE profiled_thread_;
1858 RuntimeProfilerRateLimiter rate_limiter_;
1859
1860 // Sampler thread handler.
1861 void Runner() {
1862 while (sampler_->IsActive()) {
1863 if (rate_limiter_.SuspendIfNecessary()) continue;
1864 Sample();
1865 Sleep(sampler_->interval_);
1866 }
1867 }
1868
1869 void Sample() {
1870 if (sampler_->IsProfiling()) {
1871 // Context used for sampling the register state of the profiled thread.
1872 CONTEXT context;
1873 memset(&context, 0, sizeof(context));
1874
1875 TickSample sample_obj;
1876 TickSample* sample = CpuProfiler::TickSampleEvent();
1877 if (sample == NULL) sample = &sample_obj;
1878
1879 static const DWORD kSuspendFailed = static_cast<DWORD>(-1);
1880 if (SuspendThread(profiled_thread_) == kSuspendFailed) return;
1881 sample->state = Top::current_vm_state();
1882
1883 context.ContextFlags = CONTEXT_FULL;
1884 if (GetThreadContext(profiled_thread_, &context) != 0) {
1885 #if V8_HOST_ARCH_X64
1886 sample->pc = reinterpret_cast<Address>(context.Rip);
1887 sample->sp = reinterpret_cast<Address>(context.Rsp);
1888 sample->fp = reinterpret_cast<Address>(context.Rbp);
1889 #else
1890 sample->pc = reinterpret_cast<Address>(context.Eip);
1891 sample->sp = reinterpret_cast<Address>(context.Esp);
1892 sample->fp = reinterpret_cast<Address>(context.Ebp);
1893 #endif
1894 sampler_->SampleStack(sample);
1895 sampler_->Tick(sample);
1896 }
1897 ResumeThread(profiled_thread_);
1898 }
1899 if (RuntimeProfiler::IsEnabled()) RuntimeProfiler::NotifyTick();
1900 }
1901 };
1902
1903
1904 // Entry point for sampler thread.
1905 static unsigned int __stdcall SamplerEntry(void* arg) {
1906 Sampler::PlatformData* data =
1907 reinterpret_cast<Sampler::PlatformData*>(arg);
1908 data->Runner();
1909 return 0;
1910 }
1911
1912
1913 // Initialize a profile sampler.
1914 Sampler::Sampler(int interval)
1915 : interval_(interval),
1916 profiling_(false),
1917 active_(false),
1918 samples_taken_(0) {
1919 data_ = new PlatformData(this);
1920 }
1921
1922
1923 Sampler::~Sampler() {
1924 delete data_;
1925 }
1926
1927
1928 // Start profiling.
1929 void Sampler::Start() {
1930 // Do not start multiple threads for the same sampler.
1931 ASSERT(!IsActive());
1932
1933 // Get a handle to the calling thread. This is the thread that we are 1860 // Get a handle to the calling thread. This is the thread that we are
1934 // going to profile. We need to make a copy of the handle because we are 1861 // going to profile. We need to make a copy of the handle because we are
1935 // going to use it in the sampler thread. Using GetThreadHandle() will 1862 // going to use it in the sampler thread. Using GetThreadHandle() will
1936 // not work in this case. We're using OpenThread because DuplicateHandle 1863 // not work in this case. We're using OpenThread because DuplicateHandle
1937 // for some reason doesn't work in Chrome's sandbox. 1864 // for some reason doesn't work in Chrome's sandbox.
1938 data_->profiled_thread_ = OpenThread(THREAD_GET_CONTEXT | 1865 PlatformData() : profiled_thread_(OpenThread(THREAD_GET_CONTEXT |
1939 THREAD_SUSPEND_RESUME | 1866 THREAD_SUSPEND_RESUME |
1940 THREAD_QUERY_INFORMATION, 1867 THREAD_QUERY_INFORMATION,
1941 false, 1868 false,
1942 GetCurrentThreadId()); 1869 GetCurrentThreadId())) {}
1943 BOOL ok = data_->profiled_thread_ != NULL;
1944 if (!ok) return;
1945 1870
1946 // Start sampler thread. 1871 ~PlatformData() {
1947 unsigned int tid; 1872 if (profiled_thread_ != NULL) {
1948 SetActive(true); 1873 CloseHandle(profiled_thread_);
1949 data_->sampler_thread_ = reinterpret_cast<HANDLE>( 1874 profiled_thread_ = NULL;
1950 _beginthreadex(NULL, 0, SamplerEntry, data_, 0, &tid)); 1875 }
1951 // Set thread to high priority to increase sampling accuracy. 1876 }
1952 SetThreadPriority(data_->sampler_thread_, THREAD_PRIORITY_TIME_CRITICAL); 1877
1878 HANDLE profiled_thread() { return profiled_thread_; }
1879
1880 private:
1881 HANDLE profiled_thread_;
1882 };
1883
1884
1885 class SamplerThread : public Thread {
1886 public:
1887 explicit SamplerThread(int interval) : Thread(NULL), interval_(interval) {}
1888
1889 static void AddActiveSampler(Sampler* sampler) {
1890 ScopedLock lock(mutex_);
1891 SamplerRegistry::AddActiveSampler(sampler);
1892 if (instance_ == NULL) {
1893 instance_ = new SamplerThread(sampler->interval());
1894 instance_->Start();
1895 } else {
1896 ASSERT(instance_->interval_ == sampler->interval());
1897 }
1898 }
1899
1900 static void RemoveActiveSampler(Sampler* sampler) {
1901 ScopedLock lock(mutex_);
1902 SamplerRegistry::RemoveActiveSampler(sampler);
1903 if (SamplerRegistry::GetState() == SamplerRegistry::HAS_NO_SAMPLERS) {
1904 RuntimeProfiler::WakeUpRuntimeProfilerThreadBeforeShutdown();
1905 instance_->Join();
1906 delete instance_;
1907 instance_ = NULL;
1908 }
1909 }
1910
1911 // Implement Thread::Run().
1912 virtual void Run() {
1913 SamplerRegistry::State state = SamplerRegistry::GetState();
1914 while (state != SamplerRegistry::HAS_NO_SAMPLERS) {
1915 bool cpu_profiling_enabled =
1916 (state == SamplerRegistry::HAS_CPU_PROFILING_SAMPLERS);
1917 bool runtime_profiler_enabled = RuntimeProfiler::IsEnabled();
1918 // When CPU profiling is enabled both JavaScript and C++ code is
1919 // profiled. We must not suspend.
1920 if (!cpu_profiling_enabled) {
1921 if (rate_limiter_.SuspendIfNecessary()) continue;
1922 }
1923 if (cpu_profiling_enabled) {
1924 if (!SamplerRegistry::IterateActiveSamplers(&DoCpuProfile, this)) {
1925 return;
1926 }
1927 }
1928 if (runtime_profiler_enabled) {
1929 if (!SamplerRegistry::IterateActiveSamplers(&DoRuntimeProfile, NULL)) {
1930 return;
1931 }
1932 }
1933 OS::Sleep(interval_);
1934 }
1935 }
1936
1937 static void DoCpuProfile(Sampler* sampler, void* raw_sampler_thread) {
1938 if (!sampler->isolate()->IsInitialized()) return;
1939 if (!sampler->IsProfiling()) return;
1940 SamplerThread* sampler_thread =
1941 reinterpret_cast<SamplerThread*>(raw_sampler_thread);
1942 sampler_thread->SampleContext(sampler);
1943 }
1944
1945 static void DoRuntimeProfile(Sampler* sampler, void* ignored) {
1946 if (!sampler->isolate()->IsInitialized()) return;
1947 sampler->isolate()->runtime_profiler()->NotifyTick();
1948 }
1949
1950 void SampleContext(Sampler* sampler) {
1951 HANDLE profiled_thread = sampler->platform_data()->profiled_thread();
1952 if (profiled_thread == NULL) return;
1953
1954 // Context used for sampling the register state of the profiled thread.
1955 CONTEXT context;
1956 memset(&context, 0, sizeof(context));
1957
1958 TickSample sample_obj;
1959 TickSample* sample = CpuProfiler::TickSampleEvent(sampler->isolate());
1960 if (sample == NULL) sample = &sample_obj;
1961
1962 static const DWORD kSuspendFailed = static_cast<DWORD>(-1);
1963 if (SuspendThread(profiled_thread) == kSuspendFailed) return;
1964 sample->state = sampler->isolate()->current_vm_state();
1965
1966 context.ContextFlags = CONTEXT_FULL;
1967 if (GetThreadContext(profiled_thread, &context) != 0) {
1968 #if V8_HOST_ARCH_X64
1969 sample->pc = reinterpret_cast<Address>(context.Rip);
1970 sample->sp = reinterpret_cast<Address>(context.Rsp);
1971 sample->fp = reinterpret_cast<Address>(context.Rbp);
1972 #else
1973 sample->pc = reinterpret_cast<Address>(context.Eip);
1974 sample->sp = reinterpret_cast<Address>(context.Esp);
1975 sample->fp = reinterpret_cast<Address>(context.Ebp);
1976 #endif
1977 sampler->SampleStack(sample);
1978 sampler->Tick(sample);
1979 }
1980 ResumeThread(profiled_thread);
1981 }
1982
1983 const int interval_;
1984 RuntimeProfilerRateLimiter rate_limiter_;
1985
1986 // Protects the process wide state below.
1987 static Mutex* mutex_;
1988 static SamplerThread* instance_;
1989
1990 DISALLOW_COPY_AND_ASSIGN(SamplerThread);
1991 };
1992
1993
1994 Mutex* SamplerThread::mutex_ = OS::CreateMutex();
1995 SamplerThread* SamplerThread::instance_ = NULL;
1996
1997
1998 Sampler::Sampler(Isolate* isolate, int interval)
1999 : isolate_(isolate),
2000 interval_(interval),
2001 profiling_(false),
2002 active_(false),
2003 samples_taken_(0) {
2004 data_ = new PlatformData;
1953 } 2005 }
1954 2006
1955 2007
1956 // Stop profiling. 2008 Sampler::~Sampler() {
1957 void Sampler::Stop() { 2009 ASSERT(!IsActive());
1958 // Seting active to false triggers termination of the sampler 2010 delete data_;
1959 // thread.
1960 SetActive(false);
1961
1962 // Wait for sampler thread to terminate.
1963 Top::WakeUpRuntimeProfilerThreadBeforeShutdown();
1964 WaitForSingleObject(data_->sampler_thread_, INFINITE);
1965
1966 // Release the thread handles
1967 CloseHandle(data_->sampler_thread_);
1968 CloseHandle(data_->profiled_thread_);
1969 } 2011 }
1970 2012
1971 2013
2014 void Sampler::Start() {
2015 ASSERT(!IsActive());
2016 SetActive(true);
2017 SamplerThread::AddActiveSampler(this);
2018 }
2019
2020
2021 void Sampler::Stop() {
2022 ASSERT(IsActive());
2023 SamplerThread::RemoveActiveSampler(this);
2024 SetActive(false);
2025 }
2026
1972 #endif // ENABLE_LOGGING_AND_PROFILING 2027 #endif // ENABLE_LOGGING_AND_PROFILING
1973 2028
1974 } } // namespace v8::internal 2029 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/platform-solaris.cc ('k') | src/preparse-data.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698