Reviewers: Jakob,
Message:
PTAL.
Description:
Fix CNLT regression.
This happens when a map A with no descriptors in fast_holey_elements
mode first gets some properties, making it share descriptor arrays with
a map B to which it transitions. Then map A transitions elements kind to
dictionary_elements in map B. B stores the empty_descriptor_array in its
own transition array. When adding a property to B, B transitions to C
and shares the descriptors. If C dies, a CNLT clears the transition
array of B, making the descriptor array of A shine through. If a
property is now added to an object in state B, it'll inherit all the
properties of A. If those properties had high field indices, we do not
have a large enough backing store for the single newly added property,
and we'll write out of bounds.
BUG=chromium:151749
Please review this at https://chromiumcodereview.appspot.com/11017054/
SVN Base: https://v8.googlecode.com/svn/branches/bleeding_edge
Affected files:
M src/objects-printer.cc
M src/objects.cc
A + test/mjsunit/regress/regress-cnlt-elements.js
Index: src/objects-printer.cc
diff --git a/src/objects-printer.cc b/src/objects-printer.cc
index
1ba0bb0d0988780dd6437e797ca25c1ac7f971b5..40572906790ac01961e4b742c45fdc49940a53b1
100644
--- a/src/objects-printer.cc
+++ b/src/objects-printer.cc
@@ -562,7 +562,12 @@ void Map::MapPrint(FILE* out) {
if (is_access_check_needed()) {
PrintF(out, " - access_check_needed\n");
}
- PrintF(out, " - instance descriptors: ");
+ PrintF(out, " - back pointer: ");
+ GetBackPointer()->ShortPrint(out);
+ PrintF(out, "\n - instance descriptors %i #%i %i: ",
+ owns_descriptors(),
+ NumberOfOwnDescriptors(),
+ StoresOwnDescriptors());
instance_descriptors()->ShortPrint(out);
if (HasTransitionArray()) {
PrintF(out, "\n - transitions: ");
Index: src/objects.cc
diff --git a/src/objects.cc b/src/objects.cc
index
c37a4a8b2086be48e881634f36f36acf034cc56c..1724d892ce842cbc4aed39c7a9c965597cfe70dd
100644
--- a/src/objects.cc
+++ b/src/objects.cc
@@ -5145,7 +5145,7 @@ MaybeObject* Map::CopyAsElementsKind(ElementsKind
kind, TransitionFlag flag) {
ASSERT(new_map->NumberOfOwnDescriptors() == NumberOfOwnDescriptors());
new_map->set_elements_kind(kind);
- if (flag == INSERT_TRANSITION) {
+ if (flag == INSERT_TRANSITION && !HasElementsTransition()) {
// Map::Copy does not store the descriptor array in case it is empty,
since
// it does not insert a back pointer; implicitly indicating that its
// descriptor array is empty. Since in this case we do want to insert
a back
@@ -7564,16 +7564,6 @@ void Map::ClearNonLiveTransitions(Heap* heap) {
set_owns_descriptors(true);
}
- // If the final transition array does not contain any live transitions,
remove
- // the transition array from the map.
- if (transition_index == 0 &&
- !t->HasElementsTransition() &&
- !t->HasPrototypeTransitions() &&
- number_of_own_descriptors == 0) {
- ASSERT(owns_descriptors());
- return ClearTransitions(heap);
- }
-
int trim = t->number_of_transitions() - transition_index;
if (trim > 0) {
RightTrimFixedArray<FROM_GC>(heap, t, t->IsSimpleTransition()
Index: test/mjsunit/regress/regress-cnlt-elements.js
diff --git a/test/mjsunit/regress/regress-128018.js
b/test/mjsunit/regress/regress-cnlt-elements.js
similarity index 90%
copy from test/mjsunit/regress/regress-128018.js
copy to test/mjsunit/regress/regress-cnlt-elements.js
index
7bd15858e6c9a36a651d185ad7f4d97c25c7b1f7..bb134eeaf74efeda20a18a48af7d2b6c0a321e1f
100644
--- a/test/mjsunit/regress/regress-128018.js
+++ b/test/mjsunit/regress/regress-cnlt-elements.js
@@ -27,9 +27,10 @@
// Flags: --expose-gc
-function KeyedStoreIC(a) { a[(1)] = Math.E; }
-var literal = [1.2];
-literal.length = 0;
-literal.push('0' && 0 );
-KeyedStoreIC(literal);
+var a = JSON.parse('{"b":1,"c":2,"d":3,"e":4}');
+var b = JSON.parse('{"12040200":1, "a":2, "b":2}');
+var c = JSON.parse('{"24050300":1}');
+b = null;
gc();
+gc();
+c.d = 2;
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev