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