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.