Revision: 20407
Author:   [email protected]
Date:     Tue Apr  1 14:16:54 2014 UTC
Log: Monomorphic prototype failures should be reserved for already-seen keys.

We incorrectly mark a KeyedStoreIC miss as a monomorphic prototype
failure even though it's the first time a particular (string) key has
been seen.

BUG=358088
[email protected]
LOG=N

Review URL: https://codereview.chromium.org/219313002
http://code.google.com/p/v8/source/detail?r=20407

Added:
 /branches/bleeding_edge/test/mjsunit/regress/regress-358088.js
Modified:
 /branches/bleeding_edge/src/ic.cc
 /branches/bleeding_edge/src/ic.h

=======================================
--- /dev/null
+++ /branches/bleeding_edge/test/mjsunit/regress/regress-358088.js Tue Apr 1 14:16:54 2014 UTC
@@ -0,0 +1,18 @@
+// Copyright 2014 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.
+
+function f(a) {
+  a[a.length] = 1;
+}
+
+function g(a, i, v) {
+  a[i] = v;
+}
+
+f([]);    // f KeyedStoreIC goes to 1.GROW
+o = {};
+g(o);     // We've added property "undefined" to o
+
+o = {};   // A transition on property "undefined" exists from {}
+f(o);     // Store should go generic.
=======================================
--- /branches/bleeding_edge/src/ic.cc   Tue Apr  1 13:11:12 2014 UTC
+++ /branches/bleeding_edge/src/ic.cc   Tue Apr  1 14:16:54 2014 UTC
@@ -248,12 +248,7 @@

 bool IC::TryRemoveInvalidPrototypeDependentStub(Handle<Object> receiver,
                                                 Handle<String> name) {
-  if (target()->is_keyed_stub()) {
-    // Determine whether the failure is due to a name failure.
-    if (!name->IsName()) return false;
-    Name* stub_name = target()->FindFirstName();
-    if (*name != stub_name) return false;
-  }
+  if (!IsNameCompatibleWithMonomorphicPrototypeFailure(name)) return false;

   InlineCacheHolderFlag cache_holder =
       Code::ExtractCacheHolderFromFlags(target()->flags());
@@ -334,6 +329,18 @@
     }
   }
 }
+
+
+bool IC::IsNameCompatibleWithMonomorphicPrototypeFailure(Handle<Object> name) {
+  if (target()->is_keyed_stub()) {
+    // Determine whether the failure is due to a name failure.
+    if (!name->IsName()) return false;
+    Name* stub_name = target()->FindFirstName();
+    if (*name != stub_name) return false;
+  }
+
+  return true;
+}


 void IC::UpdateState(Handle<Object> receiver, Handle<Object> name) {
@@ -352,8 +359,9 @@
   // because of changes in the prototype chain to avoid hitting it
   // again.
   if (TryRemoveInvalidPrototypeDependentStub(
-          receiver, Handle<String>::cast(name))) {
-    return MarkMonomorphicPrototypeFailure();
+          receiver, Handle<String>::cast(name)) &&
+      TryMarkMonomorphicPrototypeFailure(name)) {
+    return;
   }

   // The builtins object is special.  It only changes when JavaScript
@@ -1184,8 +1192,9 @@
     // entirely by the migration above.
     receiver->map()->LookupTransition(*holder, *name, lookup);
     if (!lookup->IsTransition()) return false;
-    ic->MarkMonomorphicPrototypeFailure();
+    return ic->TryMarkMonomorphicPrototypeFailure(name);
   }
+
   return true;
 }

=======================================
--- /branches/bleeding_edge/src/ic.h    Thu Mar 27 09:59:43 2014 UTC
+++ /branches/bleeding_edge/src/ic.h    Tue Apr  1 14:16:54 2014 UTC
@@ -96,8 +96,14 @@

// Compute the current IC state based on the target stub, receiver and name.
   void UpdateState(Handle<Object> receiver, Handle<Object> name);
-  void MarkMonomorphicPrototypeFailure() {
-    state_ = MONOMORPHIC_PROTOTYPE_FAILURE;
+
+ bool IsNameCompatibleWithMonomorphicPrototypeFailure(Handle<Object> name);
+  bool TryMarkMonomorphicPrototypeFailure(Handle<Object> name) {
+    if (IsNameCompatibleWithMonomorphicPrototypeFailure(name)) {
+      state_ = MONOMORPHIC_PROTOTYPE_FAILURE;
+      return true;
+    }
+    return false;
   }

   // Clear the inline cache to initial state.

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