From c9170c826d10adb3f4a170ce90672936663a11a9 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 21 Feb 2024 17:26:54 +0200 Subject: [PATCH] Auto update version to 12.2.281.18 (#101) Co-authored-by: auto user --- V8_DEFAULT_VERSION.txt | 2 +- v8_c_api/src/v8include/js_protocol.pdl | 8 +- v8_c_api/src/v8include/v8-context.h | 2 +- v8_c_api/src/v8include/v8-embedder-heap.h | 4 +- v8_c_api/src/v8include/v8-function-callback.h | 39 +++++- v8_c_api/src/v8include/v8-function.h | 1 - v8_c_api/src/v8include/v8-handle-base.h | 41 ++++++- v8_c_api/src/v8include/v8-inspector.h | 23 ++-- v8_c_api/src/v8include/v8-internal.h | 38 ++++-- v8_c_api/src/v8include/v8-isolate.h | 26 ++-- v8_c_api/src/v8include/v8-local-handle.h | 111 +++++++++--------- v8_c_api/src/v8include/v8-memory-span.h | 3 + v8_c_api/src/v8include/v8-persistent-handle.h | 4 +- v8_c_api/src/v8include/v8-platform.h | 65 +++++----- v8_c_api/src/v8include/v8-script.h | 4 +- v8_c_api/src/v8include/v8-snapshot.h | 14 +++ v8_c_api/src/v8include/v8-statistics.h | 4 +- v8_c_api/src/v8include/v8-traced-handle.h | 8 +- v8_c_api/src/v8include/v8-value.h | 46 +++++++- v8_c_api/src/v8include/v8-version.h | 6 +- v8_c_api/src/v8include/v8config.h | 34 ++++-- 21 files changed, 325 insertions(+), 158 deletions(-) diff --git a/V8_DEFAULT_VERSION.txt b/V8_DEFAULT_VERSION.txt index cf9918f..a6d2038 100644 --- a/V8_DEFAULT_VERSION.txt +++ b/V8_DEFAULT_VERSION.txt @@ -1 +1 @@ -12.1.285.28 +12.2.281.18 diff --git a/v8_c_api/src/v8include/js_protocol.pdl b/v8_c_api/src/v8include/js_protocol.pdl index 4754f17..8dad9c9 100644 --- a/v8_c_api/src/v8include/js_protocol.pdl +++ b/v8_c_api/src/v8include/js_protocol.pdl @@ -1665,7 +1665,7 @@ domain Runtime # Binding function takes exactly one argument, this argument should be string, # in case of any other input, function throws an exception. # Each binding function call produces Runtime.bindingCalled notification. - experimental command addBinding + command addBinding parameters string name # If specified, the binding would only be exposed to the specified @@ -1675,17 +1675,17 @@ domain Runtime # Deprecated in favor of `executionContextName` due to an unclear use case # and bugs in implementation (crbug.com/1169639). `executionContextId` will be # removed in the future. - deprecated optional ExecutionContextId executionContextId + experimental deprecated optional ExecutionContextId executionContextId # If specified, the binding is exposed to the executionContext with # matching name, even for contexts created after the binding is added. # See also `ExecutionContext.name` and `worldName` parameter to # `Page.addScriptToEvaluateOnNewDocument`. # This parameter is mutually exclusive with `executionContextId`. - experimental optional string executionContextName + optional string executionContextName # This method does not remove binding function from global object but # unsubscribes current runtime agent from Runtime.bindingCalled notifications. - experimental command removeBinding + command removeBinding parameters string name diff --git a/v8_c_api/src/v8include/v8-context.h b/v8_c_api/src/v8include/v8-context.h index 2d8063e..5552c7a 100644 --- a/v8_c_api/src/v8include/v8-context.h +++ b/v8_c_api/src/v8include/v8-context.h @@ -181,7 +181,7 @@ class V8_EXPORT Context : public Data { * also be considered for freezing should be added to the children_out * parameter. Returns true if the operation completed successfully. */ - V8_DEPRECATE_SOON("Please use the version that takes a LocalVector&") + V8_DEPRECATED("Please use the version that takes a LocalVector&") virtual bool FreezeEmbedderObjectAndGetChildren( Local obj, std::vector>& children_out) { // TODO(chromium:1454114): This method is temporarily defined in order to diff --git a/v8_c_api/src/v8include/v8-embedder-heap.h b/v8_c_api/src/v8include/v8-embedder-heap.h index 21e8af9..236e1c1 100644 --- a/v8_c_api/src/v8include/v8-embedder-heap.h +++ b/v8_c_api/src/v8include/v8-embedder-heap.h @@ -43,9 +43,7 @@ class V8_EXPORT EmbedderRootsHandler { * |TracedReference|. * * Note that the `handle` is different from the handle that the embedder holds - * for retaining the object. The embedder may use |WrapperClassId()| to - * distinguish cases where it wants handles to be treated as roots from not - * being treated as roots. + * for retaining the object. * * The concrete implementations must be thread-safe. */ diff --git a/v8_c_api/src/v8include/v8-function-callback.h b/v8_c_api/src/v8include/v8-function-callback.h index 1439989..a21d59d 100644 --- a/v8_c_api/src/v8include/v8-function-callback.h +++ b/v8_c_api/src/v8include/v8-function-callback.h @@ -393,6 +393,15 @@ template void ReturnValue::Set(bool value) { static_assert(std::is_base_of::value, "type check"); using I = internal::Internals; +#if V8_STATIC_ROOTS_BOOL +#ifdef V8_ENABLE_CHECKS + internal::PerformCastCheck( + internal::ValueHelper::SlotAsValue(value_)); +#endif // V8_ENABLE_CHECKS + *value_ = I::DecompressTaggedField( + *value_, value ? I::StaticReadOnlyRoot::kTrueValue + : I::StaticReadOnlyRoot::kFalseValue); +#else int root_index; if (value) { root_index = I::kTrueValueRootIndex; @@ -400,27 +409,55 @@ void ReturnValue::Set(bool value) { root_index = I::kFalseValueRootIndex; } *value_ = I::GetRoot(GetIsolate(), root_index); +#endif // V8_STATIC_ROOTS_BOOL } template void ReturnValue::SetNull() { static_assert(std::is_base_of::value, "type check"); using I = internal::Internals; +#if V8_STATIC_ROOTS_BOOL +#ifdef V8_ENABLE_CHECKS + internal::PerformCastCheck( + internal::ValueHelper::SlotAsValue(value_)); +#endif // V8_ENABLE_CHECKS + *value_ = + I::DecompressTaggedField(*value_, I::StaticReadOnlyRoot::kNullValue); +#else *value_ = I::GetRoot(GetIsolate(), I::kNullValueRootIndex); +#endif // V8_STATIC_ROOTS_BOOL } template void ReturnValue::SetUndefined() { static_assert(std::is_base_of::value, "type check"); using I = internal::Internals; +#if V8_STATIC_ROOTS_BOOL +#ifdef V8_ENABLE_CHECKS + internal::PerformCastCheck( + internal::ValueHelper::SlotAsValue(value_)); +#endif // V8_ENABLE_CHECKS + *value_ = + I::DecompressTaggedField(*value_, I::StaticReadOnlyRoot::kUndefinedValue); +#else *value_ = I::GetRoot(GetIsolate(), I::kUndefinedValueRootIndex); +#endif // V8_STATIC_ROOTS_BOOL } template void ReturnValue::SetEmptyString() { static_assert(std::is_base_of::value, "type check"); using I = internal::Internals; +#if V8_STATIC_ROOTS_BOOL +#ifdef V8_ENABLE_CHECKS + internal::PerformCastCheck( + internal::ValueHelper::SlotAsValue(value_)); +#endif // V8_ENABLE_CHECKS + *value_ = + I::DecompressTaggedField(*value_, I::StaticReadOnlyRoot::kEmptyString); +#else *value_ = I::GetRoot(GetIsolate(), I::kEmptyStringRootIndex); +#endif // V8_STATIC_ROOTS_BOOL } template @@ -435,7 +472,7 @@ Local ReturnValue::Get() const { if (I::is_identical(*value_, I::StaticReadOnlyRoot::kTheHoleValue)) { #else if (*value_ == I::GetRoot(GetIsolate(), I::kTheHoleValueRootIndex)) { -#endif +#endif // V8_STATIC_ROOTS_BOOL return Undefined(GetIsolate()); } return Local::New(GetIsolate(), reinterpret_cast(value_)); diff --git a/v8_c_api/src/v8include/v8-function.h b/v8_c_api/src/v8include/v8-function.h index d335202..30a9fcf 100644 --- a/v8_c_api/src/v8include/v8-function.h +++ b/v8_c_api/src/v8include/v8-function.h @@ -8,7 +8,6 @@ #include #include -#include "v8-context.h" // NOLINT(build/include_directory) #include "v8-function-callback.h" // NOLINT(build/include_directory) #include "v8-local-handle.h" // NOLINT(build/include_directory) #include "v8-message.h" // NOLINT(build/include_directory) diff --git a/v8_c_api/src/v8include/v8-handle-base.h b/v8_c_api/src/v8include/v8-handle-base.h index 4c5f4ec..c2e1947 100644 --- a/v8_c_api/src/v8include/v8-handle-base.h +++ b/v8_c_api/src/v8include/v8-handle-base.h @@ -7,7 +7,44 @@ #include "v8-internal.h" // NOLINT(build/include_directory) -namespace v8 { +namespace v8::api_internal { + +template +class StackAllocated { + public: + V8_INLINE StackAllocated() = default; + + protected: + struct no_checking_tag {}; + static constexpr no_checking_tag do_not_check{}; + + V8_INLINE explicit StackAllocated(no_checking_tag) {} + V8_INLINE explicit StackAllocated(const StackAllocated& other, + no_checking_tag) {} + + V8_INLINE void VerifyOnStack() const {} +}; + +template <> +class V8_TRIVIAL_ABI StackAllocated : public StackAllocated { + public: + V8_INLINE StackAllocated() { VerifyOnStack(); } + +#if V8_HAS_ATTRIBUTE_TRIVIAL_ABI + // In this case, StackAllocated becomes not trivially copyable. + V8_INLINE StackAllocated(const StackAllocated& other) { VerifyOnStack(); } + StackAllocated& operator=(const StackAllocated&) = default; +#endif + + protected: + V8_INLINE explicit StackAllocated(no_checking_tag tag) + : StackAllocated(tag) {} + V8_INLINE explicit StackAllocated(const StackAllocated& other, + no_checking_tag tag) + : StackAllocated(other, tag) {} + + V8_EXPORT void VerifyOnStack() const; +}; /** * A base class for abstract handles containing indirect pointers. @@ -95,6 +132,6 @@ class DirectHandleBase { #endif // V8_ENABLE_DIRECT_LOCAL -} // namespace v8 +} // namespace v8::api_internal #endif // INCLUDE_V8_HANDLE_BASE_H_ diff --git a/v8_c_api/src/v8include/v8-inspector.h b/v8_c_api/src/v8include/v8-inspector.h index cfdd5db..182b193 100644 --- a/v8_c_api/src/v8include/v8-inspector.h +++ b/v8_c_api/src/v8include/v8-inspector.h @@ -172,10 +172,6 @@ class V8_EXPORT V8InspectorSession { virtual v8::Local get(v8::Local) = 0; virtual ~Inspectable() = default; }; - class V8_EXPORT CommandLineAPIScope { - public: - virtual ~CommandLineAPIScope() = default; - }; virtual void addInspectedObject(std::unique_ptr) = 0; // Dispatching protocol messages. @@ -185,9 +181,6 @@ class V8_EXPORT V8InspectorSession { virtual std::vector> supportedDomains() = 0; - virtual std::unique_ptr - initializeCommandLineAPIScope(int executionContextId) = 0; - // Debugger actions. virtual void schedulePauseOnNextStatement(StringView breakReason, StringView breakDetails) = 0; @@ -213,6 +206,22 @@ class V8_EXPORT V8InspectorSession { virtual void releaseObjectGroup(StringView) = 0; virtual void triggerPreciseCoverageDeltaUpdate(StringView occasion) = 0; + struct V8_EXPORT EvaluateResult { + enum class ResultType { + kNotRun, + kSuccess, + kException, + }; + + ResultType type; + v8::Local value; + }; + // Evalaute 'expression' in the provided context. Does the same as + // Runtime#evaluate under-the-hood but exposed on the C++ side. + virtual EvaluateResult evaluate(v8::Local context, + StringView expression, + bool includeCommandLineAPI = false) = 0; + // Prepare for shutdown (disables debugger pausing, etc.). virtual void stop() = 0; }; diff --git a/v8_c_api/src/v8include/v8-internal.h b/v8_c_api/src/v8include/v8-internal.h index 80594ac..a10735d 100644 --- a/v8_c_api/src/v8include/v8-internal.h +++ b/v8_c_api/src/v8include/v8-internal.h @@ -175,11 +175,15 @@ using SandboxedPointer_t = Address; #ifdef V8_ENABLE_SANDBOX // Size of the sandbox, excluding the guard regions surrounding it. -#ifdef V8_TARGET_OS_ANDROID +#if defined(V8_TARGET_OS_ANDROID) // On Android, most 64-bit devices seem to be configured with only 39 bits of // virtual address space for userspace. As such, limit the sandbox to 128GB (a // quarter of the total available address space). constexpr size_t kSandboxSizeLog2 = 37; // 128 GB +#elif defined(V8_TARGET_ARCH_LOONG64) +// Some Linux distros on LoongArch64 configured with only 40 bits of virtual +// address space for userspace. Limit the sandbox to 256GB here. +constexpr size_t kSandboxSizeLog2 = 38; // 256 GB #else // Everywhere else use a 1TB sandbox. constexpr size_t kSandboxSizeLog2 = 40; // 1 TB @@ -606,7 +610,13 @@ constexpr int kCodePointerTableEntryCodeObjectOffset = 8; // Constants that can be used to mark places that should be modified once // certain types of objects are moved out of the sandbox and into trusted space. -constexpr bool kCodeObjectLiveInTrustedSpace = false; +constexpr bool kRuntimeGeneratedCodeObjectsLiveInTrustedSpace = true; +constexpr bool kBuiltinCodeObjectsLiveInTrustedSpace = false; +constexpr bool kAllCodeObjectsLiveInTrustedSpace = + kRuntimeGeneratedCodeObjectsLiveInTrustedSpace && + kBuiltinCodeObjectsLiveInTrustedSpace; + +constexpr bool kInterpreterDataObjectsLiveInTrustedSpace = false; // {obj} must be the raw tagged pointer representation of a HeapObject // that's guaranteed to never be in ReadOnlySpace. @@ -661,7 +671,7 @@ class Internals { static const int kBuiltinTier0EntryTableSize = 7 * kApiSystemPointerSize; static const int kBuiltinTier0TableSize = 7 * kApiSystemPointerSize; static const int kLinearAllocationAreaSize = 3 * kApiSystemPointerSize; - static const int kThreadLocalTopSize = 28 * kApiSystemPointerSize; + static const int kThreadLocalTopSize = 30 * kApiSystemPointerSize; static const int kHandleScopeDataSize = 2 * kApiSystemPointerSize + 2 * kApiInt32Size; @@ -688,8 +698,12 @@ class Internals { kBuiltinTier0TableOffset + kBuiltinTier0TableSize; static const int kOldAllocationInfoOffset = kNewAllocationInfoOffset + kLinearAllocationAreaSize; + + static const int kFastCCallAlignmentPaddingSize = + kApiSystemPointerSize == 8 ? 0 : kApiSystemPointerSize; static const int kIsolateFastCCallCallerFpOffset = - kOldAllocationInfoOffset + kLinearAllocationAreaSize; + kOldAllocationInfoOffset + kLinearAllocationAreaSize + + kFastCCallAlignmentPaddingSize; static const int kIsolateFastCCallCallerPcOffset = kIsolateFastCCallCallerFpOffset + kApiSystemPointerSize; static const int kIsolateFastApiCallTargetOffset = @@ -708,8 +722,10 @@ class Internals { static const int kIsolateSharedExternalPointerTableAddressOffset = kIsolateExternalPointerTableOffset + kExternalPointerTableSize; #ifdef V8_ENABLE_SANDBOX - static const int kIsolateTrustedPointerTableOffset = + static const int kIsolateTrustedCageBaseOffset = kIsolateSharedExternalPointerTableAddressOffset + kApiSystemPointerSize; + static const int kIsolateTrustedPointerTableOffset = + kIsolateTrustedCageBaseOffset + kApiSystemPointerSize; static const int kIsolateApiCallbackThunkArgumentOffset = kIsolateTrustedPointerTableOffset + kTrustedPointerTableSize; #else @@ -720,12 +736,15 @@ class Internals { static const int kIsolateApiCallbackThunkArgumentOffset = kIsolateEmbedderDataOffset + kNumIsolateDataSlots * kApiSystemPointerSize; #endif // V8_COMPRESS_POINTERS - static const int kWasm64OOBOffsetOffset = - kIsolateApiCallbackThunkArgumentOffset + kApiSystemPointerSize; static const int kContinuationPreservedEmbedderDataOffset = - kWasm64OOBOffsetOffset + sizeof(int64_t); + kIsolateApiCallbackThunkArgumentOffset + kApiSystemPointerSize; + + static const int kWasm64OOBOffsetAlignmentPaddingSize = 0; + static const int kWasm64OOBOffsetOffset = + kContinuationPreservedEmbedderDataOffset + kApiSystemPointerSize + + kWasm64OOBOffsetAlignmentPaddingSize; static const int kIsolateRootsOffset = - kContinuationPreservedEmbedderDataOffset + kApiSystemPointerSize; + kWasm64OOBOffsetOffset + sizeof(int64_t); #if V8_STATIC_ROOTS_BOOL @@ -1355,6 +1374,7 @@ class HandleHelper final { return lhs.ptr() == rhs.ptr(); } + static V8_EXPORT bool IsOnStack(const void* ptr); static V8_EXPORT void VerifyOnStack(const void* ptr); static V8_EXPORT void VerifyOnMainThread(); }; diff --git a/v8_c_api/src/v8include/v8-isolate.h b/v8_c_api/src/v8include/v8-isolate.h index 6c0aefd..add965a 100644 --- a/v8_c_api/src/v8include/v8-isolate.h +++ b/v8_c_api/src/v8include/v8-isolate.h @@ -395,16 +395,13 @@ class V8_EXPORT Isolate { */ class V8_EXPORT V8_NODISCARD SafeForTerminationScope { public: - explicit SafeForTerminationScope(v8::Isolate* v8_isolate); - ~SafeForTerminationScope(); + V8_DEPRECATE_SOON("All code should be safe for termination") + explicit SafeForTerminationScope(v8::Isolate* v8_isolate) {} + ~SafeForTerminationScope() {} // Prevent copying of Scope objects. SafeForTerminationScope(const SafeForTerminationScope&) = delete; SafeForTerminationScope& operator=(const SafeForTerminationScope&) = delete; - - private: - internal::Isolate* i_isolate_; - bool prev_value_; }; /** @@ -558,6 +555,13 @@ class V8_EXPORT Isolate { kTemporalObject = 130, kWasmModuleCompilation = 131, kInvalidatedNoUndetectableObjectsProtector = 132, + kWasmJavaScriptPromiseIntegration = 133, + kWasmReturnCall = 134, + kWasmExtendedConst = 135, + kWasmRelaxedSimd = 136, + kWasmTypeReflection = 137, + kWasmExnRef = 138, + kWasmTypedFuncRef = 139, // If you add new values here, you'll also need to update Chromium's: // web_feature.mojom, use_counter_callback.cc, and enums.xml. V8 changes to @@ -585,7 +589,7 @@ class V8_EXPORT Isolate { * Only Isolate::GetData() and Isolate::SetData(), which access the * embedder-controlled parts of the isolate, are allowed to be called on the * uninitialized isolate. To initialize the isolate, call - * Isolate::Initialize(). + * `Isolate::Initialize()` or initialize a `SnapshotCreator`. * * When an isolate is no longer used its resources should be freed * by calling Dispose(). Using the delete operator is not allowed. @@ -701,6 +705,14 @@ class V8_EXPORT Isolate { */ void MemoryPressureNotification(MemoryPressureLevel level); + /** + * Optional request from the embedder to tune v8 towards energy efficiency + * rather than speed if `battery_saver_mode_enabled` is true, because the + * embedder is in battery saver mode. If false, the correct tuning is left + * to v8 to decide. + */ + void SetBatterySaverMode(bool battery_saver_mode_enabled); + /** * Drop non-essential caches. Should only be called from testing code. * The method can potentially block for a long time and does not necessarily diff --git a/v8_c_api/src/v8include/v8-local-handle.h b/v8_c_api/src/v8include/v8-local-handle.h index 281a6a9..37efafd 100644 --- a/v8_c_api/src/v8include/v8-local-handle.h +++ b/v8_c_api/src/v8include/v8-local-handle.h @@ -135,6 +135,9 @@ class V8_EXPORT V8_NODISCARD HandleScope { internal::Isolate* i_isolate_; internal::Address* prev_next_; internal::Address* prev_limit_; +#ifdef V8_ENABLE_CHECKS + int scope_level_ = 0; +#endif // LocalBase::New uses CreateHandle with an Isolate* parameter. template @@ -155,7 +158,7 @@ class V8_EXPORT V8_NODISCARD HandleScope { #ifdef V8_ENABLE_DIRECT_LOCAL template -class LocalBase : public DirectHandleBase { +class LocalBase : public api_internal::DirectHandleBase { protected: template friend class Local; @@ -184,7 +187,7 @@ class LocalBase : public DirectHandleBase { #else // !V8_ENABLE_DIRECT_LOCAL template -class LocalBase : public IndirectHandleBase { +class LocalBase : public api_internal::IndirectHandleBase { protected: template friend class Local; @@ -245,20 +248,18 @@ class LocalBase : public IndirectHandleBase { * to these values as to their handles. */ template -class V8_TRIVIAL_ABI Local : public LocalBase { - public: - V8_INLINE Local() : LocalBase() { VerifyOnStack(); } - -#if defined(V8_ENABLE_LOCAL_OFF_STACK_CHECK) && V8_HAS_ATTRIBUTE_TRIVIAL_ABI - // In this case, Local becomes not trivially copyable. - V8_INLINE Local(const Local& other) : LocalBase(other) { VerifyOnStack(); } - Local& operator=(const Local&) = default; +class V8_TRIVIAL_ABI Local : public LocalBase, +#ifdef V8_ENABLE_LOCAL_OFF_STACK_CHECK + public api_internal::StackAllocated +#else + public api_internal::StackAllocated #endif +{ + public: + V8_INLINE Local() = default; template V8_INLINE Local(Local that) : LocalBase(that) { - VerifyOnStack(); - /** * This check fails when trying to convert between incompatible * handles. For example, converting from a Local to a @@ -377,6 +378,7 @@ class V8_TRIVIAL_ABI Local : public LocalBase { friend Local False(Isolate* isolate); friend class HandleScope; friend class EscapableHandleScope; + friend class InternalEscapableScope; template friend class PersistentValueMapBase; template @@ -390,16 +392,14 @@ class V8_TRIVIAL_ABI Local : public LocalBase { friend class debug::ConsoleCallArguments; friend class internal::LocalUnchecked; - struct no_checking_tag {}; + explicit Local(no_checking_tag do_not_check) + : LocalBase(), StackAllocated(do_not_check) {} + explicit Local(const Local& other, no_checking_tag do_not_check) + : LocalBase(other), StackAllocated(do_not_check) {} - explicit Local(no_checking_tag) : LocalBase() {} - explicit Local(const Local& other, no_checking_tag) + V8_INLINE explicit Local(const LocalBase& other) : LocalBase(other) {} - V8_INLINE explicit Local(const LocalBase& other) : LocalBase(other) { - VerifyOnStack(); - } - V8_INLINE static Local FromSlot(internal::Address* slot) { return Local(LocalBase::FromSlot(slot)); } @@ -423,12 +423,6 @@ class V8_TRIVIAL_ABI Local : public LocalBase { V8_INLINE Local UnsafeAs() const { return Local(LocalBase(*this)); } - - void VerifyOnStack() const { -#ifdef V8_ENABLE_LOCAL_OFF_STACK_CHECK - internal::HandleHelper::VerifyOnStack(this); -#endif - } }; namespace internal { @@ -437,20 +431,19 @@ namespace internal { template class V8_TRIVIAL_ABI LocalUnchecked : public Local { public: - LocalUnchecked() : Local(do_not_check) {} + LocalUnchecked() : Local(Local::do_not_check) {} #if defined(V8_ENABLE_LOCAL_OFF_STACK_CHECK) && V8_HAS_ATTRIBUTE_TRIVIAL_ABI - // In this case, LocalUnchecked becomes not trivially copyable. - LocalUnchecked(const LocalUnchecked& other) : Local(other, do_not_check) {} + // In this case, the check is also enforced in the copy constructor and we + // need to suppress it. + LocalUnchecked(const LocalUnchecked& other) + : Local(other, Local::do_not_check) {} LocalUnchecked& operator=(const LocalUnchecked&) = default; #endif // Implicit conversion from Local. LocalUnchecked(const Local& other) // NOLINT(runtime/explicit) - : Local(other, do_not_check) {} - - private: - static constexpr typename Local::no_checking_tag do_not_check{}; + : Local(other, Local::do_not_check) {} }; #ifdef V8_ENABLE_DIRECT_LOCAL @@ -690,21 +683,42 @@ class MaybeLocal { * A HandleScope which first allocates a handle in the current scope * which will be later filled with the escape value. */ -class V8_EXPORT V8_NODISCARD EscapableHandleScope : public HandleScope { +class V8_EXPORT V8_NODISCARD EscapableHandleScopeBase : public HandleScope { public: - explicit EscapableHandleScope(Isolate* isolate); - V8_INLINE ~EscapableHandleScope() = default; + explicit EscapableHandleScopeBase(Isolate* isolate); + V8_INLINE ~EscapableHandleScopeBase() = default; + EscapableHandleScopeBase(const EscapableHandleScopeBase&) = delete; + void operator=(const EscapableHandleScopeBase&) = delete; + void* operator new(size_t size) = delete; + void* operator new[](size_t size) = delete; + void operator delete(void*, size_t) = delete; + void operator delete[](void*, size_t) = delete; + + protected: /** * Pushes the value into the previous scope and returns a handle to it. * Cannot be called twice. */ + internal::Address* EscapeSlot(internal::Address* escape_value); + + private: + internal::Address* escape_slot_; +}; + +class V8_EXPORT V8_NODISCARD EscapableHandleScope + : public EscapableHandleScopeBase { + public: + explicit EscapableHandleScope(Isolate* isolate) + : EscapableHandleScopeBase(isolate) {} + V8_INLINE ~EscapableHandleScope() = default; template V8_INLINE Local Escape(Local value) { #ifdef V8_ENABLE_DIRECT_LOCAL return value; #else - return Local::FromSlot(Escape(value.slot())); + if (value.IsEmpty()) return value; + return Local::FromSlot(EscapeSlot(value.slot())); #endif } @@ -712,20 +726,6 @@ class V8_EXPORT V8_NODISCARD EscapableHandleScope : public HandleScope { V8_INLINE MaybeLocal EscapeMaybe(MaybeLocal value) { return Escape(value.FromMaybe(Local())); } - - EscapableHandleScope(const EscapableHandleScope&) = delete; - void operator=(const EscapableHandleScope&) = delete; - - private: - // Declaring operator new and delete as deleted is not spec compliant. - // Therefore declare them private instead to disable dynamic alloc - void* operator new(size_t size); - void* operator new[](size_t size); - void operator delete(void*, size_t); - void operator delete[](void*, size_t); - - internal::Address* Escape(internal::Address* escape_value); - internal::Address* escape_slot_; }; /** @@ -740,15 +740,12 @@ class V8_EXPORT V8_NODISCARD SealHandleScope { SealHandleScope(const SealHandleScope&) = delete; void operator=(const SealHandleScope&) = delete; + void* operator new(size_t size) = delete; + void* operator new[](size_t size) = delete; + void operator delete(void*, size_t) = delete; + void operator delete[](void*, size_t) = delete; private: - // Declaring operator new and delete as deleted is not spec compliant. - // Therefore declare them private instead to disable dynamic alloc - void* operator new(size_t size); - void* operator new[](size_t size); - void operator delete(void*, size_t); - void operator delete[](void*, size_t); - internal::Isolate* const i_isolate_; internal::Address* prev_limit_; int prev_sealed_level_; diff --git a/v8_c_api/src/v8include/v8-memory-span.h b/v8_c_api/src/v8include/v8-memory-span.h index daf4123..a7614cf 100644 --- a/v8_c_api/src/v8include/v8-memory-span.h +++ b/v8_c_api/src/v8include/v8-memory-span.h @@ -114,6 +114,9 @@ class V8_EXPORT MemorySpan { constexpr T& operator[](size_t i) const { return data_[i]; } + /** Returns true if the buffer is empty. */ + constexpr bool empty() const { return size() == 0; } + class Iterator { public: using iterator_category = std::forward_iterator_tag; diff --git a/v8_c_api/src/v8include/v8-persistent-handle.h b/v8_c_api/src/v8include/v8-persistent-handle.h index 41ad6fb..49518fe 100644 --- a/v8_c_api/src/v8include/v8-persistent-handle.h +++ b/v8_c_api/src/v8include/v8-persistent-handle.h @@ -44,7 +44,7 @@ V8_EXPORT void MoveGlobalReference(internal::Address** from, * isolate. */ template -class Eternal : public IndirectHandleBase { +class Eternal : public api_internal::IndirectHandleBase { public: V8_INLINE Eternal() = default; @@ -88,7 +88,7 @@ V8_EXPORT void MakeWeak(internal::Address* location, void* data, * */ template -class PersistentBase : public IndirectHandleBase { +class PersistentBase : public api_internal::IndirectHandleBase { public: /** * If non-empty, destroy the underlying storage cell diff --git a/v8_c_api/src/v8include/v8-platform.h b/v8_c_api/src/v8include/v8-platform.h index c3b04f3..b61f27a 100644 --- a/v8_c_api/src/v8include/v8-platform.h +++ b/v8_c_api/src/v8include/v8-platform.h @@ -1084,12 +1084,12 @@ class Platform { * Schedules a task to be invoked on a worker thread. * Embedders should override PostTaskOnWorkerThreadImpl() instead of * CallOnWorkerThread(). - * TODO(chromium:1424158): Make non-virtual once embedders are migrated to - * PostTaskOnWorkerThreadImpl(). */ - virtual void CallOnWorkerThread(std::unique_ptr task) { + void CallOnWorkerThread( + std::unique_ptr task, + const SourceLocation& location = SourceLocation::Current()) { PostTaskOnWorkerThreadImpl(TaskPriority::kUserVisible, std::move(task), - SourceLocation::Current()); + location); } /** @@ -1097,28 +1097,28 @@ class Platform { * high-priority on a worker thread. * Embedders should override PostTaskOnWorkerThreadImpl() instead of * CallBlockingTaskOnWorkerThread(). - * TODO(chromium:1424158): Make non-virtual once embedders are migrated to - * PostTaskOnWorkerThreadImpl(). */ - virtual void CallBlockingTaskOnWorkerThread(std::unique_ptr task) { + void CallBlockingTaskOnWorkerThread( + std::unique_ptr task, + const SourceLocation& location = SourceLocation::Current()) { // Embedders may optionally override this to process these tasks in a high // priority pool. PostTaskOnWorkerThreadImpl(TaskPriority::kUserBlocking, std::move(task), - SourceLocation::Current()); + location); } /** * Schedules a task to be invoked with low-priority on a worker thread. * Embedders should override PostTaskOnWorkerThreadImpl() instead of * CallLowPriorityTaskOnWorkerThread(). - * TODO(chromium:1424158): Make non-virtual once embedders are migrated to - * PostTaskOnWorkerThreadImpl(). */ - virtual void CallLowPriorityTaskOnWorkerThread(std::unique_ptr task) { + void CallLowPriorityTaskOnWorkerThread( + std::unique_ptr task, + const SourceLocation& location = SourceLocation::Current()) { // Embedders may optionally override this to process these tasks in a low // priority pool. PostTaskOnWorkerThreadImpl(TaskPriority::kBestEffort, std::move(task), - SourceLocation::Current()); + location); } /** @@ -1126,14 +1126,13 @@ class Platform { * expires. * Embedders should override PostDelayedTaskOnWorkerThreadImpl() instead of * CallDelayedOnWorkerThread(). - * TODO(chromium:1424158): Make non-virtual once embedders are migrated to - * PostDelayedTaskOnWorkerThreadImpl(). */ - virtual void CallDelayedOnWorkerThread(std::unique_ptr task, - double delay_in_seconds) { + void CallDelayedOnWorkerThread( + std::unique_ptr task, double delay_in_seconds, + const SourceLocation& location = SourceLocation::Current()) { PostDelayedTaskOnWorkerThreadImpl(TaskPriority::kUserVisible, std::move(task), delay_in_seconds, - SourceLocation::Current()); + location); } /** @@ -1185,12 +1184,11 @@ class Platform { * JobTask::GetMaxConcurrency may be invoked synchronously from JobHandle * (B=>JobHandle::foo=>B deadlock). * Embedders should override CreateJobImpl() instead of PostJob(). - * TODO(chromium:1424158): Make non-virtual once embedders are migrated to - * CreateJobImpl(). */ - virtual std::unique_ptr PostJob( - TaskPriority priority, std::unique_ptr job_task) { - auto handle = CreateJob(priority, std::move(job_task)); + std::unique_ptr PostJob( + TaskPriority priority, std::unique_ptr job_task, + const SourceLocation& location = SourceLocation::Current()) { + auto handle = CreateJob(priority, std::move(job_task), location); handle->NotifyConcurrencyIncrease(); return handle; } @@ -1209,13 +1207,11 @@ class Platform { * } * * Embedders should override CreateJobImpl() instead of CreateJob(). - * TODO(chromium:1424158): Make non-virtual once embedders are migrated to - * CreateJobImpl(). */ - virtual std::unique_ptr CreateJob( - TaskPriority priority, std::unique_ptr job_task) { - return CreateJobImpl(priority, std::move(job_task), - SourceLocation::Current()); + std::unique_ptr CreateJob( + TaskPriority priority, std::unique_ptr job_task, + const SourceLocation& location = SourceLocation::Current()) { + return CreateJobImpl(priority, std::move(job_task), location); } /** @@ -1297,32 +1293,25 @@ class Platform { /** * Creates and returns a JobHandle associated with a Job. - * TODO(chromium:1424158): Make pure virtual once embedders implement it. */ virtual std::unique_ptr CreateJobImpl( TaskPriority priority, std::unique_ptr job_task, - const SourceLocation& location) { - return nullptr; - } + const SourceLocation& location) = 0; /** * Schedules a task with |priority| to be invoked on a worker thread. - * TODO(chromium:1424158): Make pure virtual once embedders implement it. */ virtual void PostTaskOnWorkerThreadImpl(TaskPriority priority, std::unique_ptr task, - const SourceLocation& location) { - CallOnWorkerThread(std::move(task)); - } + const SourceLocation& location) = 0; /** * Schedules a task with |priority| to be invoked on a worker thread after * |delay_in_seconds| expires. - * TODO(chromium:1424158): Make pure virtual once embedders implement it. */ virtual void PostDelayedTaskOnWorkerThreadImpl( TaskPriority priority, std::unique_ptr task, - double delay_in_seconds, const SourceLocation& location) {} + double delay_in_seconds, const SourceLocation& location) = 0; }; } // namespace v8 diff --git a/v8_c_api/src/v8include/v8-script.h b/v8_c_api/src/v8include/v8-script.h index 57a9b14..a2d0bca 100644 --- a/v8_c_api/src/v8include/v8-script.h +++ b/v8_c_api/src/v8include/v8-script.h @@ -286,7 +286,7 @@ class V8_EXPORT Module : public Data { * module_name is used solely for logging/debugging and doesn't affect module * behavior. */ - V8_DEPRECATE_SOON("Please use the version that takes a MemorySpan") + V8_DEPRECATED("Please use the version that takes a MemorySpan") static Local CreateSyntheticModule( Isolate* isolate, Local module_name, const std::vector>& export_names, @@ -313,7 +313,7 @@ class V8_EXPORT Module : public Data { * with the pending top-level await. * An embedder may call this before exiting to improve error messages. */ - V8_DEPRECATE_SOON("Please use GetStalledTopLevelAwaitMessages") + V8_DEPRECATED("Please use GetStalledTopLevelAwaitMessages") std::vector, Local>> GetStalledTopLevelAwaitMessage(Isolate* isolate); diff --git a/v8_c_api/src/v8include/v8-snapshot.h b/v8_c_api/src/v8include/v8-snapshot.h index 9e5cbd5..70d2ca5 100644 --- a/v8_c_api/src/v8include/v8-snapshot.h +++ b/v8_c_api/src/v8include/v8-snapshot.h @@ -122,6 +122,20 @@ class V8_EXPORT SnapshotCreator { */ explicit SnapshotCreator(const v8::Isolate::CreateParams& params); + /** + * Initializes an Isolate for serialization and enters it. The creator does + * not own the Isolate but merely initialize it properly. + * + * \param isolate The isolate that was allocated by `Isolate::Allocate()~. + * \param params The parameters to initialize the Isolate for. Details: + * - `params.external_references` are expected to be a + * null-terminated array of external references. + * - `params.existing_blob` is an optional snapshot blob from + * which can be used to initialize the new blob. + */ + SnapshotCreator(v8::Isolate* isolate, + const v8::Isolate::CreateParams& params); + /** * Destroy the snapshot creator, and exit and dispose of the Isolate * associated with it. diff --git a/v8_c_api/src/v8include/v8-statistics.h b/v8_c_api/src/v8include/v8-statistics.h index dca9572..aeca8cf 100644 --- a/v8_c_api/src/v8include/v8-statistics.h +++ b/v8_c_api/src/v8include/v8-statistics.h @@ -71,7 +71,7 @@ class V8_EXPORT MeasureMemoryDelegate { * \param unattributed_size_in_bytes total size of objects that were not * attributed to any context (i.e. are likely shared objects). */ - V8_DEPRECATE_SOON("Please use the version that takes a result struct") + V8_DEPRECATED("Please use the version that takes a result struct") virtual void MeasurementComplete( const std::vector, size_t>>& context_sizes_in_bytes, @@ -84,7 +84,7 @@ class V8_EXPORT MeasureMemoryDelegate { * which ShouldMeasure returned true and that was not garbage collected * while the memory measurement was in progress. */ - V8_DEPRECATE_SOON("Please use contexts and sizes_in_bytes") + V8_DEPRECATED("Please use contexts and sizes_in_bytes") const std::vector, size_t>>& context_sizes_in_bytes; diff --git a/v8_c_api/src/v8include/v8-traced-handle.h b/v8_c_api/src/v8include/v8-traced-handle.h index 0256535..7abe0b9 100644 --- a/v8_c_api/src/v8include/v8-traced-handle.h +++ b/v8_c_api/src/v8include/v8-traced-handle.h @@ -53,7 +53,7 @@ V8_EXPORT void DisposeTracedReference(internal::Address* global_handle); * An indirect handle, where the indirect pointer points to a GlobalHandles * node. */ -class TracedReferenceBase : public IndirectHandleBase { +class TracedReferenceBase : public api_internal::IndirectHandleBase { public: /** * If non-empty, destroy the underlying storage cell. |IsEmpty| will return @@ -80,16 +80,14 @@ class TracedReferenceBase : public IndirectHandleBase { /** * Assigns a wrapper class ID to the handle. */ - V8_DEPRECATE_SOON( - "Embedders need to maintain state for references themselves.") + V8_DEPRECATED("Embedders need to maintain state for references themselves.") V8_INLINE void SetWrapperClassId(uint16_t class_id); /** * Returns the class ID previously assigned to this handle or 0 if no class ID * was previously assigned. */ - V8_DEPRECATE_SOON( - "Embedders need to maintain state for references themselves.") + V8_DEPRECATED("Embedders need to maintain state for references themselves.") V8_INLINE uint16_t WrapperClassId() const; protected: diff --git a/v8_c_api/src/v8include/v8-value.h b/v8_c_api/src/v8include/v8-value.h index 110b695..9356cd6 100644 --- a/v8_c_api/src/v8include/v8-value.h +++ b/v8_c_api/src/v8include/v8-value.h @@ -16,7 +16,7 @@ */ namespace v8 { -class Primiitive; +class Primitive; class Numeric; class BigInt; class Int32; @@ -63,7 +63,7 @@ class V8_EXPORT Value : public Data { * conversion to boolean, i.e. the result of `Boolean(value)` in JS, whereas * this checks `value === true`. */ - bool IsTrue() const; + V8_INLINE bool IsTrue() const; /** * Returns true if this value is false. @@ -72,7 +72,7 @@ class V8_EXPORT Value : public Data { * conversion to boolean, i.e. the result of `!Boolean(value)` in JS, whereas * this checks `value === false`. */ - bool IsFalse() const; + V8_INLINE bool IsFalse() const; /** * Returns true if this value is a symbol or a string. @@ -461,9 +461,15 @@ class V8_EXPORT Value : public Data { V8_INLINE bool QuickIsUndefined() const; V8_INLINE bool QuickIsNull() const; V8_INLINE bool QuickIsNullOrUndefined() const; +#if V8_STATIC_ROOTS_BOOL + V8_INLINE bool QuickIsTrue() const; + V8_INLINE bool QuickIsFalse() const; +#endif // V8_STATIC_ROOTS_BOOL V8_INLINE bool QuickIsString() const; bool FullIsUndefined() const; bool FullIsNull() const; + bool FullIsTrue() const; + bool FullIsFalse() const; bool FullIsString() const; static void CheckCast(Data* that); @@ -576,6 +582,40 @@ bool Value::QuickIsNullOrUndefined() const { #endif // V8_STATIC_ROOTS_BOOL } +bool Value::IsTrue() const { +#if V8_STATIC_ROOTS_BOOL && !defined(V8_ENABLE_CHECKS) + return QuickIsTrue(); +#else + return FullIsTrue(); +#endif +} + +#if V8_STATIC_ROOTS_BOOL +bool Value::QuickIsTrue() const { + using A = internal::Address; + using I = internal::Internals; + A obj = internal::ValueHelper::ValueAsAddress(this); + return I::is_identical(obj, I::StaticReadOnlyRoot::kTrueValue); +} +#endif // V8_STATIC_ROOTS_BOOL + +bool Value::IsFalse() const { +#if V8_STATIC_ROOTS_BOOL && !defined(V8_ENABLE_CHECKS) + return QuickIsFalse(); +#else + return FullIsFalse(); +#endif +} + +#if V8_STATIC_ROOTS_BOOL +bool Value::QuickIsFalse() const { + using A = internal::Address; + using I = internal::Internals; + A obj = internal::ValueHelper::ValueAsAddress(this); + return I::is_identical(obj, I::StaticReadOnlyRoot::kFalseValue); +} +#endif // V8_STATIC_ROOTS_BOOL + bool Value::IsString() const { #ifdef V8_ENABLE_CHECKS return FullIsString(); diff --git a/v8_c_api/src/v8include/v8-version.h b/v8_c_api/src/v8include/v8-version.h index 51adfc5..c6f6d20 100644 --- a/v8_c_api/src/v8include/v8-version.h +++ b/v8_c_api/src/v8include/v8-version.h @@ -9,9 +9,9 @@ // NOTE these macros are used by some of the tool scripts and the build // system so their names cannot be changed without changing the scripts. #define V8_MAJOR_VERSION 12 -#define V8_MINOR_VERSION 1 -#define V8_BUILD_NUMBER 285 -#define V8_PATCH_LEVEL 28 +#define V8_MINOR_VERSION 2 +#define V8_BUILD_NUMBER 281 +#define V8_PATCH_LEVEL 18 // Use 1 for candidates and 0 otherwise. // (Boolean macro values are not supported by all preprocessors.) diff --git a/v8_c_api/src/v8include/v8config.h b/v8_c_api/src/v8include/v8config.h index ae42abd..e649d8c 100644 --- a/v8_c_api/src/v8include/v8config.h +++ b/v8_c_api/src/v8include/v8config.h @@ -13,6 +13,7 @@ path. Add it with -I to the command line #include "v8-gn.h" // NOLINT(build/include_directory) #endif +#include // clang-format off // Platform headers for feature detection below. @@ -305,6 +306,8 @@ path. Add it with -I to the command line // V8_HAS_CPP_ATTRIBUTE_NODISCARD - [[nodiscard]] supported // V8_HAS_CPP_ATTRIBUTE_NO_UNIQUE_ADDRESS // - [[no_unique_address]] supported +// V8_HAS_BUILTIN_ADD_OVERFLOW - __builtin_add_overflow() supported +// V8_HAS_BUILTIN_BIT_CAST - __builtin_bit_cast() supported // V8_HAS_BUILTIN_BSWAP16 - __builtin_bswap16() supported // V8_HAS_BUILTIN_BSWAP32 - __builtin_bswap32() supported // V8_HAS_BUILTIN_BSWAP64 - __builtin_bswap64() supported @@ -312,14 +315,13 @@ path. Add it with -I to the command line // V8_HAS_BUILTIN_CTZ - __builtin_ctz() supported // V8_HAS_BUILTIN_EXPECT - __builtin_expect() supported // V8_HAS_BUILTIN_FRAME_ADDRESS - __builtin_frame_address() supported -// V8_HAS_BUILTIN_POPCOUNT - __builtin_popcount() supported -// V8_HAS_BUILTIN_ADD_OVERFLOW - __builtin_add_overflow() supported -// V8_HAS_BUILTIN_SUB_OVERFLOW - __builtin_sub_overflow() supported // V8_HAS_BUILTIN_MUL_OVERFLOW - __builtin_mul_overflow() supported +// V8_HAS_BUILTIN_POPCOUNT - __builtin_popcount() supported // V8_HAS_BUILTIN_SADD_OVERFLOW - __builtin_sadd_overflow() supported +// V8_HAS_BUILTIN_SMUL_OVERFLOW - __builtin_smul_overflow() supported // V8_HAS_BUILTIN_SSUB_OVERFLOW - __builtin_ssub_overflow() supported +// V8_HAS_BUILTIN_SUB_OVERFLOW - __builtin_sub_overflow() supported // V8_HAS_BUILTIN_UADD_OVERFLOW - __builtin_uadd_overflow() supported -// V8_HAS_BUILTIN_SMUL_OVERFLOW - __builtin_smul_overflow() supported // V8_HAS_COMPUTED_GOTO - computed goto/labels as values // supported // V8_HAS_DECLSPEC_NOINLINE - __declspec(noinline) supported @@ -377,8 +379,10 @@ path. Add it with -I to the command line # define V8_HAS_CPP_ATTRIBUTE_NO_UNIQUE_ADDRESS \ (V8_HAS_CPP_ATTRIBUTE(no_unique_address)) +# define V8_HAS_BUILTIN_ADD_OVERFLOW (__has_builtin(__builtin_add_overflow)) # define V8_HAS_BUILTIN_ASSUME (__has_builtin(__builtin_assume)) # define V8_HAS_BUILTIN_ASSUME_ALIGNED (__has_builtin(__builtin_assume_aligned)) +# define V8_HAS_BUILTIN_BIT_CAST (__has_builtin(__builtin_bit_cast)) # define V8_HAS_BUILTIN_BSWAP16 (__has_builtin(__builtin_bswap16)) # define V8_HAS_BUILTIN_BSWAP32 (__has_builtin(__builtin_bswap32)) # define V8_HAS_BUILTIN_BSWAP64 (__has_builtin(__builtin_bswap64)) @@ -386,14 +390,13 @@ path. Add it with -I to the command line # define V8_HAS_BUILTIN_CTZ (__has_builtin(__builtin_ctz)) # define V8_HAS_BUILTIN_EXPECT (__has_builtin(__builtin_expect)) # define V8_HAS_BUILTIN_FRAME_ADDRESS (__has_builtin(__builtin_frame_address)) -# define V8_HAS_BUILTIN_POPCOUNT (__has_builtin(__builtin_popcount)) -# define V8_HAS_BUILTIN_ADD_OVERFLOW (__has_builtin(__builtin_add_overflow)) -# define V8_HAS_BUILTIN_SUB_OVERFLOW (__has_builtin(__builtin_sub_overflow)) # define V8_HAS_BUILTIN_MUL_OVERFLOW (__has_builtin(__builtin_mul_overflow)) +# define V8_HAS_BUILTIN_POPCOUNT (__has_builtin(__builtin_popcount)) # define V8_HAS_BUILTIN_SADD_OVERFLOW (__has_builtin(__builtin_sadd_overflow)) +# define V8_HAS_BUILTIN_SMUL_OVERFLOW (__has_builtin(__builtin_smul_overflow)) # define V8_HAS_BUILTIN_SSUB_OVERFLOW (__has_builtin(__builtin_ssub_overflow)) +# define V8_HAS_BUILTIN_SUB_OVERFLOW (__has_builtin(__builtin_sub_overflow)) # define V8_HAS_BUILTIN_UADD_OVERFLOW (__has_builtin(__builtin_uadd_overflow)) -# define V8_HAS_BUILTIN_SMUL_OVERFLOW (__has_builtin(__builtin_smul_overflow)) # define V8_HAS_BUILTIN_UNREACHABLE (__has_builtin(__builtin_unreachable)) // Clang has no __has_feature for computed gotos. @@ -414,6 +417,11 @@ path. Add it with -I to the command line # endif # define V8_CC_MINGW (V8_CC_MINGW32 || V8_CC_MINGW64) +// FYI: __has_builtin is only available with GCC 10 and later, so explicitly +// check GCC version numbers to enable features. TODO(leszeks): Merge feature +// enabling for GCC 10 and later into the Clang section above, and leave this +// section for GCC 9 and earlier. + // always_inline is available in gcc 4.0 but not very reliable until 4.4. // Works around "sorry, unimplemented: inlining failed" build errors with // older compilers. @@ -429,6 +437,9 @@ path. Add it with -I to the command line // for V8_HAS_CPP_ATTRIBUTE_NODISCARD. See https://crbug.com/v8/11707. # define V8_HAS_BUILTIN_ASSUME_ALIGNED 1 +# if __GNUC__ >= 11 +# define V8_HAS_BUILTIN_BIT_CAST 1 +# endif # define V8_HAS_BUILTIN_CLZ 1 # define V8_HAS_BUILTIN_CTZ 1 # define V8_HAS_BUILTIN_EXPECT 1 @@ -480,14 +491,17 @@ path. Add it with -I to the command line # define V8_ASSUME USE #endif -#if V8_HAS_BUILTIN_ASSUME_ALIGNED +// Prefer c++20 std::assume_aligned +#if __cplusplus >= 202002L && defined(__cpp_lib_assume_aligned) +# define V8_ASSUME_ALIGNED(ptr, alignment) \ + std::assume_aligned<(alignment)>(ptr) +#elif V8_HAS_BUILTIN_ASSUME_ALIGNED # define V8_ASSUME_ALIGNED(ptr, alignment) \ __builtin_assume_aligned((ptr), (alignment)) #else # define V8_ASSUME_ALIGNED(ptr, alignment) (ptr) #endif - // A macro to mark functions whose values don't change (e.g. across calls) // and thereby compiler is free to hoist and fold multiple calls together. // Use like: