Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/nodejs/node.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/deps
diff options
context:
space:
mode:
authorMichaël Zasso <targos@protonmail.com>2021-04-17 17:28:43 +0300
committerMichaël Zasso <targos@protonmail.com>2021-04-30 13:53:55 +0300
commit18a4cbfb524eb9e7182e522e4d63cfd2241356ca (patch)
tree9d33f9bf69f51a08f4cb99fce94a0c7448d1575d /deps
parent70f622b5423a3be79eff0a5b764798a6fb192d4c (diff)
deps: V8: cherry-pick 3ba21a17ce2f
Original commit message: Merged: [map] Try to in-place transition during map update When searching for a target map during map update, attempt to update field representations in-place to the more general representation, where possible. Bug: chromium:1143772 No-Try: true No-Presubmit: true No-Tree-Checks: true TBR=leszeks@chromium.org, fgm@chromium.org (cherry picked from commit 8e3ae62d294818733a0322d8e8abd53d4e410f19) Change-Id: I659890c2f08c14d1cf94242fb875c19837df2dbb Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2509599 Reviewed-by: Francis McCabe <fgm@chromium.org> Reviewed-by: Michael Hablich <hablich@chromium.org> Reviewed-by: Bill Budge <bbudge@chromium.org> Reviewed-by: Igor Sheludko <ishell@chromium.org> Cr-Commit-Position: refs/branch-heads/8.6@{#44} Cr-Branched-From: a64aed2333abf49e494d2a5ce24bbd14fff19f60-refs/heads/8.6.395@{#1} Cr-Branched-From: a626bc036236c9bf92ac7b87dc40c9e538b087e3-refs/heads/master@{#69472} Refs: https://github.com/v8/v8/commit/3ba21a17ce2f26b015cc29adc473812247472776 PR-URL: https://github.com/nodejs/node/pull/38275 Reviewed-By: Matteo Collina <matteo.collina@gmail.com> Reviewed-By: Jiawen Geng <technicalcute@gmail.com> Reviewed-By: Shelley Vohr <codebytere@gmail.com>
Diffstat (limited to 'deps')
-rw-r--r--deps/v8/src/objects/map-updater.cc12
-rw-r--r--deps/v8/src/objects/map.cc1
-rw-r--r--deps/v8/test/cctest/test-field-type-tracking.cc67
-rw-r--r--deps/v8/test/mjsunit/regress/regress-1143772.js71
4 files changed, 124 insertions, 27 deletions
diff --git a/deps/v8/src/objects/map-updater.cc b/deps/v8/src/objects/map-updater.cc
index 8c9b94014f8..4ea69120d14 100644
--- a/deps/v8/src/objects/map-updater.cc
+++ b/deps/v8/src/objects/map-updater.cc
@@ -401,7 +401,17 @@ MapUpdater::State MapUpdater::FindTargetMap() {
}
Representation tmp_representation = tmp_details.representation();
if (!old_details.representation().fits_into(tmp_representation)) {
- break;
+ // Try updating the field in-place to a generalized type.
+ Representation generalized =
+ tmp_representation.generalize(old_details.representation());
+ if (!tmp_representation.CanBeInPlaceChangedTo(generalized)) {
+ break;
+ }
+ Handle<Map> field_owner(tmp_map->FindFieldOwner(isolate_, i), isolate_);
+ tmp_representation = generalized;
+ GeneralizeField(field_owner, i, tmp_details.constness(),
+ tmp_representation,
+ handle(tmp_descriptors->GetFieldType(i), isolate_));
}
if (tmp_details.location() == kField) {
diff --git a/deps/v8/src/objects/map.cc b/deps/v8/src/objects/map.cc
index bb13ace4bb0..8b7f25f1a2a 100644
--- a/deps/v8/src/objects/map.cc
+++ b/deps/v8/src/objects/map.cc
@@ -610,6 +610,7 @@ void Map::DeprecateTransitionTree(Isolate* isolate) {
transitions.GetTarget(i).DeprecateTransitionTree(isolate);
}
DCHECK(!constructor_or_backpointer().IsFunctionTemplateInfo());
+ DCHECK(CanBeDeprecated());
set_is_deprecated(true);
if (FLAG_trace_maps) {
LOG(isolate, MapEvent("Deprecate", handle(*this, isolate), Handle<Map>()));
diff --git a/deps/v8/test/cctest/test-field-type-tracking.cc b/deps/v8/test/cctest/test-field-type-tracking.cc
index d7b672a345c..5282ab499a4 100644
--- a/deps/v8/test/cctest/test-field-type-tracking.cc
+++ b/deps/v8/test/cctest/test-field-type-tracking.cc
@@ -1052,7 +1052,8 @@ namespace {
// where "p2A" and "p2B" differ only in the attributes.
//
void TestReconfigureDataFieldAttribute_GeneralizeField(
- const CRFTData& from, const CRFTData& to, const CRFTData& expected) {
+ const CRFTData& from, const CRFTData& to, const CRFTData& expected,
+ bool expected_deprecation) {
Isolate* isolate = CcTest::i_isolate();
Expectations expectations(isolate);
@@ -1121,24 +1122,29 @@ void TestReconfigureDataFieldAttribute_GeneralizeField(
CHECK_NE(*map2, *new_map);
CHECK(expectations2.Check(*map2));
- // |map| should be deprecated and |new_map| should match new expectations.
for (int i = kSplitProp; i < kPropCount; i++) {
expectations.SetDataField(i, expected.constness, expected.representation,
expected.type);
}
- CHECK(map->is_deprecated());
- CHECK(!code_field_type->marked_for_deoptimization());
- CHECK(!code_field_repr->marked_for_deoptimization());
- CHECK(!code_field_const->marked_for_deoptimization());
- CHECK_NE(*map, *new_map);
+ if (expected_deprecation) {
+ // |map| should be deprecated and |new_map| should match new expectations.
+ CHECK(map->is_deprecated());
+ CHECK(!code_field_type->marked_for_deoptimization());
+ CHECK(!code_field_repr->marked_for_deoptimization());
+ CHECK(!code_field_const->marked_for_deoptimization());
+ CHECK_NE(*map, *new_map);
- CHECK(!new_map->is_deprecated());
- CHECK(expectations.Check(*new_map));
+ CHECK(!new_map->is_deprecated());
+ CHECK(expectations.Check(*new_map));
- // Update deprecated |map|, it should become |new_map|.
- Handle<Map> updated_map = Map::Update(isolate, map);
- CHECK_EQ(*new_map, *updated_map);
- CheckMigrationTarget(isolate, *map, *updated_map);
+ // Update deprecated |map|, it should become |new_map|.
+ Handle<Map> updated_map = Map::Update(isolate, map);
+ CHECK_EQ(*new_map, *updated_map);
+ CheckMigrationTarget(isolate, *map, *updated_map);
+ } else {
+ CHECK(!map->is_deprecated());
+ CHECK(expectations.Check(*map));
+ }
}
// This test ensures that trivial field generalization (from HeapObject to
@@ -1254,22 +1260,22 @@ TEST(ReconfigureDataFieldAttribute_GeneralizeSmiFieldToDouble) {
TestReconfigureDataFieldAttribute_GeneralizeField(
{PropertyConstness::kConst, Representation::Smi(), any_type},
{PropertyConstness::kConst, Representation::Double(), any_type},
- {PropertyConstness::kConst, Representation::Double(), any_type});
+ {PropertyConstness::kConst, Representation::Double(), any_type}, true);
TestReconfigureDataFieldAttribute_GeneralizeField(
{PropertyConstness::kConst, Representation::Smi(), any_type},
{PropertyConstness::kMutable, Representation::Double(), any_type},
- {PropertyConstness::kMutable, Representation::Double(), any_type});
+ {PropertyConstness::kMutable, Representation::Double(), any_type}, true);
TestReconfigureDataFieldAttribute_GeneralizeField(
{PropertyConstness::kMutable, Representation::Smi(), any_type},
{PropertyConstness::kConst, Representation::Double(), any_type},
- {PropertyConstness::kMutable, Representation::Double(), any_type});
+ {PropertyConstness::kMutable, Representation::Double(), any_type}, true);
TestReconfigureDataFieldAttribute_GeneralizeField(
{PropertyConstness::kMutable, Representation::Smi(), any_type},
{PropertyConstness::kMutable, Representation::Double(), any_type},
- {PropertyConstness::kMutable, Representation::Double(), any_type});
+ {PropertyConstness::kMutable, Representation::Double(), any_type}, true);
}
TEST(ReconfigureDataFieldAttribute_GeneralizeSmiFieldToTagged) {
@@ -1284,22 +1290,26 @@ TEST(ReconfigureDataFieldAttribute_GeneralizeSmiFieldToTagged) {
TestReconfigureDataFieldAttribute_GeneralizeField(
{PropertyConstness::kConst, Representation::Smi(), any_type},
{PropertyConstness::kConst, Representation::HeapObject(), value_type},
- {PropertyConstness::kConst, Representation::Tagged(), any_type});
+ {PropertyConstness::kConst, Representation::Tagged(), any_type},
+ !FLAG_modify_field_representation_inplace);
TestReconfigureDataFieldAttribute_GeneralizeField(
{PropertyConstness::kConst, Representation::Smi(), any_type},
{PropertyConstness::kMutable, Representation::HeapObject(), value_type},
- {PropertyConstness::kMutable, Representation::Tagged(), any_type});
+ {PropertyConstness::kMutable, Representation::Tagged(), any_type},
+ !FLAG_modify_field_representation_inplace);
TestReconfigureDataFieldAttribute_GeneralizeField(
{PropertyConstness::kMutable, Representation::Smi(), any_type},
{PropertyConstness::kConst, Representation::HeapObject(), value_type},
- {PropertyConstness::kMutable, Representation::Tagged(), any_type});
+ {PropertyConstness::kMutable, Representation::Tagged(), any_type},
+ !FLAG_modify_field_representation_inplace);
TestReconfigureDataFieldAttribute_GeneralizeField(
{PropertyConstness::kMutable, Representation::Smi(), any_type},
{PropertyConstness::kMutable, Representation::HeapObject(), value_type},
- {PropertyConstness::kMutable, Representation::Tagged(), any_type});
+ {PropertyConstness::kMutable, Representation::Tagged(), any_type},
+ !FLAG_modify_field_representation_inplace);
}
TEST(ReconfigureDataFieldAttribute_GeneralizeDoubleFieldToTagged) {
@@ -1314,22 +1324,26 @@ TEST(ReconfigureDataFieldAttribute_GeneralizeDoubleFieldToTagged) {
TestReconfigureDataFieldAttribute_GeneralizeField(
{PropertyConstness::kConst, Representation::Double(), any_type},
{PropertyConstness::kConst, Representation::HeapObject(), value_type},
- {PropertyConstness::kConst, Representation::Tagged(), any_type});
+ {PropertyConstness::kConst, Representation::Tagged(), any_type},
+ FLAG_unbox_double_fields || !FLAG_modify_field_representation_inplace);
TestReconfigureDataFieldAttribute_GeneralizeField(
{PropertyConstness::kConst, Representation::Double(), any_type},
{PropertyConstness::kMutable, Representation::HeapObject(), value_type},
- {PropertyConstness::kMutable, Representation::Tagged(), any_type});
+ {PropertyConstness::kMutable, Representation::Tagged(), any_type},
+ FLAG_unbox_double_fields || !FLAG_modify_field_representation_inplace);
TestReconfigureDataFieldAttribute_GeneralizeField(
{PropertyConstness::kMutable, Representation::Double(), any_type},
{PropertyConstness::kConst, Representation::HeapObject(), value_type},
- {PropertyConstness::kMutable, Representation::Tagged(), any_type});
+ {PropertyConstness::kMutable, Representation::Tagged(), any_type},
+ FLAG_unbox_double_fields || !FLAG_modify_field_representation_inplace);
TestReconfigureDataFieldAttribute_GeneralizeField(
{PropertyConstness::kMutable, Representation::Double(), any_type},
{PropertyConstness::kMutable, Representation::HeapObject(), value_type},
- {PropertyConstness::kMutable, Representation::Tagged(), any_type});
+ {PropertyConstness::kMutable, Representation::Tagged(), any_type},
+ FLAG_unbox_double_fields || !FLAG_modify_field_representation_inplace);
}
TEST(ReconfigureDataFieldAttribute_GeneralizeHeapObjFieldToHeapObj) {
@@ -1415,7 +1429,8 @@ TEST(ReconfigureDataFieldAttribute_GeneralizeHeapObjectFieldToTagged) {
TestReconfigureDataFieldAttribute_GeneralizeField(
{PropertyConstness::kMutable, Representation::HeapObject(), value_type},
{PropertyConstness::kMutable, Representation::Smi(), any_type},
- {PropertyConstness::kMutable, Representation::Tagged(), any_type});
+ {PropertyConstness::kMutable, Representation::Tagged(), any_type},
+ !FLAG_modify_field_representation_inplace);
}
// Checks that given |map| is deprecated and that it updates to given |new_map|
diff --git a/deps/v8/test/mjsunit/regress/regress-1143772.js b/deps/v8/test/mjsunit/regress/regress-1143772.js
new file mode 100644
index 00000000000..40bc494d458
--- /dev/null
+++ b/deps/v8/test/mjsunit/regress/regress-1143772.js
@@ -0,0 +1,71 @@
+// Copyright 2020 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+// Flags: --allow-natives-syntax
+
+(function() {
+ // Only run this test if doubles are transitioned in-place to tagged.
+ let x = {};
+ x.a = 0.1;
+ let y = {};
+ y.a = {};
+ if (!%HaveSameMap(x, y)) return;
+
+ // m1: {}
+ let m1 = {};
+
+ // m2: {a:d}
+ let m2 = {};
+ assertTrue(%HaveSameMap(m2, m1));
+ m2.a = 13.37;
+
+ // m3: {a:d, b:s}
+ let m3 = {};
+ m3.a = 13.37;
+ assertTrue(%HaveSameMap(m3, m2));
+ m3.b = 1;
+
+ // m4: {a:d, b:s, c:h}
+ let m4 = {};
+ m4.a = 13.37;
+ m4.b = 1;
+ assertTrue(%HaveSameMap(m4, m3));
+ m4.c = {};
+
+ // m4_2 == m4
+ let m4_2 = {};
+ m4_2.a = 13.37;
+ m4_2.b = 1;
+ m4_2.c = {};
+ assertTrue(%HaveSameMap(m4_2, m4));
+
+ // m5: {a:d, b:d}
+ let m5 = {};
+ m5.a = 13.37;
+ assertTrue(%HaveSameMap(m5, m2));
+ m5.b = 13.37;
+ assertFalse(%HaveSameMap(m5, m3));
+
+ // At this point, Map3 and Map4 are both deprecated. Map2 transitions to
+ // Map5. Map5 is the migration target for Map3.
+ assertFalse(%HaveSameMap(m5, m3));
+
+ // m6: {a:d, b:d, c:d}
+ let m6 = {};
+ m6.a = 13.37;
+ assertTrue(%HaveSameMap(m6, m2));
+ m6.b = 13.37;
+ assertTrue(%HaveSameMap(m6, m5));
+ m6.c = 13.37
+
+ // Make m7: {a:d, b:d, c:t}
+ let m7 = m4_2;
+ assertTrue(%HaveSameMap(m7, m4));
+ // Map4 is deprecated, so this property access triggers a Map migration.
+ // With in-place map updates and no double unboxing, this should end up
+ // migrating to Map6, and updating it in-place.
+ m7.c;
+ assertFalse(%HaveSameMap(m7, m4));
+ assertTrue(%HaveSameMap(m6, m7));
+})();