diff options
author | Michaël Zasso <targos@protonmail.com> | 2019-03-12 09:01:49 +0100 |
---|---|---|
committer | Michaël Zasso <targos@protonmail.com> | 2019-03-14 18:49:21 +0100 |
commit | 7b48713334469818661fe276cf571de9c7899f2d (patch) | |
tree | 4dbda49ac88db76ce09dc330a0cb587e68e139ba /deps/v8/include | |
parent | 8549ac09b256666cf5275224ec58fab9939ff32e (diff) | |
download | android-node-v8-7b48713334469818661fe276cf571de9c7899f2d.tar.gz android-node-v8-7b48713334469818661fe276cf571de9c7899f2d.tar.bz2 android-node-v8-7b48713334469818661fe276cf571de9c7899f2d.zip |
deps: update V8 to 7.3.492.25
PR-URL: https://github.com/nodejs/node/pull/25852
Reviewed-By: Ujjwal Sharma <usharma1998@gmail.com>
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
Reviewed-By: Ali Ijaz Sheikh <ofrobots@google.com>
Diffstat (limited to 'deps/v8/include')
-rw-r--r-- | deps/v8/include/OWNERS | 1 | ||||
-rw-r--r-- | deps/v8/include/PRESUBMIT.py | 29 | ||||
-rw-r--r-- | deps/v8/include/libplatform/libplatform.h | 2 | ||||
-rw-r--r-- | deps/v8/include/v8-inspector.h | 3 | ||||
-rw-r--r-- | deps/v8/include/v8-internal.h | 231 | ||||
-rw-r--r-- | deps/v8/include/v8-platform.h | 38 | ||||
-rw-r--r-- | deps/v8/include/v8-profiler.h | 32 | ||||
-rw-r--r-- | deps/v8/include/v8-util.h | 32 | ||||
-rw-r--r-- | deps/v8/include/v8-version.h | 6 | ||||
-rw-r--r-- | deps/v8/include/v8-wasm-trap-handler-posix.h | 31 | ||||
-rw-r--r-- | deps/v8/include/v8-wasm-trap-handler-win.h | 28 | ||||
-rw-r--r-- | deps/v8/include/v8.h | 805 | ||||
-rw-r--r-- | deps/v8/include/v8config.h | 77 |
13 files changed, 771 insertions, 544 deletions
diff --git a/deps/v8/include/OWNERS b/deps/v8/include/OWNERS index d20fb79fe1..7953cfe133 100644 --- a/deps/v8/include/OWNERS +++ b/deps/v8/include/OWNERS @@ -5,6 +5,7 @@ danno@chromium.org ulan@chromium.org yangguo@chromium.org +per-file v8-internal.h=file://OWNERS per-file v8-inspector.h=dgozman@chromium.org per-file v8-inspector.h=pfeldman@chromium.org per-file v8-inspector.h=kozyatinskiy@chromium.org diff --git a/deps/v8/include/PRESUBMIT.py b/deps/v8/include/PRESUBMIT.py deleted file mode 100644 index 8002e4dcac..0000000000 --- a/deps/v8/include/PRESUBMIT.py +++ /dev/null @@ -1,29 +0,0 @@ -# Copyright 2017 the V8 project authors. All rights reserved.') -# Use of this source code is governed by a BSD-style license that can be -# found in the LICENSE file. - -"""Presubmit script for //v8/include - -See http://dev.chromium.org/developers/how-tos/depottools/presubmit-scripts -for more details about the presubmit API built into depot_tools. -""" - -import os - - -def PostUploadHook(cl, change, output_api): - """git cl upload will call this hook after the issue is created/modified. - - This hook adds extra try bots to the CL description in order to run layout - tests in addition to CQ try bots. - """ - def header_filter(f): - return '.h' in os.path.split(f.LocalPath())[1] - if not change.AffectedFiles(file_filter=header_filter): - return [] - return output_api.EnsureCQIncludeTrybotsAreAdded( - cl, - [ - 'luci.chromium.try:linux_chromium_rel_ng' - ], - 'Automatically added layout test trybots to run tests on CQ.') diff --git a/deps/v8/include/libplatform/libplatform.h b/deps/v8/include/libplatform/libplatform.h index 2b167cb9e5..13c0db9a85 100644 --- a/deps/v8/include/libplatform/libplatform.h +++ b/deps/v8/include/libplatform/libplatform.h @@ -41,7 +41,7 @@ V8_PLATFORM_EXPORT std::unique_ptr<v8::Platform> NewDefaultPlatform( InProcessStackDumping::kDisabled, std::unique_ptr<v8::TracingController> tracing_controller = {}); -V8_PLATFORM_EXPORT V8_DEPRECATE_SOON( +V8_PLATFORM_EXPORT V8_DEPRECATED( "Use NewDefaultPlatform instead", v8::Platform* CreateDefaultPlatform( int thread_pool_size = 0, diff --git a/deps/v8/include/v8-inspector.h b/deps/v8/include/v8-inspector.h index f0a8b5f163..702013588c 100644 --- a/deps/v8/include/v8-inspector.h +++ b/deps/v8/include/v8-inspector.h @@ -245,8 +245,7 @@ class V8_EXPORT V8Inspector { virtual void contextCreated(const V8ContextInfo&) = 0; virtual void contextDestroyed(v8::Local<v8::Context>) = 0; virtual void resetContextGroup(int contextGroupId) = 0; - virtual v8::MaybeLocal<v8::Context> contextById(int groupId, - v8::Maybe<int> contextId) = 0; + virtual v8::MaybeLocal<v8::Context> contextById(int contextId) = 0; // Various instrumentation. virtual void idleStarted() = 0; diff --git a/deps/v8/include/v8-internal.h b/deps/v8/include/v8-internal.h index 80f7367bfe..7f9c27ebb9 100644 --- a/deps/v8/include/v8-internal.h +++ b/deps/v8/include/v8-internal.h @@ -20,15 +20,19 @@ class Isolate; namespace internal { -class Object; +class Isolate; + +typedef uintptr_t Address; +static const Address kNullAddress = 0; /** * Configuration of tagging scheme. */ -const int kApiPointerSize = sizeof(void*); // NOLINT -const int kApiDoubleSize = sizeof(double); // NOLINT -const int kApiIntSize = sizeof(int); // NOLINT -const int kApiInt64Size = sizeof(int64_t); // NOLINT +const int kApiSystemPointerSize = sizeof(void*); +const int kApiTaggedSize = kApiSystemPointerSize; +const int kApiDoubleSize = sizeof(double); +const int kApiIntSize = sizeof(int); +const int kApiInt64Size = sizeof(int64_t); // Tag information for HeapObject. const int kHeapObjectTag = 1; @@ -44,33 +48,20 @@ const intptr_t kSmiTagMask = (1 << kSmiTagSize) - 1; template <size_t tagged_ptr_size> struct SmiTagging; -template <int kSmiShiftSize> -V8_INLINE internal::Object* IntToSmi(int value) { - int smi_shift_bits = kSmiTagSize + kSmiShiftSize; - intptr_t tagged_value = - (static_cast<intptr_t>(value) << smi_shift_bits) | kSmiTag; - return reinterpret_cast<internal::Object*>(tagged_value); -} - // Smi constants for systems where tagged pointer is a 32-bit value. template <> struct SmiTagging<4> { enum { kSmiShiftSize = 0, kSmiValueSize = 31 }; - static int SmiShiftSize() { return kSmiShiftSize; } - static int SmiValueSize() { return kSmiValueSize; } - V8_INLINE static int SmiToInt(const internal::Object* value) { + V8_INLINE static int SmiToInt(const internal::Address value) { int shift_bits = kSmiTagSize + kSmiShiftSize; - // Throw away top 32 bits and shift down (requires >> to be sign extending). - return static_cast<int>(reinterpret_cast<intptr_t>(value)) >> shift_bits; - } - V8_INLINE static internal::Object* IntToSmi(int value) { - return internal::IntToSmi<kSmiShiftSize>(value); + // Shift down (requires >> to be sign extending). + return static_cast<int>(static_cast<intptr_t>(value)) >> shift_bits; } V8_INLINE static constexpr bool IsValidSmi(intptr_t value) { // To be representable as an tagged small integer, the two // most-significant bits of 'value' must be either 00 or 11 due to // sign-extension. To check this we add 01 to the two - // most-significant bits, and check if the most-significant bit is 0 + // most-significant bits, and check if the most-significant bit is 0. // // CAUTION: The original code below: // bool result = ((value + 0x40000000) & 0x80000000) == 0; @@ -86,15 +77,10 @@ struct SmiTagging<4> { template <> struct SmiTagging<8> { enum { kSmiShiftSize = 31, kSmiValueSize = 32 }; - static int SmiShiftSize() { return kSmiShiftSize; } - static int SmiValueSize() { return kSmiValueSize; } - V8_INLINE static int SmiToInt(const internal::Object* value) { + V8_INLINE static int SmiToInt(const internal::Address value) { int shift_bits = kSmiTagSize + kSmiShiftSize; // Shift down and throw away top 32 bits. - return static_cast<int>(reinterpret_cast<intptr_t>(value) >> shift_bits); - } - V8_INLINE static internal::Object* IntToSmi(int value) { - return internal::IntToSmi<kSmiShiftSize>(value); + return static_cast<int>(static_cast<intptr_t>(value) >> shift_bits); } V8_INLINE static constexpr bool IsValidSmi(intptr_t value) { // To be representable as a long smi, the value must be a 32-bit integer. @@ -102,13 +88,16 @@ struct SmiTagging<8> { } }; -#if V8_COMPRESS_POINTERS +#if defined(V8_COMPRESS_POINTERS) static_assert( - kApiPointerSize == kApiInt64Size, + kApiSystemPointerSize == kApiInt64Size, "Pointer compression can be enabled only for 64-bit architectures"); -typedef SmiTagging<4> PlatformSmiTagging; +#endif + +#if defined(V8_COMPRESS_POINTERS) || defined(V8_31BIT_SMIS_ON_64BIT_ARCH) +typedef SmiTagging<kApiIntSize> PlatformSmiTagging; #else -typedef SmiTagging<kApiPointerSize> PlatformSmiTagging; +typedef SmiTagging<kApiSystemPointerSize> PlatformSmiTagging; #endif const int kSmiShiftSize = PlatformSmiTagging::kSmiShiftSize; @@ -118,6 +107,11 @@ const int kSmiMaxValue = -(kSmiMinValue + 1); constexpr bool SmiValuesAre31Bits() { return kSmiValueSize == 31; } constexpr bool SmiValuesAre32Bits() { return kSmiValueSize == 32; } +V8_INLINE static constexpr internal::Address IntToSmi(int value) { + return (static_cast<Address>(value) << (kSmiTagSize + kSmiShiftSize)) | + kSmiTag; +} + /** * This class exports constants and functionality from within v8 that * is necessary to implement inline functions in the v8 api. Don't @@ -128,30 +122,40 @@ class Internals { // These values match non-compiler-dependent values defined within // the implementation of v8. static const int kHeapObjectMapOffset = 0; - static const int kMapInstanceTypeOffset = 1 * kApiPointerSize + kApiIntSize; - static const int kStringResourceOffset = - 1 * kApiPointerSize + 2 * kApiIntSize; - - static const int kOddballKindOffset = 4 * kApiPointerSize + kApiDoubleSize; - static const int kForeignAddressOffset = kApiPointerSize; - static const int kJSObjectHeaderSize = 3 * kApiPointerSize; - static const int kFixedArrayHeaderSize = 2 * kApiPointerSize; - static const int kContextHeaderSize = 2 * kApiPointerSize; - static const int kContextEmbedderDataIndex = 5; + static const int kMapInstanceTypeOffset = 1 * kApiTaggedSize + kApiIntSize; + static const int kStringResourceOffset = 1 * kApiTaggedSize + 2 * kApiIntSize; + + static const int kOddballKindOffset = 4 * kApiTaggedSize + kApiDoubleSize; + static const int kForeignAddressOffset = kApiTaggedSize; + static const int kJSObjectHeaderSize = 3 * kApiTaggedSize; + static const int kJSObjectHeaderSizeForEmbedderFields = + (kJSObjectHeaderSize + kApiSystemPointerSize - 1) & + -kApiSystemPointerSize; + static const int kFixedArrayHeaderSize = 2 * kApiTaggedSize; + static const int kEmbedderDataArrayHeaderSize = 2 * kApiTaggedSize; + static const int kEmbedderDataSlotSize = +#ifdef V8_COMPRESS_POINTERS + 2 * +#endif + kApiSystemPointerSize; + static const int kNativeContextEmbedderDataOffset = 7 * kApiTaggedSize; static const int kFullStringRepresentationMask = 0x0f; static const int kStringEncodingMask = 0x8; static const int kExternalTwoByteRepresentationTag = 0x02; static const int kExternalOneByteRepresentationTag = 0x0a; - static const int kIsolateEmbedderDataOffset = 0 * kApiPointerSize; - static const int kExternalMemoryOffset = 4 * kApiPointerSize; + static const uint32_t kNumIsolateDataSlots = 4; + + static const int kIsolateEmbedderDataOffset = 0; + static const int kExternalMemoryOffset = + kNumIsolateDataSlots * kApiTaggedSize; static const int kExternalMemoryLimitOffset = kExternalMemoryOffset + kApiInt64Size; static const int kExternalMemoryAtLastMarkCompactOffset = kExternalMemoryLimitOffset + kApiInt64Size; - static const int kIsolateRootsOffset = kExternalMemoryLimitOffset + - kApiInt64Size + kApiInt64Size + - kApiPointerSize + kApiPointerSize; + static const int kIsolateRootsOffset = + kExternalMemoryAtLastMarkCompactOffset + kApiInt64Size; + static const int kUndefinedValueRootIndex = 4; static const int kTheHoleValueRootIndex = 5; static const int kNullValueRootIndex = 6; @@ -159,8 +163,8 @@ class Internals { static const int kFalseValueRootIndex = 8; static const int kEmptyStringRootIndex = 9; - static const int kNodeClassIdOffset = 1 * kApiPointerSize; - static const int kNodeFlagsOffset = 1 * kApiPointerSize + 3; + static const int kNodeClassIdOffset = 1 * kApiTaggedSize; + static const int kNodeFlagsOffset = 1 * kApiTaggedSize + 3; static const int kNodeStateMask = 0x7; static const int kNodeStateIsWeakValue = 2; static const int kNodeStateIsPendingValue = 3; @@ -178,8 +182,6 @@ class Internals { static const int kUndefinedOddballKind = 5; static const int kNullOddballKind = 3; - static const uint32_t kNumIsolateDataSlots = 4; - // Soft limit for AdjustAmountofExternalAllocatedMemory. Trigger an // incremental GC once the external memory reaches this limit. static constexpr int kExternalAllocationSoftLimit = 64 * 1024 * 1024; @@ -191,32 +193,30 @@ class Internals { #endif } - V8_INLINE static bool HasHeapObjectTag(const internal::Object* value) { - return ((reinterpret_cast<intptr_t>(value) & kHeapObjectTagMask) == - kHeapObjectTag); + V8_INLINE static bool HasHeapObjectTag(const internal::Address value) { + return (value & kHeapObjectTagMask) == static_cast<Address>(kHeapObjectTag); } - V8_INLINE static int SmiValue(const internal::Object* value) { + V8_INLINE static int SmiValue(const internal::Address value) { return PlatformSmiTagging::SmiToInt(value); } - V8_INLINE static internal::Object* IntToSmi(int value) { - return PlatformSmiTagging::IntToSmi(value); + V8_INLINE static constexpr internal::Address IntToSmi(int value) { + return internal::IntToSmi(value); } V8_INLINE static constexpr bool IsValidSmi(intptr_t value) { return PlatformSmiTagging::IsValidSmi(value); } - V8_INLINE static int GetInstanceType(const internal::Object* obj) { - typedef internal::Object O; - O* map = ReadField<O*>(obj, kHeapObjectMapOffset); - return ReadField<uint16_t>(map, kMapInstanceTypeOffset); + V8_INLINE static int GetInstanceType(const internal::Address obj) { + typedef internal::Address A; + A map = ReadTaggedPointerField(obj, kHeapObjectMapOffset); + return ReadRawField<uint16_t>(map, kMapInstanceTypeOffset); } - V8_INLINE static int GetOddballKind(const internal::Object* obj) { - typedef internal::Object O; - return SmiValue(ReadField<O*>(obj, kOddballKindOffset)); + V8_INLINE static int GetOddballKind(const internal::Address obj) { + return SmiValue(ReadTaggedSignedField(obj, kOddballKindOffset)); } V8_INLINE static bool IsExternalTwoByteString(int instance_type) { @@ -224,67 +224,120 @@ class Internals { return representation == kExternalTwoByteRepresentationTag; } - V8_INLINE static uint8_t GetNodeFlag(internal::Object** obj, int shift) { + V8_INLINE static uint8_t GetNodeFlag(internal::Address* obj, int shift) { uint8_t* addr = reinterpret_cast<uint8_t*>(obj) + kNodeFlagsOffset; return *addr & static_cast<uint8_t>(1U << shift); } - V8_INLINE static void UpdateNodeFlag(internal::Object** obj, bool value, + V8_INLINE static void UpdateNodeFlag(internal::Address* obj, bool value, int shift) { uint8_t* addr = reinterpret_cast<uint8_t*>(obj) + kNodeFlagsOffset; uint8_t mask = static_cast<uint8_t>(1U << shift); *addr = static_cast<uint8_t>((*addr & ~mask) | (value << shift)); } - V8_INLINE static uint8_t GetNodeState(internal::Object** obj) { + V8_INLINE static uint8_t GetNodeState(internal::Address* obj) { uint8_t* addr = reinterpret_cast<uint8_t*>(obj) + kNodeFlagsOffset; return *addr & kNodeStateMask; } - V8_INLINE static void UpdateNodeState(internal::Object** obj, uint8_t value) { + V8_INLINE static void UpdateNodeState(internal::Address* obj, uint8_t value) { uint8_t* addr = reinterpret_cast<uint8_t*>(obj) + kNodeFlagsOffset; *addr = static_cast<uint8_t>((*addr & ~kNodeStateMask) | value); } V8_INLINE static void SetEmbedderData(v8::Isolate* isolate, uint32_t slot, void* data) { - uint8_t* addr = reinterpret_cast<uint8_t*>(isolate) + - kIsolateEmbedderDataOffset + slot * kApiPointerSize; + internal::Address addr = reinterpret_cast<internal::Address>(isolate) + + kIsolateEmbedderDataOffset + + slot * kApiSystemPointerSize; *reinterpret_cast<void**>(addr) = data; } V8_INLINE static void* GetEmbedderData(const v8::Isolate* isolate, uint32_t slot) { - const uint8_t* addr = reinterpret_cast<const uint8_t*>(isolate) + - kIsolateEmbedderDataOffset + slot * kApiPointerSize; + internal::Address addr = reinterpret_cast<internal::Address>(isolate) + + kIsolateEmbedderDataOffset + + slot * kApiSystemPointerSize; return *reinterpret_cast<void* const*>(addr); } - V8_INLINE static internal::Object** GetRoot(v8::Isolate* isolate, int index) { - uint8_t* addr = reinterpret_cast<uint8_t*>(isolate) + kIsolateRootsOffset; - return reinterpret_cast<internal::Object**>(addr + index * kApiPointerSize); + V8_INLINE static internal::Address* GetRoot(v8::Isolate* isolate, int index) { + internal::Address addr = reinterpret_cast<internal::Address>(isolate) + + kIsolateRootsOffset + + index * kApiSystemPointerSize; + return reinterpret_cast<internal::Address*>(addr); } template <typename T> - V8_INLINE static T ReadField(const internal::Object* ptr, int offset) { - const uint8_t* addr = - reinterpret_cast<const uint8_t*>(ptr) + offset - kHeapObjectTag; + V8_INLINE static T ReadRawField(internal::Address heap_object_ptr, + int offset) { + internal::Address addr = heap_object_ptr + offset - kHeapObjectTag; return *reinterpret_cast<const T*>(addr); } + V8_INLINE static internal::Address ReadTaggedPointerField( + internal::Address heap_object_ptr, int offset) { +#ifdef V8_COMPRESS_POINTERS + int32_t value = ReadRawField<int32_t>(heap_object_ptr, offset); + internal::Address root = GetRootFromOnHeapAddress(heap_object_ptr); + return root + static_cast<internal::Address>(static_cast<intptr_t>(value)); +#else + return ReadRawField<internal::Address>(heap_object_ptr, offset); +#endif + } + + V8_INLINE static internal::Address ReadTaggedSignedField( + internal::Address heap_object_ptr, int offset) { +#ifdef V8_COMPRESS_POINTERS + int32_t value = ReadRawField<int32_t>(heap_object_ptr, offset); + return static_cast<internal::Address>(static_cast<intptr_t>(value)); +#else + return ReadRawField<internal::Address>(heap_object_ptr, offset); +#endif + } + + V8_INLINE static internal::Address ReadTaggedAnyField( + internal::Address heap_object_ptr, int offset) { +#ifdef V8_COMPRESS_POINTERS + int32_t value = ReadRawField<int32_t>(heap_object_ptr, offset); + internal::Address root_mask = static_cast<internal::Address>( + -static_cast<intptr_t>(value & kSmiTagMask)); + internal::Address root_or_zero = + root_mask & GetRootFromOnHeapAddress(heap_object_ptr); + return root_or_zero + + static_cast<internal::Address>(static_cast<intptr_t>(value)); +#else + return ReadRawField<internal::Address>(heap_object_ptr, offset); +#endif + } + +#ifdef V8_COMPRESS_POINTERS + static constexpr size_t kPtrComprHeapReservationSize = size_t{1} << 32; + static constexpr size_t kPtrComprIsolateRootBias = + kPtrComprHeapReservationSize / 2; + static constexpr size_t kPtrComprIsolateRootAlignment = size_t{1} << 32; + + V8_INLINE static internal::Address GetRootFromOnHeapAddress( + internal::Address addr) { + return (addr + kPtrComprIsolateRootBias) & + -static_cast<intptr_t>(kPtrComprIsolateRootAlignment); + } + +#else + template <typename T> V8_INLINE static T ReadEmbedderData(const v8::Context* context, int index) { - typedef internal::Object O; + typedef internal::Address A; typedef internal::Internals I; - O* ctx = *reinterpret_cast<O* const*>(context); - int embedder_data_offset = - I::kContextHeaderSize + - (internal::kApiPointerSize * I::kContextEmbedderDataIndex); - O* embedder_data = I::ReadField<O*>(ctx, embedder_data_offset); + A ctx = *reinterpret_cast<const A*>(context); + A embedder_data = + I::ReadTaggedPointerField(ctx, I::kNativeContextEmbedderDataOffset); int value_offset = - I::kFixedArrayHeaderSize + (internal::kApiPointerSize * index); - return I::ReadField<T>(embedder_data, value_offset); + I::kEmbedderDataArrayHeaderSize + (I::kEmbedderDataSlotSize * index); + return I::ReadRawField<T>(embedder_data, value_offset); } +#endif // V8_COMPRESS_POINTERS }; // Only perform cast check for types derived from v8::Data since @@ -310,6 +363,10 @@ V8_INLINE void PerformCastCheck(T* data) { CastCheck<std::is_base_of<Data, T>::value>::Perform(data); } +// {obj} must be the raw tagged pointer representation of a HeapObject +// that's guaranteed to never be in ReadOnlySpace. +V8_EXPORT internal::Isolate* IsolateFromNeverReadOnlySpaceObject(Address obj); + } // namespace internal } // namespace v8 diff --git a/deps/v8/include/v8-platform.h b/deps/v8/include/v8-platform.h index d983c30249..fc008979f6 100644 --- a/deps/v8/include/v8-platform.h +++ b/deps/v8/include/v8-platform.h @@ -54,6 +54,15 @@ class TaskRunner { virtual void PostTask(std::unique_ptr<Task> task) = 0; /** + * Schedules a task to be invoked by this TaskRunner. The TaskRunner + * implementation takes ownership of |task|. The |task| cannot be nested + * within other task executions. + * + * Requires that |TaskRunner::NonNestableTasksEnabled()| is true. + */ + virtual void PostNonNestableTask(std::unique_ptr<Task> task) {} + + /** * Schedules a task to be invoked by this TaskRunner. The task is scheduled * after the given number of seconds |delay_in_seconds|. The TaskRunner * implementation takes ownership of |task|. @@ -64,7 +73,7 @@ class TaskRunner { /** * Schedules an idle task to be invoked by this TaskRunner. The task is * scheduled when the embedder is idle. Requires that - * TaskRunner::SupportsIdleTasks(isolate) is true. Idle tasks may be reordered + * |TaskRunner::IdleTasksEnabled()| is true. Idle tasks may be reordered * relative to other task types and may be starved for an arbitrarily long * time if no idle time is available. The TaskRunner implementation takes * ownership of |task|. @@ -76,6 +85,11 @@ class TaskRunner { */ virtual bool IdleTasksEnabled() = 0; + /** + * Returns true if non-nestable tasks are enabled for this TaskRunner. + */ + virtual bool NonNestableTasksEnabled() const { return false; } + TaskRunner() = default; virtual ~TaskRunner() = default; @@ -236,6 +250,13 @@ class PageAllocator { */ virtual bool SetPermissions(void* address, size_t length, Permission permissions) = 0; + + /** + * Frees memory in the given [address, address + size) range. address and size + * should be operating system page-aligned. The next write to this + * memory area brings the memory transparently back. + */ + virtual bool DiscardSystemPages(void* address, size_t size) { return true; } }; /** @@ -311,6 +332,15 @@ class Platform { } /** + * Schedules a task to be invoked with low-priority on a worker thread. + */ + virtual void CallLowPriorityTaskOnWorkerThread(std::unique_ptr<Task> task) { + // Embedders may optionally override this to process these tasks in a low + // priority pool. + CallOnWorkerThread(std::move(task)); + } + + /** * Schedules a task to be invoked on a worker thread after |delay_in_seconds| * expires. */ @@ -388,6 +418,12 @@ class Platform { */ virtual TracingController* GetTracingController() = 0; + /** + * Tells the embedder to generate and upload a crashdump during an unexpected + * but non-critical scenario. + */ + virtual void DumpWithoutCrashing() {} + protected: /** * Default implementation of current wall-clock time in milliseconds diff --git a/deps/v8/include/v8-profiler.h b/deps/v8/include/v8-profiler.h index f30688582d..94d3fcfcf6 100644 --- a/deps/v8/include/v8-profiler.h +++ b/deps/v8/include/v8-profiler.h @@ -612,6 +612,11 @@ class V8_EXPORT AllocationProfile { int column_number; /** + * Unique id of the node. + */ + uint32_t node_id; + + /** * List of callees called from this node for which we have sampled * allocations. The lifetime of the children is scoped to the containing * AllocationProfile. @@ -625,11 +630,38 @@ class V8_EXPORT AllocationProfile { }; /** + * Represent a single sample recorded for an allocation. + */ + struct Sample { + /** + * id of the node in the profile tree. + */ + uint32_t node_id; + + /** + * Size of the sampled allocation object. + */ + size_t size; + + /** + * The number of objects of such size that were sampled. + */ + unsigned int count; + + /** + * Unique time-ordered id of the allocation sample. Can be used to track + * what samples were added or removed between two snapshots. + */ + uint64_t sample_id; + }; + + /** * Returns the root node of the call-graph. The root node corresponds to an * empty JS call-stack. The lifetime of the returned Node* is scoped to the * containing AllocationProfile. */ virtual Node* GetRootNode() = 0; + virtual const std::vector<Sample>& GetSamples() = 0; virtual ~AllocationProfile() = default; diff --git a/deps/v8/include/v8-util.h b/deps/v8/include/v8-util.h index 96c9acbbdc..7f12ead16b 100644 --- a/deps/v8/include/v8-util.h +++ b/deps/v8/include/v8-util.h @@ -25,13 +25,11 @@ enum PersistentContainerCallbackType { kNotWeak, // These correspond to v8::WeakCallbackType kWeakWithParameter, - kWeakWithInternalFields, - kWeak = kWeakWithParameter // For backwards compatibility. Deprecate. + kWeakWithInternalFields }; - /** - * A default trait implemenation for PersistentValueMap which uses std::map + * A default trait implementation for PersistentValueMap which uses std::map * as a backing map. * * Users will have to implement their own weak callbacks & dispose traits. @@ -203,7 +201,7 @@ class PersistentValueMapBase { void RegisterExternallyReferencedObject(K& key) { assert(Contains(key)); V8::RegisterExternallyReferencedObject( - reinterpret_cast<internal::Object**>(FromVal(Traits::Get(&impl_, key))), + reinterpret_cast<internal::Address*>(FromVal(Traits::Get(&impl_, key))), reinterpret_cast<internal::Isolate*>(GetIsolate())); } @@ -289,7 +287,10 @@ class PersistentValueMapBase { } protected: - explicit PersistentValueMapBase(Isolate* isolate) : isolate_(isolate) {} + explicit PersistentValueMapBase(Isolate* isolate) + : isolate_(isolate), label_(nullptr) {} + PersistentValueMapBase(Isolate* isolate, const char* label) + : isolate_(isolate), label_(label) {} ~PersistentValueMapBase() { Clear(); } @@ -331,6 +332,10 @@ class PersistentValueMapBase { p.Reset(); } + void AnnotateStrongRetainer(Global<V>* persistent) { + persistent->AnnotateStrongRetainer(label_); + } + private: PersistentValueMapBase(PersistentValueMapBase&); void operator=(PersistentValueMapBase&); @@ -340,13 +345,14 @@ class PersistentValueMapBase { bool hasValue = value != kPersistentContainerNotFound; if (hasValue) { returnValue->SetInternal( - *reinterpret_cast<internal::Object**>(FromVal(value))); + *reinterpret_cast<internal::Address*>(FromVal(value))); } return hasValue; } Isolate* isolate_; typename Traits::Impl impl_; + const char* label_; }; @@ -355,6 +361,8 @@ class PersistentValueMap : public PersistentValueMapBase<K, V, Traits> { public: explicit PersistentValueMap(Isolate* isolate) : PersistentValueMapBase<K, V, Traits>(isolate) {} + PersistentValueMap(Isolate* isolate, const char* label) + : PersistentValueMapBase<K, V, Traits>(isolate, label) {} typedef typename PersistentValueMapBase<K, V, Traits>::PersistentValueReference @@ -382,7 +390,9 @@ class PersistentValueMap : public PersistentValueMapBase<K, V, Traits> { * by the Traits class. */ Global<V> SetUnique(const K& key, Global<V>* persistent) { - if (Traits::kCallbackType != kNotWeak) { + if (Traits::kCallbackType == kNotWeak) { + this->AnnotateStrongRetainer(persistent); + } else { WeakCallbackType callback_type = Traits::kCallbackType == kWeakWithInternalFields ? WeakCallbackType::kInternalFields @@ -427,6 +437,8 @@ class GlobalValueMap : public PersistentValueMapBase<K, V, Traits> { public: explicit GlobalValueMap(Isolate* isolate) : PersistentValueMapBase<K, V, Traits>(isolate) {} + GlobalValueMap(Isolate* isolate, const char* label) + : PersistentValueMapBase<K, V, Traits>(isolate, label) {} typedef typename PersistentValueMapBase<K, V, Traits>::PersistentValueReference @@ -454,7 +466,9 @@ class GlobalValueMap : public PersistentValueMapBase<K, V, Traits> { * by the Traits class. */ Global<V> SetUnique(const K& key, Global<V>* persistent) { - if (Traits::kCallbackType != kNotWeak) { + if (Traits::kCallbackType == kNotWeak) { + this->AnnotateStrongRetainer(persistent); + } else { WeakCallbackType callback_type = Traits::kCallbackType == kWeakWithInternalFields ? WeakCallbackType::kInternalFields diff --git a/deps/v8/include/v8-version.h b/deps/v8/include/v8-version.h index 114e57c58e..abf640228f 100644 --- a/deps/v8/include/v8-version.h +++ b/deps/v8/include/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 7 -#define V8_MINOR_VERSION 1 -#define V8_BUILD_NUMBER 302 -#define V8_PATCH_LEVEL 33 +#define V8_MINOR_VERSION 3 +#define V8_BUILD_NUMBER 492 +#define V8_PATCH_LEVEL 25 // Use 1 for candidates and 0 otherwise. // (Boolean macro values are not supported by all preprocessors.) diff --git a/deps/v8/include/v8-wasm-trap-handler-posix.h b/deps/v8/include/v8-wasm-trap-handler-posix.h new file mode 100644 index 0000000000..998d0a41bb --- /dev/null +++ b/deps/v8/include/v8-wasm-trap-handler-posix.h @@ -0,0 +1,31 @@ +// Copyright 2018 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef V8_WASM_TRAP_HANDLER_POSIX_H_ +#define V8_WASM_TRAP_HANDLER_POSIX_H_ + +#include <signal.h> + +#include "v8config.h" // NOLINT(build/include) + +namespace v8 { +/** + * This function determines whether a memory access violation has been an + * out-of-bounds memory access in WebAssembly. If so, it will modify the context + * parameter and add a return address where the execution can continue after the + * signal handling, and return true. Otherwise, false will be returned. + * + * The parameters to this function correspond to those passed to a Posix signal + * handler. Use this function only on Linux and Mac. + * + * \param sig_code The signal code, e.g. SIGSEGV. + * \param info A pointer to the siginfo_t struct provided to the signal handler. + * \param context A pointer to a ucontext_t struct provided to the signal + * handler. + */ +V8_EXPORT bool TryHandleWebAssemblyTrapPosix(int sig_code, siginfo_t* info, + void* context); + +} // namespace v8 +#endif // V8_WASM_TRAP_HANDLER_POSIX_H_ diff --git a/deps/v8/include/v8-wasm-trap-handler-win.h b/deps/v8/include/v8-wasm-trap-handler-win.h new file mode 100644 index 0000000000..0185df6401 --- /dev/null +++ b/deps/v8/include/v8-wasm-trap-handler-win.h @@ -0,0 +1,28 @@ +// Copyright 2018 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef V8_WASM_TRAP_HANDLER_WIN_H_ +#define V8_WASM_TRAP_HANDLER_WIN_H_ + +#include <windows.h> + +#include "v8config.h" // NOLINT(build/include) + +namespace v8 { +/** + * This function determines whether a memory access violation has been an + * out-of-bounds memory access in WebAssembly. If so, it will modify the + * exception parameter and add a return address where the execution can continue + * after the exception handling, and return true. Otherwise the return value + * will be false. + * + * The parameter to this function corresponds to the one passed to a Windows + * vectored exception handler. Use this function only on Windows. + * + * \param exception An EXCEPTION_POINTERS* as provided to the exception handler. + */ +V8_EXPORT bool TryHandleWebAssemblyTrapWindows(EXCEPTION_POINTERS* exception); + +} // namespace v8 +#endif // V8_WASM_TRAP_HANDLER_WIN_H_ diff --git a/deps/v8/include/v8.h b/deps/v8/include/v8.h index 0f0eb2e739..b23114f4ff 100644 --- a/deps/v8/include/v8.h +++ b/deps/v8/include/v8.h @@ -81,7 +81,7 @@ class Private; class Uint32; class Utils; class Value; -class WasmCompiledModule; +class WasmModuleObject; template <class T> class Local; template <class T> class MaybeLocal; @@ -118,7 +118,6 @@ class HeapObject; class Isolate; class LocalEmbedderHeapTracer; class NeverReadOnlySpaceObject; -class Object; struct ScriptStreamingData; template<typename T> class CustomArguments; class PropertyCallbackArguments; @@ -212,8 +211,8 @@ class Local { */ template <class S> V8_INLINE bool operator==(const Local<S>& that) const { - internal::Object** a = reinterpret_cast<internal::Object**>(this->val_); - internal::Object** b = reinterpret_cast<internal::Object**>(that.val_); + internal::Address* a = reinterpret_cast<internal::Address*>(this->val_); + internal::Address* b = reinterpret_cast<internal::Address*>(that.val_); if (a == nullptr) return b == nullptr; if (b == nullptr) return false; return *a == *b; @@ -221,8 +220,8 @@ class Local { template <class S> V8_INLINE bool operator==( const PersistentBase<S>& that) const { - internal::Object** a = reinterpret_cast<internal::Object**>(this->val_); - internal::Object** b = reinterpret_cast<internal::Object**>(that.val_); + internal::Address* a = reinterpret_cast<internal::Address*>(this->val_); + internal::Address* b = reinterpret_cast<internal::Address*>(that.val_); if (a == nullptr) return b == nullptr; if (b == nullptr) return false; return *a == *b; @@ -477,8 +476,8 @@ template <class T> class PersistentBase { template <class S> V8_INLINE bool operator==(const PersistentBase<S>& that) const { - internal::Object** a = reinterpret_cast<internal::Object**>(this->val_); - internal::Object** b = reinterpret_cast<internal::Object**>(that.val_); + internal::Address* a = reinterpret_cast<internal::Address*>(this->val_); + internal::Address* b = reinterpret_cast<internal::Address*>(that.val_); if (a == nullptr) return b == nullptr; if (b == nullptr) return false; return *a == *b; @@ -486,8 +485,8 @@ template <class T> class PersistentBase { template <class S> V8_INLINE bool operator==(const Local<S>& that) const { - internal::Object** a = reinterpret_cast<internal::Object**>(this->val_); - internal::Object** b = reinterpret_cast<internal::Object**>(that.val_); + internal::Address* a = reinterpret_cast<internal::Address*>(this->val_); + internal::Address* b = reinterpret_cast<internal::Address*>(that.val_); if (a == nullptr) return b == nullptr; if (b == nullptr) return false; return *a == *b; @@ -569,7 +568,9 @@ template <class T> class PersistentBase { V8_INLINE bool IsIndependent() const); /** Checks if the handle holds the only reference to an object. */ - V8_INLINE bool IsNearDeath() const; + V8_DEPRECATE_SOON( + "Garbage collection internal state should not be relied on.", + V8_INLINE bool IsNearDeath() const); /** Returns true if the handle's reference is weak. */ V8_INLINE bool IsWeak() const; @@ -696,7 +697,7 @@ template <class T, class M> class Persistent : public PersistentBase<T> { V8_INLINE Persistent(const Persistent<S, M2>& that) : PersistentBase<T>(0) { Copy(that); } - V8_INLINE Persistent& operator=(const Persistent& that) { // NOLINT + V8_INLINE Persistent& operator=(const Persistent& that) { Copy(that); return *this; } @@ -780,7 +781,7 @@ class Global : public PersistentBase<T> { /** * Move constructor. */ - V8_INLINE Global(Global&& other) : PersistentBase<T>(other.val_) { // NOLINT + V8_INLINE Global(Global&& other) : PersistentBase<T>(other.val_) { other.val_ = nullptr; } V8_INLINE ~Global() { this->Reset(); } @@ -859,8 +860,8 @@ class V8_EXPORT HandleScope { void Initialize(Isolate* isolate); - static internal::Object** CreateHandle(internal::Isolate* isolate, - internal::Object* value); + static internal::Address* CreateHandle(internal::Isolate* isolate, + internal::Address value); private: // Declaring operator new and delete as deleted is not spec compliant. @@ -870,19 +871,15 @@ class V8_EXPORT HandleScope { void operator delete(void*, size_t); void operator delete[](void*, size_t); - // Uses heap_object to obtain the current Isolate. - static internal::Object** CreateHandle( - internal::NeverReadOnlySpaceObject* heap_object, internal::Object* value); - internal::Isolate* isolate_; - internal::Object** prev_next_; - internal::Object** prev_limit_; + internal::Address* prev_next_; + internal::Address* prev_limit_; // Local::New uses CreateHandle with an Isolate* parameter. template<class F> friend class Local; // Object::GetInternalField and Context::GetEmbedderData use CreateHandle with - // a HeapObject* in their shortcuts. + // a HeapObject in their shortcuts. friend class Object; friend class Context; }; @@ -903,8 +900,8 @@ class V8_EXPORT EscapableHandleScope : public HandleScope { */ template <class T> V8_INLINE Local<T> Escape(Local<T> value) { - internal::Object** slot = - Escape(reinterpret_cast<internal::Object**>(*value)); + internal::Address* slot = + Escape(reinterpret_cast<internal::Address*>(*value)); return Local<T>(reinterpret_cast<T*>(slot)); } @@ -924,8 +921,8 @@ class V8_EXPORT EscapableHandleScope : public HandleScope { void operator delete(void*, size_t); void operator delete[](void*, size_t); - internal::Object** Escape(internal::Object** escape_value); - internal::Object** escape_slot_; + internal::Address* Escape(internal::Address* escape_value); + internal::Address* escape_slot_; }; /** @@ -950,7 +947,7 @@ class V8_EXPORT SealHandleScope { void operator delete[](void*, size_t); internal::Isolate* const isolate_; - internal::Object** prev_limit_; + internal::Address* prev_limit_; int prev_sealed_level_; }; @@ -1393,10 +1390,6 @@ class V8_EXPORT ScriptCompiler { StreamedSource(ExternalSourceStream* source_stream, Encoding encoding); ~StreamedSource(); - V8_DEPRECATED("No longer used", const CachedData* GetCachedData() const) { - return nullptr; - } - internal::ScriptStreamingData* impl() const { return impl_.get(); } // Prevent copying. @@ -1426,10 +1419,6 @@ class V8_EXPORT ScriptCompiler { enum CompileOptions { kNoCompileOptions = 0, - kProduceParserCache, - kConsumeParserCache, - kProduceCodeCache, - kProduceFullCodeCache, kConsumeCodeCache, kEagerCompile }; @@ -1827,8 +1816,18 @@ struct SampleInfo { }; struct MemoryRange { - const void* start; - size_t length_in_bytes; + const void* start = nullptr; + size_t length_in_bytes = 0; +}; + +struct JSEntryStub { + MemoryRange code; +}; + +struct UnwindState { + MemoryRange code_range; + MemoryRange embedded_code_range; + JSEntryStub js_entry_stub; }; /** @@ -1840,12 +1839,10 @@ class V8_EXPORT JSON { * Tries to parse the string |json_string| and returns it as value if * successful. * + * \param the context in which to parse and create the value. * \param json_string The string to parse. * \return The corresponding value if successfully parsed. */ - static V8_DEPRECATED("Use the maybe version taking context", - MaybeLocal<Value> Parse(Isolate* isolate, - Local<String> json_string)); static V8_WARN_UNUSED_RESULT MaybeLocal<Value> Parse( Local<Context> context, Local<String> json_string); @@ -1903,7 +1900,7 @@ class V8_EXPORT ValueSerializer { Isolate* isolate, Local<SharedArrayBuffer> shared_array_buffer); virtual Maybe<uint32_t> GetWasmModuleTransferId( - Isolate* isolate, Local<WasmCompiledModule> module); + Isolate* isolate, Local<WasmModuleObject> module); /** * Allocates memory for the buffer of at least the size provided. The actual * size (which may be greater or equal) is written to |actual_size|. If no @@ -1942,12 +1939,6 @@ class V8_EXPORT ValueSerializer { Local<Value> value); /** - * Returns the stored data. This serializer should not be used once the buffer - * is released. The contents are undefined if a previous write has failed. - */ - V8_DEPRECATED("Use Release()", std::vector<uint8_t> ReleaseBuffer()); - - /** * Returns the stored data (allocated using the delegate's * ReallocateBufferMemory) and its size. This serializer should not be used * once the buffer is released. The contents are undefined if a previous write @@ -1963,13 +1954,6 @@ class V8_EXPORT ValueSerializer { void TransferArrayBuffer(uint32_t transfer_id, Local<ArrayBuffer> array_buffer); - /** - * Similar to TransferArrayBuffer, but for SharedArrayBuffer. - */ - V8_DEPRECATED("Use Delegate::GetSharedArrayBufferId", - void TransferSharedArrayBuffer( - uint32_t transfer_id, - Local<SharedArrayBuffer> shared_array_buffer)); /** * Indicate whether to treat ArrayBufferView objects as host objects, @@ -2020,10 +2004,10 @@ class V8_EXPORT ValueDeserializer { virtual MaybeLocal<Object> ReadHostObject(Isolate* isolate); /** - * Get a WasmCompiledModule given a transfer_id previously provided + * Get a WasmModuleObject given a transfer_id previously provided * by ValueSerializer::GetWasmModuleTransferId */ - virtual MaybeLocal<WasmCompiledModule> GetWasmModuleFromId( + virtual MaybeLocal<WasmModuleObject> GetWasmModuleFromId( Isolate* isolate, uint32_t transfer_id); /** @@ -2531,7 +2515,7 @@ enum class NewStringType { */ class V8_EXPORT String : public Name { public: - static constexpr int kMaxLength = internal::kApiPointerSize == 4 + static constexpr int kMaxLength = internal::kApiTaggedSize == 4 ? (1 << 28) - 16 : internal::kSmiMaxValue / 2 - 24; @@ -2765,7 +2749,7 @@ class V8_EXPORT String : public Name { }; /** Allocates a new string from UTF-8 data.*/ - static V8_DEPRECATE_SOON( + static V8_DEPRECATED( "Use maybe version", Local<String> NewFromUtf8(Isolate* isolate, const char* data, NewStringType type = kNormalString, @@ -2915,8 +2899,6 @@ class V8_EXPORT String : public Name { ExternalStringResource* GetExternalStringResourceSlow() const; ExternalStringResourceBase* GetExternalStringResourceBaseSlow( String::Encoding* encoding_out) const; - const ExternalOneByteStringResource* GetExternalOneByteStringResourceSlow() - const; static void CheckCast(v8::Value* obj); }; @@ -3237,6 +3219,10 @@ class V8_EXPORT Object : public Value { public: V8_DEPRECATE_SOON("Use maybe version", bool Set(Local<Value> key, Local<Value> value)); + /** + * Set only return Just(true) or Empty(), so if it should never fail, use + * result.Check(). + */ V8_WARN_UNUSED_RESULT Maybe<bool> Set(Local<Context> context, Local<Value> key, Local<Value> value); @@ -3307,7 +3293,6 @@ class V8_EXPORT Object : public Value { V8_WARN_UNUSED_RESULT MaybeLocal<Value> GetOwnPropertyDescriptor( Local<Context> context, Local<Name> key); - V8_DEPRECATE_SOON("Use maybe version", bool Has(Local<Value> key)); /** * Object::Has() calls the abstract operation HasProperty(O, P) described * in ECMA-262, 7.3.10. Has() returns @@ -3326,7 +3311,6 @@ class V8_EXPORT Object : public Value { V8_WARN_UNUSED_RESULT Maybe<bool> Has(Local<Context> context, Local<Value> key); - V8_DEPRECATE_SOON("Use maybe version", bool Delete(Local<Value> key)); V8_WARN_UNUSED_RESULT Maybe<bool> Delete(Local<Context> context, Local<Value> key); @@ -3397,7 +3381,7 @@ class V8_EXPORT Object : public Value { * array returned by this method contains the same values as would * be enumerated by a for-in statement over this object. */ - V8_DEPRECATE_SOON("Use maybe version", Local<Array> GetPropertyNames()); + V8_DEPRECATED("Use maybe version", Local<Array> GetPropertyNames()); V8_WARN_UNUSED_RESULT MaybeLocal<Array> GetPropertyNames( Local<Context> context); V8_WARN_UNUSED_RESULT MaybeLocal<Array> GetPropertyNames( @@ -3410,7 +3394,7 @@ class V8_EXPORT Object : public Value { * the returned array doesn't contain the names of properties from * prototype objects. */ - V8_DEPRECATE_SOON("Use maybe version", Local<Array> GetOwnPropertyNames()); + V8_DEPRECATED("Use maybe version", Local<Array> GetOwnPropertyNames()); V8_WARN_UNUSED_RESULT MaybeLocal<Array> GetOwnPropertyNames( Local<Context> context); @@ -3509,8 +3493,8 @@ class V8_EXPORT Object : public Value { Local<Name> key); V8_WARN_UNUSED_RESULT Maybe<bool> HasOwnProperty(Local<Context> context, uint32_t index); - V8_DEPRECATE_SOON("Use maybe version", - bool HasRealNamedProperty(Local<String> key)); + V8_DEPRECATED("Use maybe version", + bool HasRealNamedProperty(Local<String> key)); /** * Use HasRealNamedProperty() if you want to check if an object has an own * property without causing side effects, i.e., without calling interceptors. @@ -3526,12 +3510,12 @@ class V8_EXPORT Object : public Value { */ V8_WARN_UNUSED_RESULT Maybe<bool> HasRealNamedProperty(Local<Context> context, Local<Name> key); - V8_DEPRECATE_SOON("Use maybe version", - bool HasRealIndexedProperty(uint32_t index)); + V8_DEPRECATED("Use maybe version", + bool HasRealIndexedProperty(uint32_t index)); V8_WARN_UNUSED_RESULT Maybe<bool> HasRealIndexedProperty( Local<Context> context, uint32_t index); - V8_DEPRECATE_SOON("Use maybe version", - bool HasRealNamedCallbackProperty(Local<String> key)); + V8_DEPRECATED("Use maybe version", + bool HasRealNamedCallbackProperty(Local<String> key)); V8_WARN_UNUSED_RESULT Maybe<bool> HasRealNamedCallbackProperty( Local<Context> context, Local<Name> key); @@ -3647,6 +3631,18 @@ class V8_EXPORT Object : public Value { static Local<Object> New(Isolate* isolate); + /** + * Creates a JavaScript object with the given properties, and + * a the given prototype_or_null (which can be any JavaScript + * value, and if it's null, the newly created object won't have + * a prototype at all). This is similar to Object.create(). + * All properties will be created as enumerable, configurable + * and writable properties. + */ + static Local<Object> New(Isolate* isolate, Local<Value> prototype_or_null, + Local<Name>* names, Local<Value>* values, + size_t length); + V8_INLINE static Object* Cast(Value* obj); private: @@ -3760,8 +3756,8 @@ class ReturnValue { } // Local setters template <typename S> - V8_INLINE V8_DEPRECATE_SOON("Use Global<> instead", - void Set(const Persistent<S>& handle)); + V8_INLINE V8_DEPRECATED("Use Global<> instead", + void Set(const Persistent<S>& handle)); template <typename S> V8_INLINE void Set(const Global<S>& handle); template <typename S> @@ -3793,10 +3789,10 @@ class ReturnValue { template<class F> friend class PropertyCallbackInfo; template <class F, class G, class H> friend class PersistentValueMapBase; - V8_INLINE void SetInternal(internal::Object* value) { *value_ = value; } - V8_INLINE internal::Object* GetDefaultValue(); - V8_INLINE explicit ReturnValue(internal::Object** slot); - internal::Object** value_; + V8_INLINE void SetInternal(internal::Address value) { *value_ = value; } + V8_INLINE internal::Address GetDefaultValue(); + V8_INLINE explicit ReturnValue(internal::Address* slot); + internal::Address* value_; }; @@ -3850,10 +3846,10 @@ class FunctionCallbackInfo { static const int kDataIndex = 4; static const int kNewTargetIndex = 5; - V8_INLINE FunctionCallbackInfo(internal::Object** implicit_args, - internal::Object** values, int length); - internal::Object** implicit_args_; - internal::Object** values_; + V8_INLINE FunctionCallbackInfo(internal::Address* implicit_args, + internal::Address* values, int length); + internal::Address* implicit_args_; + internal::Address* values_; int length_; }; @@ -3965,8 +3961,8 @@ class PropertyCallbackInfo { static const int kDataIndex = 5; static const int kThisIndex = 6; - V8_INLINE PropertyCallbackInfo(internal::Object** args) : args_(args) {} - internal::Object** args_; + V8_INLINE PropertyCallbackInfo(internal::Address* args) : args_(args) {} + internal::Address* args_; }; @@ -3988,10 +3984,11 @@ class V8_EXPORT Function : public Object { Local<Value> data = Local<Value>(), int length = 0, ConstructorBehavior behavior = ConstructorBehavior::kAllow, SideEffectType side_effect_type = SideEffectType::kHasSideEffect); - static V8_DEPRECATE_SOON( - "Use maybe version", - Local<Function> New(Isolate* isolate, FunctionCallback callback, - Local<Value> data = Local<Value>(), int length = 0)); + static V8_DEPRECATED("Use maybe version", + Local<Function> New(Isolate* isolate, + FunctionCallback callback, + Local<Value> data = Local<Value>(), + int length = 0)); V8_WARN_UNUSED_RESULT MaybeLocal<Object> NewInstance( Local<Context> context, int argc, Local<Value> argv[]) const; @@ -4010,9 +4007,9 @@ class V8_EXPORT Function : public Object { Local<Context> context, int argc, Local<Value> argv[], SideEffectType side_effect_type = SideEffectType::kHasSideEffect) const; - V8_DEPRECATE_SOON("Use maybe version", - Local<Value> Call(Local<Value> recv, int argc, - Local<Value> argv[])); + V8_DEPRECATED("Use maybe version", + Local<Value> Call(Local<Value> recv, int argc, + Local<Value> argv[])); V8_WARN_UNUSED_RESULT MaybeLocal<Value> Call(Local<Context> context, Local<Value> recv, int argc, Local<Value> argv[]); @@ -4129,6 +4126,10 @@ class V8_EXPORT Promise : public Object { V8_WARN_UNUSED_RESULT MaybeLocal<Promise> Then(Local<Context> context, Local<Function> handler); + V8_WARN_UNUSED_RESULT MaybeLocal<Promise> Then(Local<Context> context, + Local<Function> on_fulfilled, + Local<Function> on_rejected); + /** * Returns true if the promise has at least one derived promise, and * therefore resolve/reject handlers (including default handler). @@ -4146,6 +4147,11 @@ class V8_EXPORT Promise : public Object { */ PromiseState State(); + /** + * Marks this promise as handled to avoid reporting unhandled rejections. + */ + void MarkAsHandled(); + V8_INLINE static Promise* Cast(Value* obj); static const int kEmbedderFieldCount = V8_PROMISE_INTERNAL_FIELD_COUNT; @@ -4188,8 +4194,16 @@ class V8_EXPORT PropertyDescriptor { // GenericDescriptor PropertyDescriptor(); + // DataDescriptor (implicit / DEPRECATED) + // Templatized such that the explicit constructor is chosen first. + // TODO(clemensh): Remove after 7.3 branch. + template <std::nullptr_t = nullptr> + V8_DEPRECATED( + "Use explicit constructor", + PropertyDescriptor(Local<Value> value)); // NOLINT(runtime/explicit) + // DataDescriptor - PropertyDescriptor(Local<Value> value); + explicit PropertyDescriptor(Local<Value> value); // DataDescriptor with writable property PropertyDescriptor(Local<Value> value, bool writable); @@ -4228,6 +4242,11 @@ class V8_EXPORT PropertyDescriptor { PrivateData* private_; }; +// TODO(clemensh): Remove after 7.3 branch. +template <std::nullptr_t> +PropertyDescriptor::PropertyDescriptor(Local<Value> value) + : PropertyDescriptor(value) {} + /** * An instance of the built-in Proxy constructor (ECMA-262, 6th Edition, * 26.2.1). @@ -4253,25 +4272,97 @@ class V8_EXPORT Proxy : public Object { static void CheckCast(Value* obj); }; -// TODO(mtrofin): rename WasmCompiledModule to WasmModuleObject, for -// consistency with internal APIs. -class V8_EXPORT WasmCompiledModule : public Object { +/** + * Points to an unowned continous buffer holding a known number of elements. + * + * This is similar to std::span (under consideration for C++20), but does not + * require advanced C++ support. In the (far) future, this may be replaced with + * or aliased to std::span. + * + * To facilitate future migration, this class exposes a subset of the interface + * implemented by std::span. + */ +template <typename T> +class V8_EXPORT MemorySpan { + public: + /** The default constructor creates an empty span. */ + constexpr MemorySpan() = default; + + constexpr MemorySpan(T* data, size_t size) : data_(data), size_(size) {} + + /** Returns a pointer to the beginning of the buffer. */ + constexpr T* data() const { return data_; } + /** Returns the number of elements that the buffer holds. */ + constexpr size_t size() const { return size_; } + + private: + T* data_ = nullptr; + size_t size_ = 0; +}; + +/** + * An owned byte buffer with associated size. + */ +struct OwnedBuffer { + std::unique_ptr<const uint8_t[]> buffer; + size_t size = 0; + OwnedBuffer(std::unique_ptr<const uint8_t[]> buffer, size_t size) + : buffer(std::move(buffer)), size(size) {} + OwnedBuffer() = default; +}; + +// Wrapper around a compiled WebAssembly module, which is potentially shared by +// different WasmModuleObjects. +class V8_EXPORT CompiledWasmModule { + public: + /** + * Serialize the compiled module. The serialized data does not include the + * wire bytes. + */ + OwnedBuffer Serialize(); + + /** + * Get the (wasm-encoded) wire bytes that were used to compile this module. + */ + MemorySpan<const uint8_t> GetWireBytesRef(); + + private: + explicit CompiledWasmModule(std::shared_ptr<internal::wasm::NativeModule>); + friend class Utils; + + const std::shared_ptr<internal::wasm::NativeModule> native_module_; +}; + +// An instance of WebAssembly.Module. +class V8_EXPORT WasmModuleObject : public Object { public: - typedef std::pair<std::unique_ptr<const uint8_t[]>, size_t> SerializedModule; + // TODO(clemensh): Remove after 7.3 branch. + V8_DEPRECATED("Use OwnedBuffer", typedef) + std::pair<std::unique_ptr<const uint8_t[]>, size_t> SerializedModule; /** * A unowned reference to a byte buffer. + * TODO(clemensh): Remove after 7.3 branch. */ - struct BufferReference { + V8_DEPRECATED("Use MemorySpan<const uint8_t>", struct) BufferReference { const uint8_t* start; size_t size; BufferReference(const uint8_t* start, size_t size) : start(start), size(size) {} + + // Implicit conversion to and from MemorySpan<const uint8_t>. + BufferReference(MemorySpan<const uint8_t> span) // NOLINT(runtime/explicit) + : start(span.data()), size(span.size()) {} + operator MemorySpan<const uint8_t>() const { + return MemorySpan<const uint8_t>{start, size}; + } }; /** * An opaque, native heap object for transferring wasm modules. It * supports move semantics, and does not support copy semantics. + * TODO(wasm): Merge this with CompiledWasmModule once code sharing is always + * enabled. */ class TransferrableModule final { public: @@ -4283,8 +4374,7 @@ class V8_EXPORT WasmCompiledModule : public Object { private: typedef std::shared_ptr<internal::wasm::NativeModule> SharedModule; - typedef std::pair<std::unique_ptr<const uint8_t[]>, size_t> OwnedBuffer; - friend class WasmCompiledModule; + friend class WasmModuleObject; explicit TransferrableModule(SharedModule shared_module) : shared_module_(std::move(shared_module)) {} TransferrableModule(OwnedBuffer serialized, OwnedBuffer bytes) @@ -4303,64 +4393,87 @@ class V8_EXPORT WasmCompiledModule : public Object { TransferrableModule GetTransferrableModule(); /** - * Efficiently re-create a WasmCompiledModule, without recompiling, from + * Efficiently re-create a WasmModuleObject, without recompiling, from * a TransferrableModule. */ - static MaybeLocal<WasmCompiledModule> FromTransferrableModule( + static MaybeLocal<WasmModuleObject> FromTransferrableModule( Isolate* isolate, const TransferrableModule&); /** * Get the wasm-encoded bytes that were used to compile this module. */ - BufferReference GetWasmWireBytesRef(); + V8_DEPRECATED("Use CompiledWasmModule::GetWireBytesRef()", + BufferReference GetWasmWireBytesRef()); + + /** + * Get the compiled module for this module object. The compiled module can be + * shared by several module objects. + */ + CompiledWasmModule GetCompiledModule(); /** * Serialize the compiled module. The serialized data does not include the * uncompiled bytes. */ - SerializedModule Serialize(); + V8_DEPRECATED("Use CompiledWasmModule::Serialize()", + SerializedModule Serialize()); /** * If possible, deserialize the module, otherwise compile it from the provided * uncompiled bytes. */ - static MaybeLocal<WasmCompiledModule> DeserializeOrCompile( - Isolate* isolate, BufferReference serialized_module, - BufferReference wire_bytes); - V8_INLINE static WasmCompiledModule* Cast(Value* obj); + static MaybeLocal<WasmModuleObject> DeserializeOrCompile( + Isolate* isolate, MemorySpan<const uint8_t> serialized_module, + MemorySpan<const uint8_t> wire_bytes); + V8_INLINE static WasmModuleObject* Cast(Value* obj); private: - static MaybeLocal<WasmCompiledModule> Deserialize( - Isolate* isolate, BufferReference serialized_module, - BufferReference wire_bytes); - static MaybeLocal<WasmCompiledModule> Compile(Isolate* isolate, - const uint8_t* start, - size_t length); - static BufferReference AsReference( - const TransferrableModule::OwnedBuffer& buff) { - return {buff.first.get(), buff.second}; + static MaybeLocal<WasmModuleObject> Deserialize( + Isolate* isolate, MemorySpan<const uint8_t> serialized_module, + MemorySpan<const uint8_t> wire_bytes); + static MaybeLocal<WasmModuleObject> Compile(Isolate* isolate, + const uint8_t* start, + size_t length); + static MemorySpan<const uint8_t> AsReference(const OwnedBuffer& buff) { + return {buff.buffer.get(), buff.size}; } - WasmCompiledModule(); + WasmModuleObject(); static void CheckCast(Value* obj); }; +V8_DEPRECATED("Use WasmModuleObject", + typedef WasmModuleObject WasmCompiledModule); + /** * The V8 interface for WebAssembly streaming compilation. When streaming * compilation is initiated, V8 passes a {WasmStreaming} object to the embedder - * such that the embedder can pass the input butes for streaming compilation to + * such that the embedder can pass the input bytes for streaming compilation to * V8. */ class V8_EXPORT WasmStreaming final { public: class WasmStreamingImpl; - WasmStreaming(std::unique_ptr<WasmStreamingImpl> impl); + /** + * Client to receive streaming event notifications. + */ + class Client { + public: + virtual ~Client() = default; + /** + * Passes the fully compiled module to the client. This can be used to + * implement code caching. + */ + virtual void OnModuleCompiled(CompiledWasmModule compiled_module) = 0; + }; + + explicit WasmStreaming(std::unique_ptr<WasmStreamingImpl> impl); ~WasmStreaming(); /** - * Pass a new chunck of bytes to WebAssembly streaming compilation. + * Pass a new chunk of bytes to WebAssembly streaming compilation. * The buffer passed into {OnBytesReceived} is owned by the caller. */ void OnBytesReceived(const uint8_t* bytes, size_t size); @@ -4380,6 +4493,21 @@ class V8_EXPORT WasmStreaming final { void Abort(MaybeLocal<Value> exception); /** + * Passes previously compiled module bytes. This must be called before + * {OnBytesReceived}, {Finish}, or {Abort}. Returns true if the module bytes + * can be used, false otherwise. The buffer passed via {bytes} and {size} + * is owned by the caller. If {SetCompiledModuleBytes} returns true, the + * buffer must remain valid until either {Finish} or {Abort} completes. + */ + bool SetCompiledModuleBytes(const uint8_t* bytes, size_t size); + + /** + * Sets the client object that will receive streaming event notifications. + * This must be called before {OnBytesReceived}, {Finish}, or {Abort}. + */ + void SetClient(std::shared_ptr<Client> client); + + /** * Unpacks a {WasmStreaming} object wrapped in a {Managed} for the embedder. * Since the embedder is on the other side of the API, it cannot unpack the * {Managed} itself. @@ -4588,17 +4716,26 @@ class V8_EXPORT ArrayBuffer : public Object { bool IsExternal() const; /** - * Returns true if this ArrayBuffer may be neutered. + * Returns true if this ArrayBuffer may be detached. */ - bool IsNeuterable() const; + bool IsDetachable() const; + + // TODO(913887): fix the use of 'neuter' in the API. + V8_DEPRECATE_SOON("Use IsDetachable() instead.", + inline bool IsNeuterable() const) { + return IsDetachable(); + } /** - * Neuters this ArrayBuffer and all its views (typed arrays). - * Neutering sets the byte length of the buffer and all typed arrays to zero, + * Detaches this ArrayBuffer and all its views (typed arrays). + * Detaching sets the byte length of the buffer and all typed arrays to zero, * preventing JavaScript from ever accessing underlying backing store. - * ArrayBuffer should have been externalized and must be neuterable. + * ArrayBuffer should have been externalized and must be detachable. */ - void Neuter(); + void Detach(); + + // TODO(913887): fix the use of 'neuter' in the API. + V8_DEPRECATE_SOON("Use Detach() instead.", inline void Neuter()) { Detach(); } /** * Make this ArrayBuffer external. The pointer to underlying memory block @@ -5045,8 +5182,6 @@ class V8_EXPORT SharedArrayBuffer : public Object { */ class V8_EXPORT Date : public Object { public: - static V8_DEPRECATED("Use maybe version.", - Local<Value> New(Isolate* isolate, double time)); static V8_WARN_UNUSED_RESULT MaybeLocal<Value> New(Local<Context> context, double time); @@ -5695,7 +5830,7 @@ class V8_EXPORT FunctionTemplate : public Template { SideEffectType side_effect_type = SideEffectType::kHasSideEffect); /** Returns the unique function instance in the current execution context.*/ - V8_DEPRECATE_SOON("Use maybe version", Local<Function> GetFunction()); + V8_DEPRECATED("Use maybe version", Local<Function> GetFunction()); V8_WARN_UNUSED_RESULT MaybeLocal<Function> GetFunction( Local<Context> context); @@ -5992,7 +6127,7 @@ class V8_EXPORT ObjectTemplate : public Template { size_t index); /** Creates a new instance of this template.*/ - V8_DEPRECATE_SOON("Use maybe version", Local<Object> NewInstance()); + V8_DEPRECATED("Use maybe version", Local<Object> NewInstance()); V8_WARN_UNUSED_RESULT MaybeLocal<Object> NewInstance(Local<Context> context); /** @@ -6212,7 +6347,7 @@ class V8_EXPORT AccessorSignature : public Data { // --- Extensions --- -V8_DEPRECATE_SOON("Implementation detail", class) +V8_DEPRECATED("Implementation detail", class) V8_EXPORT ExternalOneByteStringResourceImpl : public String::ExternalOneByteStringResource { public: @@ -6306,18 +6441,6 @@ class V8_EXPORT ResourceConstraints { void ConfigureDefaults(uint64_t physical_memory, uint64_t virtual_memory_limit); - // Returns the max semi-space size in MB. - V8_DEPRECATED("Use max_semi_space_size_in_kb()", - size_t max_semi_space_size()) { - return max_semi_space_size_in_kb_ / 1024; - } - - // Sets the max semi-space size in MB. - V8_DEPRECATED("Use set_max_semi_space_size_in_kb(size_t limit_in_kb)", - void set_max_semi_space_size(size_t limit_in_mb)) { - max_semi_space_size_in_kb_ = limit_in_mb * 1024; - } - // Returns the max semi-space size in KB. size_t max_semi_space_size_in_kb() const { return max_semi_space_size_in_kb_; @@ -6332,14 +6455,6 @@ class V8_EXPORT ResourceConstraints { void set_max_old_space_size(size_t limit_in_mb) { max_old_space_size_ = limit_in_mb; } - V8_DEPRECATED("max_executable_size_ is subsumed by max_old_space_size_", - size_t max_executable_size() const) { - return max_executable_size_; - } - V8_DEPRECATED("max_executable_size_ is subsumed by max_old_space_size_", - void set_max_executable_size(size_t limit_in_mb)) { - max_executable_size_ = limit_in_mb; - } uint32_t* stack_limit() const { return stack_limit_; } // Sets an address beyond which the VM's stack may not grow. void set_stack_limit(uint32_t* value) { stack_limit_ = value; } @@ -6356,7 +6471,6 @@ class V8_EXPORT ResourceConstraints { // The remaining limits are in MB size_t max_old_space_size_; - size_t max_executable_size_; uint32_t* stack_limit_; size_t code_range_size_; size_t max_zone_pool_size_; @@ -6463,10 +6577,12 @@ typedef void (*HostInitializeImportMetaObjectCallback)(Local<Context> context, * PrepareStackTraceCallback is called when the stack property of an error is * first accessed. The return value will be used as the stack value. If this * callback is registed, the |Error.prepareStackTrace| API will be disabled. + * |sites| is an array of call sites, specified in + * https://github.com/v8/v8/wiki/Stack-Trace-API */ typedef MaybeLocal<Value> (*PrepareStackTraceCallback)(Local<Context> context, Local<Value> error, - Local<StackTrace> trace); + Local<Array> sites); /** * PromiseHook with type kInit is called when a new promise is @@ -6761,21 +6877,6 @@ class V8_EXPORT HeapCodeStatistics { class RetainedObjectInfo; - -/** - * FunctionEntryHook is the type of the profile entry hook called at entry to - * any generated function when function-level profiling is enabled. - * - * \param function the address of the function that's being entered. - * \param return_addr_location points to a location on stack where the machine - * return address resides. This can be used to identify the caller of - * \p function, and/or modified to divert execution when \p function exits. - * - * \note the entry hook must not cause garbage collection. - */ -typedef void (*FunctionEntryHook)(uintptr_t function, - uintptr_t return_addr_location); - /** * A JIT code event is issued each time code is added, moved or removed. * @@ -6937,15 +7038,6 @@ class V8_EXPORT EmbedderHeapTracer { kEmpty, }; - enum ForceCompletionAction { FORCE_COMPLETION, DO_NOT_FORCE_COMPLETION }; - - struct AdvanceTracingActions { - explicit AdvanceTracingActions(ForceCompletionAction force_completion_) - : force_completion(force_completion_) {} - - ForceCompletionAction force_completion; - }; - virtual ~EmbedderHeapTracer() = default; /** @@ -6963,25 +7055,6 @@ class V8_EXPORT EmbedderHeapTracer { virtual void TracePrologue() = 0; /** - * Called to make a tracing step in the embedder. - * - * The embedder is expected to trace its heap starting from wrappers reported - * by RegisterV8References method, and report back all reachable wrappers. - * Furthermore, the embedder is expected to stop tracing by the given - * deadline. - * - * Returns true if there is still work to do. - * - * Note: Only one of the AdvanceTracing methods needs to be overriden by the - * embedder. - */ - V8_DEPRECATED("Use void AdvanceTracing(deadline_in_ms)", - virtual bool AdvanceTracing(double deadline_in_ms, - AdvanceTracingActions actions)) { - return false; - } - - /** * Called to advance tracing in the embedder. * * The embedder is expected to trace its heap starting from wrappers reported @@ -6990,17 +7063,14 @@ class V8_EXPORT EmbedderHeapTracer { * deadline. A deadline of infinity means that tracing should be finished. * * Returns |true| if tracing is done, and false otherwise. - * - * Note: Only one of the AdvanceTracing methods needs to be overriden by the - * embedder. */ - virtual bool AdvanceTracing(double deadline_in_ms); + virtual bool AdvanceTracing(double deadline_in_ms) = 0; /* * Returns true if there no more tracing work to be done (see AdvanceTracing) * and false otherwise. */ - virtual bool IsTracingDone(); + virtual bool IsTracingDone() = 0; /** * Called at the end of a GC cycle. @@ -7012,13 +7082,8 @@ class V8_EXPORT EmbedderHeapTracer { /** * Called upon entering the final marking pause. No more incremental marking * steps will follow this call. - * - * Note: Only one of the EnterFinalPause methods needs to be overriden by the - * embedder. */ - V8_DEPRECATED("Use void EnterFinalPause(EmbedderStackState)", - virtual void EnterFinalPause()) {} - virtual void EnterFinalPause(EmbedderStackState stack_state); + virtual void EnterFinalPause(EmbedderStackState stack_state) = 0; /** * Called when tracing is aborted. @@ -7026,8 +7091,8 @@ class V8_EXPORT EmbedderHeapTracer { * The embedder is expected to throw away all intermediate data and reset to * the initial state. */ - V8_DEPRECATE_SOON("Obsolete as V8 will not abort tracing anymore.", - virtual void AbortTracing()) {} + V8_DEPRECATED("Obsolete as V8 will not abort tracing anymore.", + virtual void AbortTracing()) {} /* * Called by the embedder to request immediate finalization of the currently @@ -7053,13 +7118,6 @@ class V8_EXPORT EmbedderHeapTracer { */ v8::Isolate* isolate() const { return isolate_; } - /** - * Returns the number of wrappers that are still to be traced by the embedder. - */ - V8_DEPRECATED("Use IsTracingDone", virtual size_t NumberOfWrappersToTrace()) { - return 0; - } - protected: v8::Isolate* isolate_ = nullptr; @@ -7069,6 +7127,10 @@ class V8_EXPORT EmbedderHeapTracer { /** * Callback and supporting data used in SnapshotCreator to implement embedder * logic to serialize internal fields. + * Internal fields that directly reference V8 objects are serialized without + * calling this callback. Internal fields that contain aligned pointers are + * serialized by this callback if it returns non-zero result. Otherwise it is + * serialized verbatim. */ struct SerializeInternalFieldsCallback { typedef StartupData (*CallbackFunction)(Local<Object> holder, int index, @@ -7114,8 +7176,7 @@ class V8_EXPORT Isolate { */ struct CreateParams { CreateParams() - : entry_hook(nullptr), - code_event_handler(nullptr), + : code_event_handler(nullptr), snapshot_blob(nullptr), counter_lookup_callback(nullptr), create_histogram_callback(nullptr), @@ -7126,16 +7187,6 @@ class V8_EXPORT Isolate { only_terminate_in_safe_scope(false) {} /** - * The optional entry_hook allows the host application to provide the - * address of a function that's invoked on entry to every V8-generated - * function. Note that entry_hook is invoked at the very start of each - * generated function. - * An entry_hook can only be provided in no-snapshot builds; in snapshot - * builds it must be nullptr. - */ - FunctionEntryHook entry_hook; - - /** * Allows the host application to provide the address of a function that is * notified each time code is added, moved or removed. */ @@ -7220,7 +7271,7 @@ class V8_EXPORT Isolate { */ class V8_EXPORT DisallowJavascriptExecutionScope { public: - enum OnFailure { CRASH_ON_FAILURE, THROW_ON_FAILURE }; + enum OnFailure { CRASH_ON_FAILURE, THROW_ON_FAILURE, DUMP_ON_FAILURE }; DisallowJavascriptExecutionScope(Isolate* isolate, OnFailure on_failure); ~DisallowJavascriptExecutionScope(); @@ -7232,7 +7283,7 @@ class V8_EXPORT Isolate { const DisallowJavascriptExecutionScope&) = delete; private: - bool on_failure_; + OnFailure on_failure_; void* internal_; }; @@ -7254,6 +7305,7 @@ class V8_EXPORT Isolate { private: void* internal_throws_; void* internal_assert_; + void* internal_dump_; }; /** @@ -7377,6 +7429,12 @@ class V8_EXPORT Isolate { kDateToLocaleString = 66, kDateToLocaleDateString = 67, kDateToLocaleTimeString = 68, + kAttemptOverrideReadOnlyOnPrototypeSloppy = 69, + kAttemptOverrideReadOnlyOnPrototypeStrict = 70, + kOptimizedFunctionWithOneShotBytecode = 71, + kRegExpMatchIsTrueishOnNonJSRegExp = 72, + kRegExpMatchIsFalseishOnJSRegExp = 73, + kDateGetTimezoneOffset = 74, // If you add new values here, you'll also need to update Chromium's: // web_feature.mojom, UseCounterCallback.cpp, and enums.xml. V8 changes to @@ -7642,9 +7700,6 @@ class V8_EXPORT Isolate { */ void SetIdle(bool is_idle); - /** Returns the ArrayBuffer::Allocator used in this isolate. */ - ArrayBuffer::Allocator* GetArrayBufferAllocator(); - /** Returns true if this isolate has a current context. */ bool InContext(); @@ -7655,7 +7710,8 @@ class V8_EXPORT Isolate { Local<Context> GetCurrentContext(); /** Returns the last context entered through V8's C++ API. */ - Local<Context> GetEnteredContext(); + V8_DEPRECATED("Use GetEnteredOrMicrotaskContext().", + Local<Context> GetEnteredContext()); /** * Returns either the last context entered through V8's C++ API, or the @@ -7781,7 +7837,7 @@ class V8_EXPORT Isolate { */ typedef void (*AtomicsWaitCallback)(AtomicsWaitEvent event, Local<SharedArrayBuffer> array_buffer, - size_t offset_in_bytes, int32_t value, + size_t offset_in_bytes, int64_t value, double timeout_in_ms, AtomicsWaitWakeHandle* stop_handle, void* data); @@ -8130,13 +8186,9 @@ class V8_EXPORT Isolate { void GetCodeRange(void** start, size_t* length_in_bytes); /** - * Returns a memory range containing the code for V8's embedded functions - * (e.g. builtins) which are shared across isolates. - * - * If embedded builtins are disabled, then the memory range will be a null - * pointer with 0 length. + * Returns the UnwindState necessary for use with the Unwinder API. */ - MemoryRange GetEmbeddedCodeRange(); + UnwindState GetUnwindState(); /** Set the callback to invoke in case of fatal errors. */ void SetFatalErrorHandler(FatalErrorCallback that); @@ -8162,6 +8214,14 @@ class V8_EXPORT Isolate { size_t heap_limit); /** + * If the heap limit was changed by the NearHeapLimitCallback, then the + * initial heap limit will be restored once the heap size falls below the + * given threshold percentage of the initial heap limit. + * The threshold percentage is a number in (0.0, 1.0) range. + */ + void AutomaticallyRestoreInitialHeapLimit(double threshold_percent = 0.5); + + /** * Set the callback to invoke to check if code generation from * strings should be allowed. */ @@ -8182,7 +8242,9 @@ class V8_EXPORT Isolate { void SetWasmModuleCallback(ExtensionCallback callback); void SetWasmInstanceCallback(ExtensionCallback callback); - void SetWasmCompileStreamingCallback(ApiImplementationCallback callback); + V8_DEPRECATED( + "The callback set in SetWasmStreamingCallback is used now", + void SetWasmCompileStreamingCallback(ApiImplementationCallback callback)); void SetWasmStreamingCallback(WasmStreamingCallback callback); @@ -8257,7 +8319,9 @@ class V8_EXPORT Isolate { * garbage collection but is free to visit an arbitrary superset of these * objects. */ - void VisitHandlesForPartialDependence(PersistentHandleVisitor* visitor); + V8_DEPRECATE_SOON( + "Use VisitHandlesWithClassIds", + void VisitHandlesForPartialDependence(PersistentHandleVisitor* visitor)); /** * Iterates through all the persistent handles in the current isolate's heap @@ -8294,7 +8358,7 @@ class V8_EXPORT Isolate { template <class K, class V, class Traits> friend class PersistentValueMapBase; - internal::Object** GetDataFromSnapshotOnce(size_t index); + internal::Address* GetDataFromSnapshotOnce(size_t index); void ReportExternalAllocationLimitReached(); void CheckMemoryPressure(); }; @@ -8476,15 +8540,17 @@ class V8_EXPORT V8 { * \param context The third argument passed to the Linux signal handler, which * points to a ucontext_t structure. */ - static bool TryHandleSignal(int signal_number, void* info, void* context); + V8_DEPRECATE_SOON("Use TryHandleWebAssemblyTrapPosix", + static bool TryHandleSignal(int signal_number, void* info, + void* context)); #endif // V8_OS_POSIX /** * Enable the default signal handler rather than using one provided by the * embedder. */ - V8_DEPRECATE_SOON("Use EnableWebAssemblyTrapHandler", - static bool RegisterDefaultSignalHandler()); + V8_DEPRECATED("Use EnableWebAssemblyTrapHandler", + static bool RegisterDefaultSignalHandler()); /** * Activate trap-based bounds checking for WebAssembly. @@ -8497,26 +8563,20 @@ class V8_EXPORT V8 { private: V8(); - static internal::Object** GlobalizeReference(internal::Isolate* isolate, - internal::Object** handle); - static internal::Object** CopyPersistent(internal::Object** handle); - static void DisposeGlobal(internal::Object** global_handle); - static void MakeWeak(internal::Object** location, void* data, + static internal::Address* GlobalizeReference(internal::Isolate* isolate, + internal::Address* handle); + static internal::Address* CopyPersistent(internal::Address* handle); + static void DisposeGlobal(internal::Address* global_handle); + static void MakeWeak(internal::Address* location, void* data, WeakCallbackInfo<void>::Callback weak_callback, WeakCallbackType type); - static void MakeWeak(internal::Object** location, void* data, - // Must be 0 or -1. - int internal_field_index1, - // Must be 1 or -1. - int internal_field_index2, - WeakCallbackInfo<void>::Callback weak_callback); - static void MakeWeak(internal::Object*** location_addr); - static void* ClearWeak(internal::Object** location); - static void AnnotateStrongRetainer(internal::Object** location, + static void MakeWeak(internal::Address** location_addr); + static void* ClearWeak(internal::Address* location); + static void AnnotateStrongRetainer(internal::Address* location, const char* label); static Value* Eternalize(Isolate* isolate, Value* handle); - static void RegisterExternallyReferencedObject(internal::Object** object, + static void RegisterExternallyReferencedObject(internal::Address* location, internal::Isolate* isolate); template <class K, class V, class T> @@ -8637,8 +8697,8 @@ class V8_EXPORT SnapshotCreator { void operator=(const SnapshotCreator&) = delete; private: - size_t AddData(Local<Context> context, internal::Object* object); - size_t AddData(internal::Object* object); + size_t AddData(Local<Context> context, internal::Address object); + size_t AddData(internal::Address object); void* data_; }; @@ -8665,6 +8725,14 @@ class Maybe { V8_INLINE T ToChecked() const { return FromJust(); } /** + * Short-hand for ToChecked(), which doesn't return a value. To be used, where + * the actual value of the Maybe is not needed like Object::Set. + */ + V8_INLINE void Check() const { + if (V8_UNLIKELY(!IsJust())) V8::FromJustIsNothing(); + } + + /** * Converts this Maybe<> to a value of type T. If this Maybe<> is * nothing (empty), |false| is returned and |out| is left untouched. */ @@ -9159,7 +9227,7 @@ class V8_EXPORT Context { * stack. * https://html.spec.whatwg.org/multipage/webappapis.html#backup-incumbent-settings-object-stack */ - class V8_EXPORT BackupIncumbentScope { + class V8_EXPORT BackupIncumbentScope final { public: /** * |backup_incumbent_context| is pushed onto the backup incumbent settings @@ -9168,10 +9236,20 @@ class V8_EXPORT Context { explicit BackupIncumbentScope(Local<Context> backup_incumbent_context); ~BackupIncumbentScope(); + /** + * Returns address that is comparable with JS stack address. Note that JS + * stack may be allocated separately from the native stack. See also + * |TryCatch::JSStackComparableAddress| for details. + */ + uintptr_t JSStackComparableAddress() const { + return js_stack_comparable_address_; + } + private: friend class internal::Isolate; Local<Context> backup_incumbent_context_; + uintptr_t js_stack_comparable_address_ = 0; const BackupIncumbentScope* prev_ = nullptr; }; @@ -9181,7 +9259,7 @@ class V8_EXPORT Context { friend class Object; friend class Function; - internal::Object** GetDataFromSnapshotOnce(size_t index); + internal::Address* GetDataFromSnapshotOnce(size_t index); Local<Value> SlowGetEmbedderData(int index); void* SlowGetAlignedPointerFromEmbedderData(int index); }; @@ -9310,6 +9388,55 @@ class V8_EXPORT Locker { internal::Isolate* isolate_; }; +/** + * Various helpers for skipping over V8 frames in a given stack. + * + * The unwinder API is only supported on the x64 architecture. + */ +class V8_EXPORT Unwinder { + public: + /** + * Attempt to unwind the stack to the most recent C++ frame. This function is + * signal-safe and does not access any V8 state and thus doesn't require an + * Isolate. + * + * The unwinder needs to know the location of the JS Entry Stub (a piece of + * code that is run when C++ code calls into generated JS code). This is used + * for edge cases where the current frame is being constructed or torn down + * when the stack sample occurs. + * + * The unwinder also needs the virtual memory range of all possible V8 code + * objects. There are two ranges required - the heap code range and the range + * for code embedded in the binary. The V8 API provides all required inputs + * via an UnwindState object through the Isolate::GetUnwindState() API. These + * values will not change after Isolate initialization, so the same + * |unwind_state| can be used for multiple calls. + * + * \param unwind_state Input state for the Isolate that the stack comes from. + * \param register_state The current registers. This is an in-out param that + * will be overwritten with the register values after unwinding, on success. + * \param stack_base The resulting stack pointer and frame pointer values are + * bounds-checked against the stack_base and the original stack pointer value + * to ensure that they are valid locations in the given stack. If these values + * or any intermediate frame pointer values used during unwinding are ever out + * of these bounds, unwinding will fail. + * + * \return True on success. + */ + static bool TryUnwindV8Frames(const UnwindState& unwind_state, + RegisterState* register_state, + const void* stack_base); + + /** + * Whether the PC is within the V8 code range represented by code_range or + * embedded_code_range in |unwind_state|. + * + * If this returns false, then calling UnwindV8Frames() with the same PC + * and unwind_state will always fail. If it returns true, then unwinding may + * (but not necessarily) be successful. + */ + static bool PCIsInV8(const UnwindState& unwind_state, void* pc); +}; // --- Implementation --- @@ -9328,7 +9455,7 @@ template <class T> Local<T> Local<T>::New(Isolate* isolate, T* that) { if (that == nullptr) return Local<T>(); T* that_ptr = that; - internal::Object** p = reinterpret_cast<internal::Object**>(that_ptr); + internal::Address* p = reinterpret_cast<internal::Address*>(that_ptr); return Local<T>(reinterpret_cast<T*>(HandleScope::CreateHandle( reinterpret_cast<internal::Isolate*>(isolate), *p))); } @@ -9371,7 +9498,7 @@ void* WeakCallbackInfo<T>::GetInternalField(int index) const { template <class T> T* PersistentBase<T>::New(Isolate* isolate, T* that) { if (that == nullptr) return nullptr; - internal::Object** p = reinterpret_cast<internal::Object**>(that); + internal::Address* p = reinterpret_cast<internal::Address*>(that); return reinterpret_cast<T*>( V8::GlobalizeReference(reinterpret_cast<internal::Isolate*>(isolate), p)); @@ -9384,7 +9511,7 @@ void Persistent<T, M>::Copy(const Persistent<S, M2>& that) { TYPE_CHECK(T, S); this->Reset(); if (that.IsEmpty()) return; - internal::Object** p = reinterpret_cast<internal::Object**>(that.val_); + internal::Address* p = reinterpret_cast<internal::Address*>(that.val_); this->val_ = reinterpret_cast<T*>(V8::CopyPersistent(p)); M::Copy(that, this); } @@ -9393,7 +9520,7 @@ template <class T> bool PersistentBase<T>::IsIndependent() const { typedef internal::Internals I; if (this->IsEmpty()) return false; - return I::GetNodeFlag(reinterpret_cast<internal::Object**>(this->val_), + return I::GetNodeFlag(reinterpret_cast<internal::Address*>(this->val_), I::kNodeIsIndependentShift); } @@ -9402,7 +9529,7 @@ bool PersistentBase<T>::IsNearDeath() const { typedef internal::Internals I; if (this->IsEmpty()) return false; uint8_t node_state = - I::GetNodeState(reinterpret_cast<internal::Object**>(this->val_)); + I::GetNodeState(reinterpret_cast<internal::Address*>(this->val_)); return node_state == I::kNodeStateIsNearDeathValue || node_state == I::kNodeStateIsPendingValue; } @@ -9412,15 +9539,15 @@ template <class T> bool PersistentBase<T>::IsWeak() const { typedef internal::Internals I; if (this->IsEmpty()) return false; - return I::GetNodeState(reinterpret_cast<internal::Object**>(this->val_)) == - I::kNodeStateIsWeakValue; + return I::GetNodeState(reinterpret_cast<internal::Address*>(this->val_)) == + I::kNodeStateIsWeakValue; } template <class T> void PersistentBase<T>::Reset() { if (this->IsEmpty()) return; - V8::DisposeGlobal(reinterpret_cast<internal::Object**>(this->val_)); + V8::DisposeGlobal(reinterpret_cast<internal::Address*>(this->val_)); val_ = nullptr; } @@ -9452,25 +9579,25 @@ V8_INLINE void PersistentBase<T>::SetWeak( P* parameter, typename WeakCallbackInfo<P>::Callback callback, WeakCallbackType type) { typedef typename WeakCallbackInfo<void>::Callback Callback; - V8::MakeWeak(reinterpret_cast<internal::Object**>(this->val_), parameter, + V8::MakeWeak(reinterpret_cast<internal::Address*>(this->val_), parameter, reinterpret_cast<Callback>(callback), type); } template <class T> void PersistentBase<T>::SetWeak() { - V8::MakeWeak(reinterpret_cast<internal::Object***>(&this->val_)); + V8::MakeWeak(reinterpret_cast<internal::Address**>(&this->val_)); } template <class T> template <typename P> P* PersistentBase<T>::ClearWeak() { return reinterpret_cast<P*>( - V8::ClearWeak(reinterpret_cast<internal::Object**>(this->val_))); + V8::ClearWeak(reinterpret_cast<internal::Address*>(this->val_))); } template <class T> void PersistentBase<T>::AnnotateStrongRetainer(const char* label) { - V8::AnnotateStrongRetainer(reinterpret_cast<internal::Object**>(this->val_), + V8::AnnotateStrongRetainer(reinterpret_cast<internal::Address*>(this->val_), label); } @@ -9478,7 +9605,7 @@ template <class T> void PersistentBase<T>::RegisterExternalReference(Isolate* isolate) const { if (IsEmpty()) return; V8::RegisterExternallyReferencedObject( - reinterpret_cast<internal::Object**>(this->val_), + reinterpret_cast<internal::Address*>(this->val_), reinterpret_cast<internal::Isolate*>(isolate)); } @@ -9486,7 +9613,7 @@ template <class T> void PersistentBase<T>::MarkIndependent() { typedef internal::Internals I; if (this->IsEmpty()) return; - I::UpdateNodeFlag(reinterpret_cast<internal::Object**>(this->val_), true, + I::UpdateNodeFlag(reinterpret_cast<internal::Address*>(this->val_), true, I::kNodeIsIndependentShift); } @@ -9494,7 +9621,7 @@ template <class T> void PersistentBase<T>::MarkActive() { typedef internal::Internals I; if (this->IsEmpty()) return; - I::UpdateNodeFlag(reinterpret_cast<internal::Object**>(this->val_), true, + I::UpdateNodeFlag(reinterpret_cast<internal::Address*>(this->val_), true, I::kNodeIsActiveShift); } @@ -9503,7 +9630,7 @@ template <class T> void PersistentBase<T>::SetWrapperClassId(uint16_t class_id) { typedef internal::Internals I; if (this->IsEmpty()) return; - internal::Object** obj = reinterpret_cast<internal::Object**>(this->val_); + internal::Address* obj = reinterpret_cast<internal::Address*>(this->val_); uint8_t* addr = reinterpret_cast<uint8_t*>(obj) + I::kNodeClassIdOffset; *reinterpret_cast<uint16_t*>(addr) = class_id; } @@ -9513,14 +9640,13 @@ template <class T> uint16_t PersistentBase<T>::WrapperClassId() const { typedef internal::Internals I; if (this->IsEmpty()) return 0; - internal::Object** obj = reinterpret_cast<internal::Object**>(this->val_); + internal::Address* obj = reinterpret_cast<internal::Address*>(this->val_); uint8_t* addr = reinterpret_cast<uint8_t*>(obj) + I::kNodeClassIdOffset; return *reinterpret_cast<uint16_t*>(addr); } - -template<typename T> -ReturnValue<T>::ReturnValue(internal::Object** slot) : value_(slot) {} +template <typename T> +ReturnValue<T>::ReturnValue(internal::Address* slot) : value_(slot) {} template<typename T> template<typename S> @@ -9529,7 +9655,7 @@ void ReturnValue<T>::Set(const Persistent<S>& handle) { if (V8_UNLIKELY(handle.IsEmpty())) { *value_ = GetDefaultValue(); } else { - *value_ = *reinterpret_cast<internal::Object**>(*handle); + *value_ = *reinterpret_cast<internal::Address*>(*handle); } } @@ -9540,7 +9666,7 @@ void ReturnValue<T>::Set(const Global<S>& handle) { if (V8_UNLIKELY(handle.IsEmpty())) { *value_ = GetDefaultValue(); } else { - *value_ = *reinterpret_cast<internal::Object**>(*handle); + *value_ = *reinterpret_cast<internal::Address*>(*handle); } } @@ -9551,7 +9677,7 @@ void ReturnValue<T>::Set(const Local<S> handle) { if (V8_UNLIKELY(handle.IsEmpty())) { *value_ = GetDefaultValue(); } else { - *value_ = *reinterpret_cast<internal::Object**>(*handle); + *value_ = *reinterpret_cast<internal::Address*>(*handle); } } @@ -9639,15 +9765,15 @@ void ReturnValue<T>::Set(S* whatever) { TYPE_CHECK(S*, Primitive); } -template<typename T> -internal::Object* ReturnValue<T>::GetDefaultValue() { +template <typename T> +internal::Address ReturnValue<T>::GetDefaultValue() { // Default value is always the pointer below value_ on the stack. return value_[-1]; } template <typename T> -FunctionCallbackInfo<T>::FunctionCallbackInfo(internal::Object** implicit_args, - internal::Object** values, +FunctionCallbackInfo<T>::FunctionCallbackInfo(internal::Address* implicit_args, + internal::Address* values, int length) : implicit_args_(implicit_args), values_(values), length_(length) {} @@ -9816,20 +9942,22 @@ AccessorSignature* AccessorSignature::Cast(Data* data) { } Local<Value> Object::GetInternalField(int index) { -#ifndef V8_ENABLE_CHECKS - typedef internal::Object O; +#if !defined(V8_ENABLE_CHECKS) && !defined(V8_COMPRESS_POINTERS) + typedef internal::Address A; typedef internal::Internals I; - O* obj = *reinterpret_cast<O**>(this); + A obj = *reinterpret_cast<A*>(this); // Fast path: If the object is a plain JSObject, which is the common case, we // know where to find the internal fields and can return the value directly. auto instance_type = I::GetInstanceType(obj); if (instance_type == I::kJSObjectType || instance_type == I::kJSApiObjectType || instance_type == I::kJSSpecialApiObjectType) { - int offset = I::kJSObjectHeaderSize + (internal::kApiPointerSize * index); - O* value = I::ReadField<O*>(obj, offset); - O** result = HandleScope::CreateHandle( - reinterpret_cast<internal::NeverReadOnlySpaceObject*>(obj), value); + int offset = I::kJSObjectHeaderSizeForEmbedderFields + + (I::kEmbedderDataSlotSize * index); + A value = I::ReadTaggedAnyField(obj, offset); + internal::Isolate* isolate = + internal::IsolateFromNeverReadOnlySpaceObject(obj); + A* result = HandleScope::CreateHandle(isolate, value); return Local<Value>(reinterpret_cast<Value*>(result)); } #endif @@ -9838,18 +9966,19 @@ Local<Value> Object::GetInternalField(int index) { void* Object::GetAlignedPointerFromInternalField(int index) { -#ifndef V8_ENABLE_CHECKS - typedef internal::Object O; +#if !defined(V8_ENABLE_CHECKS) && !defined(V8_COMPRESS_POINTERS) + typedef internal::Address A; typedef internal::Internals I; - O* obj = *reinterpret_cast<O**>(this); + A obj = *reinterpret_cast<A*>(this); // Fast path: If the object is a plain JSObject, which is the common case, we // know where to find the internal fields and can return the value directly. auto instance_type = I::GetInstanceType(obj); if (V8_LIKELY(instance_type == I::kJSObjectType || instance_type == I::kJSApiObjectType || instance_type == I::kJSSpecialApiObjectType)) { - int offset = I::kJSObjectHeaderSize + (internal::kApiPointerSize * index); - return I::ReadField<void*>(obj, offset); + int offset = I::kJSObjectHeaderSizeForEmbedderFields + + (I::kEmbedderDataSlotSize * index); + return I::ReadRawField<void*>(obj, offset); } #endif return SlowGetAlignedPointerFromInternalField(index); @@ -9864,7 +9993,7 @@ String* String::Cast(v8::Value* value) { Local<String> String::Empty(Isolate* isolate) { - typedef internal::Object* S; + typedef internal::Address S; typedef internal::Internals I; I::CheckInitialized(isolate); S* slot = I::GetRoot(isolate, I::kEmptyStringRootIndex); @@ -9873,13 +10002,13 @@ Local<String> String::Empty(Isolate* isolate) { String::ExternalStringResource* String::GetExternalStringResource() const { - typedef internal::Object O; + typedef internal::Address A; typedef internal::Internals I; - O* obj = *reinterpret_cast<O* const*>(this); + A obj = *reinterpret_cast<const A*>(this); ExternalStringResource* result; if (I::IsExternalTwoByteString(I::GetInstanceType(obj))) { - void* value = I::ReadField<void*>(obj, I::kStringResourceOffset); + void* value = I::ReadRawField<void*>(obj, I::kStringResourceOffset); result = reinterpret_cast<String::ExternalStringResource*>(value); } else { result = GetExternalStringResourceSlow(); @@ -9893,15 +10022,15 @@ String::ExternalStringResource* String::GetExternalStringResource() const { String::ExternalStringResourceBase* String::GetExternalStringResourceBase( String::Encoding* encoding_out) const { - typedef internal::Object O; + typedef internal::Address A; typedef internal::Internals I; - O* obj = *reinterpret_cast<O* const*>(this); + A obj = *reinterpret_cast<const A*>(this); int type = I::GetInstanceType(obj) & I::kFullStringRepresentationMask; *encoding_out = static_cast<Encoding>(type & I::kStringEncodingMask); ExternalStringResourceBase* resource; if (type == I::kExternalOneByteRepresentationTag || type == I::kExternalTwoByteRepresentationTag) { - void* value = I::ReadField<void*>(obj, I::kStringResourceOffset); + void* value = I::ReadRawField<void*>(obj, I::kStringResourceOffset); resource = static_cast<ExternalStringResourceBase*>(value); } else { resource = GetExternalStringResourceBaseSlow(encoding_out); @@ -9922,9 +10051,9 @@ bool Value::IsUndefined() const { } bool Value::QuickIsUndefined() const { - typedef internal::Object O; + typedef internal::Address A; typedef internal::Internals I; - O* obj = *reinterpret_cast<O* const*>(this); + A obj = *reinterpret_cast<const A*>(this); if (!I::HasHeapObjectTag(obj)) return false; if (I::GetInstanceType(obj) != I::kOddballType) return false; return (I::GetOddballKind(obj) == I::kUndefinedOddballKind); @@ -9940,9 +10069,9 @@ bool Value::IsNull() const { } bool Value::QuickIsNull() const { - typedef internal::Object O; + typedef internal::Address A; typedef internal::Internals I; - O* obj = *reinterpret_cast<O* const*>(this); + A obj = *reinterpret_cast<const A*>(this); if (!I::HasHeapObjectTag(obj)) return false; if (I::GetInstanceType(obj) != I::kOddballType) return false; return (I::GetOddballKind(obj) == I::kNullOddballKind); @@ -9957,9 +10086,9 @@ bool Value::IsNullOrUndefined() const { } bool Value::QuickIsNullOrUndefined() const { - typedef internal::Object O; + typedef internal::Address A; typedef internal::Internals I; - O* obj = *reinterpret_cast<O* const*>(this); + A obj = *reinterpret_cast<const A*>(this); if (!I::HasHeapObjectTag(obj)) return false; if (I::GetInstanceType(obj) != I::kOddballType) return false; int kind = I::GetOddballKind(obj); @@ -9975,9 +10104,9 @@ bool Value::IsString() const { } bool Value::QuickIsString() const { - typedef internal::Object O; + typedef internal::Address A; typedef internal::Internals I; - O* obj = *reinterpret_cast<O* const*>(this); + A obj = *reinterpret_cast<const A*>(this); if (!I::HasHeapObjectTag(obj)) return false; return (I::GetInstanceType(obj) < I::kFirstNonstringType); } @@ -10159,11 +10288,11 @@ Proxy* Proxy::Cast(v8::Value* value) { return static_cast<Proxy*>(value); } -WasmCompiledModule* WasmCompiledModule::Cast(v8::Value* value) { +WasmModuleObject* WasmModuleObject::Cast(v8::Value* value) { #ifdef V8_ENABLE_CHECKS CheckCast(value); #endif - return static_cast<WasmCompiledModule*>(value); + return static_cast<WasmModuleObject*>(value); } Promise::Resolver* Promise::Resolver::Cast(v8::Value* value) { @@ -10352,7 +10481,7 @@ bool PropertyCallbackInfo<T>::ShouldThrowOnError() const { Local<Primitive> Undefined(Isolate* isolate) { - typedef internal::Object* S; + typedef internal::Address S; typedef internal::Internals I; I::CheckInitialized(isolate); S* slot = I::GetRoot(isolate, I::kUndefinedValueRootIndex); @@ -10361,7 +10490,7 @@ Local<Primitive> Undefined(Isolate* isolate) { Local<Primitive> Null(Isolate* isolate) { - typedef internal::Object* S; + typedef internal::Address S; typedef internal::Internals I; I::CheckInitialized(isolate); S* slot = I::GetRoot(isolate, I::kNullValueRootIndex); @@ -10370,7 +10499,7 @@ Local<Primitive> Null(Isolate* isolate) { Local<Boolean> True(Isolate* isolate) { - typedef internal::Object* S; + typedef internal::Address S; typedef internal::Internals I; I::CheckInitialized(isolate); S* slot = I::GetRoot(isolate, I::kTrueValueRootIndex); @@ -10379,7 +10508,7 @@ Local<Boolean> True(Isolate* isolate) { Local<Boolean> False(Isolate* isolate) { - typedef internal::Object* S; + typedef internal::Address S; typedef internal::Internals I; I::CheckInitialized(isolate); S* slot = I::GetRoot(isolate, I::kFalseValueRootIndex); @@ -10414,7 +10543,7 @@ MaybeLocal<T> Isolate::GetDataFromSnapshotOnce(size_t index) { int64_t Isolate::AdjustAmountOfExternalAllocatedMemory( int64_t change_in_bytes) { typedef internal::Internals I; - const int64_t kMemoryReducerActivationLimit = 32 * 1024 * 1024; + constexpr int64_t kMemoryReducerActivationLimit = 32 * 1024 * 1024; int64_t* external_memory = reinterpret_cast<int64_t*>( reinterpret_cast<uint8_t*>(this) + I::kExternalMemoryOffset); int64_t* external_memory_limit = reinterpret_cast<int64_t*>( @@ -10422,15 +10551,14 @@ int64_t Isolate::AdjustAmountOfExternalAllocatedMemory( int64_t* external_memory_at_last_mc = reinterpret_cast<int64_t*>(reinterpret_cast<uint8_t*>(this) + I::kExternalMemoryAtLastMarkCompactOffset); - const int64_t amount = *external_memory + change_in_bytes; + const int64_t amount = *external_memory + change_in_bytes; *external_memory = amount; int64_t allocation_diff_since_last_mc = - *external_memory_at_last_mc - *external_memory; - allocation_diff_since_last_mc = allocation_diff_since_last_mc < 0 - ? -allocation_diff_since_last_mc - : allocation_diff_since_last_mc; + *external_memory - *external_memory_at_last_mc; + // Only check memory pressure and potentially trigger GC if the amount of + // external memory increased. if (allocation_diff_since_last_mc > kMemoryReducerActivationLimit) { CheckMemoryPressure(); } @@ -10446,12 +10574,13 @@ int64_t Isolate::AdjustAmountOfExternalAllocatedMemory( } Local<Value> Context::GetEmbedderData(int index) { -#ifndef V8_ENABLE_CHECKS - typedef internal::Object O; +#if !defined(V8_ENABLE_CHECKS) && !defined(V8_COMPRESS_POINTERS) + typedef internal::Address A; typedef internal::Internals I; - auto* context = *reinterpret_cast<internal::NeverReadOnlySpaceObject**>(this); - O** result = - HandleScope::CreateHandle(context, I::ReadEmbedderData<O*>(this, index)); + internal::Isolate* isolate = internal::IsolateFromNeverReadOnlySpaceObject( + *reinterpret_cast<A*>(this)); + A* result = + HandleScope::CreateHandle(isolate, I::ReadEmbedderData<A>(this, index)); return Local<Value>(reinterpret_cast<Value*>(result)); #else return SlowGetEmbedderData(index); @@ -10460,7 +10589,7 @@ Local<Value> Context::GetEmbedderData(int index) { void* Context::GetAlignedPointerFromEmbedderData(int index) { -#ifndef V8_ENABLE_CHECKS +#if !defined(V8_ENABLE_CHECKS) && !defined(V8_COMPRESS_POINTERS) typedef internal::Internals I; return I::ReadEmbedderData<void*>(this, index); #else @@ -10478,14 +10607,14 @@ MaybeLocal<T> Context::GetDataFromSnapshotOnce(size_t index) { template <class T> size_t SnapshotCreator::AddData(Local<Context> context, Local<T> object) { T* object_ptr = *object; - internal::Object** p = reinterpret_cast<internal::Object**>(object_ptr); + internal::Address* p = reinterpret_cast<internal::Address*>(object_ptr); return AddData(context, *p); } template <class T> size_t SnapshotCreator::AddData(Local<T> object) { T* object_ptr = *object; - internal::Object** p = reinterpret_cast<internal::Object**>(object_ptr); + internal::Address* p = reinterpret_cast<internal::Address*>(object_ptr); return AddData(*p); } diff --git a/deps/v8/include/v8config.h b/deps/v8/include/v8config.h index 93c4629825..e30a582e8f 100644 --- a/deps/v8/include/v8config.h +++ b/deps/v8/include/v8config.h @@ -161,14 +161,8 @@ // // C++11 feature detection // -// V8_HAS_CXX11_ALIGNAS - alignas specifier supported -// V8_HAS_CXX11_ALIGNOF - alignof(type) operator supported -// // Compiler-specific feature detection // -// V8_HAS___ALIGNOF - __alignof(type) operator supported -// V8_HAS___ALIGNOF__ - __alignof__(type) operator supported -// V8_HAS_ATTRIBUTE_ALIGNED - __attribute__((aligned(n))) supported // V8_HAS_ATTRIBUTE_ALWAYS_INLINE - __attribute__((always_inline)) // supported // V8_HAS_ATTRIBUTE_DEPRECATED - __attribute__((deprecated)) supported @@ -188,7 +182,6 @@ // V8_HAS_BUILTIN_SADD_OVERFLOW - __builtin_sadd_overflow() supported // V8_HAS_BUILTIN_SSUB_OVERFLOW - __builtin_ssub_overflow() supported // V8_HAS_BUILTIN_UADD_OVERFLOW - __builtin_uadd_overflow() supported -// V8_HAS_DECLSPEC_ALIGN - __declspec(align(n)) supported // V8_HAS_DECLSPEC_DEPRECATED - __declspec(deprecated) supported // V8_HAS_DECLSPEC_NOINLINE - __declspec(noinline) supported // V8_HAS_DECLSPEC_SELECTANY - __declspec(selectany) supported @@ -207,11 +200,6 @@ # define V8_CC_GNU 1 #endif -// Clang defines __alignof__ as alias for __alignof -# define V8_HAS___ALIGNOF 1 -# define V8_HAS___ALIGNOF__ V8_HAS___ALIGNOF - -# define V8_HAS_ATTRIBUTE_ALIGNED (__has_attribute(aligned)) # define V8_HAS_ATTRIBUTE_ALWAYS_INLINE (__has_attribute(always_inline)) # define V8_HAS_ATTRIBUTE_DEPRECATED (__has_attribute(deprecated)) # define V8_HAS_ATTRIBUTE_DEPRECATED_MESSAGE \ @@ -234,7 +222,9 @@ # define V8_HAS_BUILTIN_SSUB_OVERFLOW (__has_builtin(__builtin_ssub_overflow)) # define V8_HAS_BUILTIN_UADD_OVERFLOW (__has_builtin(__builtin_uadd_overflow)) -# define V8_HAS_CXX11_ALIGNAS (__has_feature(cxx_alignas)) +# if __cplusplus >= 201402L +# define V8_CAN_HAVE_DCHECK_IN_CONSTEXPR 1 +# endif #elif defined(__GNUC__) @@ -250,9 +240,6 @@ # endif # define V8_CC_MINGW (V8_CC_MINGW32 || V8_CC_MINGW64) -# define V8_HAS___ALIGNOF__ (V8_GNUC_PREREQ(4, 3, 0)) - -# define V8_HAS_ATTRIBUTE_ALIGNED (V8_GNUC_PREREQ(2, 95, 0)) // 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. @@ -271,17 +258,11 @@ # define V8_HAS_BUILTIN_FRAME_ADDRESS (V8_GNUC_PREREQ(2, 96, 0)) # define V8_HAS_BUILTIN_POPCOUNT (V8_GNUC_PREREQ(3, 4, 0)) -# if __cplusplus >= 201103L -# define V8_HAS_CXX11_ALIGNAS (V8_GNUC_PREREQ(4, 8, 0)) -# define V8_HAS_CXX11_ALIGNOF (V8_GNUC_PREREQ(4, 8, 0)) -# endif #endif #if defined(_MSC_VER) # define V8_CC_MSVC 1 -# define V8_HAS___ALIGNOF 1 -# define V8_HAS_DECLSPEC_ALIGN 1 # define V8_HAS_DECLSPEC_DEPRECATED 1 # define V8_HAS_DECLSPEC_NOINLINE 1 # define V8_HAS_DECLSPEC_SELECTANY 1 @@ -359,58 +340,6 @@ #endif -// This macro allows to specify memory alignment for structs, classes, etc. -// Use like: -// class V8_ALIGNED(16) MyClass { ... }; -// V8_ALIGNED(32) int array[42]; -#if V8_HAS_CXX11_ALIGNAS -# define V8_ALIGNED(n) alignas(n) -#elif V8_HAS_ATTRIBUTE_ALIGNED -# define V8_ALIGNED(n) __attribute__((aligned(n))) -#elif V8_HAS_DECLSPEC_ALIGN -# define V8_ALIGNED(n) __declspec(align(n)) -#else -# define V8_ALIGNED(n) /* NOT SUPPORTED */ -#endif - - -// This macro is similar to V8_ALIGNED(), but takes a type instead of size -// in bytes. If the compiler does not supports using the alignment of the -// |type|, it will align according to the |alignment| instead. For example, -// Visual Studio C++ cannot combine __declspec(align) and __alignof. The -// |alignment| must be a literal that is used as a kind of worst-case fallback -// alignment. -// Use like: -// struct V8_ALIGNAS(AnotherClass, 16) NewClass { ... }; -// V8_ALIGNAS(double, 8) int array[100]; -#if V8_HAS_CXX11_ALIGNAS -# define V8_ALIGNAS(type, alignment) alignas(type) -#elif V8_HAS___ALIGNOF__ && V8_HAS_ATTRIBUTE_ALIGNED -# define V8_ALIGNAS(type, alignment) __attribute__((aligned(__alignof__(type)))) -#else -# define V8_ALIGNAS(type, alignment) V8_ALIGNED(alignment) -#endif - - -// This macro returns alignment in bytes (an integer power of two) required for -// any instance of the given type, which is either complete type, an array type, -// or a reference type. -// Use like: -// size_t alignment = V8_ALIGNOF(double); -#if V8_HAS_CXX11_ALIGNOF -# define V8_ALIGNOF(type) alignof(type) -#elif V8_HAS___ALIGNOF -# define V8_ALIGNOF(type) __alignof(type) -#elif V8_HAS___ALIGNOF__ -# define V8_ALIGNOF(type) __alignof__(type) -#else -// Note that alignment of a type within a struct can be less than the -// alignment of the type stand-alone (because of ancient ABIs), so this -// should only be used as a last resort. -namespace v8 { template <typename T> class AlignOfHelper { char c; T t; }; } -# define V8_ALIGNOF(type) (sizeof(::v8::AlignOfHelper<type>) - sizeof(type)) -#endif - // Annotate a function indicating the caller must examine the return value. // Use like: // int foo() V8_WARN_UNUSED_RESULT; |