Skip to content

Commit 41234af

Browse files
authored
chore: cherry-pick 146bd99e762b from v8 (electron#26401)
1 parent 5ffe02c commit 41234af

File tree

2 files changed

+295
-0
lines changed

2 files changed

+295
-0
lines changed

patches/v8/.patches

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,3 +20,4 @@ cherry-pick-7e5c7b5964.patch
2020
cherry-pick-6aa1e71fbd09.patch
2121
cherry-pick-6a4cd97d6691.patch
2222
perf_improve_heap_snapshot_performance.patch
23+
cherry-pick-146bd99e762b.patch
Lines changed: 294 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,294 @@
1+
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
2+
From: "ishell@chromium.org" <ishell@chromium.org>
3+
Date: Tue, 3 Nov 2020 12:42:43 +0100
4+
Subject: Merged: Squashed multiple commits.
5+
6+
Merged: [map] Try to in-place transition during map update
7+
Revision: 8e3ae62d294818733a0322d8e8abd53d4e410f19
8+
9+
Merged: [map] Skip loading the field owner before GeneralizeField
10+
Revision: a928f5fcc2a67c2c8d621ece48f76deb0d36637b
11+
12+
BUG=chromium:1143772
13+
NOTRY=true
14+
NOPRESUBMIT=true
15+
NOTREECHECKS=true
16+
R=verwaest@chromium.org
17+
18+
Change-Id: I78628cb697b21caa2098cc5948e226af5fcd020c
19+
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2516474
20+
Reviewed-by: Toon Verwaest <verwaest@chromium.org>
21+
Cr-Commit-Position: refs/branch-heads/8.7@{#31}
22+
Cr-Branched-From: 0d81cd72688512abcbe1601015baee390c484a6a-refs/heads/8.7.220@{#1}
23+
Cr-Branched-From: 942c2ef85caef00fcf02517d049f05e9a3d4b440-refs/heads/master@{#70196}
24+
25+
diff --git a/src/objects/map-updater.cc b/src/objects/map-updater.cc
26+
index 8c9b94014f8efaa4463cc883877ed52d24963d4c..5a016614a1782913e2297a4a396fc4402ea41cee 100644
27+
--- a/src/objects/map-updater.cc
28+
+++ b/src/objects/map-updater.cc
29+
@@ -232,10 +232,7 @@ MapUpdater::State MapUpdater::TryReconfigureToDataFieldInplace() {
30+
handle(old_descriptors_->GetFieldType(modified_descriptor_), isolate_),
31+
MaybeHandle<Object>(), new_field_type_, MaybeHandle<Object>());
32+
}
33+
- Handle<Map> field_owner(
34+
- old_map_->FindFieldOwner(isolate_, modified_descriptor_), isolate_);
35+
-
36+
- GeneralizeField(field_owner, modified_descriptor_, new_constness_,
37+
+ GeneralizeField(old_map_, modified_descriptor_, new_constness_,
38+
new_representation_, new_field_type_);
39+
// Check that the descriptor array was updated.
40+
DCHECK(old_descriptors_->GetDetails(modified_descriptor_)
41+
@@ -401,7 +398,13 @@ MapUpdater::State MapUpdater::FindTargetMap() {
42+
}
43+
Representation tmp_representation = tmp_details.representation();
44+
if (!old_details.representation().fits_into(tmp_representation)) {
45+
- break;
46+
+ // Try updating the field in-place to a generalized type.
47+
+ Representation generalized =
48+
+ tmp_representation.generalize(old_details.representation());
49+
+ if (!tmp_representation.CanBeInPlaceChangedTo(generalized)) {
50+
+ break;
51+
+ }
52+
+ tmp_representation = generalized;
53+
}
54+
55+
if (tmp_details.location() == kField) {
56+
diff --git a/src/objects/map.cc b/src/objects/map.cc
57+
index 60100c2030ce6d32213312227f03919e8cd0c88b..565ca697423fc29072716d37a56193b530939803 100644
58+
--- a/src/objects/map.cc
59+
+++ b/src/objects/map.cc
60+
@@ -590,6 +590,7 @@ void Map::DeprecateTransitionTree(Isolate* isolate) {
61+
transitions.GetTarget(i).DeprecateTransitionTree(isolate);
62+
}
63+
DCHECK(!constructor_or_backpointer().IsFunctionTemplateInfo());
64+
+ DCHECK(CanBeDeprecated());
65+
set_is_deprecated(true);
66+
if (FLAG_trace_maps) {
67+
LOG(isolate, MapEvent("Deprecate", *this, Map()));
68+
diff --git a/test/cctest/test-field-type-tracking.cc b/test/cctest/test-field-type-tracking.cc
69+
index 9deb1ff70cf3364d9033dde00ca0a1262034f0ff..55a5b45a6a57eeeddc3934d7978eafe1a8c50fd1 100644
70+
--- a/test/cctest/test-field-type-tracking.cc
71+
+++ b/test/cctest/test-field-type-tracking.cc
72+
@@ -1019,7 +1019,8 @@ namespace {
73+
// where "p2A" and "p2B" differ only in the attributes.
74+
//
75+
void TestReconfigureDataFieldAttribute_GeneralizeField(
76+
- const CRFTData& from, const CRFTData& to, const CRFTData& expected) {
77+
+ const CRFTData& from, const CRFTData& to, const CRFTData& expected,
78+
+ bool expected_deprecation) {
79+
Isolate* isolate = CcTest::i_isolate();
80+
81+
Expectations expectations(isolate);
82+
@@ -1079,22 +1080,26 @@ void TestReconfigureDataFieldAttribute_GeneralizeField(
83+
CHECK_NE(*map2, *new_map);
84+
CHECK(expectations2.Check(*map2));
85+
86+
- // |map| should be deprecated and |new_map| should match new expectations.
87+
for (int i = kSplitProp; i < kPropCount; i++) {
88+
expectations.SetDataField(i, expected.constness, expected.representation,
89+
expected.type);
90+
}
91+
- CHECK(map->is_deprecated());
92+
- CHECK(!code->marked_for_deoptimization());
93+
- CHECK_NE(*map, *new_map);
94+
+ if (expected_deprecation) {
95+
+ CHECK(map->is_deprecated());
96+
+ CHECK(!code->marked_for_deoptimization());
97+
+ CHECK_NE(*map, *new_map);
98+
99+
- CHECK(!new_map->is_deprecated());
100+
- CHECK(expectations.Check(*new_map));
101+
+ CHECK(!new_map->is_deprecated());
102+
+ CHECK(expectations.Check(*new_map));
103+
104+
- // Update deprecated |map|, it should become |new_map|.
105+
- Handle<Map> updated_map = Map::Update(isolate, map);
106+
- CHECK_EQ(*new_map, *updated_map);
107+
- CheckMigrationTarget(isolate, *map, *updated_map);
108+
+ // Update deprecated |map|, it should become |new_map|.
109+
+ Handle<Map> updated_map = Map::Update(isolate, map);
110+
+ CHECK_EQ(*new_map, *updated_map);
111+
+ CheckMigrationTarget(isolate, *map, *updated_map);
112+
+ } else {
113+
+ CHECK(!map->is_deprecated());
114+
+ CHECK(expectations.Check(*map));
115+
+ }
116+
}
117+
118+
// This test ensures that trivial field generalization (from HeapObject to
119+
@@ -1200,22 +1205,22 @@ TEST(ReconfigureDataFieldAttribute_GeneralizeSmiFieldToDouble) {
120+
TestReconfigureDataFieldAttribute_GeneralizeField(
121+
{PropertyConstness::kConst, Representation::Smi(), any_type},
122+
{PropertyConstness::kConst, Representation::Double(), any_type},
123+
- {PropertyConstness::kConst, Representation::Double(), any_type});
124+
+ {PropertyConstness::kConst, Representation::Double(), any_type}, true);
125+
126+
TestReconfigureDataFieldAttribute_GeneralizeField(
127+
{PropertyConstness::kConst, Representation::Smi(), any_type},
128+
{PropertyConstness::kMutable, Representation::Double(), any_type},
129+
- {PropertyConstness::kMutable, Representation::Double(), any_type});
130+
+ {PropertyConstness::kMutable, Representation::Double(), any_type}, true);
131+
132+
TestReconfigureDataFieldAttribute_GeneralizeField(
133+
{PropertyConstness::kMutable, Representation::Smi(), any_type},
134+
{PropertyConstness::kConst, Representation::Double(), any_type},
135+
- {PropertyConstness::kMutable, Representation::Double(), any_type});
136+
+ {PropertyConstness::kMutable, Representation::Double(), any_type}, true);
137+
138+
TestReconfigureDataFieldAttribute_GeneralizeField(
139+
{PropertyConstness::kMutable, Representation::Smi(), any_type},
140+
{PropertyConstness::kMutable, Representation::Double(), any_type},
141+
- {PropertyConstness::kMutable, Representation::Double(), any_type});
142+
+ {PropertyConstness::kMutable, Representation::Double(), any_type}, true);
143+
}
144+
145+
TEST(ReconfigureDataFieldAttribute_GeneralizeSmiFieldToTagged) {
146+
@@ -1230,22 +1235,26 @@ TEST(ReconfigureDataFieldAttribute_GeneralizeSmiFieldToTagged) {
147+
TestReconfigureDataFieldAttribute_GeneralizeField(
148+
{PropertyConstness::kConst, Representation::Smi(), any_type},
149+
{PropertyConstness::kConst, Representation::HeapObject(), value_type},
150+
- {PropertyConstness::kConst, Representation::Tagged(), any_type});
151+
+ {PropertyConstness::kConst, Representation::Tagged(), any_type},
152+
+ !FLAG_modify_field_representation_inplace);
153+
154+
TestReconfigureDataFieldAttribute_GeneralizeField(
155+
{PropertyConstness::kConst, Representation::Smi(), any_type},
156+
{PropertyConstness::kMutable, Representation::HeapObject(), value_type},
157+
- {PropertyConstness::kMutable, Representation::Tagged(), any_type});
158+
+ {PropertyConstness::kMutable, Representation::Tagged(), any_type},
159+
+ !FLAG_modify_field_representation_inplace);
160+
161+
TestReconfigureDataFieldAttribute_GeneralizeField(
162+
{PropertyConstness::kMutable, Representation::Smi(), any_type},
163+
{PropertyConstness::kConst, Representation::HeapObject(), value_type},
164+
- {PropertyConstness::kMutable, Representation::Tagged(), any_type});
165+
+ {PropertyConstness::kMutable, Representation::Tagged(), any_type},
166+
+ !FLAG_modify_field_representation_inplace);
167+
168+
TestReconfigureDataFieldAttribute_GeneralizeField(
169+
{PropertyConstness::kMutable, Representation::Smi(), any_type},
170+
{PropertyConstness::kMutable, Representation::HeapObject(), value_type},
171+
- {PropertyConstness::kMutable, Representation::Tagged(), any_type});
172+
+ {PropertyConstness::kMutable, Representation::Tagged(), any_type},
173+
+ !FLAG_modify_field_representation_inplace);
174+
}
175+
176+
TEST(ReconfigureDataFieldAttribute_GeneralizeDoubleFieldToTagged) {
177+
@@ -1260,22 +1269,26 @@ TEST(ReconfigureDataFieldAttribute_GeneralizeDoubleFieldToTagged) {
178+
TestReconfigureDataFieldAttribute_GeneralizeField(
179+
{PropertyConstness::kConst, Representation::Double(), any_type},
180+
{PropertyConstness::kConst, Representation::HeapObject(), value_type},
181+
- {PropertyConstness::kConst, Representation::Tagged(), any_type});
182+
+ {PropertyConstness::kConst, Representation::Tagged(), any_type},
183+
+ FLAG_unbox_double_fields || !FLAG_modify_field_representation_inplace);
184+
185+
TestReconfigureDataFieldAttribute_GeneralizeField(
186+
{PropertyConstness::kConst, Representation::Double(), any_type},
187+
{PropertyConstness::kMutable, Representation::HeapObject(), value_type},
188+
- {PropertyConstness::kMutable, Representation::Tagged(), any_type});
189+
+ {PropertyConstness::kMutable, Representation::Tagged(), any_type},
190+
+ FLAG_unbox_double_fields || !FLAG_modify_field_representation_inplace);
191+
192+
TestReconfigureDataFieldAttribute_GeneralizeField(
193+
{PropertyConstness::kMutable, Representation::Double(), any_type},
194+
{PropertyConstness::kConst, Representation::HeapObject(), value_type},
195+
- {PropertyConstness::kMutable, Representation::Tagged(), any_type});
196+
+ {PropertyConstness::kMutable, Representation::Tagged(), any_type},
197+
+ FLAG_unbox_double_fields || !FLAG_modify_field_representation_inplace);
198+
199+
TestReconfigureDataFieldAttribute_GeneralizeField(
200+
{PropertyConstness::kMutable, Representation::Double(), any_type},
201+
{PropertyConstness::kMutable, Representation::HeapObject(), value_type},
202+
- {PropertyConstness::kMutable, Representation::Tagged(), any_type});
203+
+ {PropertyConstness::kMutable, Representation::Tagged(), any_type},
204+
+ FLAG_unbox_double_fields || !FLAG_modify_field_representation_inplace);
205+
}
206+
207+
TEST(ReconfigureDataFieldAttribute_GeneralizeHeapObjFieldToHeapObj) {
208+
@@ -1361,7 +1374,8 @@ TEST(ReconfigureDataFieldAttribute_GeneralizeHeapObjectFieldToTagged) {
209+
TestReconfigureDataFieldAttribute_GeneralizeField(
210+
{PropertyConstness::kMutable, Representation::HeapObject(), value_type},
211+
{PropertyConstness::kMutable, Representation::Smi(), any_type},
212+
- {PropertyConstness::kMutable, Representation::Tagged(), any_type});
213+
+ {PropertyConstness::kMutable, Representation::Tagged(), any_type},
214+
+ !FLAG_modify_field_representation_inplace);
215+
}
216+
217+
218+
diff --git a/test/mjsunit/regress/regress-1143772.js b/test/mjsunit/regress/regress-1143772.js
219+
new file mode 100644
220+
index 0000000000000000000000000000000000000000..40bc494d458afec816fd72e3fbb36b20a7942649
221+
--- /dev/null
222+
+++ b/test/mjsunit/regress/regress-1143772.js
223+
@@ -0,0 +1,71 @@
224+
+// Copyright 2020 the V8 project authors. All rights reserved.
225+
+// Use of this source code is governed by a BSD-style license that can be
226+
+// found in the LICENSE file.
227+
+//
228+
+// Flags: --allow-natives-syntax
229+
+
230+
+(function() {
231+
+ // Only run this test if doubles are transitioned in-place to tagged.
232+
+ let x = {};
233+
+ x.a = 0.1;
234+
+ let y = {};
235+
+ y.a = {};
236+
+ if (!%HaveSameMap(x, y)) return;
237+
+
238+
+ // m1: {}
239+
+ let m1 = {};
240+
+
241+
+ // m2: {a:d}
242+
+ let m2 = {};
243+
+ assertTrue(%HaveSameMap(m2, m1));
244+
+ m2.a = 13.37;
245+
+
246+
+ // m3: {a:d, b:s}
247+
+ let m3 = {};
248+
+ m3.a = 13.37;
249+
+ assertTrue(%HaveSameMap(m3, m2));
250+
+ m3.b = 1;
251+
+
252+
+ // m4: {a:d, b:s, c:h}
253+
+ let m4 = {};
254+
+ m4.a = 13.37;
255+
+ m4.b = 1;
256+
+ assertTrue(%HaveSameMap(m4, m3));
257+
+ m4.c = {};
258+
+
259+
+ // m4_2 == m4
260+
+ let m4_2 = {};
261+
+ m4_2.a = 13.37;
262+
+ m4_2.b = 1;
263+
+ m4_2.c = {};
264+
+ assertTrue(%HaveSameMap(m4_2, m4));
265+
+
266+
+ // m5: {a:d, b:d}
267+
+ let m5 = {};
268+
+ m5.a = 13.37;
269+
+ assertTrue(%HaveSameMap(m5, m2));
270+
+ m5.b = 13.37;
271+
+ assertFalse(%HaveSameMap(m5, m3));
272+
+
273+
+ // At this point, Map3 and Map4 are both deprecated. Map2 transitions to
274+
+ // Map5. Map5 is the migration target for Map3.
275+
+ assertFalse(%HaveSameMap(m5, m3));
276+
+
277+
+ // m6: {a:d, b:d, c:d}
278+
+ let m6 = {};
279+
+ m6.a = 13.37;
280+
+ assertTrue(%HaveSameMap(m6, m2));
281+
+ m6.b = 13.37;
282+
+ assertTrue(%HaveSameMap(m6, m5));
283+
+ m6.c = 13.37
284+
+
285+
+ // Make m7: {a:d, b:d, c:t}
286+
+ let m7 = m4_2;
287+
+ assertTrue(%HaveSameMap(m7, m4));
288+
+ // Map4 is deprecated, so this property access triggers a Map migration.
289+
+ // With in-place map updates and no double unboxing, this should end up
290+
+ // migrating to Map6, and updating it in-place.
291+
+ m7.c;
292+
+ assertFalse(%HaveSameMap(m7, m4));
293+
+ assertTrue(%HaveSameMap(m6, m7));
294+
+})();

0 commit comments

Comments
 (0)