Chromium Code Reviews| Index: src/ic/ic.cc |
| diff --git a/src/ic/ic.cc b/src/ic/ic.cc |
| index 7062a5c3dc97ddc5d37ad5515db658c041704462..73ac666a41c991bfef72c6996cda50787d4a1703 100644 |
| --- a/src/ic/ic.cc |
| +++ b/src/ic/ic.cc |
| @@ -972,6 +972,39 @@ Handle<Code> LoadIC::SimpleFieldLoad(FieldIndex index) { |
| } |
| +bool IsCompatibleReceiver(LookupIterator* lookup, Handle<Map> receiver_map) { |
|
Jakob Kummerow
2015/12/17 11:36:31
This is factored out from below.
|
| + DCHECK(lookup->state() == LookupIterator::ACCESSOR); |
| + Isolate* isolate = lookup->isolate(); |
| + Handle<Object> accessors = lookup->GetAccessors(); |
| + if (accessors->IsExecutableAccessorInfo()) { |
| + Handle<ExecutableAccessorInfo> info = |
| + Handle<ExecutableAccessorInfo>::cast(accessors); |
| + if (info->getter() != NULL && |
| + !ExecutableAccessorInfo::IsCompatibleReceiverMap(isolate, info, |
| + receiver_map)) { |
| + return false; |
| + } |
| + } else if (accessors->IsAccessorPair()) { |
| + Handle<Object> getter(Handle<AccessorPair>::cast(accessors)->getter(), |
| + isolate); |
| + Handle<JSObject> holder = lookup->GetHolder<JSObject>(); |
| + Handle<Object> receiver = lookup->GetReceiver(); |
| + if (getter->IsJSFunction() && holder->HasFastProperties()) { |
| + Handle<JSFunction> function = Handle<JSFunction>::cast(getter); |
| + if (receiver->IsJSObject() || function->shared()->IsBuiltin() || |
| + !is_sloppy(function->shared()->language_mode())) { |
| + CallOptimization call_optimization(function); |
| + if (call_optimization.is_simple_api_call() && |
| + !call_optimization.IsCompatibleReceiverMap(receiver_map, holder)) { |
| + return false; |
| + } |
| + } |
| + } |
| + } |
| + return true; |
| +} |
| + |
| + |
| void LoadIC::UpdateCaches(LookupIterator* lookup) { |
| if (state() == UNINITIALIZED) { |
| // This is the first time we execute this inline cache. Set the target to |
| @@ -996,35 +1029,20 @@ void LoadIC::UpdateCaches(LookupIterator* lookup) { |
| } |
| } else { |
| if (lookup->state() == LookupIterator::ACCESSOR) { |
| - Handle<Object> accessors = lookup->GetAccessors(); |
| - Handle<Map> map = receiver_map(); |
| - if (accessors->IsExecutableAccessorInfo()) { |
| - Handle<ExecutableAccessorInfo> info = |
| - Handle<ExecutableAccessorInfo>::cast(accessors); |
| - if ((v8::ToCData<Address>(info->getter()) != 0) && |
| - !ExecutableAccessorInfo::IsCompatibleReceiverMap(isolate(), info, |
| - map)) { |
| - TRACE_GENERIC_IC(isolate(), "LoadIC", "incompatible receiver type"); |
| - code = slow_stub(); |
| - } |
| - } else if (accessors->IsAccessorPair()) { |
| - Handle<Object> getter(Handle<AccessorPair>::cast(accessors)->getter(), |
| - isolate()); |
| - Handle<JSObject> holder = lookup->GetHolder<JSObject>(); |
| - Handle<Object> receiver = lookup->GetReceiver(); |
| - if (getter->IsJSFunction() && holder->HasFastProperties()) { |
| - Handle<JSFunction> function = Handle<JSFunction>::cast(getter); |
| - if (receiver->IsJSObject() || function->shared()->IsBuiltin() || |
| - !is_sloppy(function->shared()->language_mode())) { |
| - CallOptimization call_optimization(function); |
| - if (call_optimization.is_simple_api_call() && |
| - !call_optimization.IsCompatibleReceiver(receiver, holder)) { |
| - TRACE_GENERIC_IC(isolate(), "LoadIC", |
| - "incompatible receiver type"); |
| - code = slow_stub(); |
| - } |
| - } |
| - } |
| + if (!IsCompatibleReceiver(lookup, receiver_map())) { |
| + TRACE_GENERIC_IC(isolate(), "LoadIC", "incompatible receiver type"); |
| + code = slow_stub(); |
| + } |
| + } else if (lookup->state() == LookupIterator::INTERCEPTOR) { |
| + // Perform a lookup behind the interceptor. Copy the LookupIterator since |
| + // the original iterator will be used to fetch the value. |
| + LookupIterator it = *lookup; |
| + it.Next(); |
| + LookupForRead(&it); |
| + if (it.state() == LookupIterator::ACCESSOR && |
| + !IsCompatibleReceiver(&it, receiver_map())) { |
| + TRACE_GENERIC_IC(isolate(), "LoadIC", "incompatible receiver type"); |
| + code = slow_stub(); |
| } |
| } |
| if (code.is_null()) code = ComputeHandler(lookup); |