Reviewers: Jakob,
Description:
Version 4.4.63.7 (cherry-pick)
Merged 4cc4bc591cc8ffe7d458f4e89e1fbe3944d44c9f
Map::TryUpdate() must be in sync with Map::Update().
BUG=v8:4173
LOG=N
[email protected]
Please review this at https://codereview.chromium.org/1186883005/
Base URL: https://chromium.googlesource.com/v8/[email protected]
Affected files (+82, -9 lines):
M include/v8-version.h
M src/objects.cc
M test/cctest/test-migrations.cc
A test/mjsunit/regress/regress-4121.js
Index: include/v8-version.h
diff --git a/include/v8-version.h b/include/v8-version.h
index
c99cc781dba5cd3eb24136847859948a35963bcd..6bfa9c931f7e9ff1945ad78418633efdbfca0a12
100644
--- a/include/v8-version.h
+++ b/include/v8-version.h
@@ -11,7 +11,7 @@
#define V8_MAJOR_VERSION 4
#define V8_MINOR_VERSION 4
#define V8_BUILD_NUMBER 63
-#define V8_PATCH_LEVEL 6
+#define V8_PATCH_LEVEL 7
// Use 1 for candidates and 0 otherwise.
// (Boolean macro values are not supported by all preprocessors.)
Index: src/objects.cc
diff --git a/src/objects.cc b/src/objects.cc
index
03e6994a42b87b5e5abefd722decd437889f3cc7..67e32a63ac4bb1db49d6702eac5a2b793ab67575
100644
--- a/src/objects.cc
+++ b/src/objects.cc
@@ -2571,7 +2571,7 @@ Handle<Map> Map::ReconfigureProperty(Handle<Map>
old_map, int modify_index,
ElementsKind from_kind = root_map->elements_kind();
ElementsKind to_kind = old_map->elements_kind();
- if (from_kind != to_kind &&
+ if (from_kind != to_kind && to_kind != DICTIONARY_ELEMENTS &&
!(IsTransitionableFastElementsKind(from_kind) &&
IsMoreGeneralElementsKindTransition(from_kind, to_kind))) {
return CopyGeneralizeAllRepresentations(old_map, modify_index,
store_mode,
@@ -3035,6 +3035,15 @@ MaybeHandle<Map> Map::TryUpdate(Handle<Map> old_map)
{
// Check the state of the root map.
Map* root_map = old_map->FindRootMap();
if (!old_map->EquivalentToForTransition(root_map)) return
MaybeHandle<Map>();
+
+ ElementsKind from_kind = root_map->elements_kind();
+ ElementsKind to_kind = old_map->elements_kind();
+ if (from_kind != to_kind) {
+ // Try to follow existing elements kind transitions.
+ root_map = root_map->LookupElementsTransitionMap(to_kind);
+ if (root_map == NULL) return MaybeHandle<Map>();
+ // From here on, use the map with correct elements kind as root map.
+ }
int root_nof = root_map->NumberOfOwnDescriptors();
int old_nof = old_map->NumberOfOwnDescriptors();
Index: test/cctest/test-migrations.cc
diff --git a/test/cctest/test-migrations.cc b/test/cctest/test-migrations.cc
index
544278575ce1e189bbe00a71abbf60e28f5d6328..340e81d27ea521d2578640eda1faf308d684a6b6
100644
--- a/test/cctest/test-migrations.cc
+++ b/test/cctest/test-migrations.cc
@@ -20,11 +20,6 @@
using namespace v8::internal;
-// TODO(ishell): fix this once ReconfigureProperty supports "non
equivalent"
-// transitions.
-const bool IS_NON_EQUIVALENT_TRANSITION_SUPPORTED = false;
-
-
// TODO(ishell): fix this once TransitionToPrototype stops generalizing
// all field representations (similar to crbug/448711 where elements kind
// and observed transitions caused generalization of all field
representations).
@@ -1592,7 +1587,14 @@ static void
TestGeneralizeRepresentationWithSpecialTransition(
CHECK(!new_map2->is_deprecated());
CHECK(!new_map2->is_dictionary_map());
- if (!IS_NON_EQUIVALENT_TRANSITION_SUPPORTED) {
+ Handle<Map> tmp_map;
+ if (Map::TryUpdate(map2).ToHandle(&tmp_map)) {
+ // If Map::TryUpdate() manages to succeed the result must match the
result
+ // of Map::Update().
+ CHECK_EQ(*new_map2, *tmp_map);
+ }
+
+ if (config.is_non_equevalent_transition()) {
// In case of non-equivalent transition currently we generalize all
// representations.
for (int i = 0; i < kPropCount; i++) {
@@ -1601,7 +1603,8 @@ static void
TestGeneralizeRepresentationWithSpecialTransition(
CHECK(new_map2->GetBackPointer()->IsUndefined());
CHECK(expectations2.Check(*new_map2));
} else {
- CHECK(expectations.Check(*new_map2));
+ CHECK(!new_map2->GetBackPointer()->IsUndefined());
+ CHECK(expectations2.Check(*new_map2));
}
}
@@ -1633,6 +1636,7 @@ TEST(ElementsKindTransitionFromMapOwningDescriptor) {
}
// TODO(ishell): remove once IS_PROTO_TRANS_ISSUE_FIXED is removed.
bool generalizes_representations() const { return false; }
+ bool is_non_equevalent_transition() const { return false; }
};
TestConfig config;
TestGeneralizeRepresentationWithSpecialTransition(
@@ -1667,6 +1671,7 @@
TEST(ElementsKindTransitionFromMapNotOwningDescriptor) {
}
// TODO(ishell): remove once IS_PROTO_TRANS_ISSUE_FIXED is removed.
bool generalizes_representations() const { return false; }
+ bool is_non_equevalent_transition() const { return false; }
};
TestConfig config;
TestGeneralizeRepresentationWithSpecialTransition(
@@ -1689,6 +1694,7 @@ TEST(ForObservedTransitionFromMapOwningDescriptor) {
}
// TODO(ishell): remove once IS_PROTO_TRANS_ISSUE_FIXED is removed.
bool generalizes_representations() const { return false; }
+ bool is_non_equevalent_transition() const { return true; }
};
TestConfig config;
TestGeneralizeRepresentationWithSpecialTransition(
@@ -1722,6 +1728,7 @@ TEST(ForObservedTransitionFromMapNotOwningDescriptor)
{
}
// TODO(ishell): remove once IS_PROTO_TRANS_ISSUE_FIXED is removed.
bool generalizes_representations() const { return false; }
+ bool is_non_equevalent_transition() const { return true; }
};
TestConfig config;
TestGeneralizeRepresentationWithSpecialTransition(
@@ -1755,6 +1762,7 @@ TEST(PrototypeTransitionFromMapOwningDescriptor) {
bool generalizes_representations() const {
return !IS_PROTO_TRANS_ISSUE_FIXED;
}
+ bool is_non_equevalent_transition() const { return true; }
};
TestConfig config;
TestGeneralizeRepresentationWithSpecialTransition(
@@ -1799,6 +1807,7 @@ TEST(PrototypeTransitionFromMapNotOwningDescriptor) {
bool generalizes_representations() const {
return !IS_PROTO_TRANS_ISSUE_FIXED;
}
+ bool is_non_equevalent_transition() const { return true; }
};
TestConfig config;
TestGeneralizeRepresentationWithSpecialTransition(
Index: test/mjsunit/regress/regress-4121.js
diff --git a/test/mjsunit/regress/regress-4121.js
b/test/mjsunit/regress/regress-4121.js
new file mode 100644
index
0000000000000000000000000000000000000000..3d777c26b355054d71cd0f0efea6a5e203af4b8a
--- /dev/null
+++ b/test/mjsunit/regress/regress-4121.js
@@ -0,0 +1,55 @@
+// Copyright 2015 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 Migrator(o) {
+ return o.foo;
+}
+function Loader(o) {
+ return o[0];
+}
+
+var first_smi_array = [1];
+var second_smi_array = [2];
+var first_object_array = ["first"];
+var second_object_array = ["string"];
+
+assertTrue(%HasFastSmiElements(first_smi_array));
+assertTrue(%HasFastSmiElements(second_smi_array));
+assertTrue(%HasFastObjectElements(first_object_array));
+assertTrue(%HasFastObjectElements(second_object_array));
+
+// Prepare identical transition chains for smi and object arrays.
+first_smi_array.foo = 0;
+second_smi_array.foo = 0;
+first_object_array.foo = 0;
+second_object_array.foo = 0;
+
+// Collect type feedback for not-yet-deprecated original object array map.
+for (var i = 0; i < 3; i++) Migrator(second_object_array);
+
+// Blaze a migration trail for smi array maps.
+// This marks the migrated smi array map as a migration target.
+first_smi_array.foo = 0.5;
+print(second_smi_array.foo);
+
+// Deprecate original object array map.
+// Use TryMigrate from deferred optimized code to migrate second object
array.
+first_object_array.foo = 0.5;
+%OptimizeFunctionOnNextCall(Migrator);
+Migrator(second_object_array);
+
+// |second_object_array| now erroneously has a smi map.
+// Optimized code assuming smi elements will expose this.
+
+for (var i = 0; i < 3; i++) Loader(second_smi_array);
+%OptimizeFunctionOnNextCall(Loader);
+assertEquals("string", Loader(second_object_array));
+
+// Any of the following checks will also fail:
+assertTrue(%HasFastObjectElements(second_object_array));
+assertFalse(%HasFastSmiElements(second_object_array));
+assertTrue(%HaveSameMap(first_object_array, second_object_array));
+assertFalse(%HaveSameMap(first_smi_array, second_object_array));
--
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
---
You received this message because you are subscribed to the Google Groups "v8-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
For more options, visit https://groups.google.com/d/optout.