Index: src/ic/ic.cc |
diff --git a/src/ic/ic.cc b/src/ic/ic.cc |
index daf7704c71d5ffa5d197ce4fb06bbb95255e8b4d..65b2e3df9ad15de4599e3ed1edfdde0b070b09ac 100644 |
--- a/src/ic/ic.cc |
+++ b/src/ic/ic.cc |
@@ -1112,7 +1112,39 @@ void LoadIC::UpdateCaches(LookupIterator* lookup) { |
code = slow_stub(); |
} |
} else { |
- code = ComputeHandler(lookup); |
+ 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->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 (code.is_null()) code = ComputeHandler(lookup); |
} |
PatchCache(lookup->name(), code); |
@@ -1242,6 +1274,8 @@ Handle<Code> LoadIC::CompileHandler(LookupIterator* lookup, |
if (v8::ToCData<Address>(info->getter()) == 0) break; |
if (!ExecutableAccessorInfo::IsCompatibleReceiverMap(isolate(), info, |
map)) { |
+ // This case should be already handled in LoadIC::UpdateCaches. |
+ UNREACHABLE(); |
break; |
} |
if (!holder->HasFastProperties()) break; |
@@ -1262,10 +1296,14 @@ Handle<Code> LoadIC::CompileHandler(LookupIterator* lookup, |
} |
CallOptimization call_optimization(function); |
NamedLoadHandlerCompiler compiler(isolate(), map, holder, cache_holder); |
- if (call_optimization.is_simple_api_call() && |
- call_optimization.IsCompatibleReceiver(receiver, holder)) { |
- return compiler.CompileLoadCallback(lookup->name(), call_optimization, |
- lookup->GetAccessorIndex()); |
+ if (call_optimization.is_simple_api_call()) { |
+ if (call_optimization.IsCompatibleReceiver(receiver, holder)) { |
+ return compiler.CompileLoadCallback( |
+ lookup->name(), call_optimization, lookup->GetAccessorIndex()); |
+ } else { |
+ // This case should be already handled in LoadIC::UpdateCaches. |
+ UNREACHABLE(); |
+ } |
} |
int expected_arguments = |
function->shared()->internal_formal_parameter_count(); |