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

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

Issue 6529055: [Isolates] Merge crankshaft (r5922 from bleeding_edge). (Closed)
Patch Set: Win32 port Created 9 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
« no previous file with comments | « src/platform-solaris.cc ('k') | src/prettyprinter.h » ('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
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 // Platform specific code for Win32. 28 // Platform specific code for Win32.
29 #ifndef WIN32_LEAN_AND_MEAN
30 // WIN32_LEAN_AND_MEAN implies NOCRYPT and NOGDI.
31 #define WIN32_LEAN_AND_MEAN
32 #endif
33 #ifndef NOMINMAX
34 #define NOMINMAX
35 #endif
36 #ifndef NOKERNEL
37 #define NOKERNEL
38 #endif
39 #ifndef NOUSER
40 #define NOUSER
41 #endif
42 #ifndef NOSERVICE
43 #define NOSERVICE
44 #endif
45 #ifndef NOSOUND
46 #define NOSOUND
47 #endif
48 #ifndef NOMCX
49 #define NOMCX
50 #endif
51 // Require Windows XP or higher (this is required for the RtlCaptureContext
52 // function to be present).
53 #ifndef _WIN32_WINNT
54 #define _WIN32_WINNT 0x501
55 #endif
56 29
57 #include <windows.h> 30 #define V8_WIN32_HEADERS_FULL
58 31 #include "win32-headers.h"
59 #include <time.h> // For LocalOffset() implementation.
60 #include <mmsystem.h> // For timeGetTime().
61 #ifdef __MINGW32__
62 // Require Windows XP or higher when compiling with MinGW. This is for MinGW
63 // header files to expose getaddrinfo.
64 #undef _WIN32_WINNT
65 #define _WIN32_WINNT 0x501
66 #endif // __MINGW32__
67 #ifndef __MINGW32__
68 #include <dbghelp.h> // For SymLoadModule64 and al.
69 #endif // __MINGW32__
70 #include <limits.h> // For INT_MAX and al.
71 #include <tlhelp32.h> // For Module32First and al.
72
73 // These additional WIN32 includes have to be right here as the #undef's below
74 // makes it impossible to have them elsewhere.
75 #include <winsock2.h>
76 #include <ws2tcpip.h>
77 #include <process.h> // for _beginthreadex()
78 #include <stdlib.h>
79
80 #undef VOID
81 #undef DELETE
82 #undef IN
83 #undef THIS
84 #undef CONST
85 #undef NAN
86 #undef GetObject
87 #undef CreateMutex
88 #undef CreateSemaphore
89 32
90 #include "v8.h" 33 #include "v8.h"
91 34
92 #include "platform.h" 35 #include "platform.h"
36 #include "vm-state-inl.h"
93 37
94 // Extra POSIX/ANSI routines for Win32 when when using Visual Studio C++. Please 38 // Extra POSIX/ANSI routines for Win32 when when using Visual Studio C++. Please
95 // refer to The Open Group Base Specification for specification of the correct 39 // refer to The Open Group Base Specification for specification of the correct
96 // semantics for these functions. 40 // semantics for these functions.
97 // (http://www.opengroup.org/onlinepubs/000095399/) 41 // (http://www.opengroup.org/onlinepubs/000095399/)
98 #ifdef _MSC_VER 42 #ifdef _MSC_VER
99 43
100 namespace v8 { 44 namespace v8 {
101 namespace internal { 45 namespace internal {
102 46
(...skipping 1060 matching lines...) Expand 10 before | Expand all | Expand 10 after
1163 static bool LoadSymbols(HANDLE process_handle) { 1107 static bool LoadSymbols(HANDLE process_handle) {
1164 static bool symbols_loaded = false; 1108 static bool symbols_loaded = false;
1165 1109
1166 if (symbols_loaded) return true; 1110 if (symbols_loaded) return true;
1167 1111
1168 BOOL ok; 1112 BOOL ok;
1169 1113
1170 // Initialize the symbol engine. 1114 // Initialize the symbol engine.
1171 ok = _SymInitialize(process_handle, // hProcess 1115 ok = _SymInitialize(process_handle, // hProcess
1172 NULL, // UserSearchPath 1116 NULL, // UserSearchPath
1173 FALSE); // fInvadeProcess 1117 false); // fInvadeProcess
1174 if (!ok) return false; 1118 if (!ok) return false;
1175 1119
1176 DWORD options = _SymGetOptions(); 1120 DWORD options = _SymGetOptions();
1177 options |= SYMOPT_LOAD_LINES; 1121 options |= SYMOPT_LOAD_LINES;
1178 options |= SYMOPT_FAIL_CRITICAL_ERRORS; 1122 options |= SYMOPT_FAIL_CRITICAL_ERRORS;
1179 options = _SymSetOptions(options); 1123 options = _SymSetOptions(options);
1180 1124
1181 char buf[OS::kStackWalkMaxNameLen] = {0}; 1125 char buf[OS::kStackWalkMaxNameLen] = {0};
1182 ok = _SymGetSearchPath(process_handle, buf, OS::kStackWalkMaxNameLen); 1126 ok = _SymGetSearchPath(process_handle, buf, OS::kStackWalkMaxNameLen);
1183 if (!ok) { 1127 if (!ok) {
(...skipping 239 matching lines...) Expand 10 before | Expand all | Expand 10 after
1423 return false; 1367 return false;
1424 } 1368 }
1425 1369
1426 UpdateAllocatedSpaceLimits(address, static_cast<int>(size)); 1370 UpdateAllocatedSpaceLimits(address, static_cast<int>(size));
1427 return true; 1371 return true;
1428 } 1372 }
1429 1373
1430 1374
1431 bool VirtualMemory::Uncommit(void* address, size_t size) { 1375 bool VirtualMemory::Uncommit(void* address, size_t size) {
1432 ASSERT(IsReserved()); 1376 ASSERT(IsReserved());
1433 return VirtualFree(address, size, MEM_DECOMMIT) != FALSE; 1377 return VirtualFree(address, size, MEM_DECOMMIT) != false;
1434 } 1378 }
1435 1379
1436 1380
1437 // ---------------------------------------------------------------------------- 1381 // ----------------------------------------------------------------------------
1438 // Win32 thread support. 1382 // Win32 thread support.
1439 1383
1440 // Definition of invalid thread handle and id. 1384 // Definition of invalid thread handle and id.
1441 static const HANDLE kNoThread = INVALID_HANDLE_VALUE; 1385 static const HANDLE kNoThread = INVALID_HANDLE_VALUE;
1442 static const DWORD kNoThreadId = 0; 1386 static const DWORD kNoThreadId = 0;
1443 1387
(...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after
1586 // On Win32 mutexes are implemented using CRITICAL_SECTION objects. These are 1530 // On Win32 mutexes are implemented using CRITICAL_SECTION objects. These are
1587 // faster than Win32 Mutex objects because they are implemented using user mode 1531 // faster than Win32 Mutex objects because they are implemented using user mode
1588 // atomic instructions. Therefore we only do ring transitions if there is lock 1532 // atomic instructions. Therefore we only do ring transitions if there is lock
1589 // contention. 1533 // contention.
1590 1534
1591 class Win32Mutex : public Mutex { 1535 class Win32Mutex : public Mutex {
1592 public: 1536 public:
1593 1537
1594 Win32Mutex() { InitializeCriticalSection(&cs_); } 1538 Win32Mutex() { InitializeCriticalSection(&cs_); }
1595 1539
1596 ~Win32Mutex() { DeleteCriticalSection(&cs_); } 1540 virtual ~Win32Mutex() { DeleteCriticalSection(&cs_); }
1597 1541
1598 int Lock() { 1542 virtual int Lock() {
1599 EnterCriticalSection(&cs_); 1543 EnterCriticalSection(&cs_);
1600 return 0; 1544 return 0;
1601 } 1545 }
1602 1546
1603 int Unlock() { 1547 virtual int Unlock() {
1604 LeaveCriticalSection(&cs_); 1548 LeaveCriticalSection(&cs_);
1605 return 0; 1549 return 0;
1606 } 1550 }
1607 1551
1552
1553 virtual bool TryLock() {
1554 // Returns non-zero if critical section is entered successfully entered.
1555 return TryEnterCriticalSection(&cs_);
1556 }
1557
1608 private: 1558 private:
1609 CRITICAL_SECTION cs_; // Critical section used for mutex 1559 CRITICAL_SECTION cs_; // Critical section used for mutex
1610 }; 1560 };
1611 1561
1612 1562
1613 Mutex* OS::CreateMutex() { 1563 Mutex* OS::CreateMutex() {
1614 return new Win32Mutex(); 1564 return new Win32Mutex();
1615 } 1565 }
1616 1566
1617 1567
(...skipping 162 matching lines...) Expand 10 before | Expand all | Expand 10 after
1780 } 1730 }
1781 1731
1782 1732
1783 int Win32Socket::Receive(char* data, int len) const { 1733 int Win32Socket::Receive(char* data, int len) const {
1784 int status = recv(socket_, data, len, 0); 1734 int status = recv(socket_, data, len, 0);
1785 return status; 1735 return status;
1786 } 1736 }
1787 1737
1788 1738
1789 bool Win32Socket::SetReuseAddress(bool reuse_address) { 1739 bool Win32Socket::SetReuseAddress(bool reuse_address) {
1790 BOOL on = reuse_address ? TRUE : FALSE; 1740 BOOL on = reuse_address ? true : false;
1791 int status = setsockopt(socket_, SOL_SOCKET, SO_REUSEADDR, 1741 int status = setsockopt(socket_, SOL_SOCKET, SO_REUSEADDR,
1792 reinterpret_cast<char*>(&on), sizeof(on)); 1742 reinterpret_cast<char*>(&on), sizeof(on));
1793 return status == SOCKET_ERROR; 1743 return status == SOCKET_ERROR;
1794 } 1744 }
1795 1745
1796 1746
1797 bool Socket::Setup() { 1747 bool Socket::Setup() {
1798 // Initialize Winsock32 1748 // Initialize Winsock32
1799 int err; 1749 int err;
1800 WSADATA winsock_data; 1750 WSADATA winsock_data;
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
1835 1785
1836 Socket* OS::CreateSocket() { 1786 Socket* OS::CreateSocket() {
1837 return new Win32Socket(); 1787 return new Win32Socket();
1838 } 1788 }
1839 1789
1840 1790
1841 #ifdef ENABLE_LOGGING_AND_PROFILING 1791 #ifdef ENABLE_LOGGING_AND_PROFILING
1842 1792
1843 // ---------------------------------------------------------------------------- 1793 // ----------------------------------------------------------------------------
1844 // Win32 profiler support. 1794 // Win32 profiler support.
1845 //
1846 // On win32 we use a sampler thread with high priority to sample the program
1847 // counter for the profiled thread.
1848 1795
1849 class Sampler::PlatformData : public Malloced { 1796 class Sampler::PlatformData : public Malloced {
1850 public: 1797 public:
1851 explicit PlatformData(Sampler* sampler) { 1798 // Get a handle to the calling thread. This is the thread that we are
1852 sampler_ = sampler; 1799 // going to profile. We need to make a copy of the handle because we are
1853 sampler_thread_ = INVALID_HANDLE_VALUE; 1800 // going to use it in the sampler thread. Using GetThreadHandle() will
1854 profiled_thread_ = INVALID_HANDLE_VALUE; 1801 // not work in this case. We're using OpenThread because DuplicateHandle
1802 // for some reason doesn't work in Chrome's sandbox.
1803 PlatformData() : profiled_thread_(OpenThread(THREAD_GET_CONTEXT |
1804 THREAD_SUSPEND_RESUME |
1805 THREAD_QUERY_INFORMATION,
1806 false,
1807 GetCurrentThreadId())) {}
1808
1809 ~PlatformData() {
1810 if (profiled_thread_ != NULL) {
1811 CloseHandle(profiled_thread_);
1812 profiled_thread_ = NULL;
1813 }
1855 } 1814 }
1856 1815
1857 Sampler* sampler_; 1816 HANDLE profiled_thread() { return profiled_thread_; }
1858 HANDLE sampler_thread_; 1817
1818 private:
1859 HANDLE profiled_thread_; 1819 HANDLE profiled_thread_;
1820 };
1860 1821
1861 // Sampler thread handler. 1822
1862 void Runner() { 1823 class SamplerThread : public Thread {
1824 public:
1825 explicit SamplerThread(int interval) : Thread(NULL), interval_(interval) {}
1826
1827 static void AddActiveSampler(Sampler* sampler) {
1828 ScopedLock lock(mutex_);
1829 SamplerRegistry::AddActiveSampler(sampler);
1830 if (instance_ == NULL) {
1831 instance_ = new SamplerThread(sampler->interval());
1832 instance_->Start();
1833 } else {
1834 ASSERT(instance_->interval_ == sampler->interval());
1835 }
1836 }
1837
1838 static void RemoveActiveSampler(Sampler* sampler) {
1839 ScopedLock lock(mutex_);
1840 SamplerRegistry::RemoveActiveSampler(sampler);
1841 if (SamplerRegistry::GetState() == SamplerRegistry::HAS_NO_SAMPLERS) {
1842 RuntimeProfiler::WakeUpRuntimeProfilerThreadBeforeShutdown();
1843 instance_->Join();
1844 delete instance_;
1845 instance_ = NULL;
1846 }
1847 }
1848
1849 // Implement Thread::Run().
1850 virtual void Run() {
1851 SamplerRegistry::State state = SamplerRegistry::GetState();
1852 while (state != SamplerRegistry::HAS_NO_SAMPLERS) {
1853 bool cpu_profiling_enabled =
1854 (state == SamplerRegistry::HAS_CPU_PROFILING_SAMPLERS);
1855 bool runtime_profiler_enabled = RuntimeProfiler::IsEnabled();
1856 // When CPU profiling is enabled both JavaScript and C++ code is
1857 // profiled. We must not suspend.
1858 if (!cpu_profiling_enabled) {
1859 if (rate_limiter_.SuspendIfNecessary()) continue;
1860 }
1861 if (cpu_profiling_enabled) {
1862 if (!SamplerRegistry::IterateActiveSamplers(&DoCpuProfile, this)) {
1863 return;
1864 }
1865 }
1866 if (runtime_profiler_enabled) {
1867 if (!SamplerRegistry::IterateActiveSamplers(&DoRuntimeProfile, NULL)) {
1868 return;
1869 }
1870 }
1871 OS::Sleep(interval_);
1872 }
1873 }
1874
1875 static void DoCpuProfile(Sampler* sampler, void* raw_sampler_thread) {
1876 if (!sampler->IsProfiling()) return;
1877 SamplerThread* sampler_thread =
1878 reinterpret_cast<SamplerThread*>(raw_sampler_thread);
1879 sampler_thread->SampleContext(sampler);
1880 }
1881
1882 static void DoRuntimeProfile(Sampler* sampler, void* ignored) {
1883 if (!sampler->isolate()->IsInitialized()) return;
1884 sampler->isolate()->runtime_profiler()->NotifyTick();
1885 }
1886
1887 void SampleContext(Sampler* sampler) {
1888 HANDLE profiled_thread = sampler->platform_data()->profiled_thread();
1889 if (profiled_thread == NULL) return;
1890
1863 // Context used for sampling the register state of the profiled thread. 1891 // Context used for sampling the register state of the profiled thread.
1864 CONTEXT context; 1892 CONTEXT context;
1865 memset(&context, 0, sizeof(context)); 1893 memset(&context, 0, sizeof(context));
1866 // Loop until the sampler is disengaged, keeping the specified
1867 // sampling frequency.
1868 for ( ; sampler_->IsActive(); Sleep(sampler_->interval_)) {
1869 TickSample sample_obj;
1870 TickSample* sample = CpuProfiler::TickSampleEvent();
1871 if (sample == NULL) sample = &sample_obj;
1872 1894
1873 // If the sampler runs in sync with the JS thread, we try to 1895 TickSample sample_obj;
1874 // suspend it. If we fail, we skip the current sample. 1896 TickSample* sample = CpuProfiler::TickSampleEvent(sampler->isolate());
1875 if (sampler_->IsSynchronous()) { 1897 if (sample == NULL) sample = &sample_obj;
1876 static const DWORD kSuspendFailed = static_cast<DWORD>(-1);
1877 if (SuspendThread(profiled_thread_) == kSuspendFailed) continue;
1878 }
1879 1898
1880 // We always sample the VM state. 1899 static const DWORD kSuspendFailed = static_cast<DWORD>(-1);
1881 sample->state = VMState::current_state(); 1900 if (SuspendThread(profiled_thread) == kSuspendFailed) return;
1901 sample->state = sampler->isolate()->current_vm_state();
1882 1902
1883 // If profiling, we record the pc and sp of the profiled thread. 1903 context.ContextFlags = CONTEXT_FULL;
1884 if (sampler_->IsProfiling()) { 1904 if (GetThreadContext(profiled_thread, &context) != 0) {
1885 context.ContextFlags = CONTEXT_FULL;
1886 if (GetThreadContext(profiled_thread_, &context) != 0) {
1887 #if V8_HOST_ARCH_X64 1905 #if V8_HOST_ARCH_X64
1888 sample->pc = reinterpret_cast<Address>(context.Rip); 1906 sample->pc = reinterpret_cast<Address>(context.Rip);
1889 sample->sp = reinterpret_cast<Address>(context.Rsp); 1907 sample->sp = reinterpret_cast<Address>(context.Rsp);
1890 sample->fp = reinterpret_cast<Address>(context.Rbp); 1908 sample->fp = reinterpret_cast<Address>(context.Rbp);
1891 #else 1909 #else
1892 sample->pc = reinterpret_cast<Address>(context.Eip); 1910 sample->pc = reinterpret_cast<Address>(context.Eip);
1893 sample->sp = reinterpret_cast<Address>(context.Esp); 1911 sample->sp = reinterpret_cast<Address>(context.Esp);
1894 sample->fp = reinterpret_cast<Address>(context.Ebp); 1912 sample->fp = reinterpret_cast<Address>(context.Ebp);
1895 #endif 1913 #endif
1896 sampler_->SampleStack(sample); 1914 sampler->SampleStack(sample);
1897 } 1915 sampler->Tick(sample);
1898 } 1916 }
1917 ResumeThread(profiled_thread);
1918 }
1899 1919
1900 // Invoke tick handler with program counter and stack pointer. 1920 const int interval_;
1901 sampler_->Tick(sample); 1921 RuntimeProfilerRateLimiter rate_limiter_;
1902 1922
1903 // If the sampler runs in sync with the JS thread, we have to 1923 // Protects the process wide state below.
1904 // remember to resume it. 1924 static Mutex* mutex_;
1905 if (sampler_->IsSynchronous()) ResumeThread(profiled_thread_); 1925 static SamplerThread* instance_;
1906 } 1926
1907 } 1927 DISALLOW_COPY_AND_ASSIGN(SamplerThread);
1908 }; 1928 };
1909 1929
1910 1930
1911 // Entry point for sampler thread. 1931 Mutex* SamplerThread::mutex_ = OS::CreateMutex();
1912 static unsigned int __stdcall SamplerEntry(void* arg) { 1932 SamplerThread* SamplerThread::instance_ = NULL;
1913 Sampler::PlatformData* data =
1914 reinterpret_cast<Sampler::PlatformData*>(arg);
1915 Thread::SetThreadLocal(Isolate::isolate_key(), data->sampler_->isolate());
1916 data->Runner();
1917 return 0;
1918 }
1919 1933
1920 1934
1921 // Initialize a profile sampler. 1935 Sampler::Sampler(Isolate* isolate, int interval)
1922 Sampler::Sampler(Isolate* isolate, int interval, bool profiling)
1923 : isolate_(isolate), 1936 : isolate_(isolate),
1924 interval_(interval), 1937 interval_(interval),
1925 profiling_(profiling), 1938 profiling_(false),
1926 synchronous_(profiling),
1927 active_(false), 1939 active_(false),
1928 samples_taken_(0) { 1940 samples_taken_(0) {
1929 data_ = new PlatformData(this); 1941 data_ = new PlatformData;
1930 } 1942 }
1931 1943
1932 1944
1933 Sampler::~Sampler() { 1945 Sampler::~Sampler() {
1946 ASSERT(!IsActive());
1934 delete data_; 1947 delete data_;
1935 } 1948 }
1936 1949
1937 1950
1938 // Start profiling.
1939 void Sampler::Start() { 1951 void Sampler::Start() {
1940 // If we are starting a synchronous sampler, we need to be able to 1952 ASSERT(!IsActive());
1941 // access the calling thread. 1953 SetActive(true);
1942 if (IsSynchronous()) { 1954 SamplerThread::AddActiveSampler(this);
1943 // Get a handle to the calling thread. This is the thread that we are
1944 // going to profile. We need to make a copy of the handle because we are
1945 // going to use it in the sampler thread. Using GetThreadHandle() will
1946 // not work in this case. We're using OpenThread because DuplicateHandle
1947 // for some reason doesn't work in Chrome's sandbox.
1948 data_->profiled_thread_ = OpenThread(THREAD_GET_CONTEXT |
1949 THREAD_SUSPEND_RESUME |
1950 THREAD_QUERY_INFORMATION,
1951 FALSE,
1952 GetCurrentThreadId());
1953 BOOL ok = data_->profiled_thread_ != NULL;
1954 if (!ok) return;
1955 }
1956
1957 // Start sampler thread.
1958 unsigned int tid;
1959 active_ = true;
1960 data_->sampler_thread_ = reinterpret_cast<HANDLE>(
1961 _beginthreadex(NULL, 0, SamplerEntry, data_, 0, &tid));
1962 // Set thread to high priority to increase sampling accuracy.
1963 SetThreadPriority(data_->sampler_thread_, THREAD_PRIORITY_TIME_CRITICAL);
1964 } 1955 }
1965 1956
1966 1957
1967 // Stop profiling.
1968 void Sampler::Stop() { 1958 void Sampler::Stop() {
1969 // Seting active to false triggers termination of the sampler 1959 ASSERT(IsActive());
1970 // thread. 1960 SamplerThread::RemoveActiveSampler(this);
1971 active_ = false; 1961 SetActive(false);
1972
1973 // Wait for sampler thread to terminate.
1974 WaitForSingleObject(data_->sampler_thread_, INFINITE);
1975
1976 // Release the thread handles
1977 CloseHandle(data_->sampler_thread_);
1978 CloseHandle(data_->profiled_thread_);
1979 } 1962 }
1980 1963
1981
1982 #endif // ENABLE_LOGGING_AND_PROFILING 1964 #endif // ENABLE_LOGGING_AND_PROFILING
1983 1965
1984 } } // namespace v8::internal 1966 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/platform-solaris.cc ('k') | src/prettyprinter.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698