Skip to content

Commit 11505ad

Browse files
committed
deps: patch V8 to 8.4.371.23
Refs: v8/v8@8.4.371.19...8.4.371.23 PR-URL: #38001 Reviewed-By: Richard Lau <rlau@redhat.com> Reviewed-By: Michael Dawson <midawson@redhat.com> Reviewed-By: Colin Ihrig <cjihrig@gmail.com> Reviewed-By: Jiawen Geng <technicalcute@gmail.com>
1 parent fe5e2e3 commit 11505ad

File tree

8 files changed

+126
-23
lines changed

8 files changed

+126
-23
lines changed

deps/v8/include/v8-version.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
#define V8_MAJOR_VERSION 8
1212
#define V8_MINOR_VERSION 4
1313
#define V8_BUILD_NUMBER 371
14-
#define V8_PATCH_LEVEL 19
14+
#define V8_PATCH_LEVEL 23
1515

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

deps/v8/src/builtins/promise-all-element-closure.tq

+35-10
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,8 @@ const kPropertyArrayHashFieldMax: constexpr int31
8282

8383
transitioning macro PromiseAllResolveElementClosure<F: type>(
8484
implicit context: Context)(
85-
value: JSAny, function: JSFunction, wrapResultFunctor: F): JSAny {
85+
value: JSAny, function: JSFunction, wrapResultFunctor: F,
86+
hasResolveAndRejectClosures: constexpr bool): JSAny {
8687
// We use the {function}s context as the marker to remember whether this
8788
// resolve element closure was already called. It points to the resolve
8889
// element context (which is a FunctionContext) until it was called the
@@ -98,10 +99,6 @@ transitioning macro PromiseAllResolveElementClosure<F: type>(
9899
const nativeContext = LoadNativeContext(context);
99100
function.context = nativeContext;
100101

101-
// Update the value depending on whether Promise.all or
102-
// Promise.allSettled is called.
103-
const updatedValue = wrapResultFunctor.Call(nativeContext, value);
104-
105102
// Determine the index from the {function}.
106103
assert(kPropertyArrayNoHashSentinel == 0);
107104
const identityHash =
@@ -116,13 +113,41 @@ transitioning macro PromiseAllResolveElementClosure<F: type>(
116113
const elements = UnsafeCast<FixedArray>(valuesArray.elements);
117114
const valuesLength = Convert<intptr>(valuesArray.length);
118115
if (index < valuesLength) {
119-
// The {index} is in bounds of the {values_array},
120-
// just store the {value} and continue.
116+
// The {index} is in bounds of the {values_array}, check if this element has
117+
// already been resolved, and store the {value} if not.
118+
//
119+
// Promise.allSettled, for each input element, has both a resolve and a
120+
// reject closure that share an [[AlreadyCalled]] boolean. That is, the
121+
// input element can only be settled once: after resolve is called, reject
122+
// returns early, and vice versa. Using {function}'s context as the marker
123+
// only tracks per-closure instead of per-element. When the second
124+
// resolve/reject closure is called on the same index, values.object[index]
125+
// will already exist and will not be the hole value. In that case, return
126+
// early. Everything up to this point is not yet observable to user code.
127+
// This is not a problem for Promise.all since Promise.all has a single
128+
// resolve closure (no reject) per element.
129+
if (hasResolveAndRejectClosures) {
130+
if (elements.objects[index] != TheHole) deferred {
131+
return Undefined;
132+
}
133+
}
134+
135+
// Update the value depending on whether Promise.all or
136+
// Promise.allSettled is called.
137+
const updatedValue = wrapResultFunctor.Call(nativeContext, value);
121138
elements.objects[index] = updatedValue;
122139
} else {
123140
// Check if we need to grow the backing store.
141+
//
142+
// There's no need to check if this element has already been resolved for
143+
// Promise.allSettled if {values_array} has not yet grown to the index.
124144
const newLength = index + 1;
125145
const elementsLength = elements.length_intptr;
146+
147+
// Update the value depending on whether Promise.all or
148+
// Promise.allSettled is called.
149+
const updatedValue = wrapResultFunctor.Call(nativeContext, value);
150+
126151
if (index < elementsLength) {
127152
// The {index} is within bounds of the {elements} backing store, so
128153
// just store the {value} and update the "length" of the {values_array}.
@@ -166,22 +191,22 @@ PromiseAllResolveElementClosure(
166191
js-implicit context: Context, receiver: JSAny,
167192
target: JSFunction)(value: JSAny): JSAny {
168193
return PromiseAllResolveElementClosure(
169-
value, target, PromiseAllWrapResultAsFulfilledFunctor{});
194+
value, target, PromiseAllWrapResultAsFulfilledFunctor{}, false);
170195
}
171196

172197
transitioning javascript builtin
173198
PromiseAllSettledResolveElementClosure(
174199
js-implicit context: Context, receiver: JSAny,
175200
target: JSFunction)(value: JSAny): JSAny {
176201
return PromiseAllResolveElementClosure(
177-
value, target, PromiseAllSettledWrapResultAsFulfilledFunctor{});
202+
value, target, PromiseAllSettledWrapResultAsFulfilledFunctor{}, true);
178203
}
179204

180205
transitioning javascript builtin
181206
PromiseAllSettledRejectElementClosure(
182207
js-implicit context: Context, receiver: JSAny,
183208
target: JSFunction)(value: JSAny): JSAny {
184209
return PromiseAllResolveElementClosure(
185-
value, target, PromiseAllSettledWrapResultAsRejectedFunctor{});
210+
value, target, PromiseAllSettledWrapResultAsRejectedFunctor{}, true);
186211
}
187212
}

deps/v8/src/heap/mark-compact.cc

+5
Original file line numberDiff line numberDiff line change
@@ -2531,6 +2531,11 @@ void MarkCompactCollector::ClearJSWeakRefs() {
25312531
matched_cell.set_unregister_token(undefined);
25322532
},
25332533
gc_notify_updated_slot);
2534+
// The following is necessary because in the case that weak_cell has
2535+
// already been popped and removed from the FinalizationRegistry, the call
2536+
// to JSFinalizationRegistry::RemoveUnregisterToken above will not find
2537+
// weak_cell itself to clear its unregister token.
2538+
weak_cell.set_unregister_token(undefined);
25342539
} else {
25352540
// The unregister_token is alive.
25362541
ObjectSlot slot = weak_cell.RawField(WeakCell::kUnregisterTokenOffset);

deps/v8/src/wasm/baseline/arm/liftoff-assembler-arm.h

+8-3
Original file line numberDiff line numberDiff line change
@@ -122,11 +122,16 @@ template <void (Assembler::*op)(Register, Register, Register, SBit, Condition),
122122
SBit, Condition)>
123123
inline void I64Binop(LiftoffAssembler* assm, LiftoffRegister dst,
124124
LiftoffRegister lhs, LiftoffRegister rhs) {
125-
DCHECK_NE(dst.low_gp(), lhs.high_gp());
126-
DCHECK_NE(dst.low_gp(), rhs.high_gp());
127-
(assm->*op)(dst.low_gp(), lhs.low_gp(), rhs.low_gp(), SetCC, al);
125+
Register dst_low = dst.low_gp();
126+
if (dst_low == lhs.high_gp() || dst_low == rhs.high_gp()) {
127+
dst_low = assm->GetUnusedRegister(
128+
kGpReg, LiftoffRegList::ForRegs(lhs, rhs, dst.high_gp()))
129+
.gp();
130+
}
131+
(assm->*op)(dst_low, lhs.low_gp(), rhs.low_gp(), SetCC, al);
128132
(assm->*op_with_carry)(dst.high_gp(), lhs.high_gp(), Operand(rhs.high_gp()),
129133
LeaveCC, al);
134+
if (dst_low != dst.low_gp()) assm->mov(dst.low_gp(), dst_low);
130135
}
131136

132137
template <void (Assembler::*op)(Register, Register, const Operand&, SBit,

deps/v8/src/wasm/baseline/liftoff-assembler.h

-9
Original file line numberDiff line numberDiff line change
@@ -354,15 +354,6 @@ class LiftoffAssembler : public TurboAssembler {
354354
LiftoffRegList candidates = kGpCacheRegList;
355355
Register low = pinned.set(GetUnusedRegister(candidates, pinned)).gp();
356356
Register high = GetUnusedRegister(candidates, pinned).gp();
357-
if (low.code() > high.code()) {
358-
// Establish the invariant that the register of the low word always has
359-
// a lower code than the register of the high word. This guarantees that
360-
// if a register pair of an input is reused for the result, the low
361-
// word and high word registers are not swapped, i.e. the low word
362-
// register of the result is not the high word register of the input,
363-
// and vice versa.
364-
std::swap(low, high);
365-
}
366357
return LiftoffRegister::ForPair(low, high);
367358
} else if (kNeedS128RegPair && rc == kFpRegPair) {
368359
// kFpRegPair specific logic here because we need adjacent registers, not

deps/v8/test/cctest/test-js-weak-refs.cc

+47
Original file line numberDiff line numberDiff line change
@@ -968,5 +968,52 @@ TEST(JSWeakRefTenuredInWorklist) {
968968
CHECK(weak_ref->target().IsUndefined(isolate));
969969
}
970970

971+
TEST(UnregisterTokenHeapVerifier) {
972+
FLAG_harmony_weak_refs = true;
973+
if (!FLAG_incremental_marking) return;
974+
ManualGCScope manual_gc_scope;
975+
#ifdef VERIFY_HEAP
976+
FLAG_verify_heap = true;
977+
#endif
978+
979+
CcTest::InitializeVM();
980+
v8::Isolate* isolate = CcTest::isolate();
981+
Heap* heap = CcTest::heap();
982+
v8::HandleScope outer_scope(isolate);
983+
984+
{
985+
// Make a new FinalizationRegistry and register an object with an unregister
986+
// token that's unreachable after the IIFE returns.
987+
v8::HandleScope scope(isolate);
988+
CompileRun(
989+
"var token = {}; "
990+
"var registry = new FinalizationRegistry(function () {}); "
991+
"(function () { "
992+
" let o = {}; "
993+
" registry.register(o, {}, token); "
994+
"})();");
995+
}
996+
997+
// GC so the WeakCell corresponding to o is moved from the active_cells to
998+
// cleared_cells.
999+
CcTest::CollectAllGarbage();
1000+
CcTest::CollectAllGarbage();
1001+
1002+
{
1003+
// Override the unregister token to make the original object collectible.
1004+
v8::HandleScope scope(isolate);
1005+
CompileRun("token = 0;");
1006+
}
1007+
1008+
heap::SimulateIncrementalMarking(heap, true);
1009+
1010+
// Pump message loop to run the finalizer task, then the incremental marking
1011+
// task. The finalizer task will pop the WeakCell from the cleared list. This
1012+
// should make the unregister_token slot undefined. That slot is iterated as a
1013+
// custom weak pointer, so if it is not made undefined, the verifier as part
1014+
// of the incremental marking task will crash.
1015+
EmptyMessageQueues(isolate);
1016+
}
1017+
9711018
} // namespace internal
9721019
} // namespace v8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
// Copyright 2020 the V8 project authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style license that can be
3+
// found in the LICENSE file.
4+
5+
load('test/mjsunit/wasm/wasm-module-builder.js');
6+
7+
const builder = new WasmModuleBuilder();
8+
builder.addType(makeSig(
9+
[kWasmI64, kWasmI32, kWasmF64, kWasmI64, kWasmI64, kWasmI32, kWasmI64],
10+
[]));
11+
builder.addFunction(undefined, 0 /* sig */).addBody([
12+
kExprI32Const, 0, // i32.const
13+
kExprIf, kWasmStmt, // if @3
14+
kExprI32Const, 1, // i32.const
15+
kExprIf, kWasmStmt, // if @7
16+
kExprNop, // nop
17+
kExprElse, // else @10
18+
kExprUnreachable, // unreachable
19+
kExprEnd, // end @12
20+
kExprLocalGet, 0x06, // local.get
21+
kExprLocalSet, 0x00, // local.set
22+
kExprLocalGet, 0x03, // local.get
23+
kExprLocalGet, 0x00, // local.get
24+
kExprI64Sub, // i64.sub
25+
kExprDrop, // drop
26+
kExprUnreachable, // unreachable
27+
kExprEnd // end @24
28+
]);
29+
builder.toModule();

deps/v8/tools/whitespace.txt

+1
Original file line numberDiff line numberDiff line change
@@ -14,3 +14,4 @@ I'm starting to think that just adding trailing whitespaces might not be bad.
1414
Because whitespaces are not that funny.....
1515
Today's answer to life the universe and everything is 12950!
1616
Today's answer to life the universe and everything is 6728!
17+
+1

0 commit comments

Comments
 (0)