Chromium Code Reviews| Index: src/ic/ic.cc |
| diff --git a/src/ic/ic.cc b/src/ic/ic.cc |
| index 3015e01686d2ae9c1b4e03b4bf5c6509bcdf55bc..a4ccc489aad30e1c1678771a56aed9cc610d31d7 100644 |
| --- a/src/ic/ic.cc |
| +++ b/src/ic/ic.cc |
| @@ -567,11 +567,11 @@ void IC::ConfigureVectorState(Handle<Name> name, Handle<Map> map, |
| nexus->ConfigureMonomorphic(name, map, handler); |
| } else if (kind() == Code::STORE_IC) { |
| StoreICNexus* nexus = casted_nexus<StoreICNexus>(); |
| - nexus->ConfigureMonomorphic(map, Handle<Code>::cast(handler)); |
| + nexus->ConfigureMonomorphic(map, handler); |
| } else { |
| DCHECK(kind() == Code::KEYED_STORE_IC); |
| KeyedStoreICNexus* nexus = casted_nexus<KeyedStoreICNexus>(); |
| - nexus->ConfigureMonomorphic(name, map, Handle<Code>::cast(handler)); |
| + nexus->ConfigureMonomorphic(name, map, handler); |
| } |
| vector_set_ = true; |
| @@ -790,8 +790,10 @@ bool IC::IsTransitionOfMonomorphicTarget(Map* source_map, Map* target_map) { |
| void IC::PatchCache(Handle<Name> name, Handle<Object> handler) { |
| DCHECK(IsHandler(*handler)); |
| // Currently only LoadIC and KeyedLoadIC support non-code handlers. |
| - DCHECK_IMPLIES(!handler->IsCode(), |
| - kind() == Code::LOAD_IC || kind() == Code::KEYED_LOAD_IC); |
| + DCHECK_IMPLIES(!handler->IsCode(), kind() == Code::LOAD_IC || |
| + kind() == Code::KEYED_LOAD_IC || |
| + kind() == Code::STORE_IC || |
| + kind() == Code::KEYED_STORE_IC); |
| switch (state()) { |
| case UNINITIALIZED: |
| case PREMONOMORPHIC: |
| @@ -1010,6 +1012,37 @@ StubCache* IC::stub_cache() { |
| } |
| void IC::UpdateMegamorphicCache(Map* map, Name* name, Object* handler) { |
| + if (FLAG_store_ic_smi_handlers && handler->IsSmi() && |
| + (kind() == Code::STORE_IC || kind() == Code::KEYED_STORE_IC)) { |
| + // TODO(ishell, jkummerow): Implement data handlers support in |
| + // KeyedStoreIC_Megamorphic. |
| + Handle<Map> map_handle(map, isolate()); |
| + Handle<Name> name_handle(name, isolate()); |
| + int config = Smi::cast(handler)->value(); |
| + int value_index = StoreHandler::DescriptorValueIndexBits::decode(config); |
| + int descriptor = (value_index - DescriptorArray::kDescriptorValue - |
| + DescriptorArray::kFirstIndex) / |
| + DescriptorArray::kDescriptorSize; |
| + if (map->instance_descriptors()->length()) { |
| + PropertyDetails details = |
| + map->instance_descriptors()->GetDetails(descriptor); |
| + DCHECK_EQ(DATA, details.type()); |
| + DCHECK_EQ(name, map->instance_descriptors()->GetKey(descriptor)); |
| + Representation representation = details.representation(); |
| + FieldIndex index = FieldIndex::ForDescriptor(map, descriptor); |
| + TRACE_HANDLER_STATS(isolate(), StoreIC_StoreFieldStub); |
| + StoreFieldStub stub(isolate(), index, representation); |
| + handler = *stub.GetCode(); |
| + } else { |
| + // It must be a prototype map that some prototype used to have. This map |
| + // check will never succeed so write a dummy smi to the cache. |
| + DCHECK(!map->is_dictionary_map()); |
| + DCHECK(map->is_prototype_map()); |
| + handler = Smi::FromInt(1); |
|
Jakob Kummerow
2016/10/24 09:56:19
Come to think of it: why is this line not "return;
Igor Sheludko
2016/12/05 07:30:07
Actually, we should have not even got here with su
|
| + } |
| + stub_cache()->Set(*name_handle, *map_handle, handler); |
| + return; |
| + } |
| stub_cache()->Set(name, map, handler); |
| } |
| @@ -1641,10 +1674,10 @@ void StoreIC::UpdateCaches(LookupIterator* lookup, Handle<Object> value, |
| if (!use_ic) { |
| TRACE_GENERIC_IC(isolate(), "StoreIC", "LookupForWrite said 'false'"); |
| } |
| - Handle<Code> code = |
| - use_ic ? Handle<Code>::cast(ComputeHandler(lookup, value)) : slow_stub(); |
| + Handle<Object> handler = use_ic ? ComputeHandler(lookup, value) |
| + : Handle<Object>::cast(slow_stub()); |
| - PatchCache(lookup->name(), code); |
| + PatchCache(lookup->name(), handler); |
| TRACE_IC("StoreIC", lookup->name()); |
| } |
| @@ -1770,10 +1803,18 @@ Handle<Object> StoreIC::GetMapIndependentHandler(LookupIterator* lookup) { |
| use_stub = !field_type->IsClass(); |
| } |
| if (use_stub) { |
| - TRACE_HANDLER_STATS(isolate(), StoreIC_StoreFieldStub); |
| - StoreFieldStub stub(isolate(), lookup->GetFieldIndex(), |
| - lookup->representation()); |
| - return stub.GetCode(); |
| + if (FLAG_store_ic_smi_handlers) { |
| + TRACE_HANDLER_STATS(isolate(), StoreIC_StoreFieldDH); |
| + int descriptor = lookup->GetFieldDescriptorIndex(); |
| + FieldIndex index = lookup->GetFieldIndex(); |
| + return StoreHandler::StoreField(isolate(), descriptor, index, |
| + lookup->representation()); |
| + } else { |
| + TRACE_HANDLER_STATS(isolate(), StoreIC_StoreFieldStub); |
| + StoreFieldStub stub(isolate(), lookup->GetFieldIndex(), |
| + lookup->representation()); |
| + return stub.GetCode(); |
| + } |
| } |
| break; // Custom-compiled handler. |
| } |