11cb0ef41Sopenharmony_ci// Copyright 2012 the V8 project authors. All rights reserved.
21cb0ef41Sopenharmony_ci// Use of this source code is governed by a BSD-style license that can be
31cb0ef41Sopenharmony_ci// found in the LICENSE file.
41cb0ef41Sopenharmony_ci
51cb0ef41Sopenharmony_ci#ifndef V8_UTILS_UTILS_H_
61cb0ef41Sopenharmony_ci#define V8_UTILS_UTILS_H_
71cb0ef41Sopenharmony_ci
81cb0ef41Sopenharmony_ci#include <limits.h>
91cb0ef41Sopenharmony_ci#include <stdlib.h>
101cb0ef41Sopenharmony_ci#include <string.h>
111cb0ef41Sopenharmony_ci
121cb0ef41Sopenharmony_ci#include <cmath>
131cb0ef41Sopenharmony_ci#include <string>
141cb0ef41Sopenharmony_ci#include <type_traits>
151cb0ef41Sopenharmony_ci
161cb0ef41Sopenharmony_ci#include "src/base/bits.h"
171cb0ef41Sopenharmony_ci#include "src/base/compiler-specific.h"
181cb0ef41Sopenharmony_ci#include "src/base/logging.h"
191cb0ef41Sopenharmony_ci#include "src/base/macros.h"
201cb0ef41Sopenharmony_ci#include "src/base/platform/platform.h"
211cb0ef41Sopenharmony_ci#include "src/base/safe_conversions.h"
221cb0ef41Sopenharmony_ci#include "src/base/v8-fallthrough.h"
231cb0ef41Sopenharmony_ci#include "src/base/vector.h"
241cb0ef41Sopenharmony_ci#include "src/common/globals.h"
251cb0ef41Sopenharmony_ci#include "src/utils/allocation.h"
261cb0ef41Sopenharmony_ci
271cb0ef41Sopenharmony_ci#if defined(V8_USE_SIPHASH)
281cb0ef41Sopenharmony_ci#include "src/third_party/siphash/halfsiphash.h"
291cb0ef41Sopenharmony_ci#endif
301cb0ef41Sopenharmony_ci
311cb0ef41Sopenharmony_ci#if defined(V8_OS_AIX)
321cb0ef41Sopenharmony_ci#include <fenv.h>  // NOLINT(build/c++11)
331cb0ef41Sopenharmony_ci#endif
341cb0ef41Sopenharmony_ci
351cb0ef41Sopenharmony_cinamespace v8 {
361cb0ef41Sopenharmony_cinamespace internal {
371cb0ef41Sopenharmony_ci
381cb0ef41Sopenharmony_ci// ----------------------------------------------------------------------------
391cb0ef41Sopenharmony_ci// General helper functions
401cb0ef41Sopenharmony_ci
411cb0ef41Sopenharmony_citemplate <typename T>
421cb0ef41Sopenharmony_cistatic T ArithmeticShiftRight(T x, int shift) {
431cb0ef41Sopenharmony_ci  DCHECK_LE(0, shift);
441cb0ef41Sopenharmony_ci  if (x < 0) {
451cb0ef41Sopenharmony_ci    // Right shift of signed values is implementation defined. Simulate a
461cb0ef41Sopenharmony_ci    // true arithmetic right shift by adding leading sign bits.
471cb0ef41Sopenharmony_ci    using UnsignedT = typename std::make_unsigned<T>::type;
481cb0ef41Sopenharmony_ci    UnsignedT mask = ~(static_cast<UnsignedT>(~0) >> shift);
491cb0ef41Sopenharmony_ci    return (static_cast<UnsignedT>(x) >> shift) | mask;
501cb0ef41Sopenharmony_ci  } else {
511cb0ef41Sopenharmony_ci    return x >> shift;
521cb0ef41Sopenharmony_ci  }
531cb0ef41Sopenharmony_ci}
541cb0ef41Sopenharmony_ci
551cb0ef41Sopenharmony_ci// Returns the maximum of the two parameters according to JavaScript semantics.
561cb0ef41Sopenharmony_citemplate <typename T>
571cb0ef41Sopenharmony_ciT JSMax(T x, T y) {
581cb0ef41Sopenharmony_ci  if (std::isnan(x)) return x;
591cb0ef41Sopenharmony_ci  if (std::isnan(y)) return y;
601cb0ef41Sopenharmony_ci  if (std::signbit(x) < std::signbit(y)) return x;
611cb0ef41Sopenharmony_ci  return x > y ? x : y;
621cb0ef41Sopenharmony_ci}
631cb0ef41Sopenharmony_ci
641cb0ef41Sopenharmony_ci// Returns the maximum of the two parameters according to JavaScript semantics.
651cb0ef41Sopenharmony_citemplate <typename T>
661cb0ef41Sopenharmony_ciT JSMin(T x, T y) {
671cb0ef41Sopenharmony_ci  if (std::isnan(x)) return x;
681cb0ef41Sopenharmony_ci  if (std::isnan(y)) return y;
691cb0ef41Sopenharmony_ci  if (std::signbit(x) < std::signbit(y)) return y;
701cb0ef41Sopenharmony_ci  return x > y ? y : x;
711cb0ef41Sopenharmony_ci}
721cb0ef41Sopenharmony_ci
731cb0ef41Sopenharmony_ci// Returns the absolute value of its argument.
741cb0ef41Sopenharmony_citemplate <typename T,
751cb0ef41Sopenharmony_ci          typename = typename std::enable_if<std::is_signed<T>::value>::type>
761cb0ef41Sopenharmony_citypename std::make_unsigned<T>::type Abs(T a) {
771cb0ef41Sopenharmony_ci  // This is a branch-free implementation of the absolute value function and is
781cb0ef41Sopenharmony_ci  // described in Warren's "Hacker's Delight", chapter 2. It avoids undefined
791cb0ef41Sopenharmony_ci  // behavior with the arithmetic negation operation on signed values as well.
801cb0ef41Sopenharmony_ci  using unsignedT = typename std::make_unsigned<T>::type;
811cb0ef41Sopenharmony_ci  unsignedT x = static_cast<unsignedT>(a);
821cb0ef41Sopenharmony_ci  unsignedT y = static_cast<unsignedT>(a >> (sizeof(T) * 8 - 1));
831cb0ef41Sopenharmony_ci  return (x ^ y) - y;
841cb0ef41Sopenharmony_ci}
851cb0ef41Sopenharmony_ci
861cb0ef41Sopenharmony_ciinline double Modulo(double x, double y) {
871cb0ef41Sopenharmony_ci#if defined(V8_OS_WIN)
881cb0ef41Sopenharmony_ci  // Workaround MS fmod bugs. ECMA-262 says:
891cb0ef41Sopenharmony_ci  // dividend is finite and divisor is an infinity => result equals dividend
901cb0ef41Sopenharmony_ci  // dividend is a zero and divisor is nonzero finite => result equals dividend
911cb0ef41Sopenharmony_ci  if (!(std::isfinite(x) && (!std::isfinite(y) && !std::isnan(y))) &&
921cb0ef41Sopenharmony_ci      !(x == 0 && (y != 0 && std::isfinite(y)))) {
931cb0ef41Sopenharmony_ci    double result = fmod(x, y);
941cb0ef41Sopenharmony_ci    // Workaround MS bug in VS CRT in some OS versions, https://crbug.com/915045
951cb0ef41Sopenharmony_ci    // fmod(-17, +/-1) should equal -0.0 but now returns 0.0.
961cb0ef41Sopenharmony_ci    if (x < 0 && result == 0) result = -0.0;
971cb0ef41Sopenharmony_ci    x = result;
981cb0ef41Sopenharmony_ci  }
991cb0ef41Sopenharmony_ci  return x;
1001cb0ef41Sopenharmony_ci#elif defined(V8_OS_AIX)
1011cb0ef41Sopenharmony_ci  // AIX raises an underflow exception for (Number.MIN_VALUE % Number.MAX_VALUE)
1021cb0ef41Sopenharmony_ci  feclearexcept(FE_ALL_EXCEPT);
1031cb0ef41Sopenharmony_ci  double result = std::fmod(x, y);
1041cb0ef41Sopenharmony_ci  int exception = fetestexcept(FE_UNDERFLOW);
1051cb0ef41Sopenharmony_ci  return (exception ? x : result);
1061cb0ef41Sopenharmony_ci#else
1071cb0ef41Sopenharmony_ci  return std::fmod(x, y);
1081cb0ef41Sopenharmony_ci#endif
1091cb0ef41Sopenharmony_ci}
1101cb0ef41Sopenharmony_ci
1111cb0ef41Sopenharmony_citemplate <typename T>
1121cb0ef41Sopenharmony_ciT SaturateAdd(T a, T b) {
1131cb0ef41Sopenharmony_ci  if (std::is_signed<T>::value) {
1141cb0ef41Sopenharmony_ci    if (a > 0 && b > 0) {
1151cb0ef41Sopenharmony_ci      if (a > std::numeric_limits<T>::max() - b) {
1161cb0ef41Sopenharmony_ci        return std::numeric_limits<T>::max();
1171cb0ef41Sopenharmony_ci      }
1181cb0ef41Sopenharmony_ci    } else if (a < 0 && b < 0) {
1191cb0ef41Sopenharmony_ci      if (a < std::numeric_limits<T>::min() - b) {
1201cb0ef41Sopenharmony_ci        return std::numeric_limits<T>::min();
1211cb0ef41Sopenharmony_ci      }
1221cb0ef41Sopenharmony_ci    }
1231cb0ef41Sopenharmony_ci  } else {
1241cb0ef41Sopenharmony_ci    CHECK(std::is_unsigned<T>::value);
1251cb0ef41Sopenharmony_ci    if (a > std::numeric_limits<T>::max() - b) {
1261cb0ef41Sopenharmony_ci      return std::numeric_limits<T>::max();
1271cb0ef41Sopenharmony_ci    }
1281cb0ef41Sopenharmony_ci  }
1291cb0ef41Sopenharmony_ci  return a + b;
1301cb0ef41Sopenharmony_ci}
1311cb0ef41Sopenharmony_ci
1321cb0ef41Sopenharmony_citemplate <typename T>
1331cb0ef41Sopenharmony_ciT SaturateSub(T a, T b) {
1341cb0ef41Sopenharmony_ci  if (std::is_signed<T>::value) {
1351cb0ef41Sopenharmony_ci    if (a >= 0 && b < 0) {
1361cb0ef41Sopenharmony_ci      if (a > std::numeric_limits<T>::max() + b) {
1371cb0ef41Sopenharmony_ci        return std::numeric_limits<T>::max();
1381cb0ef41Sopenharmony_ci      }
1391cb0ef41Sopenharmony_ci    } else if (a < 0 && b > 0) {
1401cb0ef41Sopenharmony_ci      if (a < std::numeric_limits<T>::min() + b) {
1411cb0ef41Sopenharmony_ci        return std::numeric_limits<T>::min();
1421cb0ef41Sopenharmony_ci      }
1431cb0ef41Sopenharmony_ci    }
1441cb0ef41Sopenharmony_ci  } else {
1451cb0ef41Sopenharmony_ci    CHECK(std::is_unsigned<T>::value);
1461cb0ef41Sopenharmony_ci    if (a < b) {
1471cb0ef41Sopenharmony_ci      return static_cast<T>(0);
1481cb0ef41Sopenharmony_ci    }
1491cb0ef41Sopenharmony_ci  }
1501cb0ef41Sopenharmony_ci  return a - b;
1511cb0ef41Sopenharmony_ci}
1521cb0ef41Sopenharmony_ci
1531cb0ef41Sopenharmony_citemplate <typename T>
1541cb0ef41Sopenharmony_ciT SaturateRoundingQMul(T a, T b) {
1551cb0ef41Sopenharmony_ci  // Saturating rounding multiplication for Q-format numbers. See
1561cb0ef41Sopenharmony_ci  // https://en.wikipedia.org/wiki/Q_(number_format) for a description.
1571cb0ef41Sopenharmony_ci  // Specifically this supports Q7, Q15, and Q31. This follows the
1581cb0ef41Sopenharmony_ci  // implementation in simulator-logic-arm64.cc (sqrdmulh) to avoid overflow
1591cb0ef41Sopenharmony_ci  // when a == b == int32 min.
1601cb0ef41Sopenharmony_ci  static_assert(std::is_integral<T>::value, "only integral types");
1611cb0ef41Sopenharmony_ci
1621cb0ef41Sopenharmony_ci  constexpr int size_in_bits = sizeof(T) * 8;
1631cb0ef41Sopenharmony_ci  int round_const = 1 << (size_in_bits - 2);
1641cb0ef41Sopenharmony_ci  int64_t product = a * b;
1651cb0ef41Sopenharmony_ci  product += round_const;
1661cb0ef41Sopenharmony_ci  product >>= (size_in_bits - 1);
1671cb0ef41Sopenharmony_ci  return base::saturated_cast<T>(product);
1681cb0ef41Sopenharmony_ci}
1691cb0ef41Sopenharmony_ci
1701cb0ef41Sopenharmony_ci// Multiply two numbers, returning a result that is twice as wide, no overflow.
1711cb0ef41Sopenharmony_ci// Put Wide first so we can use function template argument deduction for Narrow,
1721cb0ef41Sopenharmony_ci// and callers can provide only Wide.
1731cb0ef41Sopenharmony_citemplate <typename Wide, typename Narrow>
1741cb0ef41Sopenharmony_ciWide MultiplyLong(Narrow a, Narrow b) {
1751cb0ef41Sopenharmony_ci  static_assert(
1761cb0ef41Sopenharmony_ci      std::is_integral<Narrow>::value && std::is_integral<Wide>::value,
1771cb0ef41Sopenharmony_ci      "only integral types");
1781cb0ef41Sopenharmony_ci  static_assert(std::is_signed<Narrow>::value == std::is_signed<Wide>::value,
1791cb0ef41Sopenharmony_ci                "both must have same signedness");
1801cb0ef41Sopenharmony_ci  static_assert(sizeof(Narrow) * 2 == sizeof(Wide), "only twice as long");
1811cb0ef41Sopenharmony_ci
1821cb0ef41Sopenharmony_ci  return static_cast<Wide>(a) * static_cast<Wide>(b);
1831cb0ef41Sopenharmony_ci}
1841cb0ef41Sopenharmony_ci
1851cb0ef41Sopenharmony_ci// Add two numbers, returning a result that is twice as wide, no overflow.
1861cb0ef41Sopenharmony_ci// Put Wide first so we can use function template argument deduction for Narrow,
1871cb0ef41Sopenharmony_ci// and callers can provide only Wide.
1881cb0ef41Sopenharmony_citemplate <typename Wide, typename Narrow>
1891cb0ef41Sopenharmony_ciWide AddLong(Narrow a, Narrow b) {
1901cb0ef41Sopenharmony_ci  static_assert(
1911cb0ef41Sopenharmony_ci      std::is_integral<Narrow>::value && std::is_integral<Wide>::value,
1921cb0ef41Sopenharmony_ci      "only integral types");
1931cb0ef41Sopenharmony_ci  static_assert(std::is_signed<Narrow>::value == std::is_signed<Wide>::value,
1941cb0ef41Sopenharmony_ci                "both must have same signedness");
1951cb0ef41Sopenharmony_ci  static_assert(sizeof(Narrow) * 2 == sizeof(Wide), "only twice as long");
1961cb0ef41Sopenharmony_ci
1971cb0ef41Sopenharmony_ci  return static_cast<Wide>(a) + static_cast<Wide>(b);
1981cb0ef41Sopenharmony_ci}
1991cb0ef41Sopenharmony_ci
2001cb0ef41Sopenharmony_citemplate <typename T>
2011cb0ef41Sopenharmony_ciinline T RoundingAverageUnsigned(T a, T b) {
2021cb0ef41Sopenharmony_ci  static_assert(std::is_unsigned<T>::value, "Only for unsiged types");
2031cb0ef41Sopenharmony_ci  static_assert(sizeof(T) < sizeof(uint64_t), "Must be smaller than uint64_t");
2041cb0ef41Sopenharmony_ci  return (static_cast<uint64_t>(a) + static_cast<uint64_t>(b) + 1) >> 1;
2051cb0ef41Sopenharmony_ci}
2061cb0ef41Sopenharmony_ci
2071cb0ef41Sopenharmony_ci// Helper macros for defining a contiguous sequence of field offset constants.
2081cb0ef41Sopenharmony_ci// Example: (backslashes at the ends of respective lines of this multi-line
2091cb0ef41Sopenharmony_ci// macro definition are omitted here to please the compiler)
2101cb0ef41Sopenharmony_ci//
2111cb0ef41Sopenharmony_ci// #define MAP_FIELDS(V)
2121cb0ef41Sopenharmony_ci//   V(kField1Offset, kTaggedSize)
2131cb0ef41Sopenharmony_ci//   V(kField2Offset, kIntSize)
2141cb0ef41Sopenharmony_ci//   V(kField3Offset, kIntSize)
2151cb0ef41Sopenharmony_ci//   V(kField4Offset, kSystemPointerSize)
2161cb0ef41Sopenharmony_ci//   V(kSize, 0)
2171cb0ef41Sopenharmony_ci//
2181cb0ef41Sopenharmony_ci// DEFINE_FIELD_OFFSET_CONSTANTS(HeapObject::kHeaderSize, MAP_FIELDS)
2191cb0ef41Sopenharmony_ci//
2201cb0ef41Sopenharmony_ci#define DEFINE_ONE_FIELD_OFFSET(Name, Size, ...) \
2211cb0ef41Sopenharmony_ci  Name, Name##End = Name + (Size)-1,
2221cb0ef41Sopenharmony_ci
2231cb0ef41Sopenharmony_ci#define DEFINE_FIELD_OFFSET_CONSTANTS(StartOffset, LIST_MACRO) \
2241cb0ef41Sopenharmony_ci  enum {                                                       \
2251cb0ef41Sopenharmony_ci    LIST_MACRO##_StartOffset = StartOffset - 1,                \
2261cb0ef41Sopenharmony_ci    LIST_MACRO(DEFINE_ONE_FIELD_OFFSET)                        \
2271cb0ef41Sopenharmony_ci  };
2281cb0ef41Sopenharmony_ci
2291cb0ef41Sopenharmony_ci// Size of the field defined by DEFINE_FIELD_OFFSET_CONSTANTS
2301cb0ef41Sopenharmony_ci#define FIELD_SIZE(Name) (Name##End + 1 - Name)
2311cb0ef41Sopenharmony_ci
2321cb0ef41Sopenharmony_ci// Compare two offsets with static cast
2331cb0ef41Sopenharmony_ci#define STATIC_ASSERT_FIELD_OFFSETS_EQUAL(Offset1, Offset2) \
2341cb0ef41Sopenharmony_ci  STATIC_ASSERT(static_cast<int>(Offset1) == Offset2)
2351cb0ef41Sopenharmony_ci// ----------------------------------------------------------------------------
2361cb0ef41Sopenharmony_ci// Hash function.
2371cb0ef41Sopenharmony_ci
2381cb0ef41Sopenharmony_cistatic const uint64_t kZeroHashSeed = 0;
2391cb0ef41Sopenharmony_ci
2401cb0ef41Sopenharmony_ci// Thomas Wang, Integer Hash Functions.
2411cb0ef41Sopenharmony_ci// http://www.concentric.net/~Ttwang/tech/inthash.htm`
2421cb0ef41Sopenharmony_ciinline uint32_t ComputeUnseededHash(uint32_t key) {
2431cb0ef41Sopenharmony_ci  uint32_t hash = key;
2441cb0ef41Sopenharmony_ci  hash = ~hash + (hash << 15);  // hash = (hash << 15) - hash - 1;
2451cb0ef41Sopenharmony_ci  hash = hash ^ (hash >> 12);
2461cb0ef41Sopenharmony_ci  hash = hash + (hash << 2);
2471cb0ef41Sopenharmony_ci  hash = hash ^ (hash >> 4);
2481cb0ef41Sopenharmony_ci  hash = hash * 2057;  // hash = (hash + (hash << 3)) + (hash << 11);
2491cb0ef41Sopenharmony_ci  hash = hash ^ (hash >> 16);
2501cb0ef41Sopenharmony_ci  return hash & 0x3fffffff;
2511cb0ef41Sopenharmony_ci}
2521cb0ef41Sopenharmony_ci
2531cb0ef41Sopenharmony_ciinline uint32_t ComputeLongHash(uint64_t key) {
2541cb0ef41Sopenharmony_ci  uint64_t hash = key;
2551cb0ef41Sopenharmony_ci  hash = ~hash + (hash << 18);  // hash = (hash << 18) - hash - 1;
2561cb0ef41Sopenharmony_ci  hash = hash ^ (hash >> 31);
2571cb0ef41Sopenharmony_ci  hash = hash * 21;  // hash = (hash + (hash << 2)) + (hash << 4);
2581cb0ef41Sopenharmony_ci  hash = hash ^ (hash >> 11);
2591cb0ef41Sopenharmony_ci  hash = hash + (hash << 6);
2601cb0ef41Sopenharmony_ci  hash = hash ^ (hash >> 22);
2611cb0ef41Sopenharmony_ci  return static_cast<uint32_t>(hash & 0x3fffffff);
2621cb0ef41Sopenharmony_ci}
2631cb0ef41Sopenharmony_ci
2641cb0ef41Sopenharmony_ciinline uint32_t ComputeSeededHash(uint32_t key, uint64_t seed) {
2651cb0ef41Sopenharmony_ci#ifdef V8_USE_SIPHASH
2661cb0ef41Sopenharmony_ci  return halfsiphash(key, seed);
2671cb0ef41Sopenharmony_ci#else
2681cb0ef41Sopenharmony_ci  return ComputeLongHash(static_cast<uint64_t>(key) ^ seed);
2691cb0ef41Sopenharmony_ci#endif  // V8_USE_SIPHASH
2701cb0ef41Sopenharmony_ci}
2711cb0ef41Sopenharmony_ci
2721cb0ef41Sopenharmony_ciinline uint32_t ComputePointerHash(void* ptr) {
2731cb0ef41Sopenharmony_ci  return ComputeUnseededHash(
2741cb0ef41Sopenharmony_ci      static_cast<uint32_t>(reinterpret_cast<intptr_t>(ptr)));
2751cb0ef41Sopenharmony_ci}
2761cb0ef41Sopenharmony_ci
2771cb0ef41Sopenharmony_ciinline uint32_t ComputeAddressHash(Address address) {
2781cb0ef41Sopenharmony_ci  return ComputeUnseededHash(static_cast<uint32_t>(address & 0xFFFFFFFFul));
2791cb0ef41Sopenharmony_ci}
2801cb0ef41Sopenharmony_ci
2811cb0ef41Sopenharmony_ci// ----------------------------------------------------------------------------
2821cb0ef41Sopenharmony_ci// Miscellaneous
2831cb0ef41Sopenharmony_ci
2841cb0ef41Sopenharmony_ci// Memory offset for lower and higher bits in a 64 bit integer.
2851cb0ef41Sopenharmony_ci#if defined(V8_TARGET_LITTLE_ENDIAN)
2861cb0ef41Sopenharmony_cistatic const int kInt64LowerHalfMemoryOffset = 0;
2871cb0ef41Sopenharmony_cistatic const int kInt64UpperHalfMemoryOffset = 4;
2881cb0ef41Sopenharmony_ci#elif defined(V8_TARGET_BIG_ENDIAN)
2891cb0ef41Sopenharmony_cistatic const int kInt64LowerHalfMemoryOffset = 4;
2901cb0ef41Sopenharmony_cistatic const int kInt64UpperHalfMemoryOffset = 0;
2911cb0ef41Sopenharmony_ci#endif  // V8_TARGET_LITTLE_ENDIAN
2921cb0ef41Sopenharmony_ci
2931cb0ef41Sopenharmony_ci// A pointer that can only be set once and doesn't allow NULL values.
2941cb0ef41Sopenharmony_citemplate <typename T>
2951cb0ef41Sopenharmony_ciclass SetOncePointer {
2961cb0ef41Sopenharmony_ci public:
2971cb0ef41Sopenharmony_ci  SetOncePointer() = default;
2981cb0ef41Sopenharmony_ci
2991cb0ef41Sopenharmony_ci  bool is_set() const { return pointer_ != nullptr; }
3001cb0ef41Sopenharmony_ci
3011cb0ef41Sopenharmony_ci  T* get() const {
3021cb0ef41Sopenharmony_ci    DCHECK_NOT_NULL(pointer_);
3031cb0ef41Sopenharmony_ci    return pointer_;
3041cb0ef41Sopenharmony_ci  }
3051cb0ef41Sopenharmony_ci
3061cb0ef41Sopenharmony_ci  void set(T* value) {
3071cb0ef41Sopenharmony_ci    DCHECK(pointer_ == nullptr && value != nullptr);
3081cb0ef41Sopenharmony_ci    pointer_ = value;
3091cb0ef41Sopenharmony_ci  }
3101cb0ef41Sopenharmony_ci
3111cb0ef41Sopenharmony_ci  SetOncePointer& operator=(T* value) {
3121cb0ef41Sopenharmony_ci    set(value);
3131cb0ef41Sopenharmony_ci    return *this;
3141cb0ef41Sopenharmony_ci  }
3151cb0ef41Sopenharmony_ci
3161cb0ef41Sopenharmony_ci  bool operator==(std::nullptr_t) const { return pointer_ == nullptr; }
3171cb0ef41Sopenharmony_ci  bool operator!=(std::nullptr_t) const { return pointer_ != nullptr; }
3181cb0ef41Sopenharmony_ci
3191cb0ef41Sopenharmony_ci private:
3201cb0ef41Sopenharmony_ci  T* pointer_ = nullptr;
3211cb0ef41Sopenharmony_ci};
3221cb0ef41Sopenharmony_ci
3231cb0ef41Sopenharmony_ci// Compare 8bit/16bit chars to 8bit/16bit chars.
3241cb0ef41Sopenharmony_citemplate <typename lchar, typename rchar>
3251cb0ef41Sopenharmony_ciinline bool CompareCharsEqualUnsigned(const lchar* lhs, const rchar* rhs,
3261cb0ef41Sopenharmony_ci                                      size_t chars) {
3271cb0ef41Sopenharmony_ci  STATIC_ASSERT(std::is_unsigned<lchar>::value);
3281cb0ef41Sopenharmony_ci  STATIC_ASSERT(std::is_unsigned<rchar>::value);
3291cb0ef41Sopenharmony_ci  if (sizeof(*lhs) == sizeof(*rhs)) {
3301cb0ef41Sopenharmony_ci    // memcmp compares byte-by-byte, but for equality it doesn't matter whether
3311cb0ef41Sopenharmony_ci    // two-byte char comparison is little- or big-endian.
3321cb0ef41Sopenharmony_ci    return memcmp(lhs, rhs, chars * sizeof(*lhs)) == 0;
3331cb0ef41Sopenharmony_ci  }
3341cb0ef41Sopenharmony_ci  for (const lchar* limit = lhs + chars; lhs < limit; ++lhs, ++rhs) {
3351cb0ef41Sopenharmony_ci    if (*lhs != *rhs) return false;
3361cb0ef41Sopenharmony_ci  }
3371cb0ef41Sopenharmony_ci  return true;
3381cb0ef41Sopenharmony_ci}
3391cb0ef41Sopenharmony_ci
3401cb0ef41Sopenharmony_citemplate <typename lchar, typename rchar>
3411cb0ef41Sopenharmony_ciinline bool CompareCharsEqual(const lchar* lhs, const rchar* rhs,
3421cb0ef41Sopenharmony_ci                              size_t chars) {
3431cb0ef41Sopenharmony_ci  using ulchar = typename std::make_unsigned<lchar>::type;
3441cb0ef41Sopenharmony_ci  using urchar = typename std::make_unsigned<rchar>::type;
3451cb0ef41Sopenharmony_ci  return CompareCharsEqualUnsigned(reinterpret_cast<const ulchar*>(lhs),
3461cb0ef41Sopenharmony_ci                                   reinterpret_cast<const urchar*>(rhs), chars);
3471cb0ef41Sopenharmony_ci}
3481cb0ef41Sopenharmony_ci
3491cb0ef41Sopenharmony_ci// Compare 8bit/16bit chars to 8bit/16bit chars.
3501cb0ef41Sopenharmony_citemplate <typename lchar, typename rchar>
3511cb0ef41Sopenharmony_ciinline int CompareCharsUnsigned(const lchar* lhs, const rchar* rhs,
3521cb0ef41Sopenharmony_ci                                size_t chars) {
3531cb0ef41Sopenharmony_ci  STATIC_ASSERT(std::is_unsigned<lchar>::value);
3541cb0ef41Sopenharmony_ci  STATIC_ASSERT(std::is_unsigned<rchar>::value);
3551cb0ef41Sopenharmony_ci  if (sizeof(*lhs) == sizeof(char) && sizeof(*rhs) == sizeof(char)) {
3561cb0ef41Sopenharmony_ci    // memcmp compares byte-by-byte, yielding wrong results for two-byte
3571cb0ef41Sopenharmony_ci    // strings on little-endian systems.
3581cb0ef41Sopenharmony_ci    return memcmp(lhs, rhs, chars);
3591cb0ef41Sopenharmony_ci  }
3601cb0ef41Sopenharmony_ci  for (const lchar* limit = lhs + chars; lhs < limit; ++lhs, ++rhs) {
3611cb0ef41Sopenharmony_ci    int r = static_cast<int>(*lhs) - static_cast<int>(*rhs);
3621cb0ef41Sopenharmony_ci    if (r != 0) return r;
3631cb0ef41Sopenharmony_ci  }
3641cb0ef41Sopenharmony_ci  return 0;
3651cb0ef41Sopenharmony_ci}
3661cb0ef41Sopenharmony_ci
3671cb0ef41Sopenharmony_citemplate <typename lchar, typename rchar>
3681cb0ef41Sopenharmony_ciinline int CompareChars(const lchar* lhs, const rchar* rhs, size_t chars) {
3691cb0ef41Sopenharmony_ci  using ulchar = typename std::make_unsigned<lchar>::type;
3701cb0ef41Sopenharmony_ci  using urchar = typename std::make_unsigned<rchar>::type;
3711cb0ef41Sopenharmony_ci  return CompareCharsUnsigned(reinterpret_cast<const ulchar*>(lhs),
3721cb0ef41Sopenharmony_ci                              reinterpret_cast<const urchar*>(rhs), chars);
3731cb0ef41Sopenharmony_ci}
3741cb0ef41Sopenharmony_ci
3751cb0ef41Sopenharmony_ci// Calculate 10^exponent.
3761cb0ef41Sopenharmony_ciinline int TenToThe(int exponent) {
3771cb0ef41Sopenharmony_ci  DCHECK_LE(exponent, 9);
3781cb0ef41Sopenharmony_ci  DCHECK_GE(exponent, 1);
3791cb0ef41Sopenharmony_ci  int answer = 10;
3801cb0ef41Sopenharmony_ci  for (int i = 1; i < exponent; i++) answer *= 10;
3811cb0ef41Sopenharmony_ci  return answer;
3821cb0ef41Sopenharmony_ci}
3831cb0ef41Sopenharmony_ci
3841cb0ef41Sopenharmony_ci// Bit field extraction.
3851cb0ef41Sopenharmony_ciinline uint32_t unsigned_bitextract_32(int msb, int lsb, uint32_t x) {
3861cb0ef41Sopenharmony_ci  return (x >> lsb) & ((1 << (1 + msb - lsb)) - 1);
3871cb0ef41Sopenharmony_ci}
3881cb0ef41Sopenharmony_ci
3891cb0ef41Sopenharmony_ciinline uint64_t unsigned_bitextract_64(int msb, int lsb, uint64_t x) {
3901cb0ef41Sopenharmony_ci  return (x >> lsb) & ((static_cast<uint64_t>(1) << (1 + msb - lsb)) - 1);
3911cb0ef41Sopenharmony_ci}
3921cb0ef41Sopenharmony_ci
3931cb0ef41Sopenharmony_ciinline int32_t signed_bitextract_32(int msb, int lsb, uint32_t x) {
3941cb0ef41Sopenharmony_ci  return static_cast<int32_t>(x << (31 - msb)) >> (lsb + 31 - msb);
3951cb0ef41Sopenharmony_ci}
3961cb0ef41Sopenharmony_ci
3971cb0ef41Sopenharmony_ci// Check number width.
3981cb0ef41Sopenharmony_ciinline bool is_intn(int64_t x, unsigned n) {
3991cb0ef41Sopenharmony_ci  DCHECK((0 < n) && (n < 64));
4001cb0ef41Sopenharmony_ci  int64_t limit = static_cast<int64_t>(1) << (n - 1);
4011cb0ef41Sopenharmony_ci  return (-limit <= x) && (x < limit);
4021cb0ef41Sopenharmony_ci}
4031cb0ef41Sopenharmony_ci
4041cb0ef41Sopenharmony_ciinline bool is_uintn(int64_t x, unsigned n) {
4051cb0ef41Sopenharmony_ci  DCHECK((0 < n) && (n < (sizeof(x) * kBitsPerByte)));
4061cb0ef41Sopenharmony_ci  return !(x >> n);
4071cb0ef41Sopenharmony_ci}
4081cb0ef41Sopenharmony_ci
4091cb0ef41Sopenharmony_citemplate <class T>
4101cb0ef41Sopenharmony_ciinline T truncate_to_intn(T x, unsigned n) {
4111cb0ef41Sopenharmony_ci  DCHECK((0 < n) && (n < (sizeof(x) * kBitsPerByte)));
4121cb0ef41Sopenharmony_ci  return (x & ((static_cast<T>(1) << n) - 1));
4131cb0ef41Sopenharmony_ci}
4141cb0ef41Sopenharmony_ci
4151cb0ef41Sopenharmony_ci// clang-format off
4161cb0ef41Sopenharmony_ci#define INT_1_TO_63_LIST(V)                                   \
4171cb0ef41Sopenharmony_ci  V(1) V(2) V(3) V(4) V(5) V(6) V(7) V(8) V(9) V(10)          \
4181cb0ef41Sopenharmony_ci  V(11) V(12) V(13) V(14) V(15) V(16) V(17) V(18) V(19) V(20) \
4191cb0ef41Sopenharmony_ci  V(21) V(22) V(23) V(24) V(25) V(26) V(27) V(28) V(29) V(30) \
4201cb0ef41Sopenharmony_ci  V(31) V(32) V(33) V(34) V(35) V(36) V(37) V(38) V(39) V(40) \
4211cb0ef41Sopenharmony_ci  V(41) V(42) V(43) V(44) V(45) V(46) V(47) V(48) V(49) V(50) \
4221cb0ef41Sopenharmony_ci  V(51) V(52) V(53) V(54) V(55) V(56) V(57) V(58) V(59) V(60) \
4231cb0ef41Sopenharmony_ci  V(61) V(62) V(63)
4241cb0ef41Sopenharmony_ci// clang-format on
4251cb0ef41Sopenharmony_ci
4261cb0ef41Sopenharmony_ci#define DECLARE_IS_INT_N(N) \
4271cb0ef41Sopenharmony_ci  inline bool is_int##N(int64_t x) { return is_intn(x, N); }
4281cb0ef41Sopenharmony_ci#define DECLARE_IS_UINT_N(N)    \
4291cb0ef41Sopenharmony_ci  template <class T>            \
4301cb0ef41Sopenharmony_ci  inline bool is_uint##N(T x) { \
4311cb0ef41Sopenharmony_ci    return is_uintn(x, N);      \
4321cb0ef41Sopenharmony_ci  }
4331cb0ef41Sopenharmony_ci#define DECLARE_TRUNCATE_TO_INT_N(N) \
4341cb0ef41Sopenharmony_ci  template <class T>                 \
4351cb0ef41Sopenharmony_ci  inline T truncate_to_int##N(T x) { \
4361cb0ef41Sopenharmony_ci    return truncate_to_intn(x, N);   \
4371cb0ef41Sopenharmony_ci  }
4381cb0ef41Sopenharmony_ciINT_1_TO_63_LIST(DECLARE_IS_INT_N)
4391cb0ef41Sopenharmony_ciINT_1_TO_63_LIST(DECLARE_IS_UINT_N)
4401cb0ef41Sopenharmony_ciINT_1_TO_63_LIST(DECLARE_TRUNCATE_TO_INT_N)
4411cb0ef41Sopenharmony_ci#undef DECLARE_IS_INT_N
4421cb0ef41Sopenharmony_ci#undef DECLARE_IS_UINT_N
4431cb0ef41Sopenharmony_ci#undef DECLARE_TRUNCATE_TO_INT_N
4441cb0ef41Sopenharmony_ci
4451cb0ef41Sopenharmony_ci// clang-format off
4461cb0ef41Sopenharmony_ci#define INT_0_TO_127_LIST(V)                                          \
4471cb0ef41Sopenharmony_ciV(0)   V(1)   V(2)   V(3)   V(4)   V(5)   V(6)   V(7)   V(8)   V(9)   \
4481cb0ef41Sopenharmony_ciV(10)  V(11)  V(12)  V(13)  V(14)  V(15)  V(16)  V(17)  V(18)  V(19)  \
4491cb0ef41Sopenharmony_ciV(20)  V(21)  V(22)  V(23)  V(24)  V(25)  V(26)  V(27)  V(28)  V(29)  \
4501cb0ef41Sopenharmony_ciV(30)  V(31)  V(32)  V(33)  V(34)  V(35)  V(36)  V(37)  V(38)  V(39)  \
4511cb0ef41Sopenharmony_ciV(40)  V(41)  V(42)  V(43)  V(44)  V(45)  V(46)  V(47)  V(48)  V(49)  \
4521cb0ef41Sopenharmony_ciV(50)  V(51)  V(52)  V(53)  V(54)  V(55)  V(56)  V(57)  V(58)  V(59)  \
4531cb0ef41Sopenharmony_ciV(60)  V(61)  V(62)  V(63)  V(64)  V(65)  V(66)  V(67)  V(68)  V(69)  \
4541cb0ef41Sopenharmony_ciV(70)  V(71)  V(72)  V(73)  V(74)  V(75)  V(76)  V(77)  V(78)  V(79)  \
4551cb0ef41Sopenharmony_ciV(80)  V(81)  V(82)  V(83)  V(84)  V(85)  V(86)  V(87)  V(88)  V(89)  \
4561cb0ef41Sopenharmony_ciV(90)  V(91)  V(92)  V(93)  V(94)  V(95)  V(96)  V(97)  V(98)  V(99)  \
4571cb0ef41Sopenharmony_ciV(100) V(101) V(102) V(103) V(104) V(105) V(106) V(107) V(108) V(109) \
4581cb0ef41Sopenharmony_ciV(110) V(111) V(112) V(113) V(114) V(115) V(116) V(117) V(118) V(119) \
4591cb0ef41Sopenharmony_ciV(120) V(121) V(122) V(123) V(124) V(125) V(126) V(127)
4601cb0ef41Sopenharmony_ci// clang-format on
4611cb0ef41Sopenharmony_ci
4621cb0ef41Sopenharmony_ciclass FeedbackSlot {
4631cb0ef41Sopenharmony_ci public:
4641cb0ef41Sopenharmony_ci  FeedbackSlot() : id_(kInvalidSlot) {}
4651cb0ef41Sopenharmony_ci  explicit FeedbackSlot(int id) : id_(id) {}
4661cb0ef41Sopenharmony_ci
4671cb0ef41Sopenharmony_ci  int ToInt() const { return id_; }
4681cb0ef41Sopenharmony_ci
4691cb0ef41Sopenharmony_ci  static FeedbackSlot Invalid() { return FeedbackSlot(); }
4701cb0ef41Sopenharmony_ci  bool IsInvalid() const { return id_ == kInvalidSlot; }
4711cb0ef41Sopenharmony_ci
4721cb0ef41Sopenharmony_ci  bool operator==(FeedbackSlot that) const { return this->id_ == that.id_; }
4731cb0ef41Sopenharmony_ci  bool operator!=(FeedbackSlot that) const { return !(*this == that); }
4741cb0ef41Sopenharmony_ci
4751cb0ef41Sopenharmony_ci  friend size_t hash_value(FeedbackSlot slot) { return slot.ToInt(); }
4761cb0ef41Sopenharmony_ci  V8_EXPORT_PRIVATE friend std::ostream& operator<<(std::ostream& os,
4771cb0ef41Sopenharmony_ci                                                    FeedbackSlot);
4781cb0ef41Sopenharmony_ci
4791cb0ef41Sopenharmony_ci  FeedbackSlot WithOffset(int offset) const {
4801cb0ef41Sopenharmony_ci    return FeedbackSlot(id_ + offset);
4811cb0ef41Sopenharmony_ci  }
4821cb0ef41Sopenharmony_ci
4831cb0ef41Sopenharmony_ci private:
4841cb0ef41Sopenharmony_ci  static const int kInvalidSlot = -1;
4851cb0ef41Sopenharmony_ci
4861cb0ef41Sopenharmony_ci  int id_;
4871cb0ef41Sopenharmony_ci};
4881cb0ef41Sopenharmony_ci
4891cb0ef41Sopenharmony_ciV8_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& os, FeedbackSlot);
4901cb0ef41Sopenharmony_ci
4911cb0ef41Sopenharmony_ciclass BytecodeOffset {
4921cb0ef41Sopenharmony_ci public:
4931cb0ef41Sopenharmony_ci  explicit constexpr BytecodeOffset(int id) : id_(id) {}
4941cb0ef41Sopenharmony_ci  constexpr int ToInt() const { return id_; }
4951cb0ef41Sopenharmony_ci
4961cb0ef41Sopenharmony_ci  static constexpr BytecodeOffset None() { return BytecodeOffset(kNoneId); }
4971cb0ef41Sopenharmony_ci
4981cb0ef41Sopenharmony_ci  // Special bailout id support for deopting into the {JSConstructStub} stub.
4991cb0ef41Sopenharmony_ci  // The following hard-coded deoptimization points are supported by the stub:
5001cb0ef41Sopenharmony_ci  //  - {ConstructStubCreate} maps to {construct_stub_create_deopt_pc_offset}.
5011cb0ef41Sopenharmony_ci  //  - {ConstructStubInvoke} maps to {construct_stub_invoke_deopt_pc_offset}.
5021cb0ef41Sopenharmony_ci  static BytecodeOffset ConstructStubCreate() { return BytecodeOffset(1); }
5031cb0ef41Sopenharmony_ci  static BytecodeOffset ConstructStubInvoke() { return BytecodeOffset(2); }
5041cb0ef41Sopenharmony_ci  bool IsValidForConstructStub() const {
5051cb0ef41Sopenharmony_ci    return id_ == ConstructStubCreate().ToInt() ||
5061cb0ef41Sopenharmony_ci           id_ == ConstructStubInvoke().ToInt();
5071cb0ef41Sopenharmony_ci  }
5081cb0ef41Sopenharmony_ci
5091cb0ef41Sopenharmony_ci  constexpr bool IsNone() const { return id_ == kNoneId; }
5101cb0ef41Sopenharmony_ci  bool operator==(const BytecodeOffset& other) const {
5111cb0ef41Sopenharmony_ci    return id_ == other.id_;
5121cb0ef41Sopenharmony_ci  }
5131cb0ef41Sopenharmony_ci  bool operator!=(const BytecodeOffset& other) const {
5141cb0ef41Sopenharmony_ci    return id_ != other.id_;
5151cb0ef41Sopenharmony_ci  }
5161cb0ef41Sopenharmony_ci  friend size_t hash_value(BytecodeOffset);
5171cb0ef41Sopenharmony_ci  V8_EXPORT_PRIVATE friend std::ostream& operator<<(std::ostream&,
5181cb0ef41Sopenharmony_ci                                                    BytecodeOffset);
5191cb0ef41Sopenharmony_ci
5201cb0ef41Sopenharmony_ci private:
5211cb0ef41Sopenharmony_ci  friend class Builtins;
5221cb0ef41Sopenharmony_ci
5231cb0ef41Sopenharmony_ci  static const int kNoneId = -1;
5241cb0ef41Sopenharmony_ci
5251cb0ef41Sopenharmony_ci  // Using 0 could disguise errors.
5261cb0ef41Sopenharmony_ci  // Builtin continuations bailout ids start here. If you need to add a
5271cb0ef41Sopenharmony_ci  // non-builtin BytecodeOffset, add it before this id so that this Id has the
5281cb0ef41Sopenharmony_ci  // highest number.
5291cb0ef41Sopenharmony_ci  static const int kFirstBuiltinContinuationId = 1;
5301cb0ef41Sopenharmony_ci
5311cb0ef41Sopenharmony_ci  int id_;
5321cb0ef41Sopenharmony_ci};
5331cb0ef41Sopenharmony_ci
5341cb0ef41Sopenharmony_ci// ----------------------------------------------------------------------------
5351cb0ef41Sopenharmony_ci// I/O support.
5361cb0ef41Sopenharmony_ci
5371cb0ef41Sopenharmony_ci// Our version of printf().
5381cb0ef41Sopenharmony_ciV8_EXPORT_PRIVATE void PRINTF_FORMAT(1, 2) PrintF(const char* format, ...);
5391cb0ef41Sopenharmony_ciV8_EXPORT_PRIVATE void PRINTF_FORMAT(2, 3)
5401cb0ef41Sopenharmony_ci    PrintF(FILE* out, const char* format, ...);
5411cb0ef41Sopenharmony_ci
5421cb0ef41Sopenharmony_ci// Prepends the current process ID to the output.
5431cb0ef41Sopenharmony_civoid PRINTF_FORMAT(1, 2) PrintPID(const char* format, ...);
5441cb0ef41Sopenharmony_ci
5451cb0ef41Sopenharmony_ci// Prepends the current process ID and given isolate pointer to the output.
5461cb0ef41Sopenharmony_civoid PRINTF_FORMAT(2, 3) PrintIsolate(void* isolate, const char* format, ...);
5471cb0ef41Sopenharmony_ci
5481cb0ef41Sopenharmony_ci// Read a line of characters after printing the prompt to stdout. The resulting
5491cb0ef41Sopenharmony_ci// char* needs to be disposed off with DeleteArray by the caller.
5501cb0ef41Sopenharmony_cichar* ReadLine(const char* prompt);
5511cb0ef41Sopenharmony_ci
5521cb0ef41Sopenharmony_ci// Write size chars from str to the file given by filename.
5531cb0ef41Sopenharmony_ci// The file is overwritten. Returns the number of chars written.
5541cb0ef41Sopenharmony_ciint WriteChars(const char* filename, const char* str, int size,
5551cb0ef41Sopenharmony_ci               bool verbose = true);
5561cb0ef41Sopenharmony_ci
5571cb0ef41Sopenharmony_ci// Write size bytes to the file given by filename.
5581cb0ef41Sopenharmony_ci// The file is overwritten. Returns the number of bytes written.
5591cb0ef41Sopenharmony_ciint WriteBytes(const char* filename, const byte* bytes, int size,
5601cb0ef41Sopenharmony_ci               bool verbose = true);
5611cb0ef41Sopenharmony_ci
5621cb0ef41Sopenharmony_ci// Simple support to read a file into std::string.
5631cb0ef41Sopenharmony_ci// On return, *exits tells whether the file existed.
5641cb0ef41Sopenharmony_ciV8_EXPORT_PRIVATE std::string ReadFile(const char* filename, bool* exists,
5651cb0ef41Sopenharmony_ci                                       bool verbose = true);
5661cb0ef41Sopenharmony_ciV8_EXPORT_PRIVATE std::string ReadFile(FILE* file, bool* exists,
5671cb0ef41Sopenharmony_ci                                       bool verbose = true);
5681cb0ef41Sopenharmony_ci
5691cb0ef41Sopenharmony_cibool DoubleToBoolean(double d);
5701cb0ef41Sopenharmony_ci
5711cb0ef41Sopenharmony_citemplate <typename Char>
5721cb0ef41Sopenharmony_cibool TryAddIndexChar(uint32_t* index, Char c);
5731cb0ef41Sopenharmony_ci
5741cb0ef41Sopenharmony_cienum ToIndexMode { kToArrayIndex, kToIntegerIndex };
5751cb0ef41Sopenharmony_ci
5761cb0ef41Sopenharmony_ci// {index_t} is meant to be {uint32_t} or {size_t}.
5771cb0ef41Sopenharmony_citemplate <typename Stream, typename index_t,
5781cb0ef41Sopenharmony_ci          enum ToIndexMode mode = kToArrayIndex>
5791cb0ef41Sopenharmony_cibool StringToIndex(Stream* stream, index_t* index);
5801cb0ef41Sopenharmony_ci
5811cb0ef41Sopenharmony_ci// Returns the current stack top. Works correctly with ASAN and SafeStack.
5821cb0ef41Sopenharmony_ci// GetCurrentStackPosition() should not be inlined, because it works on stack
5831cb0ef41Sopenharmony_ci// frames if it were inlined into a function with a huge stack frame it would
5841cb0ef41Sopenharmony_ci// return an address significantly above the actual current stack position.
5851cb0ef41Sopenharmony_ciV8_EXPORT_PRIVATE V8_NOINLINE uintptr_t GetCurrentStackPosition();
5861cb0ef41Sopenharmony_ci
5871cb0ef41Sopenharmony_cistatic inline uint16_t ByteReverse16(uint16_t value) {
5881cb0ef41Sopenharmony_ci#if V8_HAS_BUILTIN_BSWAP16
5891cb0ef41Sopenharmony_ci  return __builtin_bswap16(value);
5901cb0ef41Sopenharmony_ci#else
5911cb0ef41Sopenharmony_ci  return value << 8 | (value >> 8 & 0x00FF);
5921cb0ef41Sopenharmony_ci#endif
5931cb0ef41Sopenharmony_ci}
5941cb0ef41Sopenharmony_ci
5951cb0ef41Sopenharmony_cistatic inline uint32_t ByteReverse32(uint32_t value) {
5961cb0ef41Sopenharmony_ci#if V8_HAS_BUILTIN_BSWAP32
5971cb0ef41Sopenharmony_ci  return __builtin_bswap32(value);
5981cb0ef41Sopenharmony_ci#else
5991cb0ef41Sopenharmony_ci  return value << 24 | ((value << 8) & 0x00FF0000) |
6001cb0ef41Sopenharmony_ci         ((value >> 8) & 0x0000FF00) | ((value >> 24) & 0x00000FF);
6011cb0ef41Sopenharmony_ci#endif
6021cb0ef41Sopenharmony_ci}
6031cb0ef41Sopenharmony_ci
6041cb0ef41Sopenharmony_cistatic inline uint64_t ByteReverse64(uint64_t value) {
6051cb0ef41Sopenharmony_ci#if V8_HAS_BUILTIN_BSWAP64
6061cb0ef41Sopenharmony_ci  return __builtin_bswap64(value);
6071cb0ef41Sopenharmony_ci#else
6081cb0ef41Sopenharmony_ci  size_t bits_of_v = sizeof(value) * kBitsPerByte;
6091cb0ef41Sopenharmony_ci  return value << (bits_of_v - 8) |
6101cb0ef41Sopenharmony_ci         ((value << (bits_of_v - 24)) & 0x00FF000000000000) |
6111cb0ef41Sopenharmony_ci         ((value << (bits_of_v - 40)) & 0x0000FF0000000000) |
6121cb0ef41Sopenharmony_ci         ((value << (bits_of_v - 56)) & 0x000000FF00000000) |
6131cb0ef41Sopenharmony_ci         ((value >> (bits_of_v - 56)) & 0x00000000FF000000) |
6141cb0ef41Sopenharmony_ci         ((value >> (bits_of_v - 40)) & 0x0000000000FF0000) |
6151cb0ef41Sopenharmony_ci         ((value >> (bits_of_v - 24)) & 0x000000000000FF00) |
6161cb0ef41Sopenharmony_ci         ((value >> (bits_of_v - 8)) & 0x00000000000000FF);
6171cb0ef41Sopenharmony_ci#endif
6181cb0ef41Sopenharmony_ci}
6191cb0ef41Sopenharmony_ci
6201cb0ef41Sopenharmony_citemplate <typename V>
6211cb0ef41Sopenharmony_cistatic inline V ByteReverse(V value) {
6221cb0ef41Sopenharmony_ci  size_t size_of_v = sizeof(value);
6231cb0ef41Sopenharmony_ci  switch (size_of_v) {
6241cb0ef41Sopenharmony_ci    case 1:
6251cb0ef41Sopenharmony_ci      return value;
6261cb0ef41Sopenharmony_ci    case 2:
6271cb0ef41Sopenharmony_ci      return static_cast<V>(ByteReverse16(static_cast<uint16_t>(value)));
6281cb0ef41Sopenharmony_ci    case 4:
6291cb0ef41Sopenharmony_ci      return static_cast<V>(ByteReverse32(static_cast<uint32_t>(value)));
6301cb0ef41Sopenharmony_ci    case 8:
6311cb0ef41Sopenharmony_ci      return static_cast<V>(ByteReverse64(static_cast<uint64_t>(value)));
6321cb0ef41Sopenharmony_ci    default:
6331cb0ef41Sopenharmony_ci      UNREACHABLE();
6341cb0ef41Sopenharmony_ci  }
6351cb0ef41Sopenharmony_ci}
6361cb0ef41Sopenharmony_ci
6371cb0ef41Sopenharmony_ci#if V8_OS_AIX
6381cb0ef41Sopenharmony_ci// glibc on aix has a bug when using ceil, trunc or nearbyint:
6391cb0ef41Sopenharmony_ci// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=97086
6401cb0ef41Sopenharmony_citemplate <typename T>
6411cb0ef41Sopenharmony_ciT FpOpWorkaround(T input, T value) {
6421cb0ef41Sopenharmony_ci  if (/*if -*/ std::signbit(input) && value == 0.0 &&
6431cb0ef41Sopenharmony_ci      /*if +*/ !std::signbit(value)) {
6441cb0ef41Sopenharmony_ci    return -0.0;
6451cb0ef41Sopenharmony_ci  }
6461cb0ef41Sopenharmony_ci  return value;
6471cb0ef41Sopenharmony_ci}
6481cb0ef41Sopenharmony_ci#endif
6491cb0ef41Sopenharmony_ci
6501cb0ef41Sopenharmony_ciV8_EXPORT_PRIVATE bool PassesFilter(base::Vector<const char> name,
6511cb0ef41Sopenharmony_ci                                    base::Vector<const char> filter);
6521cb0ef41Sopenharmony_ci
6531cb0ef41Sopenharmony_ci// Zap the specified area with a specific byte pattern. This currently defaults
6541cb0ef41Sopenharmony_ci// to int3 on x64 and ia32. On other architectures this will produce unspecified
6551cb0ef41Sopenharmony_ci// instruction sequences.
6561cb0ef41Sopenharmony_ci// TODO(jgruber): Better support for other architectures.
6571cb0ef41Sopenharmony_ciV8_INLINE void ZapCode(Address addr, size_t size_in_bytes) {
6581cb0ef41Sopenharmony_ci  static constexpr int kZapByte = 0xCC;
6591cb0ef41Sopenharmony_ci  std::memset(reinterpret_cast<void*>(addr), kZapByte, size_in_bytes);
6601cb0ef41Sopenharmony_ci}
6611cb0ef41Sopenharmony_ci
6621cb0ef41Sopenharmony_ciinline bool RoundUpToPageSize(size_t byte_length, size_t page_size,
6631cb0ef41Sopenharmony_ci                              size_t max_allowed_byte_length, size_t* pages) {
6641cb0ef41Sopenharmony_ci  size_t bytes_wanted = RoundUp(byte_length, page_size);
6651cb0ef41Sopenharmony_ci  if (bytes_wanted > max_allowed_byte_length) {
6661cb0ef41Sopenharmony_ci    return false;
6671cb0ef41Sopenharmony_ci  }
6681cb0ef41Sopenharmony_ci  *pages = bytes_wanted / page_size;
6691cb0ef41Sopenharmony_ci  return true;
6701cb0ef41Sopenharmony_ci}
6711cb0ef41Sopenharmony_ci
6721cb0ef41Sopenharmony_ci}  // namespace internal
6731cb0ef41Sopenharmony_ci}  // namespace v8
6741cb0ef41Sopenharmony_ci
6751cb0ef41Sopenharmony_ci#endif  // V8_UTILS_UTILS_H_
676