Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion common.gypi
Original file line number Diff line number Diff line change
Expand Up @@ -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 #####

Expand Down
3 changes: 0 additions & 3 deletions deps/v8/src/builtins/base.tq
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
9 changes: 0 additions & 9 deletions deps/v8/src/compiler/access-builder.cc
Original file line number Diff line number Diff line change
Expand Up @@ -891,15 +891,6 @@ FieldAccess AccessBuilder::ForNameRawHashField() {
return access;
}

// static
FieldAccess AccessBuilder::ForFreeSpaceSize() {
FieldAccess access = {kTaggedBase, FreeSpace::kSizeOffset,
MaybeHandle<Name>(), OptionalMapRef(),
Type::SignedSmall(), MachineType::TaggedSigned(),
kNoWriteBarrier};
return access;
}

// static
FieldAccess AccessBuilder::ForStringLength() {
FieldAccess access = {kTaggedBase,
Expand Down
3 changes: 0 additions & 3 deletions deps/v8/src/compiler/access-builder.h
Original file line number Diff line number Diff line change
Expand Up @@ -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();

Expand Down
12 changes: 12 additions & 0 deletions deps/v8/src/diagnostics/objects-debug.cc
Original file line number Diff line number Diff line change
Expand Up @@ -330,6 +330,10 @@ void HeapObject::HeapObjectVerify(Isolate* isolate) {
Cast<BigIntBase>(*this)->BigIntBaseVerify(isolate);
break;

case FREE_SPACE_TYPE:
Cast<FreeSpace>(*this)->FreeSpaceVerify(isolate);
break;

case JS_CLASS_CONSTRUCTOR_TYPE:
case JS_PROMISE_CONSTRUCTOR_TYPE:
case JS_REG_EXP_CONSTRUCTOR_TYPE:
Expand Down Expand Up @@ -362,6 +366,14 @@ void HeapObject::VerifyCodePointer(Isolate* isolate, Tagged<Object> p) {
CHECK(IsInstructionStream(Cast<HeapObject>(p), cage_base));
}

void FreeSpace::FreeSpaceVerify(Isolate* isolate) {
CHECK(IsFreeSpace(this));
{
Tagged<Object> size_in_tagged = size_in_tagged_.Relaxed_Load();
CHECK(IsSmi(size_in_tagged));
}
}

void Name::NameVerify(Isolate* isolate) {
PrimitiveHeapObjectVerify(isolate);
CHECK(IsName(this));
Expand Down
3 changes: 3 additions & 0 deletions deps/v8/src/diagnostics/objects-printer.cc
Original file line number Diff line number Diff line change
Expand Up @@ -357,6 +357,9 @@ void HeapObject::HeapObjectPrint(std::ostream& os) {
case BIG_INT_BASE_TYPE:
Cast<BigIntBase>(*this)->BigIntBasePrint(os);
break;
case FREE_SPACE_TYPE:
Cast<FreeSpace>(*this)->FreeSpacePrint(os);
break;
case JS_CLASS_CONSTRUCTOR_TYPE:
case JS_PROMISE_CONSTRUCTOR_TYPE:
case JS_REG_EXP_CONSTRUCTOR_TYPE:
Expand Down
8 changes: 4 additions & 4 deletions deps/v8/src/heap/free-list.cc
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ void FreeListCategory::Unlink(FreeList* owner) {

void FreeListCategory::Reset(FreeList* owner) {
Unlink(owner);
set_top(FreeSpace());
set_top(Tagged<FreeSpace>());
available_ = 0;
}

Expand All @@ -39,7 +39,7 @@ Tagged<FreeSpace> FreeListCategory::PickNodeFromList(size_t minimum_size,
DCHECK(MemoryChunk::FromHeapObject(node)->CanAllocate());
if (static_cast<size_t>(node->Size()) < minimum_size) {
*node_size = 0;
return FreeSpace();
return Tagged<FreeSpace>();
}
set_top(node->next());
*node_size = node->Size();
Expand Down Expand Up @@ -80,7 +80,7 @@ Tagged<FreeSpace> FreeListCategory::SearchForNodeInList(size_t minimum_size,

prev_non_evac_node = cur_node;
}
return FreeSpace();
return Tagged<FreeSpace>();
}

void FreeListCategory::Free(const WritableFreeSpace& writable_free_space,
Expand Down Expand Up @@ -140,7 +140,7 @@ Tagged<FreeSpace> 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<FreeSpace>();
Tagged<FreeSpace> node = category->PickNodeFromList(minimum_size, node_size);
if (!node.is_null()) {
DecreaseAvailableBytes(*node_size);
Expand Down
7 changes: 4 additions & 3 deletions deps/v8/src/heap/heap.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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<Object> 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;
}

Expand Down
2 changes: 1 addition & 1 deletion deps/v8/src/heap/heap.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
4 changes: 2 additions & 2 deletions deps/v8/src/heap/sweeper.cc
Original file line number Diff line number Diff line change
Expand Up @@ -947,11 +947,11 @@ std::optional<base::AddressRegion> 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));
Expand Down
15 changes: 6 additions & 9 deletions deps/v8/src/objects/fixed-array.h
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand All @@ -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 <class Super, bool kLengthEqualsCapacity>
Expand Down Expand Up @@ -181,11 +184,8 @@ class TaggedArrayBase : public detail::TaggedArrayHeader<ShapeT, Super> {
// 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 =
Expand Down Expand Up @@ -425,11 +425,8 @@ class PrimitiveArrayBase : public detail::ArrayHeaderBase<Super, true> {
// 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 =
Expand Down
35 changes: 18 additions & 17 deletions deps/v8/src/objects/free-space-inl.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,34 +19,34 @@
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, kSizeOffset>(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, offsetof(FreeSpace, size_in_tagged_)>(
Smi::FromInt(size / kTaggedSize), tag);
}

int FreeSpace::Size() { return size(kRelaxedLoad); }

Tagged<FreeSpace> FreeSpace::next() const {
DCHECK(IsValid());
#ifdef V8_EXTERNAL_CODE_SPACE
intptr_t diff_to_next =
static_cast<intptr_t>(TaggedField<Smi, kNextOffset>::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<FreeSpace>(Tagged<Object>(next_ptr));
#else
return UncheckedCast<FreeSpace>(
TaggedField<Object, kNextOffset>::load(*this));
return next_.Relaxed_Load();
#endif // V8_EXTERNAL_CODE_SPACE
}

Expand All @@ -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, kNextOffset>(Smi::zero(),
kRelaxedStore);
writable_free_space.WriteHeaderSlot<Smi, offsetof(FreeSpace, next_)>(
Smi::zero(), kRelaxedStore);
return;
}
intptr_t diff_to_next = next.ptr() - ptr();
DCHECK(IsAligned(diff_to_next, kObjectAlignment));
writable_free_space.WriteHeaderSlot<Smi, kNextOffset>(
writable_free_space.WriteHeaderSlot<Smi, offsetof(FreeSpace, next_)>(
Smi::FromIntptr(diff_to_next / kObjectAlignment), kRelaxedStore);
#else
writable_free_space.WriteHeaderSlot<Object, kNextOffset>(next, kRelaxedStore);
writable_free_space.WriteHeaderSlot<Object, offsetof(FreeSpace, next_)>(
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
Expand Down
23 changes: 18 additions & 5 deletions deps/v8/src/objects/free-space.h
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand All @@ -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<FreeSpace, HeapObject> {
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();
Expand All @@ -45,13 +50,21 @@ class FreeSpace : public TorqueGeneratedFreeSpace<FreeSpace, HeapObject> {

// Dispatched behavior.
DECL_PRINTER(FreeSpace)
DECL_VERIFIER(FreeSpace)

class BodyDescriptor;

private:
friend class Heap;

inline bool IsValid() const;

TQ_OBJECT_CONSTRUCTORS(FreeSpace)
TaggedMember<Smi> size_in_tagged_;
#ifdef V8_EXTERNAL_CODE_SPACE
TaggedMember<Smi> next_;
#else
TaggedMember<FreeSpace> next_;
#endif // V8_EXTERNAL_CODE_SPACE
};

} // namespace internal
Expand Down
5 changes: 1 addition & 4 deletions deps/v8/src/objects/free-space.tq
Original file line number Diff line number Diff line change
Expand Up @@ -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;
2 changes: 2 additions & 0 deletions deps/v8/src/objects/heap-object.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,8 @@ V8_OBJECT class HeapObjectLayout {
inline void set_map_safe_transition(IsolateT* isolate, Tagged<Map> value,
ReleaseStoreTag);

inline ObjectSlot map_slot() const;

inline void set_map_safe_transition_no_write_barrier(
Isolate* isolate, Tagged<Map> value, RelaxedStoreTag = kRelaxedStore);

Expand Down
4 changes: 4 additions & 0 deletions deps/v8/src/objects/objects-inl.h
Original file line number Diff line number Diff line change
Expand Up @@ -1496,6 +1496,10 @@ DEF_ACQUIRE_GETTER(HeapObject, map, Tagged<Map>) {
return map_word(cage_base, kAcquireLoad).ToMap();
}

ObjectSlot HeapObjectLayout::map_slot() const {
return Tagged<HeapObject>(this)->map_slot();
}

ObjectSlot HeapObject::map_slot() const {
return ObjectSlot(MapField::address(*this));
}
Expand Down
2 changes: 1 addition & 1 deletion deps/v8/src/snapshot/read-only-serializer.cc
Original file line number Diff line number Diff line change
Expand Up @@ -421,7 +421,7 @@ std::vector<ReadOnlyHeapImageSerializer::MemoryRegion> GetUnmappedRegions(
Tagged<HeapObject> 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<ReadOnlyHeapImageSerializer::MemoryRegion> unmapped;
if (wasm_null.address() > wasm_null_padding_start) {
unmapped.push_back({wasm_null_padding_start,
Expand Down
1 change: 0 additions & 1 deletion deps/v8/src/torque/constants.h
Original file line number Diff line number Diff line change
Expand Up @@ -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";
Expand Down
2 changes: 0 additions & 2 deletions deps/v8/src/torque/implementation-visitor.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down
Loading
Loading