📄 platform-win32.cc.svn-base
字号:
} } DeleteArray(symbol); frames_count++; } // Return the number of frames filled in. return frames_count;}// Restore warnings to previous settings.#pragma warning(pop)double OS::nan_value() { static const __int64 nanval = 0xfff8000000000000; return *reinterpret_cast<const double*>(&nanval);}int OS::ActivationFrameAlignment() { // No constraint on Windows. return 0;}bool VirtualMemory::IsReserved() { return address_ != NULL;}VirtualMemory::VirtualMemory(size_t size) { address_ = VirtualAlloc(NULL, size, MEM_RESERVE, PAGE_NOACCESS); size_ = size;}VirtualMemory::~VirtualMemory() { if (IsReserved()) { if (0 == VirtualFree(address(), 0, MEM_RELEASE)) address_ = NULL; }}bool VirtualMemory::Commit(void* address, size_t size, bool executable) { int prot = executable ? PAGE_EXECUTE_READWRITE : PAGE_READWRITE; if (NULL == VirtualAlloc(address, size, MEM_COMMIT, prot)) { return false; } UpdateAllocatedSpaceLimits(address, size); return true;}bool VirtualMemory::Uncommit(void* address, size_t size) { ASSERT(IsReserved()); return VirtualFree(address, size, MEM_DECOMMIT) != NULL;}// ----------------------------------------------------------------------------// Win32 thread support.// Definition of invalid thread handle and id.static const HANDLE kNoThread = INVALID_HANDLE_VALUE;static const DWORD kNoThreadId = 0;class ThreadHandle::PlatformData : public Malloced { public: explicit PlatformData(ThreadHandle::Kind kind) { Initialize(kind); } void Initialize(ThreadHandle::Kind kind) { switch (kind) { case ThreadHandle::SELF: tid_ = GetCurrentThreadId(); break; case ThreadHandle::INVALID: tid_ = kNoThreadId; break; } } DWORD tid_; // Win32 thread identifier.};// Entry point for threads. The supplied argument is a pointer to the thread// object. The entry function dispatches to the run method in the thread// object. It is important that this function has __stdcall calling// convention.static unsigned int __stdcall ThreadEntry(void* arg) { Thread* thread = reinterpret_cast<Thread*>(arg); // This is also initialized by the last parameter to _beginthreadex() but we // don't know which thread will run first (the original thread or the new // one) so we initialize it here too. thread->thread_handle_data()->tid_ = GetCurrentThreadId(); thread->Run(); return 0;}// Initialize thread handle to invalid handle.ThreadHandle::ThreadHandle(ThreadHandle::Kind kind) { data_ = new PlatformData(kind);}ThreadHandle::~ThreadHandle() { delete data_;}// The thread is running if it has the same id as the current thread.bool ThreadHandle::IsSelf() const { return GetCurrentThreadId() == data_->tid_;}// Test for invalid thread handle.bool ThreadHandle::IsValid() const { return data_->tid_ != kNoThreadId;}void ThreadHandle::Initialize(ThreadHandle::Kind kind) { data_->Initialize(kind);}class Thread::PlatformData : public Malloced { public: explicit PlatformData(HANDLE thread) : thread_(thread) {} HANDLE thread_;};// Initialize a Win32 thread object. The thread has an invalid thread// handle until it is started.Thread::Thread() : ThreadHandle(ThreadHandle::INVALID) { data_ = new PlatformData(kNoThread);}// Close our own handle for the thread.Thread::~Thread() { if (data_->thread_ != kNoThread) CloseHandle(data_->thread_); delete data_;}// Create a new thread. It is important to use _beginthreadex() instead of// the Win32 function CreateThread(), because the CreateThread() does not// initialize thread specific structures in the C runtime library.void Thread::Start() { data_->thread_ = reinterpret_cast<HANDLE>( _beginthreadex(NULL, 0, ThreadEntry, this, 0, reinterpret_cast<unsigned int*>( &thread_handle_data()->tid_))); ASSERT(IsValid());}// Wait for thread to terminate.void Thread::Join() { WaitForSingleObject(data_->thread_, INFINITE);}Thread::LocalStorageKey Thread::CreateThreadLocalKey() { DWORD result = TlsAlloc(); ASSERT(result != TLS_OUT_OF_INDEXES); return static_cast<LocalStorageKey>(result);}void Thread::DeleteThreadLocalKey(LocalStorageKey key) { BOOL result = TlsFree(static_cast<DWORD>(key)); USE(result); ASSERT(result);}void* Thread::GetThreadLocal(LocalStorageKey key) { return TlsGetValue(static_cast<DWORD>(key));}void Thread::SetThreadLocal(LocalStorageKey key, void* value) { BOOL result = TlsSetValue(static_cast<DWORD>(key), value); USE(result); ASSERT(result);}void Thread::YieldCPU() { Sleep(0);}// ----------------------------------------------------------------------------// Win32 mutex support.//// On Win32 mutexes are implemented using CRITICAL_SECTION objects. These are// faster than Win32 Mutex objects because they are implemented using user mode// atomic instructions. Therefore we only do ring transitions if there is lock// contention.class Win32Mutex : public Mutex { public: Win32Mutex() { InitializeCriticalSection(&cs_); } ~Win32Mutex() { DeleteCriticalSection(&cs_); } int Lock() { EnterCriticalSection(&cs_); return 0; } int Unlock() { LeaveCriticalSection(&cs_); return 0; } private: CRITICAL_SECTION cs_; // Critical section used for mutex};Mutex* OS::CreateMutex() { return new Win32Mutex();}// ----------------------------------------------------------------------------// Win32 semaphore support.//// On Win32 semaphores are implemented using Win32 Semaphore objects. The// semaphores are anonymous. Also, the semaphores are initialized to have// no upper limit on count.class Win32Semaphore : public Semaphore { public: explicit Win32Semaphore(int count) { sem = ::CreateSemaphoreA(NULL, count, 0x7fffffff, NULL); } ~Win32Semaphore() { CloseHandle(sem); } void Wait() { WaitForSingleObject(sem, INFINITE); } void Signal() { LONG dummy; ReleaseSemaphore(sem, 1, &dummy); } private: HANDLE sem;};Semaphore* OS::CreateSemaphore(int count) { return new Win32Semaphore(count);}#ifdef ENABLE_LOGGING_AND_PROFILING// ----------------------------------------------------------------------------// Win32 profiler support.//// On win32 we use a sampler thread with high priority to sample the program// counter for the profiled thread.class Sampler::PlatformData : public Malloced { public: explicit PlatformData(Sampler* sampler) { sampler_ = sampler; sampler_thread_ = INVALID_HANDLE_VALUE; profiled_thread_ = INVALID_HANDLE_VALUE; } Sampler* sampler_; HANDLE sampler_thread_; HANDLE profiled_thread_; // Sampler thread handler. void Runner() { // Context used for sampling the register state of the profiled thread. CONTEXT context; memset(&context, 0, sizeof(context)); // Loop until the sampler is disengaged. while (sampler_->IsActive()) { TickSample sample; // If profiling, we record the pc and sp of the profiled thread. if (sampler_->IsProfiling()) { // Pause the profiled thread and get its context. SuspendThread(profiled_thread_); context.ContextFlags = CONTEXT_FULL; GetThreadContext(profiled_thread_, &context); ResumeThread(profiled_thread_); // Invoke tick handler with program counter and stack pointer. sample.pc = context.Eip; sample.sp = context.Esp; } // We always sample the VM state. sample.state = Logger::state(); sampler_->Tick(&sample); // Wait until next sampling. Sleep(sampler_->interval_); } }};// Entry point for sampler thread.static unsigned int __stdcall SamplerEntry(void* arg) { Sampler::PlatformData* data = reinterpret_cast<Sampler::PlatformData*>(arg); data->Runner(); return 0;}// Initialize a profile sampler.Sampler::Sampler(int interval, bool profiling) : interval_(interval), profiling_(profiling), active_(false) { data_ = new PlatformData(this);}Sampler::~Sampler() { delete data_;}// Start profiling.void Sampler::Start() { // If we are profiling, we need to be able to access the calling // thread. if (IsProfiling()) { // Get a handle to the calling thread. This is the thread that we are // going to profile. We need to duplicate the handle because we are // going to use it in the sampler thread. using GetThreadHandle() will // not work in this case. BOOL ok = DuplicateHandle(GetCurrentProcess(), GetCurrentThread(), GetCurrentProcess(), &data_->profiled_thread_, THREAD_GET_CONTEXT | THREAD_SUSPEND_RESUME | THREAD_QUERY_INFORMATION, FALSE, 0); if (!ok) return; } // Start sampler thread. unsigned int tid; active_ = true; data_->sampler_thread_ = reinterpret_cast<HANDLE>( _beginthreadex(NULL, 0, SamplerEntry, data_, 0, &tid)); // Set thread to high priority to increase sampling accuracy. SetThreadPriority(data_->sampler_thread_, THREAD_PRIORITY_TIME_CRITICAL);}// Stop profiling.void Sampler::Stop() { // Seting active to false triggers termination of the sampler // thread. active_ = false; // Wait for sampler thread to terminate. WaitForSingleObject(data_->sampler_thread_, INFINITE); // Release the thread handles CloseHandle(data_->sampler_thread_); CloseHandle(data_->profiled_thread_);}#endif // ENABLE_LOGGING_AND_PROFILING} } // namespace v8::internal
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -