From c45c2b9ced26b24ae4a6990b1be350f5a1568f5d Mon Sep 17 00:00:00 2001 From: Toon Verwaest Date: Wed, 18 Sep 2019 15:25:35 +0200 Subject: [PATCH] [ic] Only use StorePropertyWithInterceptor if there's an own setter This fixes the issue highlighted in https://chromium-review.googlesource.com/c/v8/v8/+/1803236. Change-Id: Iea2d6c4f9585a56d017f2cb1eb8e23b52de1f795 Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1807356 Commit-Queue: Toon Verwaest Reviewed-by: Igor Sheludko Cr-Commit-Position: refs/heads/master@{#63871} --- src/ic/ic.cc | 29 +++++++++++++++++------------ 1 file changed, 17 insertions(+), 12 deletions(-) diff --git a/src/ic/ic.cc b/src/ic/ic.cc index 4025634ad4..1bed0d4bda 100644 --- a/src/ic/ic.cc +++ b/src/ic/ic.cc @@ -1315,7 +1315,8 @@ bool StoreIC::LookupForWrite(LookupIterator* it, Handle value, case LookupIterator::INTERCEPTOR: { Handle holder = it->GetHolder(); InterceptorInfo info = holder->GetNamedInterceptor(); - if (it->HolderIsReceiverOrHiddenPrototype() || + if ((it->HolderIsReceiverOrHiddenPrototype() && + !info.non_masking()) || !info.getter().IsUndefined(isolate()) || !info.query().IsUndefined(isolate())) { return true; @@ -1541,22 +1542,26 @@ MaybeObjectHandle StoreIC::ComputeHandler(LookupIterator* lookup) { case LookupIterator::INTERCEPTOR: { Handle holder = lookup->GetHolder(); - Handle smi_handler = StoreHandler::StoreInterceptor(isolate()); InterceptorInfo info = holder->GetNamedInterceptor(); - if (!info.getter().IsUndefined(isolate()) || - !info.query().IsUndefined(isolate()) || info.non_masking()) { - smi_handler = StoreHandler::StoreSlow(isolate()); - } - - if (receiver_map().is_identical_to(holder) && - !info.setter().IsUndefined(isolate()) && !info.non_masking()) { - DCHECK(!holder->GetNamedInterceptor().setter().IsUndefined(isolate())); - return MaybeObjectHandle(smi_handler); + // If the interceptor is on the receiver + if (lookup->HolderIsReceiverOrHiddenPrototype() && !info.non_masking()) { + // return a store interceptor smi handler if there is one, + if (!info.setter().IsUndefined(isolate())) { + return MaybeObjectHandle(StoreHandler::StoreInterceptor(isolate())); + } + // otherwise return a slow-case smi handler. + return MaybeObjectHandle(StoreHandler::StoreSlow(isolate())); } + // If the interceptor is a getter/query interceptor on the prototype + // chain, return an invalidatable slow handler so it can turn fast if the + // interceptor is masked by a regular property later. + DCHECK(!info.getter().IsUndefined(isolate()) || + !info.query().IsUndefined(isolate())); Handle handler = StoreHandler::StoreThroughPrototype( - isolate(), receiver_map(), holder, smi_handler); + isolate(), receiver_map(), holder, + StoreHandler::StoreSlow(isolate())); return MaybeObjectHandle(handler); }