// Copyright 2012 the V8 project authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // This module contains the platform-specific code. This make the rest of the // code less dependent on operating system, compilers and runtime libraries. // This module does specifically not deal with differences between different // processor architecture. // The platform classes have the same definition for all platforms. The // implementation for a particular platform is put in platform_<os>.cc. // The build system then uses the implementation for the target platform. // // This design has been chosen because it is simple and fast. Alternatively, // the platform dependent classes could have been implemented using abstract // superclasses with virtual methods and having specializations for each // platform. This design was rejected because it was more complicated and // slower. It would require factory methods for selecting the right // implementation and the overhead of virtual methods for performance // sensitive like mutex locking/unlocking. #ifndef V8_BASE_PLATFORM_PLATFORM_H_ #define V8_BASE_PLATFORM_PLATFORM_H_ #include <cstdarg> #include <cstdint> #include <optional> #include <string> #include <vector> #include "include/v8-platform.h" #include "src/base/abort-mode.h" #include "src/base/base-export.h" #include "src/base/build_config.h" #include "src/base/compiler-specific.h" #include "src/base/macros.h" #include "src/base/platform/mutex.h" #include "src/base/platform/semaphore.h" #include "testing/gtest/include/gtest/gtest_prod.h" // nogncheck #if V8_OS_QNX #include "src/base/qnx-math.h" #endif #if V8_CC_MSVC #include <intrin.h> #endif // V8_CC_MSVC #if V8_OS_FUCHSIA #include <zircon/types.h> #endif // V8_OS_FUCHSIA #ifdef V8_USE_ADDRESS_SANITIZER #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. extern "C" unsigned long __readfsdword(unsigned long); // NOLINT(runtime/int) #endif // V8_CC_MSVC && V8_HOST_ARCH_IA32 #endif // V8_NO_FAST_TLS #if V8_OS_OPENBSD #define PERMISSION_MUTABLE_SECTION … #else #define PERMISSION_MUTABLE_SECTION #endif namespace heap::base { class Stack; } namespace v8::base { // ---------------------------------------------------------------------------- // Fast TLS support #ifndef V8_NO_FAST_TLS #if V8_CC_MSVC && V8_HOST_ARCH_IA32 #define V8_FAST_TLS_SUPPORTED … V8_INLINE intptr_t InternalGetExistingThreadLocal(intptr_t index) { const intptr_t kTibInlineTlsOffset = 0xE10; const intptr_t kTibExtraTlsOffset = 0xF94; const intptr_t kMaxInlineSlots = 64; const intptr_t kMaxSlots = kMaxInlineSlots + 1024; const intptr_t kSystemPointerSize = sizeof(void*); DCHECK(0 <= index && index < kMaxSlots); USE(kMaxSlots); if (index < kMaxInlineSlots) { return static_cast<intptr_t>( __readfsdword(kTibInlineTlsOffset + kSystemPointerSize * index)); } intptr_t extra = static_cast<intptr_t>(__readfsdword(kTibExtraTlsOffset)); if (!extra) return 0; return *reinterpret_cast<intptr_t*>(extra + kSystemPointerSize * (index - kMaxInlineSlots)); } // Not possible on ARM64, the register holding the base pointer is not stable // across major releases. #elif defined(__APPLE__) && (V8_HOST_ARCH_IA32 || V8_HOST_ARCH_X64) // tvOS simulator does not use intptr_t as TLS key. #if !defined(V8_OS_STARBOARD) || !defined(TARGET_OS_SIMULATOR) #define V8_FAST_TLS_SUPPORTED … V8_INLINE intptr_t InternalGetExistingThreadLocal(intptr_t index) { intptr_t result; #if V8_HOST_ARCH_IA32 asm("movl %%gs:(,%1,4), %0;" : "=r"(result) // Output must be a writable register. : "r"(index)); #else asm("movq %%gs:(,%1,8), %0;" : "=r"(result) : "r"(index)); #endif return result; } #endif // !defined(V8_OS_STARBOARD) || !defined(TARGET_OS_SIMULATOR) #endif #endif // V8_NO_FAST_TLS class AddressSpaceReservation; class PageAllocator; class TimezoneCache; class VirtualAddressSpace; class VirtualAddressSubspace; // ---------------------------------------------------------------------------- // OS // // This class has static methods for the different platform specific // functions. Add methods here to cope with differences between the // supported platforms. class V8_BASE_EXPORT OS { … }; #if defined(V8_OS_WIN) V8_BASE_EXPORT void EnsureConsoleOutputWin32(); #endif // defined(V8_OS_WIN) inline void EnsureConsoleOutput() { … } // ---------------------------------------------------------------------------- // AddressSpaceReservation // // This class provides the same memory management functions as OS but operates // inside a previously reserved contiguous region of virtual address space. // // Reserved address space in which no pages have been allocated is guaranteed // to be inaccessible and cause a fault on access. As such, creating guard // regions requires no further action. class V8_BASE_EXPORT AddressSpaceReservation { … }; // ---------------------------------------------------------------------------- // Thread // // Thread objects are used for creating and running threads. When the start() // method is called the new thread starts running the run() method in the new // thread. The Thread object should not be deallocated before the thread has // terminated. class V8_BASE_EXPORT Thread { … }; // TODO(v8:10354): Make use of the stack utilities here in V8. class V8_BASE_EXPORT Stack { … }; #if V8_HAS_PTHREAD_JIT_WRITE_PROTECT V8_BASE_EXPORT void SetJitWriteProtected(int enable); #endif } // namespace v8::base #endif // V8_BASE_PLATFORM_PLATFORM_H_