Commit cfbd1617 authored by jkummerow's avatar jkummerow Committed by Commit bot

[IC] Fix "compatible receiver" checks hidden behind interceptors

BUG=chromium:497632
LOG=y

Review URL: https://codereview.chromium.org/1531583005

Cr-Commit-Position: refs/heads/master@{#32945}
parent 641cdd30
...@@ -972,6 +972,39 @@ Handle<Code> LoadIC::SimpleFieldLoad(FieldIndex index) { ...@@ -972,6 +972,39 @@ Handle<Code> LoadIC::SimpleFieldLoad(FieldIndex index) {
} }
bool IsCompatibleReceiver(LookupIterator* lookup, Handle<Map> receiver_map) {
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) { void LoadIC::UpdateCaches(LookupIterator* lookup) {
if (state() == UNINITIALIZED) { if (state() == UNINITIALIZED) {
// This is the first time we execute this inline cache. Set the target to // This is the first time we execute this inline cache. Set the target to
...@@ -996,35 +1029,20 @@ void LoadIC::UpdateCaches(LookupIterator* lookup) { ...@@ -996,35 +1029,20 @@ void LoadIC::UpdateCaches(LookupIterator* lookup) {
} }
} else { } else {
if (lookup->state() == LookupIterator::ACCESSOR) { if (lookup->state() == LookupIterator::ACCESSOR) {
Handle<Object> accessors = lookup->GetAccessors(); if (!IsCompatibleReceiver(lookup, receiver_map())) {
Handle<Map> map = receiver_map(); TRACE_GENERIC_IC(isolate(), "LoadIC", "incompatible receiver type");
if (accessors->IsExecutableAccessorInfo()) { code = slow_stub();
Handle<ExecutableAccessorInfo> info = }
Handle<ExecutableAccessorInfo>::cast(accessors); } else if (lookup->state() == LookupIterator::INTERCEPTOR) {
if ((v8::ToCData<Address>(info->getter()) != 0) && // Perform a lookup behind the interceptor. Copy the LookupIterator since
!ExecutableAccessorInfo::IsCompatibleReceiverMap(isolate(), info, // the original iterator will be used to fetch the value.
map)) { LookupIterator it = *lookup;
TRACE_GENERIC_IC(isolate(), "LoadIC", "incompatible receiver type"); it.Next();
code = slow_stub(); LookupForRead(&it);
} if (it.state() == LookupIterator::ACCESSOR &&
} else if (accessors->IsAccessorPair()) { !IsCompatibleReceiver(&it, receiver_map())) {
Handle<Object> getter(Handle<AccessorPair>::cast(accessors)->getter(), TRACE_GENERIC_IC(isolate(), "LoadIC", "incompatible receiver type");
isolate()); code = slow_stub();
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 (code.is_null()) code = ComputeHandler(lookup); if (code.is_null()) code = ComputeHandler(lookup);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment