diff --git a/common.gypi b/common.gypi index f6d13602384837..a6896876d45e4c 100644 --- a/common.gypi +++ b/common.gypi @@ -38,7 +38,7 @@ # Reset this number to 0 on major V8 upgrades. # Increment by one for each non-official patch applied to deps/v8. - 'v8_embedder_string': '-node.30', + 'v8_embedder_string': '-node.31', ##### V8 defaults for Node.js ##### diff --git a/deps/v8/src/builtins/base.tq b/deps/v8/src/builtins/base.tq index b5f1e324a1002b..8f27a20034ef3f 100644 --- a/deps/v8/src/builtins/base.tq +++ b/deps/v8/src/builtins/base.tq @@ -58,9 +58,6 @@ type Zero extends PositiveSmi; // A tagged value represented by an all-zero bitpattern. type TaggedZeroPattern extends TaggedIndex; -// A value with the size of Tagged which may contain arbitrary data. -type Uninitialized extends Tagged; - type BuiltinsName extends int31 constexpr 'Builtin'; type UseCounterFeature extends int31 diff --git a/deps/v8/src/compiler/access-builder.cc b/deps/v8/src/compiler/access-builder.cc index cb94b3b57c8d52..826f1c1418719d 100644 --- a/deps/v8/src/compiler/access-builder.cc +++ b/deps/v8/src/compiler/access-builder.cc @@ -891,15 +891,6 @@ FieldAccess AccessBuilder::ForNameRawHashField() { return access; } -// static -FieldAccess AccessBuilder::ForFreeSpaceSize() { - FieldAccess access = {kTaggedBase, FreeSpace::kSizeOffset, - MaybeHandle(), OptionalMapRef(), - Type::SignedSmall(), MachineType::TaggedSigned(), - kNoWriteBarrier}; - return access; -} - // static FieldAccess AccessBuilder::ForStringLength() { FieldAccess access = {kTaggedBase, diff --git a/deps/v8/src/compiler/access-builder.h b/deps/v8/src/compiler/access-builder.h index 392089b79296ee..ac7a2713b57da4 100644 --- a/deps/v8/src/compiler/access-builder.h +++ b/deps/v8/src/compiler/access-builder.h @@ -266,9 +266,6 @@ class V8_EXPORT_PRIVATE AccessBuilder final // Provides access to Name::raw_hash_field() field. static FieldAccess ForNameRawHashField(); - // Provides access to FreeSpace::size() field - static FieldAccess ForFreeSpaceSize(); - // Provides access to String::length() field. static FieldAccess ForStringLength(); diff --git a/deps/v8/src/diagnostics/objects-debug.cc b/deps/v8/src/diagnostics/objects-debug.cc index 1f0d0f46acae8a..1223b47383dd8e 100644 --- a/deps/v8/src/diagnostics/objects-debug.cc +++ b/deps/v8/src/diagnostics/objects-debug.cc @@ -330,6 +330,10 @@ void HeapObject::HeapObjectVerify(Isolate* isolate) { Cast(*this)->BigIntBaseVerify(isolate); break; + case FREE_SPACE_TYPE: + Cast(*this)->FreeSpaceVerify(isolate); + break; + case JS_CLASS_CONSTRUCTOR_TYPE: case JS_PROMISE_CONSTRUCTOR_TYPE: case JS_REG_EXP_CONSTRUCTOR_TYPE: @@ -362,6 +366,14 @@ void HeapObject::VerifyCodePointer(Isolate* isolate, Tagged p) { CHECK(IsInstructionStream(Cast(p), cage_base)); } +void FreeSpace::FreeSpaceVerify(Isolate* isolate) { + CHECK(IsFreeSpace(this)); + { + Tagged size_in_tagged = size_in_tagged_.Relaxed_Load(); + CHECK(IsSmi(size_in_tagged)); + } +} + void Name::NameVerify(Isolate* isolate) { PrimitiveHeapObjectVerify(isolate); CHECK(IsName(this)); diff --git a/deps/v8/src/diagnostics/objects-printer.cc b/deps/v8/src/diagnostics/objects-printer.cc index d3e5ec68657f77..3c8720dfaf399b 100644 --- a/deps/v8/src/diagnostics/objects-printer.cc +++ b/deps/v8/src/diagnostics/objects-printer.cc @@ -357,6 +357,9 @@ void HeapObject::HeapObjectPrint(std::ostream& os) { case BIG_INT_BASE_TYPE: Cast(*this)->BigIntBasePrint(os); break; + case FREE_SPACE_TYPE: + Cast(*this)->FreeSpacePrint(os); + break; case JS_CLASS_CONSTRUCTOR_TYPE: case JS_PROMISE_CONSTRUCTOR_TYPE: case JS_REG_EXP_CONSTRUCTOR_TYPE: diff --git a/deps/v8/src/heap/free-list.cc b/deps/v8/src/heap/free-list.cc index 689a16112b4cf4..7ee848b0d2978d 100644 --- a/deps/v8/src/heap/free-list.cc +++ b/deps/v8/src/heap/free-list.cc @@ -28,7 +28,7 @@ void FreeListCategory::Unlink(FreeList* owner) { void FreeListCategory::Reset(FreeList* owner) { Unlink(owner); - set_top(FreeSpace()); + set_top(Tagged()); available_ = 0; } @@ -39,7 +39,7 @@ Tagged FreeListCategory::PickNodeFromList(size_t minimum_size, DCHECK(MemoryChunk::FromHeapObject(node)->CanAllocate()); if (static_cast(node->Size()) < minimum_size) { *node_size = 0; - return FreeSpace(); + return Tagged(); } set_top(node->next()); *node_size = node->Size(); @@ -80,7 +80,7 @@ Tagged FreeListCategory::SearchForNodeInList(size_t minimum_size, prev_non_evac_node = cur_node; } - return FreeSpace(); + return Tagged(); } void FreeListCategory::Free(const WritableFreeSpace& writable_free_space, @@ -140,7 +140,7 @@ Tagged FreeList::TryFindNodeIn(FreeListCategoryType type, size_t minimum_size, size_t* node_size) { FreeListCategory* category = categories_[type]; - if (category == nullptr) return FreeSpace(); + if (category == nullptr) return Tagged(); Tagged node = category->PickNodeFromList(minimum_size, node_size); if (!node.is_null()) { DecreaseAvailableBytes(*node_size); diff --git a/deps/v8/src/heap/heap.cc b/deps/v8/src/heap/heap.cc index f4e94e406e2690..62ae8089e9d73a 100644 --- a/deps/v8/src/heap/heap.cc +++ b/deps/v8/src/heap/heap.cc @@ -6247,13 +6247,14 @@ void Heap::TearDown() { } // static -bool Heap::IsFreeSpaceValid(FreeSpace object) { +bool Heap::IsFreeSpaceValid(const FreeSpace* object) { Heap* heap = HeapUtils::GetOwnerHeap(object); Tagged free_space_map = heap->isolate()->root(RootIndex::kFreeSpaceMap); CHECK(!heap->deserialization_complete() || - object.map_slot().contains_map_value(free_space_map.ptr())); - CHECK_LE(FreeSpace::kNextOffset + kTaggedSize, object.size(kRelaxedLoad)); + object->map_slot().contains_map_value(free_space_map.ptr())); + CHECK_LE(offsetof(FreeSpace, next_) + kTaggedSize, + object->size(kRelaxedLoad)); return true; } diff --git a/deps/v8/src/heap/heap.h b/deps/v8/src/heap/heap.h index f2c5a25010d2a8..c209a1c98d9860 100644 --- a/deps/v8/src/heap/heap.h +++ b/deps/v8/src/heap/heap.h @@ -352,7 +352,7 @@ class Heap final { collector == GarbageCollector::MINOR_MARK_SWEEPER; } - V8_EXPORT_PRIVATE static bool IsFreeSpaceValid(FreeSpace object); + V8_EXPORT_PRIVATE static bool IsFreeSpaceValid(const FreeSpace* object); static inline GarbageCollector YoungGenerationCollector() { return (v8_flags.minor_ms) ? GarbageCollector::MINOR_MARK_SWEEPER diff --git a/deps/v8/src/heap/sweeper.cc b/deps/v8/src/heap/sweeper.cc index c89bf286ed4d9d..02c080b86aaa39 100644 --- a/deps/v8/src/heap/sweeper.cc +++ b/deps/v8/src/heap/sweeper.cc @@ -947,11 +947,11 @@ std::optional Sweeper::ComputeDiscardMemoryArea( void Sweeper::ZeroOrDiscardUnusedMemory(PageMetadata* page, Address addr, size_t size) { - if (size < FreeSpace::kSize) { + if (size < sizeof(FreeSpace)) { return; } - const Address unused_start = addr + FreeSpace::kSize; + const Address unused_start = addr + sizeof(FreeSpace); DCHECK(page->ContainsLimit(unused_start)); const Address unused_end = addr + size; DCHECK(page->ContainsLimit(unused_end)); diff --git a/deps/v8/src/objects/fixed-array.h b/deps/v8/src/objects/fixed-array.h index 19c4a6fb6112b3..885f332ad7a480 100644 --- a/deps/v8/src/objects/fixed-array.h +++ b/deps/v8/src/objects/fixed-array.h @@ -9,6 +9,7 @@ #include "src/common/globals.h" #include "src/handles/maybe-handles.h" +#include "src/objects/free-space.h" #include "src/objects/heap-object.h" #include "src/objects/instance-type.h" #include "src/objects/maybe-object.h" @@ -29,8 +30,10 @@ namespace v8::internal { // Limit all fixed arrays to the same max capacity, so that non-resizing // transitions between different elements kinds (like Smi to Double) will not // error. +// This could be larger, but the next power of two up would push the maximum +// byte size of FixedDoubleArray out of int32 range. static constexpr int kMaxFixedArrayCapacity = - V8_LOWER_LIMITS_MODE_BOOL ? (16 * 1024 * 1024) : (64 * 1024 * 1024); + V8_LOWER_LIMITS_MODE_BOOL ? (16 * 1024 * 1024) : (128 * 1024 * 1024); namespace detail { template @@ -181,11 +184,8 @@ class TaggedArrayBase : public detail::TaggedArrayHeader { // Maximal allowed capacity, in number of elements. Chosen s.t. the byte size // fits into a Smi which is necessary for being able to create a free space // filler. - // TODO(jgruber): The kMaxCapacity could be larger (`(Smi::kMaxValue - - // Shape::kHeaderSize) / kElementSize`), but our tests rely on a - // smaller maximum to avoid timeouts. static constexpr int kMaxCapacity = kMaxFixedArrayCapacity; - static_assert(Smi::IsValid(SizeFor(kMaxCapacity))); + static_assert(SizeFor(kMaxCapacity) <= FreeSpace::kMaxSizeInBytes); // Maximally allowed length for regular (non large object space) object. static constexpr int kMaxRegularCapacity = @@ -425,11 +425,8 @@ class PrimitiveArrayBase : public detail::ArrayHeaderBase { // Maximal allowed length, in number of elements. Chosen s.t. the byte size // fits into a Smi which is necessary for being able to create a free space // filler. - // TODO(jgruber): The kMaxLength could be larger (`(Smi::kMaxValue - - // sizeof(Header)) / kElementSize`), but our tests rely on a - // smaller maximum to avoid timeouts. static constexpr int kMaxLength = kMaxFixedArrayCapacity; - static_assert(Smi::IsValid(SizeFor(kMaxLength))); + static_assert(SizeFor(kMaxLength) <= FreeSpace::kMaxSizeInBytes); // Maximally allowed length for regular (non large object space) object. static constexpr int kMaxRegularLength = diff --git a/deps/v8/src/objects/free-space-inl.h b/deps/v8/src/objects/free-space-inl.h index 4384a0087563d5..324889794bbf3c 100644 --- a/deps/v8/src/objects/free-space-inl.h +++ b/deps/v8/src/objects/free-space-inl.h @@ -19,17 +19,19 @@ namespace v8 { namespace internal { -#include "torque-generated/src/objects/free-space-tq-inl.inc" - -TQ_OBJECT_CONSTRUCTORS_IMPL(FreeSpace) - -RELAXED_SMI_ACCESSORS(FreeSpace, size, kSizeOffset) +int FreeSpace::size(RelaxedLoadTag) const { + return size_in_tagged_.Relaxed_Load().value() * kTaggedSize; +} // static inline void FreeSpace::SetSize(const WritableFreeSpace& writable_free_space, int size, RelaxedStoreTag tag) { - writable_free_space.WriteHeaderSlot(Smi::FromInt(size), - tag); + // For size <= 2 * kTaggedSize, we expect to use one/two pointer filler maps. + DCHECK_GT(size, 2 * kTaggedSize); + DCHECK_EQ(size % kTaggedSize, 0); + writable_free_space + .WriteHeaderSlot( + Smi::FromInt(size / kTaggedSize), tag); } int FreeSpace::Size() { return size(kRelaxedLoad); } @@ -37,16 +39,14 @@ int FreeSpace::Size() { return size(kRelaxedLoad); } Tagged FreeSpace::next() const { DCHECK(IsValid()); #ifdef V8_EXTERNAL_CODE_SPACE - intptr_t diff_to_next = - static_cast(TaggedField::load(*this).value()); + intptr_t diff_to_next{next_.Relaxed_Load().value()}; if (diff_to_next == 0) { - return FreeSpace(); + return {}; } Address next_ptr = ptr() + diff_to_next * kObjectAlignment; return UncheckedCast(Tagged(next_ptr)); #else - return UncheckedCast( - TaggedField::load(*this)); + return next_.Relaxed_Load(); #endif // V8_EXTERNAL_CODE_SPACE } @@ -56,20 +56,21 @@ void FreeSpace::SetNext(const WritableFreeSpace& writable_free_space, #ifdef V8_EXTERNAL_CODE_SPACE if (next.is_null()) { - writable_free_space.WriteHeaderSlot(Smi::zero(), - kRelaxedStore); + writable_free_space.WriteHeaderSlot( + Smi::zero(), kRelaxedStore); return; } intptr_t diff_to_next = next.ptr() - ptr(); DCHECK(IsAligned(diff_to_next, kObjectAlignment)); - writable_free_space.WriteHeaderSlot( + writable_free_space.WriteHeaderSlot( Smi::FromIntptr(diff_to_next / kObjectAlignment), kRelaxedStore); #else - writable_free_space.WriteHeaderSlot(next, kRelaxedStore); + writable_free_space.WriteHeaderSlot( + next, kRelaxedStore); #endif // V8_EXTERNAL_CODE_SPACE } -bool FreeSpace::IsValid() const { return Heap::IsFreeSpaceValid(*this); } +bool FreeSpace::IsValid() const { return Heap::IsFreeSpaceValid(this); } } // namespace internal } // namespace v8 diff --git a/deps/v8/src/objects/free-space.h b/deps/v8/src/objects/free-space.h index 517240f8aff7ae..e89466b4a816a0 100644 --- a/deps/v8/src/objects/free-space.h +++ b/deps/v8/src/objects/free-space.h @@ -5,16 +5,17 @@ #ifndef V8_OBJECTS_FREE_SPACE_H_ #define V8_OBJECTS_FREE_SPACE_H_ +#include "src/common/globals.h" #include "src/objects/heap-object.h" +#include "src/objects/smi.h" // Has to be the last include (doesn't have include guards): #include "src/objects/object-macros.h" +#include "src/objects/tagged-field.h" namespace v8 { namespace internal { -#include "torque-generated/src/objects/free-space-tq.inc" - // FreeSpace are fixed-size free memory blocks used by the heap and GC. // They look like heap objects (are heap object tagged and have a map) so that // the heap remains iterable. They have a size and a next pointer. @@ -30,10 +31,14 @@ namespace internal { // 31 bits), // b) it's independent of the pointer compression base and pointer compression // scheme. -class FreeSpace : public TorqueGeneratedFreeSpace { +class FreeSpace : public HeapObjectLayout { public: + static constexpr uint32_t kMaxSizeInBytes = + uint32_t{Smi::kMaxValue} * kTaggedSize; + // [size]: size of the free space including the header. - DECL_RELAXED_INT_ACCESSORS(size) + inline int size(RelaxedLoadTag) const; + static inline void SetSize(const WritableFreeSpace& writable_free_space, int size, RelaxedStoreTag); inline int Size(); @@ -45,13 +50,21 @@ class FreeSpace : public TorqueGeneratedFreeSpace { // Dispatched behavior. DECL_PRINTER(FreeSpace) + DECL_VERIFIER(FreeSpace) class BodyDescriptor; private: + friend class Heap; + inline bool IsValid() const; - TQ_OBJECT_CONSTRUCTORS(FreeSpace) + TaggedMember size_in_tagged_; +#ifdef V8_EXTERNAL_CODE_SPACE + TaggedMember next_; +#else + TaggedMember next_; +#endif // V8_EXTERNAL_CODE_SPACE }; } // namespace internal diff --git a/deps/v8/src/objects/free-space.tq b/deps/v8/src/objects/free-space.tq index acdf1de97b0206..638c5a1dd8a623 100644 --- a/deps/v8/src/objects/free-space.tq +++ b/deps/v8/src/objects/free-space.tq @@ -2,7 +2,4 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -extern class FreeSpace extends HeapObject { - size: Smi; - next: FreeSpace|Smi|Uninitialized; -} +extern class FreeSpace extends HeapObject; diff --git a/deps/v8/src/objects/heap-object.h b/deps/v8/src/objects/heap-object.h index f1d04b536b2a47..8a45de7d258c2e 100644 --- a/deps/v8/src/objects/heap-object.h +++ b/deps/v8/src/objects/heap-object.h @@ -48,6 +48,8 @@ V8_OBJECT class HeapObjectLayout { inline void set_map_safe_transition(IsolateT* isolate, Tagged value, ReleaseStoreTag); + inline ObjectSlot map_slot() const; + inline void set_map_safe_transition_no_write_barrier( Isolate* isolate, Tagged value, RelaxedStoreTag = kRelaxedStore); diff --git a/deps/v8/src/objects/objects-inl.h b/deps/v8/src/objects/objects-inl.h index ff5ca70f3fdce7..849003fd2ea3a8 100644 --- a/deps/v8/src/objects/objects-inl.h +++ b/deps/v8/src/objects/objects-inl.h @@ -1496,6 +1496,10 @@ DEF_ACQUIRE_GETTER(HeapObject, map, Tagged) { return map_word(cage_base, kAcquireLoad).ToMap(); } +ObjectSlot HeapObjectLayout::map_slot() const { + return Tagged(this)->map_slot(); +} + ObjectSlot HeapObject::map_slot() const { return ObjectSlot(MapField::address(*this)); } diff --git a/deps/v8/src/snapshot/read-only-serializer.cc b/deps/v8/src/snapshot/read-only-serializer.cc index fa60b3d07e00b6..0178607289563f 100644 --- a/deps/v8/src/snapshot/read-only-serializer.cc +++ b/deps/v8/src/snapshot/read-only-serializer.cc @@ -421,7 +421,7 @@ std::vector GetUnmappedRegions( Tagged wasm_null_padding = ro_roots.wasm_null_padding(); CHECK(IsFreeSpace(wasm_null_padding)); Address wasm_null_padding_start = - wasm_null_padding.address() + FreeSpace::kHeaderSize; + wasm_null_padding.address() + sizeof(FreeSpace); std::vector unmapped; if (wasm_null.address() > wasm_null_padding_start) { unmapped.push_back({wasm_null_padding_start, diff --git a/deps/v8/src/torque/constants.h b/deps/v8/src/torque/constants.h index ccfa2a5f52dc57..3a7cef24b96e08 100644 --- a/deps/v8/src/torque/constants.h +++ b/deps/v8/src/torque/constants.h @@ -37,7 +37,6 @@ static const char* const JSOBJECT_TYPE_STRING = "JSObject"; static const char* const SMI_TYPE_STRING = "Smi"; static const char* const TAGGED_TYPE_STRING = "Tagged"; static const char* const STRONG_TAGGED_TYPE_STRING = "StrongTagged"; -static const char* const UNINITIALIZED_TYPE_STRING = "Uninitialized"; static const char* const UNINITIALIZED_HEAP_OBJECT_TYPE_STRING = "UninitializedHeapObject"; static const char* const RAWPTR_TYPE_STRING = "RawPtr"; diff --git a/deps/v8/src/torque/implementation-visitor.cc b/deps/v8/src/torque/implementation-visitor.cc index 95f42ab919e123..fc4dbbcc3877a1 100644 --- a/deps/v8/src/torque/implementation-visitor.cc +++ b/deps/v8/src/torque/implementation-visitor.cc @@ -5307,8 +5307,6 @@ void GenerateClassFieldVerifier(const std::string& class_name, // Protected pointer fields cannot be read or verified from torque yet. if (field_type->IsSubtypeOf(TypeOracle::GetProtectedPointerType())) return; if (field_type == TypeOracle::GetFloat64OrUndefinedOrHoleType()) return; - // Do not verify if the field may be uninitialized. - if (TypeOracle::GetUninitializedType()->IsSubtypeOf(field_type)) return; std::string field_start_offset; if (f.index) { diff --git a/deps/v8/src/torque/type-oracle.h b/deps/v8/src/torque/type-oracle.h index 97fcd5df548f83..b96f347e1bb1c8 100644 --- a/deps/v8/src/torque/type-oracle.h +++ b/deps/v8/src/torque/type-oracle.h @@ -249,10 +249,6 @@ class TypeOracle : public base::ContextualClass { return Get().GetBuiltinType(STRONG_TAGGED_TYPE_STRING); } - static const Type* GetUninitializedType() { - return Get().GetBuiltinType(UNINITIALIZED_TYPE_STRING); - } - static const Type* GetUninitializedHeapObjectType() { return Get().GetBuiltinType( QualifiedName({TORQUE_INTERNAL_NAMESPACE_STRING}, diff --git a/deps/v8/test/mjsunit/regress/regress-crbug-1057653.js b/deps/v8/test/mjsunit/regress/regress-crbug-1057653.js index 343e72367a516a..3ca12e097b2949 100644 --- a/deps/v8/test/mjsunit/regress/regress-crbug-1057653.js +++ b/deps/v8/test/mjsunit/regress/regress-crbug-1057653.js @@ -3,6 +3,6 @@ // found in the LICENSE file. Object.prototype.length = 3642395160; -const array = new Float32Array(2**27); +const array = new Float32Array(2**28); assertThrows(() => {for (const key in array) {}}, RangeError); diff --git a/deps/v8/test/unittests/torque/torque-unittest.cc b/deps/v8/test/unittests/torque/torque-unittest.cc index 900c770d070e4f..6141c2e0b85a1c 100644 --- a/deps/v8/test/unittests/torque/torque-unittest.cc +++ b/deps/v8/test/unittests/torque/torque-unittest.cc @@ -48,7 +48,6 @@ type StrongTagged extends Tagged type Smi extends StrongTagged generates 'TNode' constexpr 'Smi'; type WeakHeapObject extends Tagged; type Weak extends WeakHeapObject; -type Uninitialized extends Tagged; type TaggedIndex extends StrongTagged; type TaggedZeroPattern extends TaggedIndex;