Skip to content

Commit 1a48a0f

Browse files
committed
deps: V8: cherry-pick 7d5eb1df2a72
Backport the Maglev HeapNumber materialization fix to V8 13.6. Emit a captured HeapNumber with its map and constant numeric value, using the existing deoptimizer to allocate a fresh box. Reserve a nonduplicatable object ID for each box. Keep the literal-number helper for fixed double arrays and captured-object numeric values. No virtual object slot traversal changes or prerequisite commits are needed. This mirrors the existing V8 13.6 Turbolev map/value materialization. Original commit message: [maglev] Materialize a fresh HeapNumber per deoptimization This matches what Turbolev graph builder already does to Maglev. Fixed: 547819997 Change-Id: Iafc1185ef96db8816db36b295a3a4b7e528f9863 Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/8255554 Reviewed-by: Leszek Swirski <leszeks@chromium.org> Commit-Queue: Victor Gomes <victorgomes@chromium.org> Cr-Commit-Position: refs/heads/main@{#109347} Refs: v8/v8@7d5eb1d Refs: #66457 Refs: https://www.cve.org/CVERecord?id=CVE-2026-85045 Signed-off-by: inoway46 <inoueyuya416@gmail.com> Assisted-by: Codex
1 parent 83b3431 commit 1a48a0f

3 files changed

Lines changed: 55 additions & 8 deletions

File tree

‎common.gypi‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@
4242

4343
# Reset this number to 0 on major V8 upgrades.
4444
# Increment by one for each non-official patch applied to deps/v8.
45-
'v8_embedder_string': '-node.54',
45+
'v8_embedder_string': '-node.55',
4646

4747
##### V8 defaults for Node.js #####
4848

‎deps/v8/src/maglev/maglev-code-generator.cc‎

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1466,6 +1466,11 @@ class MaglevFrameTranslationBuilder {
14661466
return kNotDuplicated;
14671467
}
14681468

1469+
int CreateUnduplicatableId() {
1470+
object_ids_.push_back(kNotDuplicated);
1471+
return kNotDuplicated;
1472+
}
1473+
14691474
void BuildHeapNumber(Float64 number) {
14701475
DirectHandle<Object> value =
14711476
local_isolate_->factory()->NewHeapNumberFromBits<AllocationType::kOld>(
@@ -1535,11 +1540,12 @@ class MaglevFrameTranslationBuilder {
15351540
void BuildVirtualObject(const VirtualObject* object,
15361541
const InputLocation*& input_location,
15371542
const VirtualObjectList& virtual_objects) {
1538-
if (object->type() == VirtualObject::kHeapNumber) {
1539-
return BuildHeapNumber(object->number());
1540-
}
1543+
// HeapNumbers may be mutable object fields; each materialization must
1544+
// create a fresh box, so they are never deduplicated.
15411545
int dup_id =
1542-
GetDuplicatedId(reinterpret_cast<intptr_t>(object->allocation()));
1546+
object->type() == VirtualObject::kHeapNumber
1547+
? CreateUnduplicatableId()
1548+
: GetDuplicatedId(reinterpret_cast<intptr_t>(object->allocation()));
15431549
if (dup_id != kNotDuplicated) {
15441550
translation_array_builder_->DuplicateObject(dup_id);
15451551
object->ForEachNestedRuntimeInput(virtual_objects,
@@ -1548,8 +1554,11 @@ class MaglevFrameTranslationBuilder {
15481554
}
15491555
switch (object->type()) {
15501556
case VirtualObject::kHeapNumber:
1551-
// Handled above.
1552-
UNREACHABLE();
1557+
translation_array_builder_->BeginCapturedObject(2);
1558+
translation_array_builder_->StoreLiteral(
1559+
GetDeoptLiteral(*object->map().object()));
1560+
BuildHeapNumber(object->number());
1561+
return;
15531562
case VirtualObject::kConsString:
15541563
return BuildConsString(object, input_location, virtual_objects);
15551564
case VirtualObject::kFixedDoubleArray:
@@ -1699,7 +1708,7 @@ class MaglevFrameTranslationBuilder {
16991708
IdentityMap<int, base::DefaultAllocationPolicy>* protected_deopt_literals_;
17001709
IdentityMap<int, base::DefaultAllocationPolicy>* deopt_literals_;
17011710

1702-
static const int kNotDuplicated = -1;
1711+
static constexpr int kNotDuplicated = -1;
17031712
std::vector<intptr_t> object_ids_;
17041713
};
17051714

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
// Copyright 2026 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+
// Flags: --allow-natives-syntax --maglev
6+
7+
const boxes = [];
8+
9+
// Never called during warm-up, so this call site has no feedback and Maglev
10+
// emits an unconditional deopt for it. The literal below is therefore only
11+
// used by deopt frames and gets elided by escape analysis.
12+
function sink(o) {
13+
boxes.push(o);
14+
}
15+
16+
function foo(depth, take) {
17+
const o = {x: 1.5};
18+
if (depth > 0) foo(depth - 1, take);
19+
if (take) sink(o);
20+
}
21+
22+
%PrepareFunctionForOptimization(foo);
23+
foo(3, false);
24+
foo(3, false);
25+
%OptimizeMaglevOnNextCall(foo);
26+
foo(3, false);
27+
28+
// Deopts the innermost activation eagerly and the outer ones lazily, so every
29+
// activation materializes its own object.
30+
foo(3, true);
31+
32+
assertEquals(4, boxes.length);
33+
for (let i = 0; i < boxes.length; i++) {
34+
boxes[i].x = i;
35+
}
36+
for (let i = 0; i < boxes.length; i++) {
37+
assertEquals(i, boxes[i].x);
38+
}

0 commit comments

Comments
 (0)