| Index: src/ic.cc
|
| diff --git a/src/ic.cc b/src/ic.cc
|
| index 7fa7eaf09b81d8c676b5360501dff36d2ddc1c92..9d5bf17b936a44b966ac658fa5e12310f26d12d7 100644
|
| --- a/src/ic.cc
|
| +++ b/src/ic.cc
|
| @@ -1139,32 +1139,35 @@ static bool AddOneReceiverMapIfMissing(MapHandleList* receiver_maps,
|
| static void GetReceiverMapsForStub(Handle<Code> stub,
|
| MapHandleList* result) {
|
| ASSERT(stub->is_inline_cache_stub());
|
| - if (stub->is_keyed_load_stub() || stub->is_keyed_store_stub()) {
|
| - switch (stub->ic_state()) {
|
| - case MONOMORPHIC:
|
| - result->Add(Handle<Map>(stub->FindFirstMap()));
|
| - break;
|
| - case POLYMORPHIC: {
|
| - AssertNoAllocation no_allocation;
|
| - int mask = RelocInfo::ModeMask(RelocInfo::EMBEDDED_OBJECT);
|
| - for (RelocIterator it(*stub, mask); !it.done(); it.next()) {
|
| - RelocInfo* info = it.rinfo();
|
| - Handle<Object> object(info->target_object());
|
| - ASSERT(object->IsMap());
|
| - AddOneReceiverMapIfMissing(result, Handle<Map>::cast(object));
|
| - }
|
| - break;
|
| + ASSERT(stub->is_keyed_load_stub() || stub->is_keyed_store_stub());
|
| + switch (stub->ic_state()) {
|
| + case MONOMORPHIC: {
|
| + Map* map = stub->FindFirstMap();
|
| + if (map != NULL) {
|
| + result->Add(Handle<Map>(map));
|
| + }
|
| + break;
|
| + }
|
| + case POLYMORPHIC: {
|
| + AssertNoAllocation no_allocation;
|
| + int mask = RelocInfo::ModeMask(RelocInfo::EMBEDDED_OBJECT);
|
| + for (RelocIterator it(*stub, mask); !it.done(); it.next()) {
|
| + RelocInfo* info = it.rinfo();
|
| + Handle<Object> object(info->target_object());
|
| + ASSERT(object->IsMap());
|
| + AddOneReceiverMapIfMissing(result, Handle<Map>::cast(object));
|
| }
|
| - case MEGAMORPHIC:
|
| - case GENERIC:
|
| - break;
|
| - case UNINITIALIZED:
|
| - case PREMONOMORPHIC:
|
| - case MONOMORPHIC_PROTOTYPE_FAILURE:
|
| - case DEBUG_STUB:
|
| - UNREACHABLE();
|
| - break;
|
| + break;
|
| }
|
| + case MEGAMORPHIC:
|
| + case GENERIC:
|
| + break;
|
| + case UNINITIALIZED:
|
| + case PREMONOMORPHIC:
|
| + case MONOMORPHIC_PROTOTYPE_FAILURE:
|
| + case DEBUG_STUB:
|
| + UNREACHABLE();
|
| + break;
|
| }
|
| }
|
|
|
| @@ -1192,6 +1195,9 @@ Handle<Code> KeyedLoadIC::LoadElementStub(Handle<JSObject> receiver) {
|
| target_receiver_maps.Add(isolate()->factory()->string_map());
|
| } else {
|
| GetReceiverMapsForStub(Handle<Code>(target()), &target_receiver_maps);
|
| + if (target_receiver_maps.length() == 0) {
|
| + return isolate()->stub_cache()->ComputeKeyedLoadElement(receiver_map);
|
| + }
|
| }
|
|
|
| // The first time a receiver is seen that is a transitioned version of the
|
| @@ -1564,6 +1570,13 @@ Handle<Code> KeyedStoreIC::StoreElementStub(Handle<JSObject> receiver,
|
| }
|
|
|
| GetReceiverMapsForStub(Handle<Code>(target()), &target_receiver_maps);
|
| + if (target_receiver_maps.length() == 0) {
|
| + // Optimistically assume that ICs that haven't reached the MONOMORPHIC state
|
| + // yet will do so and stay there.
|
| + stub_kind = GetNoTransitionStubKind(stub_kind);
|
| + return isolate()->stub_cache()->ComputeKeyedStoreElement(
|
| + receiver_map, stub_kind, strict_mode, grow_mode);
|
| + }
|
| // The first time a receiver is seen that is a transitioned version of the
|
| // previous monomorphic receiver type, assume the new ElementsKind is the
|
| // monomorphic type. This benefits global arrays that only transition
|
|
|