summaryrefslogtreecommitdiff
path: root/chromium/v8/src/base
diff options
context:
space:
mode:
Diffstat (limited to 'chromium/v8/src/base')
-rw-r--r--chromium/v8/src/base/bit-field.h4
-rw-r--r--chromium/v8/src/base/bits.h29
-rw-r--r--chromium/v8/src/base/bounds.h8
-rw-r--r--chromium/v8/src/base/cpu.cc67
-rw-r--r--chromium/v8/src/base/cpu.h2
-rw-r--r--chromium/v8/src/base/enum-set.h4
-rw-r--r--chromium/v8/src/base/iterator.h3
-rw-r--r--chromium/v8/src/base/logging.h6
-rw-r--r--chromium/v8/src/base/macros.h14
-rw-r--r--chromium/v8/src/base/optional.h24
-rw-r--r--chromium/v8/src/base/platform/platform-posix.cc8
-rw-r--r--chromium/v8/src/base/platform/platform-solaris.cc18
-rw-r--r--chromium/v8/src/base/platform/time.h14
-rw-r--r--chromium/v8/src/base/template-utils.h14
14 files changed, 160 insertions, 55 deletions
diff --git a/chromium/v8/src/base/bit-field.h b/chromium/v8/src/base/bit-field.h
index 9cebac32de4..ca5fb459210 100644
--- a/chromium/v8/src/base/bit-field.h
+++ b/chromium/v8/src/base/bit-field.h
@@ -52,9 +52,7 @@ class BitField final {
// Returns a type U with the bit field value encoded.
static constexpr U encode(T value) {
-#if V8_HAS_CXX14_CONSTEXPR
- DCHECK(is_valid(value));
-#endif
+ CONSTEXPR_DCHECK(is_valid(value));
return static_cast<U>(value) << kShift;
}
diff --git a/chromium/v8/src/base/bits.h b/chromium/v8/src/base/bits.h
index b74b98e1069..cf4b77fa186 100644
--- a/chromium/v8/src/base/bits.h
+++ b/chromium/v8/src/base/bits.h
@@ -32,22 +32,27 @@ constexpr inline
return sizeof(T) == 8 ? __builtin_popcountll(static_cast<uint64_t>(value))
: __builtin_popcount(static_cast<uint32_t>(value));
#else
+ // Fall back to divide-and-conquer popcount (see "Hacker's Delight" by Henry
+ // S. Warren, Jr.), chapter 5-1.
constexpr uint64_t mask[] = {0x5555555555555555, 0x3333333333333333,
0x0f0f0f0f0f0f0f0f};
- // Start with 1 bit wide buckets of [0,1].
+ // Start with 64 buckets of 1 bits, holding values from [0,1].
value = ((value >> 1) & mask[0]) + (value & mask[0]);
- // Having 2 bit wide buckets of [0,2] now.
+ // Having 32 buckets of 2 bits, holding values from [0,2] now.
value = ((value >> 2) & mask[1]) + (value & mask[1]);
- // Having 4 bit wide buckets of [0,4] now.
- value = (value >> 4) + value;
- // Having 4 bit wide buckets of [0,8] now.
- if (sizeof(T) > 1)
- value = ((value >> (sizeof(T) > 1 ? 8 : 0)) & mask[2]) + (value & mask[2]);
- // Having 8 bit wide buckets of [0,16] now.
+ // Having 16 buckets of 4 bits, holding values from [0,4] now.
+ value = ((value >> 4) & mask[2]) + (value & mask[2]);
+ // Having 8 buckets of 8 bits, holding values from [0,8] now.
+ // From this point on, the buckets are bigger than the number of bits
+ // required to hold the values, and the buckets are bigger the maximum
+ // result, so there's no need to mask value anymore, since there's no
+ // more risk of overflow between buckets.
+ if (sizeof(T) > 1) value = (value >> (sizeof(T) > 1 ? 8 : 0)) + value;
+ // Having 4 buckets of 16 bits, holding values from [0,16] now.
if (sizeof(T) > 2) value = (value >> (sizeof(T) > 2 ? 16 : 0)) + value;
- // Having 8 bit wide buckets of [0,32] now.
+ // Having 2 buckets of 32 bits, holding values from [0,32] now.
if (sizeof(T) > 4) value = (value >> (sizeof(T) > 4 ? 32 : 0)) + value;
- // Having 8 bit wide buckets of [0,64] now.
+ // Having 1 buckets of 64 bits, holding values from [0,64] now.
return static_cast<unsigned>(value & 0xff);
#endif
}
@@ -140,9 +145,7 @@ constexpr inline bool IsPowerOfTwo(T value) {
template <typename T,
typename = typename std::enable_if<std::is_integral<T>::value>::type>
inline constexpr int WhichPowerOfTwo(T value) {
-#if V8_HAS_CXX14_CONSTEXPR
- DCHECK(IsPowerOfTwo(value));
-#endif
+ CONSTEXPR_DCHECK(IsPowerOfTwo(value));
#if V8_HAS_BUILTIN_CTZ
STATIC_ASSERT(sizeof(T) <= 8);
return sizeof(T) == 8 ? __builtin_ctzll(static_cast<uint64_t>(value))
diff --git a/chromium/v8/src/base/bounds.h b/chromium/v8/src/base/bounds.h
index 236e29b7ccd..fb8c968d660 100644
--- a/chromium/v8/src/base/bounds.h
+++ b/chromium/v8/src/base/bounds.h
@@ -15,9 +15,7 @@ namespace base {
// branch.
template <typename T, typename U>
inline constexpr bool IsInRange(T value, U lower_limit, U higher_limit) {
-#if V8_HAS_CXX14_CONSTEXPR
- DCHECK_LE(lower_limit, higher_limit);
-#endif
+ CONSTEXPR_DCHECK(lower_limit <= higher_limit);
STATIC_ASSERT(sizeof(U) <= sizeof(T));
using unsigned_T = typename std::make_unsigned<T>::type;
// Use static_cast to support enum classes.
@@ -29,7 +27,9 @@ inline constexpr bool IsInRange(T value, U lower_limit, U higher_limit) {
// Checks if [index, index+length) is in range [0, max). Note that this check
// works even if {index+length} would wrap around.
-inline constexpr bool IsInBounds(size_t index, size_t length, size_t max) {
+template <typename T,
+ typename = typename std::enable_if<std::is_unsigned<T>::value>::type>
+inline constexpr bool IsInBounds(T index, T length, T max) {
return length <= max && index <= (max - length);
}
diff --git a/chromium/v8/src/base/cpu.cc b/chromium/v8/src/base/cpu.cc
index bbdae525e30..bae1afe7d1d 100644
--- a/chromium/v8/src/base/cpu.cc
+++ b/chromium/v8/src/base/cpu.cc
@@ -75,7 +75,8 @@ static V8_INLINE void __cpuid(int cpu_info[4], int info_type) {
#endif // !V8_LIBC_MSVCRT
-#elif V8_HOST_ARCH_ARM || V8_HOST_ARCH_MIPS || V8_HOST_ARCH_MIPS64
+#elif V8_HOST_ARCH_ARM || V8_HOST_ARCH_ARM64 || V8_HOST_ARCH_MIPS || \
+ V8_HOST_ARCH_MIPS64
#if V8_OS_LINUX
@@ -108,6 +109,51 @@ static V8_INLINE void __cpuid(int cpu_info[4], int info_type) {
#define HWCAP_IDIV (HWCAP_IDIVA | HWCAP_IDIVT)
#define HWCAP_LPAE (1 << 20)
+#endif // V8_HOST_ARCH_ARM
+
+#if V8_HOST_ARCH_ARM64
+
+// See <uapi/asm/hwcap.h> kernel header.
+/*
+ * HWCAP flags - for elf_hwcap (in kernel) and AT_HWCAP
+ */
+#define HWCAP_FP (1 << 0)
+#define HWCAP_ASIMD (1 << 1)
+#define HWCAP_EVTSTRM (1 << 2)
+#define HWCAP_AES (1 << 3)
+#define HWCAP_PMULL (1 << 4)
+#define HWCAP_SHA1 (1 << 5)
+#define HWCAP_SHA2 (1 << 6)
+#define HWCAP_CRC32 (1 << 7)
+#define HWCAP_ATOMICS (1 << 8)
+#define HWCAP_FPHP (1 << 9)
+#define HWCAP_ASIMDHP (1 << 10)
+#define HWCAP_CPUID (1 << 11)
+#define HWCAP_ASIMDRDM (1 << 12)
+#define HWCAP_JSCVT (1 << 13)
+#define HWCAP_FCMA (1 << 14)
+#define HWCAP_LRCPC (1 << 15)
+#define HWCAP_DCPOP (1 << 16)
+#define HWCAP_SHA3 (1 << 17)
+#define HWCAP_SM3 (1 << 18)
+#define HWCAP_SM4 (1 << 19)
+#define HWCAP_ASIMDDP (1 << 20)
+#define HWCAP_SHA512 (1 << 21)
+#define HWCAP_SVE (1 << 22)
+#define HWCAP_ASIMDFHM (1 << 23)
+#define HWCAP_DIT (1 << 24)
+#define HWCAP_USCAT (1 << 25)
+#define HWCAP_ILRCPC (1 << 26)
+#define HWCAP_FLAGM (1 << 27)
+#define HWCAP_SSBS (1 << 28)
+#define HWCAP_SB (1 << 29)
+#define HWCAP_PACA (1 << 30)
+#define HWCAP_PACG (1UL << 31)
+
+#endif // V8_HOST_ARCH_ARM64
+
+#if V8_HOST_ARCH_ARM || V8_HOST_ARCH_ARM64
+
static uint32_t ReadELFHWCaps() {
uint32_t result = 0;
#if V8_GLIBC_PREREQ(2, 16)
@@ -136,7 +182,7 @@ static uint32_t ReadELFHWCaps() {
return result;
}
-#endif // V8_HOST_ARCH_ARM
+#endif // V8_HOST_ARCH_ARM || V8_HOST_ARCH_ARM64
#if V8_HOST_ARCH_MIPS
int __detect_fp64_mode(void) {
@@ -298,7 +344,8 @@ static bool HasListItem(const char* list, const char* item) {
#endif // V8_OS_LINUX
-#endif // V8_HOST_ARCH_ARM || V8_HOST_ARCH_MIPS || V8_HOST_ARCH_MIPS64
+#endif // V8_HOST_ARCH_ARM || V8_HOST_ARCH_ARM64 ||
+ // V8_HOST_ARCH_MIPS || V8_HOST_ARCH_MIPS64
CPU::CPU()
: stepping_(0),
@@ -337,6 +384,7 @@ CPU::CPU()
has_vfp_(false),
has_vfp3_(false),
has_vfp3_d32_(false),
+ has_jscvt_(false),
is_fp64_mode_(false),
has_non_stop_time_stamp_counter_(false),
has_msa_(false) {
@@ -609,6 +657,19 @@ CPU::CPU()
// Windows makes high-resolution thread timing information available in
// user-space.
has_non_stop_time_stamp_counter_ = true;
+
+#elif V8_OS_LINUX
+ // Try to extract the list of CPU features from ELF hwcaps.
+ uint32_t hwcaps = ReadELFHWCaps();
+ if (hwcaps != 0) {
+ has_jscvt_ = (hwcaps & HWCAP_JSCVT) != 0;
+ } else {
+ // Try to fallback to "Features" CPUInfo field
+ CPUInfo cpu_info;
+ char* features = cpu_info.ExtractField("Features");
+ has_jscvt_ = HasListItem(features, "jscvt");
+ delete[] features;
+ }
#endif // V8_OS_WIN
#elif V8_HOST_ARCH_PPC || V8_HOST_ARCH_PPC64
diff --git a/chromium/v8/src/base/cpu.h b/chromium/v8/src/base/cpu.h
index 4b4becfa204..8cec23c8e8e 100644
--- a/chromium/v8/src/base/cpu.h
+++ b/chromium/v8/src/base/cpu.h
@@ -110,6 +110,7 @@ class V8_BASE_EXPORT CPU final {
bool has_vfp() const { return has_vfp_; }
bool has_vfp3() const { return has_vfp3_; }
bool has_vfp3_d32() const { return has_vfp3_d32_; }
+ bool has_jscvt() const { return has_jscvt_; }
// mips features
bool is_fp64_mode() const { return is_fp64_mode_; }
@@ -153,6 +154,7 @@ class V8_BASE_EXPORT CPU final {
bool has_vfp_;
bool has_vfp3_;
bool has_vfp3_d32_;
+ bool has_jscvt_;
bool is_fp64_mode_;
bool has_non_stop_time_stamp_counter_;
bool has_msa_;
diff --git a/chromium/v8/src/base/enum-set.h b/chromium/v8/src/base/enum-set.h
index 927a8f87fe0..2415f1c500b 100644
--- a/chromium/v8/src/base/enum-set.h
+++ b/chromium/v8/src/base/enum-set.h
@@ -63,9 +63,7 @@ class EnumSet {
explicit constexpr EnumSet(T bits) : bits_(bits) {}
static constexpr T Mask(E element) {
-#if V8_HAS_CXX14_CONSTEXPR
- DCHECK_GT(sizeof(T) * 8, static_cast<int>(element));
-#endif
+ CONSTEXPR_DCHECK(sizeof(T) * 8 > static_cast<size_t>(element));
return T{1} << static_cast<typename std::underlying_type<E>::type>(element);
}
diff --git a/chromium/v8/src/base/iterator.h b/chromium/v8/src/base/iterator.h
index 86d4b068d33..0bec8725227 100644
--- a/chromium/v8/src/base/iterator.h
+++ b/chromium/v8/src/base/iterator.h
@@ -36,8 +36,7 @@ class iterator_range {
typename std::iterator_traits<iterator>::difference_type;
iterator_range() : begin_(), end_() {}
- template <typename ForwardIterator1, typename ForwardIterator2>
- iterator_range(ForwardIterator1 begin, ForwardIterator2 end)
+ iterator_range(ForwardIterator begin, ForwardIterator end)
: begin_(begin), end_(end) {}
iterator begin() { return begin_; }
diff --git a/chromium/v8/src/base/logging.h b/chromium/v8/src/base/logging.h
index 790018c98e9..fe39f988225 100644
--- a/chromium/v8/src/base/logging.h
+++ b/chromium/v8/src/base/logging.h
@@ -134,6 +134,12 @@ V8_BASE_EXPORT void SetDcheckFunction(void (*dcheck_Function)(const char*, int,
#endif
+#if V8_HAS_CXX14_CONSTEXPR
+#define CONSTEXPR_DCHECK(cond) DCHECK(cond)
+#else
+#define CONSTEXPR_DCHECK(cond)
+#endif
+
// Define PrintCheckOperand<T> for each T which defines operator<< for ostream.
template <typename T>
typename std::enable_if<
diff --git a/chromium/v8/src/base/macros.h b/chromium/v8/src/base/macros.h
index e22dd00895a..4eb652cae55 100644
--- a/chromium/v8/src/base/macros.h
+++ b/chromium/v8/src/base/macros.h
@@ -171,22 +171,12 @@ V8_INLINE Dest bit_cast(Source const& source) {
#endif
#endif
-// Helper macro to define no_sanitize attributes only with clang.
-#if defined(__clang__) && defined(__has_attribute)
-#if __has_attribute(no_sanitize)
-#define CLANG_NO_SANITIZE(what) __attribute__((no_sanitize(what)))
-#endif
-#endif
-#if !defined(CLANG_NO_SANITIZE)
-#define CLANG_NO_SANITIZE(what)
-#endif
-
// DISABLE_CFI_PERF -- Disable Control Flow Integrity checks for Perf reasons.
-#define DISABLE_CFI_PERF CLANG_NO_SANITIZE("cfi")
+#define DISABLE_CFI_PERF V8_CLANG_NO_SANITIZE("cfi")
// DISABLE_CFI_ICALL -- Disable Control Flow Integrity indirect call checks,
// useful because calls into JITed code can not be CFI verified.
-#define DISABLE_CFI_ICALL CLANG_NO_SANITIZE("cfi-icall")
+#define DISABLE_CFI_ICALL V8_CLANG_NO_SANITIZE("cfi-icall")
#if V8_CC_GNU
#define V8_IMMEDIATE_CRASH() __builtin_trap()
diff --git a/chromium/v8/src/base/optional.h b/chromium/v8/src/base/optional.h
index 6610c7ffc33..3c13e654c80 100644
--- a/chromium/v8/src/base/optional.h
+++ b/chromium/v8/src/base/optional.h
@@ -557,33 +557,33 @@ class OPTIONAL_DECLSPEC_EMPTY_BASES Optional
return *this;
}
- const T* operator->() const {
- DCHECK(storage_.is_populated_);
+ constexpr const T* operator->() const {
+ CONSTEXPR_DCHECK(storage_.is_populated_);
return &storage_.value_;
}
- T* operator->() {
- DCHECK(storage_.is_populated_);
+ constexpr T* operator->() {
+ CONSTEXPR_DCHECK(storage_.is_populated_);
return &storage_.value_;
}
- const T& operator*() const & {
- DCHECK(storage_.is_populated_);
+ constexpr const T& operator*() const& {
+ CONSTEXPR_DCHECK(storage_.is_populated_);
return storage_.value_;
}
- T& operator*() & {
- DCHECK(storage_.is_populated_);
+ constexpr T& operator*() & {
+ CONSTEXPR_DCHECK(storage_.is_populated_);
return storage_.value_;
}
- const T&& operator*() const && {
- DCHECK(storage_.is_populated_);
+ constexpr const T&& operator*() const&& {
+ CONSTEXPR_DCHECK(storage_.is_populated_);
return std::move(storage_.value_);
}
- T&& operator*() && {
- DCHECK(storage_.is_populated_);
+ constexpr T&& operator*() && {
+ CONSTEXPR_DCHECK(storage_.is_populated_);
return std::move(storage_.value_);
}
diff --git a/chromium/v8/src/base/platform/platform-posix.cc b/chromium/v8/src/base/platform/platform-posix.cc
index c3f0b08ddde..238750bab16 100644
--- a/chromium/v8/src/base/platform/platform-posix.cc
+++ b/chromium/v8/src/base/platform/platform-posix.cc
@@ -531,7 +531,7 @@ OS::MemoryMappedFile* OS::MemoryMappedFile::open(const char* name,
OS::MemoryMappedFile* OS::MemoryMappedFile::create(const char* name,
size_t size, void* initial) {
if (FILE* file = fopen(name, "w+")) {
- if (size == 0) return new PosixMemoryMappedFile(file, 0, 0);
+ if (size == 0) return new PosixMemoryMappedFile(file, nullptr, 0);
size_t result = fwrite(initial, 1, size, file);
if (result == size && !ferror(file)) {
void* memory = mmap(OS::GetRandomMmapAddr(), result,
@@ -970,7 +970,8 @@ void Thread::SetThreadLocal(LocalStorageKey key, void* value) {
// pthread_getattr_np used below is non portable (hence the _np suffix). We
// keep this version in POSIX as most Linux-compatible derivatives will
// support it. MacOS and FreeBSD are different here.
-#if !defined(V8_OS_FREEBSD) && !defined(V8_OS_MACOSX) && !defined(_AIX)
+#if !defined(V8_OS_FREEBSD) && !defined(V8_OS_MACOSX) && !defined(_AIX) && \
+ !defined(V8_OS_SOLARIS)
// static
void* Stack::GetStackStart() {
@@ -996,7 +997,8 @@ void* Stack::GetStackStart() {
return nullptr;
}
-#endif // !defined(V8_OS_FREEBSD) && !defined(V8_OS_MACOSX) && !defined(_AIX)
+#endif // !defined(V8_OS_FREEBSD) && !defined(V8_OS_MACOSX) &&
+ // !defined(_AIX) && !defined(V8_OS_SOLARIS)
// static
void* Stack::GetCurrentStackPosition() { return __builtin_frame_address(0); }
diff --git a/chromium/v8/src/base/platform/platform-solaris.cc b/chromium/v8/src/base/platform/platform-solaris.cc
index b5b16dac568..b4ac98ce73b 100644
--- a/chromium/v8/src/base/platform/platform-solaris.cc
+++ b/chromium/v8/src/base/platform/platform-solaris.cc
@@ -65,5 +65,23 @@ void OS::SignalCodeMovingGC() {}
void OS::AdjustSchedulingParams() {}
+// static
+void* Stack::GetStackStart() {
+ pthread_attr_t attr;
+ int error;
+ pthread_attr_init(&attr);
+ error = pthread_attr_get_np(pthread_self(), &attr);
+ if (!error) {
+ void* base;
+ size_t size;
+ error = pthread_attr_getstack(&attr, &base, &size);
+ CHECK(!error);
+ pthread_attr_destroy(&attr);
+ return reinterpret_cast<uint8_t*>(base) + size;
+ }
+ pthread_attr_destroy(&attr);
+ return nullptr;
+}
+
} // namespace base
} // namespace v8
diff --git a/chromium/v8/src/base/platform/time.h b/chromium/v8/src/base/platform/time.h
index 5f69129ecbc..63a5e8a0591 100644
--- a/chromium/v8/src/base/platform/time.h
+++ b/chromium/v8/src/base/platform/time.h
@@ -14,6 +14,7 @@
#include "src/base/base-export.h"
#include "src/base/bits.h"
#include "src/base/macros.h"
+#include "src/base/safe_conversions.h"
#if V8_OS_WIN
#include "src/base/win32-headers.h"
#endif
@@ -90,6 +91,11 @@ class V8_BASE_EXPORT TimeDelta final {
return TimeDelta(nanoseconds / TimeConstants::kNanosecondsPerMicrosecond);
}
+ static TimeDelta FromMillisecondsD(double milliseconds) {
+ return FromDouble(milliseconds *
+ TimeConstants::kMicrosecondsPerMillisecond);
+ }
+
// Returns the maximum time delta, which should be greater than any reasonable
// time delta we might compare it to. Adding or subtracting the maximum time
// delta to a time or another time delta has an undefined result.
@@ -201,6 +207,9 @@ class V8_BASE_EXPORT TimeDelta final {
}
private:
+ // TODO(v8:10620): constexpr requires constexpr saturated_cast.
+ static inline TimeDelta FromDouble(double value);
+
template<class TimeClass> friend class time_internal::TimeBase;
// Constructs a delta given the duration in microseconds. This is private
// to avoid confusion by callers with an integer constructor. Use
@@ -212,6 +221,11 @@ class V8_BASE_EXPORT TimeDelta final {
};
// static
+TimeDelta TimeDelta::FromDouble(double value) {
+ return TimeDelta(saturated_cast<int64_t>(value));
+}
+
+// static
constexpr TimeDelta TimeDelta::Max() {
return TimeDelta(std::numeric_limits<int64_t>::max());
}
diff --git a/chromium/v8/src/base/template-utils.h b/chromium/v8/src/base/template-utils.h
index 8f89672e1af..617ef6ce34b 100644
--- a/chromium/v8/src/base/template-utils.h
+++ b/chromium/v8/src/base/template-utils.h
@@ -7,6 +7,7 @@
#include <array>
#include <functional>
+#include <iosfwd>
#include <type_traits>
#include <utility>
@@ -22,6 +23,12 @@ constexpr inline auto make_array_helper(Function f,
return {{f(Indexes)...}};
}
+template <template <size_t> class Value, std::size_t... Indexes>
+constexpr inline auto make_array_helper(std::index_sequence<Indexes...>)
+ -> std::array<typename Value<0>::value_type, sizeof...(Indexes)> {
+ return {{Value<Indexes>()...}};
+}
+
} // namespace detail
// base::make_array: Create an array of fixed length, initialized by a function.
@@ -35,6 +42,13 @@ constexpr auto make_array(Function f) {
return detail::make_array_helper(f, std::make_index_sequence<Size>{});
}
+// The same as above, but taking a template instead of a function to generate
+// the values for the array.
+template <std::size_t Size, template <size_t> class Value>
+constexpr auto make_array() {
+ return detail::make_array_helper<Value>(std::make_index_sequence<Size>{});
+}
+
// Helper to determine how to pass values: Pass scalars and arrays by value,
// others by const reference (even if it was a non-const ref before; this is
// disallowed by the style guide anyway).