Skip to content

Commit 168229f

Browse files
deps: patch V8 to 15.6.75.33
Refs: v8/v8@15.6.75.25...15.6.75.33 PR-URL: #67174 Reviewed-By: Chengzhong Wu <legendecas@gmail.com> Reviewed-By: Luigi Pinca <luigipinca@gmail.com> Reviewed-By: Joyee Cheung <joyeec9h3@gmail.com>
1 parent 2265763 commit 168229f

22 files changed

Lines changed: 535 additions & 101 deletions

‎deps/v8/include/cppgc/heap-consistency.h‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -146,8 +146,8 @@ class HeapConsistency final {
146146
}
147147

148148
/**
149-
* Steele-style write barrier that re-processes an object if it has already
150-
* been processed.
149+
* Steele-style write barrier that processes an object regardless of whether
150+
* or not it has already been processed.
151151
*
152152
* \param params The parameters retrieved from `GetWriteBarrierType()`.
153153
* \param object The pointer to the object which must point to an object that

‎deps/v8/include/v8-version.h‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
#define V8_MAJOR_VERSION 15
1212
#define V8_MINOR_VERSION 6
1313
#define V8_BUILD_NUMBER 75
14-
#define V8_PATCH_LEVEL 25
14+
#define V8_PATCH_LEVEL 33
1515

1616
// Use 1 for candidates and 0 otherwise.
1717
// (Boolean macro values are not supported by all preprocessors.)

‎deps/v8/src/builtins/promise-any.tq‎

Lines changed: 24 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -26,9 +26,7 @@ extern operator '[]' macro LoadContextElementNoCell(
2626
// together with the errors array. Since all closures for a single Promise.any
2727
// call use the same context, we need to store the indices for the individual
2828
// closures somewhere else (we put them into the identity hash field of the
29-
// closures), and we also need to have a separate marker for when the closure
30-
// was called already (we slap the native context onto the closure in that
31-
// case to mark it's done). See Promise.all which uses the same approach.
29+
// closures).
3230
transitioning macro CreatePromiseAnyRejectElementContext(
3331
implicit context: Context)(capability: PromiseCapability,
3432
nativeContext: NativeContext): PromiseAnyRejectElementContext {
@@ -75,36 +73,30 @@ transitioning javascript builtin PromiseAnyRejectElementClosure(
7573
js-implicit context: Context, receiver: JSAny, target: JSFunction)(
7674
value: JSAny): JSAny {
7775
// 1. Let F be the active function object.
78-
79-
// 2. Let alreadyCalled be F.[[AlreadyCalled]].
80-
81-
// 3. If alreadyCalled.[[Value]] is true, return undefined.
82-
83-
// We use the function's context as the marker to remember whether this
84-
// reject element closure was already called. It points to the reject
85-
// element context (which is a FunctionContext) until it was called the
86-
// first time, in which case we make it point to the native context here
87-
// to mark this reject element closure as done.
88-
if (IsNativeContext(context)) deferred {
89-
return Undefined;
90-
}
91-
9276
dcheck(
9377
context.length ==
9478
SmiTag(
9579
PromiseAnyRejectElementContextSlots::kPromiseAnyRejectElementLength));
9680
const context = %RawDownCast<PromiseAnyRejectElementContext>(context);
9781

98-
// 4. Set alreadyCalled.[[Value]] to true.
99-
const nativeContext = LoadNativeContext(context);
100-
target.context = nativeContext;
101-
10282
// 5. Let index be F.[[Index]].
10383
dcheck(kPropertyArrayNoHashSentinel == 0);
10484
const identityHash = LoadJSReceiverIdentityHash(target) otherwise unreachable;
10585
dcheck(ChangeUint32ToWord(identityHash) < kSmiMaxValue);
10686
const index = Signed(ChangeUint32ToWord(identityHash)) - 1;
10787

88+
// 8. Let remainingElementsCount be F.[[RemainingElements]].
89+
let remainingElementsCount = *ContextSlot(
90+
context,
91+
PromiseAnyRejectElementContextSlots::
92+
kPromiseAnyRejectElementRemainingSlot);
93+
94+
// If all promises were already rejected, the remaining count will already be
95+
// 0.
96+
if (remainingElementsCount == 0) deferred {
97+
return Undefined;
98+
}
99+
108100
// 6. Let errors be F.[[Errors]].
109101
let errorsRef:&FixedArray = ContextSlot(
110102
context,
@@ -113,12 +105,6 @@ transitioning javascript builtin PromiseAnyRejectElementClosure(
113105

114106
// 7. Let promiseCapability be F.[[Capability]].
115107

116-
// 8. Let remainingElementsCount be F.[[RemainingElements]].
117-
let remainingElementsCount = *ContextSlot(
118-
context,
119-
PromiseAnyRejectElementContextSlots::
120-
kPromiseAnyRejectElementRemainingSlot);
121-
122108
// 9. Set errors[index] to x.
123109

124110
// The max computation below is an optimization to avoid excessive allocations
@@ -138,11 +124,22 @@ transitioning javascript builtin PromiseAnyRejectElementClosure(
138124
errors, 0, errors.length_intptr, newCapacity, PromiseHole);
139125
*errorsRef = errors;
140126
}
127+
128+
// 2. Let alreadyCalled be F.[[AlreadyCalled]].
129+
// 3. If alreadyCalled.[[Value]] is true, return undefined.
130+
// 4. Set alreadyCalled.[[Value]] to true.
131+
if (errors.objects[index] != PromiseHole) deferred {
132+
return Undefined;
133+
}
134+
135+
// Make sure that we never see the PromiseHole here as a result.
136+
check(value != PromiseHole);
141137
errors.objects[index] = value;
142138

143139
// 10. Set remainingElementsCount.[[Value]] to
144140
// remainingElementsCount.[[Value]] - 1.
145141
remainingElementsCount = remainingElementsCount - 1;
142+
check(remainingElementsCount >= 0);
146143
*ContextSlot(
147144
context,
148145
PromiseAnyRejectElementContextSlots::

‎deps/v8/src/compiler/js-generic-lowering.cc‎

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -759,9 +759,6 @@ void JSGenericLowering::LowerJSGetTemplateObject(Node* node) {
759759
SharedFunctionInfoRef shared = p.shared();
760760
TemplateObjectDescriptionRef description = p.description();
761761

762-
DCHECK_EQ(node->op()->ControlInputCount(), 1);
763-
node->RemoveInput(NodeProperties::FirstControlIndex(node));
764-
765762
static_assert(JSGetTemplateObjectNode::FeedbackVectorIndex() == 0);
766763
node->InsertInput(zone(), 0, jsgraph()->ConstantNoHole(shared, broker()));
767764
node->InsertInput(zone(), 1,

‎deps/v8/src/compiler/js-operator.cc‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1614,7 +1614,7 @@ const Operator* JSOperatorBuilder::GetTemplateObject(
16141614
GetTemplateObjectParameters parameters(description, shared, feedback);
16151615
return zone()->New<Operator1<GetTemplateObjectParameters>>( // --
16161616
IrOpcode::kJSGetTemplateObject, // opcode
1617-
Operator::kEliminatable, // properties
1617+
Operator::kNoDeopt | Operator::kNoThrow, // properties
16181618
"JSGetTemplateObject", // name
16191619
1, 1, 1, 1, 1, 0, // counts
16201620
parameters); // parameter

‎deps/v8/src/compiler/turboshaft/pipelines.cc‎

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,21 @@ bool Pipeline::AllocateRegisters(const RegisterConfiguration* config,
8585

8686
RUN_MAYBE_ABORT(DecideSpillingModePhase);
8787
RUN_MAYBE_ABORT(AssignSpillSlotsPhase);
88+
89+
// The prologue grows the frame with a single stack pointer decrement, before
90+
// the function entry stack check runs. A frame no larger than the smallest OS
91+
// page cannot step over a guard page, so bail out rather than emit an
92+
// unchecked stack pointer jump of arbitrary size.
93+
// When replacing this bailout with a different strategy, consider doing the
94+
// same in Maglev as well.
95+
constexpr int kMaxStackSlots = 4 * KB / kSystemPointerSize;
96+
if (data_->info()->IsOptimizing() &&
97+
data_->frame()->GetTotalFrameSlotCount() > kMaxStackSlots) {
98+
data_->info()->AbortOptimization(BailoutReason::kFunctionTooBig);
99+
data()->ClearRegisterComponent();
100+
return false;
101+
}
102+
88103
RUN_MAYBE_ABORT(CommitAssignmentPhase);
89104

90105
// TODO(chromium:725559): remove this check once

‎deps/v8/src/heap/cppgc-internal/marker.h‎

Lines changed: 22 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
#include "include/cppgc/heap.h"
1111
#include "include/cppgc/platform.h"
1212
#include "include/cppgc/visitor.h"
13+
#include "src/base/logging.h"
1314
#include "src/base/macros.h"
1415
#include "src/base/platform/time.h"
1516
#include "src/heap/base/incremental-marking-schedule.h"
@@ -238,20 +239,15 @@ class V8_EXPORT_PRIVATE Marker final : public MarkerBase {
238239

239240
template <MarkerBase::WriteBarrierType type>
240241
void MarkerBase::WriteBarrierForObject(HeapObjectHeader& header) {
241-
// The barrier optimizes for the bailout cases:
242-
// - kDijkstra: Marked objects.
243-
// - kSteele: Unmarked objects.
244-
switch (type) {
245-
case MarkerBase::WriteBarrierType::kDijkstra:
246-
if (!header.TryMarkAtomic()) {
247-
return;
248-
}
249-
break;
250-
case MarkerBase::WriteBarrierType::kSteele:
251-
if (!header.IsMarked<AccessMode::kAtomic>()) {
252-
return;
253-
}
254-
break;
242+
// The Dijkstra barrier bails out on marked objects.
243+
// The Steele barrier marks the object regardless of its current state.
244+
// It's important to make sure the object is marked here since unmarking
245+
// below for in construction objects expects a marked object.
246+
const bool was_already_marked = !header.TryMarkAtomic();
247+
if (type == MarkerBase::WriteBarrierType::kDijkstra) {
248+
if (was_already_marked) {
249+
return;
250+
}
255251
}
256252

257253
// The barrier fired. Filter out in-construction objects here. This possibly
@@ -267,13 +263,18 @@ void MarkerBase::WriteBarrierForObject(HeapObjectHeader& header) {
267263
return;
268264
}
269265

270-
switch (type) {
271-
case MarkerBase::WriteBarrierType::kDijkstra:
272-
mutator_marking_state_.write_barrier_worklist().Push(&header);
273-
break;
274-
case MarkerBase::WriteBarrierType::kSteele:
275-
mutator_marking_state_.retrace_marked_objects_worklist().Push(&header);
276-
break;
266+
DCHECK_IMPLIES(was_already_marked,
267+
type == MarkerBase::WriteBarrierType::kSteele);
268+
if ((type == MarkerBase::WriteBarrierType::kDijkstra) ||
269+
!was_already_marked) {
270+
// Push previously unmarked objects to the write barrier worklist, even for
271+
// the Steele barrier, since popping from that worklist would also update
272+
// the marked bytes counter.
273+
mutator_marking_state_.write_barrier_worklist().Push(&header);
274+
} else {
275+
DCHECK((type == MarkerBase::WriteBarrierType::kSteele) &&
276+
was_already_marked);
277+
mutator_marking_state_.retrace_marked_objects_worklist().Push(&header);
277278
}
278279
}
279280

‎deps/v8/src/maglev/maglev-compiler.cc‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -285,6 +285,8 @@ bool MaglevCompiler::Compile(LocalIsolate* local_isolate,
285285
// FunctionEntryStackCheck runs. A frame no larger than the smallest OS page
286286
// cannot step over a guard page, so bail out rather than emit an unchecked
287287
// stack pointer jump of arbitrary size.
288+
// When replacing this bailout with a different strategy, consider doing the
289+
// same in Turboshaft as well.
288290
if (graph->tagged_stack_slots() + graph->untagged_stack_slots() >
289291
kMaxStackSlots) {
290292
return false;

‎deps/v8/src/maglev/maglev-graph-builder.cc‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6368,6 +6368,7 @@ void MaglevGraphBuilder::AdvanceThroughContinuationForPolymorphicPropertyLoad(
63686368
while (iterator_.current_offset() < continuation.last_continuation) {
63696369
iterator_.Advance();
63706370
UpdateSourceAndBytecodePosition(iterator_.current_offset());
6371+
PrewalkBytecode();
63716372
}
63726373
}
63736374

‎deps/v8/src/objects/js-function.cc‎

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -991,8 +991,9 @@ void JSFunction::EnsureHasInitialMap(Isolate* isolate,
991991
// system.
992992
// TODO(leszeks): Figure out if this CHECK is needed.
993993
CHECK(IsJSReceiver(*prototype));
994-
JSFunction::SetInitialMap(isolate, function, map, prototype);
994+
// Initialize slack tracking before publishing the map to concurrent readers.
995995
map->StartInobjectSlackTracking();
996+
JSFunction::SetInitialMap(isolate, function, map, prototype);
996997
}
997998

998999
namespace {
@@ -1183,11 +1184,12 @@ bool FastInitializeDerivedMap(Isolate* isolate,
11831184
Map::CopyInitialMap(isolate, constructor_initial_map, instance_size,
11841185
in_object_properties, unused_property_fields);
11851186
map->set_new_target_is_base(false);
1187+
// Initialize slack tracking before publishing the map to concurrent readers.
1188+
map->set_construction_counter(Map::kNoSlackTracking);
1189+
map->StartInobjectSlackTracking();
11861190
DirectHandle<JSReceiver> prototype(new_target->instance_prototype(), isolate);
11871191
JSFunction::SetInitialMap(isolate, new_target, map, prototype, constructor);
11881192
DCHECK(IsJSReceiver(new_target->instance_prototype()));
1189-
map->set_construction_counter(Map::kNoSlackTracking);
1190-
map->StartInobjectSlackTracking();
11911193
return true;
11921194
}
11931195

0 commit comments

Comments
 (0)