chromium/v8/src/base/platform/platform.h

// 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_