Index: src/ic.cc |
diff --git a/src/ic.cc b/src/ic.cc |
index 248f4fc891d16430d602c613c81deb21badbaf86..6163f09ded506a48b0befe67430a1f345b3aef0f 100644 |
--- a/src/ic.cc |
+++ b/src/ic.cc |
@@ -1503,8 +1503,29 @@ Handle<Code> KeyedIC::ComputeStub(Handle<JSObject> receiver, |
KeyedAccessGrowMode grow_mode = IsGrowStubKind(stub_kind) |
? ALLOW_JSARRAY_GROWTH |
: DO_NOT_ALLOW_JSARRAY_GROWTH; |
- if ((ic_state == UNINITIALIZED || ic_state == PREMONOMORPHIC) && |
- !IsTransitionStubKind(stub_kind)) { |
+ |
+ bool monomorphic = false; |
+ MapHandleList target_receiver_maps; |
+ if (!IsTransitionStubKind(stub_kind)) { |
+ if (ic_state == UNINITIALIZED || ic_state == PREMONOMORPHIC) { |
+ monomorphic = true; |
+ } else { |
+ GetReceiverMapsForStub(Handle<Code>(target()), &target_receiver_maps); |
+ if (ic_state == MONOMORPHIC) { |
+ // The first time there's an element transition, assume the new |
Jakob Kummerow
2012/02/13 10:50:58
Suggestion:
s/The first time there's an element tr
|
+ // ElementsKind is the monomorphic type. This benefits global arrays |
+ // that only transition once, and all call sites accessing them are |
+ // faster if they remain monomorphic. If this optimistic assumption is |
+ // not true, the IC will miss again and it will become polymorphic and |
+ // support both the untransitioned and transition maps. |
Jakob Kummerow
2012/02/13 10:50:58
s/transition/transitioned/
|
+ monomorphic = IsMoreGeneralElementsKindTransition( |
+ target_receiver_maps.at(0)->elements_kind(), |
+ receiver->GetElementsKind()); |
+ } |
+ } |
+ } |
+ |
+ if (monomorphic) { |
return ComputeMonomorphicStub( |
receiver, stub_kind, strict_mode, generic_stub); |
} |
@@ -1520,12 +1541,9 @@ Handle<Code> KeyedIC::ComputeStub(Handle<JSObject> receiver, |
// Determine the list of receiver maps that this call site has seen, |
// adding the map that was just encountered. |
- MapHandleList target_receiver_maps; |
Handle<Map> receiver_map(receiver->map()); |
if (ic_state == UNINITIALIZED || ic_state == PREMONOMORPHIC) { |
Jakob Kummerow
2012/02/13 10:50:58
I think we don't need this if-block anymore. Note
|
target_receiver_maps.Add(receiver_map); |
- } else { |
- GetReceiverMapsForStub(Handle<Code>(target()), &target_receiver_maps); |
} |
bool map_added = |
AddOneReceiverMapIfMissing(&target_receiver_maps, receiver_map); |