Skip to content

Commit c37daa7

Browse files
authored
chore: cherry-pick dba49550b12d from v8 (#49487)
* chore: cherry-pick dba49550b12d from v8 * chore: update patch
1 parent e555e52 commit c37daa7

File tree

2 files changed

+271
-0
lines changed

2 files changed

+271
-0
lines changed

patches/v8/.patches

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
11
chore_allow_customizing_microtask_policy_per_context.patch
2+
cherry-pick-dba49550b12d.patch
Lines changed: 270 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,270 @@
1+
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
2+
From: =?UTF-8?q?Olivier=20Fl=C3=BCckiger?= <[email protected]>
3+
Date: Mon, 12 Jan 2026 15:41:30 +0100
4+
Subject: Merged: [map] Fix publishing of integrity-level transitions
5+
MIME-Version: 1.0
6+
Content-Type: text/plain; charset=UTF-8
7+
Content-Transfer-Encoding: 8bit
8+
9+
Integrity level transition target maps should not be published to the
10+
map tree before they are fully initialized. Otherwise concurrent access
11+
might pick up not fully updated target maps.
12+
13+
Drive-By: Fix a dcheck in the map-updater to not fire when an indirectly
14+
reachable non-deprecatable map is deprecated due to the whole subtree
15+
being deprecated.
16+
17+
Fixed: 473851441
18+
(cherry picked from commit e7f117bdb2fb4acbe619cf26aae2e011bf7f0e25)
19+
20+
Change-Id: I8530281a55bbeed1dd158a126bad807029bf47ae
21+
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/7485546
22+
Bot-Commit: Rubber Stamper <[email protected]>
23+
Commit-Queue: Rubber Stamper <[email protected]>
24+
Auto-Submit: Olivier Flückiger <[email protected]>
25+
Cr-Commit-Position: refs/branch-heads/14.4@{#40}
26+
Cr-Branched-From: 80acc26727d5a34e77dabeebe7c9213ec1bd4768-refs/heads/14.4.258@{#1}
27+
Cr-Branched-From: ce7e597e90f6df3fa4b6df224bc613b80c635450-refs/heads/main@{#104020}
28+
29+
diff --git a/src/objects/map.cc b/src/objects/map.cc
30+
index 1428c1c5cc3a6809c99400b5eb1e800087d721b8..c316181c7e3ad8ad21177f1e1b7e2420d4a5f7f3 100644
31+
--- a/src/objects/map.cc
32+
+++ b/src/objects/map.cc
33+
@@ -646,20 +646,25 @@ Map::FieldCounts Map::GetFieldCounts() const {
34+
}
35+
36+
void Map::DeprecateTransitionTree(Isolate* isolate) {
37+
+ DCHECK(CanBeDeprecated());
38+
+ return DeprecateTransitionTreeImpl(isolate);
39+
+}
40+
+
41+
+void Map::DeprecateTransitionTreeImpl(Isolate* isolate) {
42+
if (is_deprecated()) return;
43+
DisallowGarbageCollection no_gc;
44+
ReadOnlyRoots roots(isolate);
45+
TransitionsAccessor transitions(isolate, *this);
46+
transitions.ForEachTransition(
47+
- &no_gc, [&](Tagged<Map> map) { map->DeprecateTransitionTree(isolate); },
48+
+ &no_gc,
49+
+ [&](Tagged<Map> map) { map->DeprecateTransitionTreeImpl(isolate); },
50+
[&](Tagged<Map> map) {
51+
if (v8_flags.move_prototype_transitions_first) {
52+
- map->DeprecateTransitionTree(isolate);
53+
+ map->DeprecateTransitionTreeImpl(isolate);
54+
}
55+
},
56+
nullptr);
57+
DCHECK(!IsFunctionTemplateInfo(constructor_or_back_pointer()));
58+
- DCHECK(CanBeDeprecated());
59+
set_is_deprecated(true);
60+
if (v8_flags.log_maps) {
61+
LOG(isolate, MapEvent("Deprecate", direct_handle(*this, isolate), {}));
62+
@@ -1574,6 +1579,22 @@ Handle<Map> Map::CopyReplaceDescriptors(
63+
DirectHandle<DescriptorArray> descriptors, TransitionFlag flag,
64+
MaybeDirectHandle<Name> maybe_name, const char* reason,
65+
TransitionKindFlag transition_kind) {
66+
+ // Special transitions need to pass an InitMap function to initialize the map
67+
+ // before inserting it into the transition tree.
68+
+ CHECK_IMPLIES(flag == INSERT_TRANSITION,
69+
+ transition_kind == PROPERTY_TRANSITION ||
70+
+ transition_kind == SIMPLE_PROPERTY_TRANSITION);
71+
+ return CopyReplaceDescriptors(
72+
+ isolate, map, descriptors, flag, [&](Handle<Map>) {}, maybe_name, reason,
73+
+ transition_kind);
74+
+}
75+
+
76+
+template <typename InitMapCb>
77+
+Handle<Map> Map::CopyReplaceDescriptors(
78+
+ Isolate* isolate, DirectHandle<Map> map,
79+
+ DirectHandle<DescriptorArray> descriptors, TransitionFlag flag,
80+
+ const InitMapCb& InitMap, MaybeDirectHandle<Name> maybe_name,
81+
+ const char* reason, TransitionKindFlag transition_kind) {
82+
DCHECK(descriptors->IsSortedNoDuplicates());
83+
84+
Handle<Map> result = CopyDropDescriptors(isolate, map);
85+
@@ -1585,15 +1606,16 @@ Handle<Map> Map::CopyReplaceDescriptors(
86+
result->set_may_have_interesting_properties(true);
87+
}
88+
89+
+ bool insert_transition = false;
90+
if (map->is_prototype_map()) {
91+
result->InitializeDescriptors(isolate, *descriptors);
92+
} else {
93+
if (flag == INSERT_TRANSITION &&
94+
TransitionsAccessor::CanHaveMoreTransitions(isolate, map)) {
95+
+ insert_transition = true;
96+
result->InitializeDescriptors(isolate, *descriptors);
97+
98+
DCHECK(!maybe_name.is_null());
99+
- ConnectTransition(isolate, map, result, name, transition_kind);
100+
is_connected = true;
101+
} else if ((transition_kind == PROTOTYPE_TRANSITION &&
102+
v8_flags.move_prototype_transitions_first) ||
103+
@@ -1611,6 +1633,10 @@ Handle<Map> Map::CopyReplaceDescriptors(
104+
result->InitializeDescriptors(isolate, *descriptors);
105+
}
106+
}
107+
+ InitMap(result);
108+
+ if (insert_transition) {
109+
+ ConnectTransition(isolate, map, result, name, transition_kind);
110+
+ }
111+
if (v8_flags.log_maps && !is_connected) {
112+
LOG(isolate,
113+
MapEvent("ReplaceDescriptors", map, result, reason,
114+
@@ -1866,68 +1892,70 @@ Handle<Map> Map::CopyForPreventExtensions(
115+
DescriptorArray::CopyUpToAddAttributes(
116+
isolate, direct_handle(map->instance_descriptors(isolate), isolate),
117+
num_descriptors, attrs_to_add);
118+
+
119+
+ auto InitMap = [&](Handle<Map> new_map) {
120+
+ new_map->set_is_extensible(false);
121+
+ if (!IsTypedArrayOrRabGsabTypedArrayElementsKind(map->elements_kind())) {
122+
+ ElementsKind new_kind = IsStringWrapperElementsKind(map->elements_kind())
123+
+ ? SLOW_STRING_WRAPPER_ELEMENTS
124+
+ : DICTIONARY_ELEMENTS;
125+
+ if (!old_map_is_dictionary_elements_kind) {
126+
+ switch (map->elements_kind()) {
127+
+ case PACKED_ELEMENTS:
128+
+ if (attrs_to_add == SEALED) {
129+
+ new_kind = PACKED_SEALED_ELEMENTS;
130+
+ } else if (attrs_to_add == FROZEN) {
131+
+ new_kind = PACKED_FROZEN_ELEMENTS;
132+
+ } else {
133+
+ new_kind = PACKED_NONEXTENSIBLE_ELEMENTS;
134+
+ }
135+
+ break;
136+
+ case PACKED_NONEXTENSIBLE_ELEMENTS:
137+
+ if (attrs_to_add == SEALED) {
138+
+ new_kind = PACKED_SEALED_ELEMENTS;
139+
+ } else if (attrs_to_add == FROZEN) {
140+
+ new_kind = PACKED_FROZEN_ELEMENTS;
141+
+ }
142+
+ break;
143+
+ case PACKED_SEALED_ELEMENTS:
144+
+ if (attrs_to_add == FROZEN) {
145+
+ new_kind = PACKED_FROZEN_ELEMENTS;
146+
+ }
147+
+ break;
148+
+ case HOLEY_ELEMENTS:
149+
+ if (attrs_to_add == SEALED) {
150+
+ new_kind = HOLEY_SEALED_ELEMENTS;
151+
+ } else if (attrs_to_add == FROZEN) {
152+
+ new_kind = HOLEY_FROZEN_ELEMENTS;
153+
+ } else {
154+
+ new_kind = HOLEY_NONEXTENSIBLE_ELEMENTS;
155+
+ }
156+
+ break;
157+
+ case HOLEY_NONEXTENSIBLE_ELEMENTS:
158+
+ if (attrs_to_add == SEALED) {
159+
+ new_kind = HOLEY_SEALED_ELEMENTS;
160+
+ } else if (attrs_to_add == FROZEN) {
161+
+ new_kind = HOLEY_FROZEN_ELEMENTS;
162+
+ }
163+
+ break;
164+
+ case HOLEY_SEALED_ELEMENTS:
165+
+ if (attrs_to_add == FROZEN) {
166+
+ new_kind = HOLEY_FROZEN_ELEMENTS;
167+
+ }
168+
+ break;
169+
+ default:
170+
+ break;
171+
+ }
172+
+ }
173+
+ new_map->set_elements_kind(new_kind);
174+
+ }
175+
+ };
176+
+
177+
// Do not track transitions during bootstrapping.
178+
TransitionFlag flag =
179+
isolate->bootstrapper()->IsActive() ? OMIT_TRANSITION : INSERT_TRANSITION;
180+
- Handle<Map> new_map =
181+
- CopyReplaceDescriptors(isolate, map, new_desc, flag, transition_marker,
182+
- reason, SPECIAL_TRANSITION);
183+
- new_map->set_is_extensible(false);
184+
- if (!IsTypedArrayOrRabGsabTypedArrayElementsKind(map->elements_kind())) {
185+
- ElementsKind new_kind = IsStringWrapperElementsKind(map->elements_kind())
186+
- ? SLOW_STRING_WRAPPER_ELEMENTS
187+
- : DICTIONARY_ELEMENTS;
188+
- if (!old_map_is_dictionary_elements_kind) {
189+
- switch (map->elements_kind()) {
190+
- case PACKED_ELEMENTS:
191+
- if (attrs_to_add == SEALED) {
192+
- new_kind = PACKED_SEALED_ELEMENTS;
193+
- } else if (attrs_to_add == FROZEN) {
194+
- new_kind = PACKED_FROZEN_ELEMENTS;
195+
- } else {
196+
- new_kind = PACKED_NONEXTENSIBLE_ELEMENTS;
197+
- }
198+
- break;
199+
- case PACKED_NONEXTENSIBLE_ELEMENTS:
200+
- if (attrs_to_add == SEALED) {
201+
- new_kind = PACKED_SEALED_ELEMENTS;
202+
- } else if (attrs_to_add == FROZEN) {
203+
- new_kind = PACKED_FROZEN_ELEMENTS;
204+
- }
205+
- break;
206+
- case PACKED_SEALED_ELEMENTS:
207+
- if (attrs_to_add == FROZEN) {
208+
- new_kind = PACKED_FROZEN_ELEMENTS;
209+
- }
210+
- break;
211+
- case HOLEY_ELEMENTS:
212+
- if (attrs_to_add == SEALED) {
213+
- new_kind = HOLEY_SEALED_ELEMENTS;
214+
- } else if (attrs_to_add == FROZEN) {
215+
- new_kind = HOLEY_FROZEN_ELEMENTS;
216+
- } else {
217+
- new_kind = HOLEY_NONEXTENSIBLE_ELEMENTS;
218+
- }
219+
- break;
220+
- case HOLEY_NONEXTENSIBLE_ELEMENTS:
221+
- if (attrs_to_add == SEALED) {
222+
- new_kind = HOLEY_SEALED_ELEMENTS;
223+
- } else if (attrs_to_add == FROZEN) {
224+
- new_kind = HOLEY_FROZEN_ELEMENTS;
225+
- }
226+
- break;
227+
- case HOLEY_SEALED_ELEMENTS:
228+
- if (attrs_to_add == FROZEN) {
229+
- new_kind = HOLEY_FROZEN_ELEMENTS;
230+
- }
231+
- break;
232+
- default:
233+
- break;
234+
- }
235+
- }
236+
- new_map->set_elements_kind(new_kind);
237+
- }
238+
- return new_map;
239+
+ return CopyReplaceDescriptors(isolate, map, new_desc, flag, InitMap,
240+
+ transition_marker, reason, SPECIAL_TRANSITION);
241+
}
242+
243+
namespace {
244+
diff --git a/src/objects/map.h b/src/objects/map.h
245+
index 37ce48e7f4340687e19c895888da41b71409e12b..3b50cc46d10f5b8052f5659abca8baf17b77febe 100644
246+
--- a/src/objects/map.h
247+
+++ b/src/objects/map.h
248+
@@ -1070,6 +1070,14 @@ class Map : public TorqueGeneratedMap<Map, HeapObject> {
249+
static Handle<Map> CopyAddDescriptor(Isolate* isolate, DirectHandle<Map> map,
250+
Descriptor* descriptor,
251+
TransitionFlag flag);
252+
+
253+
+ template <typename InitMapCb>
254+
+ static Handle<Map> CopyReplaceDescriptors(
255+
+ Isolate* isolate, DirectHandle<Map> map,
256+
+ DirectHandle<DescriptorArray> descriptors, TransitionFlag flag,
257+
+ const InitMapCb& InitMap, MaybeDirectHandle<Name> maybe_name,
258+
+ const char* reason, TransitionKindFlag transition_kind);
259+
+
260+
static Handle<Map> CopyReplaceDescriptors(
261+
Isolate* isolate, DirectHandle<Map> map,
262+
DirectHandle<DescriptorArray> descriptors, TransitionFlag flag,
263+
@@ -1084,6 +1092,7 @@ class Map : public TorqueGeneratedMap<Map, HeapObject> {
264+
PropertyNormalizationMode mode);
265+
266+
void DeprecateTransitionTree(Isolate* isolate);
267+
+ void DeprecateTransitionTreeImpl(Isolate* isolate);
268+
269+
void ReplaceDescriptors(Isolate* isolate,
270+
Tagged<DescriptorArray> new_descriptors);

0 commit comments

Comments
 (0)