Remove windows.h from win32-headers.h

Windows.h causes massive namespace pollution with its defining of many
macros, it adds to build times, it disables warnings, and it makes it
easier to write non-portable code.

This change removes windows.h from V8's win32-headers.h. It does this
by replicating the small number of typedefs that are needed and by
defining three "proxy" types that are the same size and layout. The
V8ToWindowsType functions are used to reinterpret_cast between the
types.

Prior to this change there were over 760 v8-related source files that
include windows.h. After this change there are 16.

Bug: chromium:796644
Change-Id: I89efeed47028faae72de2da4f1dae345d8d7746c
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3042215
Commit-Queue: Bruce Dawson <brucedawson@chromium.org>
Reviewed-by: Hannes Payer <hpayer@chromium.org>
Reviewed-by: Leszek Swirski <leszeks@chromium.org>
Cr-Commit-Position: refs/heads/master@{#76064}
This commit is contained in:
Bruce Dawson 2021-07-27 08:35:59 -07:00 committed by V8 LUCI CQ
parent 2a654716c8
commit fb9e129964
19 changed files with 189 additions and 62 deletions

View File

@ -130,9 +130,11 @@
#endif
#if V8_OS_WIN
#include <versionhelpers.h>
#include <windows.h>
// This has to come after windows.h.
#include <versionhelpers.h>
#include "include/v8-wasm-trap-handler-win.h"
#include "src/trap-handler/handler-inside-win.h"
#if defined(V8_OS_WIN64)

View File

@ -194,7 +194,9 @@ inline size_t RoundUpToPowerOfTwo(size_t value) {
if (sizeof(size_t) == sizeof(uint64_t)) {
return RoundUpToPowerOfTwo64(value);
} else {
return RoundUpToPowerOfTwo32(value);
// Without windows.h included this line triggers a truncation warning on
// 64-bit builds. Presumably windows.h disables the relevant warning.
return RoundUpToPowerOfTwo32(static_cast<uint32_t>(value));
}
}

View File

@ -9,6 +9,10 @@
#include "src/base/platform/time.h"
#if V8_OS_WIN
#include <windows.h>
#endif
namespace v8 {
namespace base {
@ -119,22 +123,25 @@ bool ConditionVariable::WaitFor(Mutex* mutex, const TimeDelta& rel_time) {
#elif V8_OS_WIN
ConditionVariable::ConditionVariable() {
InitializeConditionVariable(&native_handle_);
InitializeConditionVariable(V8ToWindowsType(&native_handle_));
}
ConditionVariable::~ConditionVariable() {}
void ConditionVariable::NotifyOne() { WakeConditionVariable(&native_handle_); }
void ConditionVariable::NotifyOne() {
WakeConditionVariable(V8ToWindowsType(&native_handle_));
}
void ConditionVariable::NotifyAll() {
WakeAllConditionVariable(&native_handle_);
WakeAllConditionVariable(V8ToWindowsType(&native_handle_));
}
void ConditionVariable::Wait(Mutex* mutex) {
mutex->AssertHeldAndUnmark();
SleepConditionVariableSRW(&native_handle_, &mutex->native_handle(), INFINITE,
SleepConditionVariableSRW(V8ToWindowsType(&native_handle_),
V8ToWindowsType(&mutex->native_handle()), INFINITE,
0);
mutex->AssertUnheldAndMark();
}
@ -144,7 +151,8 @@ bool ConditionVariable::WaitFor(Mutex* mutex, const TimeDelta& rel_time) {
int64_t msec = rel_time.InMilliseconds();
mutex->AssertHeldAndUnmark();
BOOL result = SleepConditionVariableSRW(
&native_handle_, &mutex->native_handle(), static_cast<DWORD>(msec), 0);
V8ToWindowsType(&native_handle_),
V8ToWindowsType(&mutex->native_handle()), static_cast<DWORD>(msec), 0);
#ifdef DEBUG
if (!result) {
// On failure, we only expect the CV to timeout. Any other error value means

View File

@ -69,7 +69,7 @@ class V8_BASE_EXPORT ConditionVariable final {
#if V8_OS_POSIX
using NativeHandle = pthread_cond_t;
#elif V8_OS_WIN
using NativeHandle = CONDITION_VARIABLE;
using NativeHandle = V8_CONDITION_VARIABLE;
#elif V8_OS_STARBOARD
using NativeHandle = SbConditionVariable;
#endif

View File

@ -10,6 +10,10 @@
#include <unordered_set>
#endif // DEBUG
#if V8_OS_WIN
#include <windows.h>
#endif
namespace v8 {
namespace base {
@ -314,19 +318,19 @@ Mutex::~Mutex() {
void Mutex::Lock() {
AcquireSRWLockExclusive(&native_handle_);
AcquireSRWLockExclusive(V8ToWindowsType(&native_handle_));
AssertUnheldAndMark();
}
void Mutex::Unlock() {
AssertHeldAndUnmark();
ReleaseSRWLockExclusive(&native_handle_);
ReleaseSRWLockExclusive(V8ToWindowsType(&native_handle_));
}
bool Mutex::TryLock() {
if (!TryAcquireSRWLockExclusive(&native_handle_)) {
if (!TryAcquireSRWLockExclusive(V8ToWindowsType(&native_handle_))) {
return false;
}
AssertUnheldAndMark();
@ -335,7 +339,7 @@ bool Mutex::TryLock() {
RecursiveMutex::RecursiveMutex() {
InitializeCriticalSection(&native_handle_);
InitializeCriticalSection(V8ToWindowsType(&native_handle_));
#ifdef DEBUG
level_ = 0;
#endif
@ -343,13 +347,13 @@ RecursiveMutex::RecursiveMutex() {
RecursiveMutex::~RecursiveMutex() {
DeleteCriticalSection(&native_handle_);
DeleteCriticalSection(V8ToWindowsType(&native_handle_));
DCHECK_EQ(0, level_);
}
void RecursiveMutex::Lock() {
EnterCriticalSection(&native_handle_);
EnterCriticalSection(V8ToWindowsType(&native_handle_));
#ifdef DEBUG
DCHECK_LE(0, level_);
level_++;
@ -362,12 +366,12 @@ void RecursiveMutex::Unlock() {
DCHECK_LT(0, level_);
level_--;
#endif
LeaveCriticalSection(&native_handle_);
LeaveCriticalSection(V8ToWindowsType(&native_handle_));
}
bool RecursiveMutex::TryLock() {
if (!TryEnterCriticalSection(&native_handle_)) {
if (!TryEnterCriticalSection(V8ToWindowsType(&native_handle_))) {
return false;
}
#ifdef DEBUG
@ -383,34 +387,34 @@ SharedMutex::~SharedMutex() {}
void SharedMutex::LockShared() {
DCHECK(TryHoldSharedMutex(this));
AcquireSRWLockShared(&native_handle_);
AcquireSRWLockShared(V8ToWindowsType(&native_handle_));
}
void SharedMutex::LockExclusive() {
DCHECK(TryHoldSharedMutex(this));
AcquireSRWLockExclusive(&native_handle_);
AcquireSRWLockExclusive(V8ToWindowsType(&native_handle_));
}
void SharedMutex::UnlockShared() {
DCHECK(TryReleaseSharedMutex(this));
ReleaseSRWLockShared(&native_handle_);
ReleaseSRWLockShared(V8ToWindowsType(&native_handle_));
}
void SharedMutex::UnlockExclusive() {
DCHECK(TryReleaseSharedMutex(this));
ReleaseSRWLockExclusive(&native_handle_);
ReleaseSRWLockExclusive(V8ToWindowsType(&native_handle_));
}
bool SharedMutex::TryLockShared() {
DCHECK(SharedMutexNotHeld(this));
bool result = TryAcquireSRWLockShared(&native_handle_);
bool result = TryAcquireSRWLockShared(V8ToWindowsType(&native_handle_));
if (result) DCHECK(TryHoldSharedMutex(this));
return result;
}
bool SharedMutex::TryLockExclusive() {
DCHECK(SharedMutexNotHeld(this));
bool result = TryAcquireSRWLockExclusive(&native_handle_);
bool result = TryAcquireSRWLockExclusive(V8ToWindowsType(&native_handle_));
if (result) DCHECK(TryHoldSharedMutex(this));
return result;
}

View File

@ -66,7 +66,7 @@ class V8_BASE_EXPORT Mutex final {
#if V8_OS_POSIX
using NativeHandle = pthread_mutex_t;
#elif V8_OS_WIN
using NativeHandle = SRWLOCK;
using NativeHandle = V8_SRWLOCK;
#elif V8_OS_STARBOARD
using NativeHandle = SbMutex;
#endif
@ -171,7 +171,7 @@ class V8_BASE_EXPORT RecursiveMutex final {
#if V8_OS_POSIX
using NativeHandle = pthread_mutex_t;
#elif V8_OS_WIN
using NativeHandle = CRITICAL_SECTION;
using NativeHandle = V8_CRITICAL_SECTION;
#elif V8_OS_STARBOARD
using NativeHandle = starboard::RecursiveMutex;
#endif
@ -273,7 +273,7 @@ class V8_BASE_EXPORT SharedMutex final {
#elif V8_OS_POSIX
using NativeHandle = pthread_rwlock_t;
#elif V8_OS_WIN
using NativeHandle = SRWLOCK;
using NativeHandle = V8_SRWLOCK;
#elif V8_OS_STARBOARD
using NativeHandle = starboard::RWLock;
#endif

View File

@ -15,9 +15,15 @@
#endif // MINGW_HAS_SECURE_API
#endif // __MINGW32__
#include <limits>
#include <windows.h>
#include "src/base/win32-headers.h"
// This has to come after windows.h.
#include <VersionHelpers.h>
#include <dbghelp.h> // For SymLoadModule64 and al.
#include <mmsystem.h> // For timeGetTime().
#include <tlhelp32.h> // For Module32First and al.
#include <limits>
#include "src/base/bits.h"
#include "src/base/lazy-instance.h"
@ -26,13 +32,34 @@
#include "src/base/platform/time.h"
#include "src/base/timezone-cache.h"
#include "src/base/utils/random-number-generator.h"
#include <VersionHelpers.h>
#include "src/base/win32-headers.h"
#if defined(_MSC_VER)
#include <crtdbg.h>
#endif // defined(_MSC_VER)
// Check that type sizes and alignments match.
STATIC_ASSERT(sizeof(V8_CONDITION_VARIABLE) == sizeof(CONDITION_VARIABLE));
STATIC_ASSERT(alignof(V8_CONDITION_VARIABLE) == alignof(CONDITION_VARIABLE));
STATIC_ASSERT(sizeof(V8_SRWLOCK) == sizeof(SRWLOCK));
STATIC_ASSERT(alignof(V8_SRWLOCK) == alignof(SRWLOCK));
STATIC_ASSERT(sizeof(V8_CRITICAL_SECTION) == sizeof(CRITICAL_SECTION));
STATIC_ASSERT(alignof(V8_CRITICAL_SECTION) == alignof(CRITICAL_SECTION));
// Check that CRITICAL_SECTION offsets match.
STATIC_ASSERT(offsetof(V8_CRITICAL_SECTION, DebugInfo) ==
offsetof(CRITICAL_SECTION, DebugInfo));
STATIC_ASSERT(offsetof(V8_CRITICAL_SECTION, LockCount) ==
offsetof(CRITICAL_SECTION, LockCount));
STATIC_ASSERT(offsetof(V8_CRITICAL_SECTION, RecursionCount) ==
offsetof(CRITICAL_SECTION, RecursionCount));
STATIC_ASSERT(offsetof(V8_CRITICAL_SECTION, OwningThread) ==
offsetof(CRITICAL_SECTION, OwningThread));
STATIC_ASSERT(offsetof(V8_CRITICAL_SECTION, LockSemaphore) ==
offsetof(CRITICAL_SECTION, LockSemaphore));
STATIC_ASSERT(offsetof(V8_CRITICAL_SECTION, SpinCount) ==
offsetof(CRITICAL_SECTION, SpinCount));
// Extra functions for MinGW. Most of these are the _s functions which are in
// the Microsoft Visual Studio C++ CRT.
#ifdef __MINGW32__

View File

@ -40,6 +40,17 @@
#include <sanitizer/asan_interface.h>
#endif // V8_USE_ADDRESS_SANITIZER
#ifndef V8_NO_FAST_TLS
#if V8_CC_MSVC && V8_HOST_ARCH_IA32
// __readfsdword is supposed to be declared in intrin.h but it is missing from
// some versions of that file. See https://bugs.llvm.org/show_bug.cgi?id=51188
// And, intrin.h is a very expensive header that we want to avoid here, and
// the cheaper intrin0.h is not available for all build configurations. That is
// why we declare this intrinsic.
unsigned long __readfsdword(unsigned long); // NOLINT(runtime/int)
#endif // V8_CC_MSVC && V8_HOST_ARCH_IA32
#endif // V8_NO_FAST_TLS
namespace v8 {
namespace base {

View File

@ -6,6 +6,8 @@
#if V8_OS_MACOSX
#include <dispatch/dispatch.h>
#elif V8_OS_WIN
#include <windows.h>
#endif
#include <errno.h>

View File

@ -19,6 +19,11 @@
#include <ostream>
#if V8_OS_WIN
#include <windows.h>
// This has to come after windows.h.
#include <mmsystem.h> // For timeGetTime().
#include "src/base/lazy-instance.h"
#include "src/base/win32-headers.h"
#endif

View File

@ -23,6 +23,8 @@
#include "src/base/logging.h"
#include "src/base/macros.h"
#if V8_OS_WIN
#include <windows.h>
#include "src/base/win32-headers.h"
#endif

View File

@ -5,6 +5,12 @@
#ifndef V8_BASE_WIN32_HEADERS_H_
#define V8_BASE_WIN32_HEADERS_H_
// This file contains defines and typedefs that allow popular Windows types to
// be used without the overhead of including windows.h.
// This file no longer includes windows.h but it still sets the defines that
// tell windows.h to omit some includes so that the V8 source files that do
// include windows.h will still get the minimal version.
#ifndef WIN32_LEAN_AND_MEAN
// WIN32_LEAN_AND_MEAN implies NOCRYPT and NOGDI.
#define WIN32_LEAN_AND_MEAN
@ -33,9 +39,6 @@
#define _WIN32_WINNT 0x0600
#endif
#include <windows.h>
#include <mmsystem.h> // For timeGetTime().
#include <signal.h> // For raise().
#include <time.h> // For LocalOffset() implementation.
#ifdef __MINGW32__
@ -45,40 +48,81 @@
#define _WIN32_WINNT 0x501
#endif // __MINGW32__
#if !defined(__MINGW32__) || defined(__MINGW64_VERSION_MAJOR)
#include <dbghelp.h> // For SymLoadModule64 and al.
#include <errno.h> // For STRUNCATE
#include <versionhelpers.h> // For IsWindows8OrGreater().
#endif // !defined(__MINGW32__) || defined(__MINGW64_VERSION_MAJOR)
#include <limits.h> // For INT_MAX and al.
#include <tlhelp32.h> // For Module32First and al.
// These additional WIN32 includes have to be right here as the #undef's below
// makes it impossible to have them elsewhere.
#include <winsock2.h>
#include <ws2tcpip.h>
#ifndef __MINGW32__
#include <wspiapi.h>
#endif // __MINGW32__
#include <process.h> // For _beginthreadex().
#include <stdlib.h>
#undef VOID
#undef DELETE
#undef IN
#undef THIS
#undef CONST
#undef NAN
#undef UNKNOWN
#undef NONE
#undef ANY
#undef IGNORE
#undef STRICT
#undef GetObject
#undef CreateSemaphore
#undef Yield
#undef RotateRight32
#undef RotateLeft32
#undef RotateRight64
#undef RotateLeft64
// typedef and define the most commonly used Windows integer types.
typedef int BOOL; // NOLINT(runtime/int)
typedef unsigned long DWORD; // NOLINT(runtime/int)
typedef long LONG; // NOLINT(runtime/int)
typedef void* LPVOID;
typedef void* PVOID;
typedef void* HANDLE;
#define WINAPI __stdcall
#if defined(_WIN64)
typedef unsigned __int64 ULONG_PTR, *PULONG_PTR;
#else
typedef __w64 unsigned long ULONG_PTR, *PULONG_PTR; // NOLINT(runtime/int)
#endif
typedef struct _RTL_SRWLOCK SRWLOCK;
typedef struct _RTL_CONDITION_VARIABLE CONDITION_VARIABLE;
typedef struct _RTL_CRITICAL_SECTION CRITICAL_SECTION;
typedef struct _RTL_CRITICAL_SECTION_DEBUG* PRTL_CRITICAL_SECTION_DEBUG;
// Declare V8 versions of some Windows structures. These are needed for
// when we need a concrete type but don't want to pull in Windows.h. We can't
// declare the Windows types so we declare our types and cast to the Windows
// types in a few places. The sizes must match the Windows types so we verify
// that with static asserts in platform-win32.cc.
// ChromeToWindowsType functions are provided for pointer conversions.
struct V8_SRWLOCK {
PVOID Ptr;
};
struct V8_CONDITION_VARIABLE {
PVOID Ptr;
};
struct V8_CRITICAL_SECTION {
PRTL_CRITICAL_SECTION_DEBUG DebugInfo;
LONG LockCount;
LONG RecursionCount;
HANDLE OwningThread;
HANDLE LockSemaphore;
ULONG_PTR SpinCount;
};
inline SRWLOCK* V8ToWindowsType(V8_SRWLOCK* p) {
return reinterpret_cast<SRWLOCK*>(p);
}
inline const SRWLOCK* V8ToWindowsType(const V8_SRWLOCK* p) {
return reinterpret_cast<const SRWLOCK*>(p);
}
inline CONDITION_VARIABLE* V8ToWindowsType(V8_CONDITION_VARIABLE* p) {
return reinterpret_cast<CONDITION_VARIABLE*>(p);
}
inline const CONDITION_VARIABLE* V8ToWindowsType(
const V8_CONDITION_VARIABLE* p) {
return reinterpret_cast<const CONDITION_VARIABLE*>(p);
}
inline CRITICAL_SECTION* V8ToWindowsType(V8_CRITICAL_SECTION* p) {
return reinterpret_cast<CRITICAL_SECTION*>(p);
}
inline const CRITICAL_SECTION* V8ToWindowsType(const V8_CRITICAL_SECTION* p) {
return reinterpret_cast<const CRITICAL_SECTION*>(p);
}
#endif // V8_BASE_WIN32_HEADERS_H_

View File

@ -17,6 +17,11 @@
#error "Unsupported OS"
#endif // V8_OS_WIN_X64
#include <windows.h>
// This has to come after windows.h.
#include <versionhelpers.h> // For IsWindows8OrGreater().
namespace v8 {
namespace internal {
namespace win64_unwindinfo {

View File

@ -28,6 +28,8 @@
#elif V8_OS_WIN || V8_OS_CYGWIN
#include <windows.h>
#include "src/base/win32-headers.h"
#elif V8_OS_FUCHSIA

View File

@ -13,7 +13,7 @@
extern "C" {
BOOL WINAPI DllMain(HANDLE hinstDLL, DWORD dwReason, LPVOID lpvReserved) {
// Do nothing.
return TRUE;
return 1;
}
}
#endif // V8_OS_WIN

View File

@ -19,6 +19,8 @@
#ifdef V8_OS_POSIX
#include <dirent.h>
#elif V8_OS_WIN
#include <windows.h>
#endif
using v8::internal::interpreter::BytecodeExpectationsPrinter;

View File

@ -12,6 +12,11 @@
#define CONTEXT_PC(context) (context.Pc)
#endif
#include <windows.h>
// This has to come after windows.h.
#include <versionhelpers.h> // For IsWindows8OrGreater().
class UnwindingWin64Callbacks {
public:
UnwindingWin64Callbacks() = default;

View File

@ -6,6 +6,10 @@
#include "testing/gtest/include/gtest/gtest.h"
#if V8_OS_WIN
#include <windows.h>
#endif
namespace v8 {
namespace base {

View File

@ -12,6 +12,8 @@
#endif
#if V8_OS_WIN
#include <windows.h>
#include "src/base/win32-headers.h"
#endif