Reviewers: Toon Verwaest,

Message:
Hi Toon, here is the bug we discussed today, PTAL, thanks!
--Michael

Description:
350884: KeyedStoreIC miss didn't handle a transitioning case.

It's possible to get a transitioned map with no links to the origin
map if it's a shared map. Code in KeyedStoreIC::StoreElementStub
assumes it can check if two maps are in the same family by
traversing the transition array. Long term, the "family" relationship
should be recognized with the Normalized Map Cache. For now, allow
the IC to remain monomorphic in this case if the receiver map and
the previous receiver map are the same.

Filed V8 issue 3210 (https://code.google.com/p/v8/issues/detail?id=3210)
to track the issue with the Normalized Map Cache.

BUG=350884
LOG=N
[email protected]

Please review this at https://codereview.chromium.org/194623005/

SVN Base: https://v8.googlecode.com/svn/branches/bleeding_edge

Affected files (+20, -19 lines):
  M src/ic.cc
  A + test/mjsunit/regress/regress-350884.js


Index: src/ic.cc
diff --git a/src/ic.cc b/src/ic.cc
index 033246fa075229266e3a6c332109f1bb8ac48fdf..d78651ef05f8243d6ea2759e15ee43f880d64b47 100644
--- a/src/ic.cc
+++ b/src/ic.cc
@@ -1435,19 +1435,19 @@ Handle<Code> KeyedStoreIC::StoreElementStub(Handle<JSObject> receiver,
       KeyedStoreIC::GetKeyedAccessStoreMode(target()->extra_ic_state());
   Handle<Map> previous_receiver_map = target_receiver_maps.at(0);
   if (state() == MONOMORPHIC) {
- // If the "old" and "new" maps are in the same elements map family, stay
-      // MONOMORPHIC and use the map for the most generic ElementsKind.
-    Handle<Map> transitioned_receiver_map = receiver_map;
     if (IsTransitionStoreMode(store_mode)) {
-      transitioned_receiver_map =
+ // If the "old" and "new" maps are in the same elements map family, or + // if they at least come from the same origin for a transitioning store, + // stay MONOMORPHIC and use the map for the most generic ElementsKind.
+      Handle<Map> transitioned_receiver_map =
           ComputeTransitionedMap(receiver, store_mode);
-    }
-    if (IsTransitionOfMonomorphicTarget(
-            MapToType<HeapType>(transitioned_receiver_map, isolate()))) {
-      // Element family is the same, use the "worst" case map.
-      store_mode = GetNonTransitioningStoreMode(store_mode);
-      return isolate()->stub_cache()->ComputeKeyedStoreElement(
-          transitioned_receiver_map, strict_mode(), store_mode);
+      if (*previous_receiver_map == receiver->map() ||
+          IsTransitionOfMonomorphicTarget(
+              MapToType<HeapType>(transitioned_receiver_map, isolate()))) {
+        store_mode = GetNonTransitioningStoreMode(store_mode);
+        return isolate()->stub_cache()->ComputeKeyedStoreElement(
+            transitioned_receiver_map, strict_mode(), store_mode);
+      }
     } else if (*previous_receiver_map == receiver->map() &&
                old_store_mode == STANDARD_STORE &&
                (IsGrowStoreMode(store_mode) ||
Index: test/mjsunit/regress/regress-350884.js
diff --git a/test/mjsunit/regress/regress-347906.js b/test/mjsunit/regress/regress-350884.js
similarity index 51%
copy from test/mjsunit/regress/regress-347906.js
copy to test/mjsunit/regress/regress-350884.js
index c751618928c93015679087ee1b500637657aa341..86568534ee705e0adfb945912dde5e1487b192a7 100644
--- a/test/mjsunit/regress/regress-347906.js
+++ b/test/mjsunit/regress/regress-350884.js
@@ -2,13 +2,14 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.

-// Flags: --allow-natives-syntax --harmony
-
-function foo() {
-  return Math.clz32(12.34);
+var obj = new Array(1);
+obj[0] = 0;
+obj[1] = 0;
+function foo(flag_index) {
+  obj[flag_index]++;
 }

-foo();
-foo();
-%OptimizeFunctionOnNextCall(foo);
-foo();
+// Force dictionary properties on obj.
+obj[-8] = 3;
+foo(1);
+foo(2);


--
--
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.

Reply via email to