From 5bbcfd1859ab43de48c4b63a9da379a00140f91d Mon Sep 17 00:00:00 2001 From: Sathya Gunasekaran Date: Tue, 9 Mar 2021 14:48:00 +0000 Subject: [PATCH] [ic] Use slow handler for lazy native accessors Lazy native accessors require special handling to rewrite the accessor into a data property, so transition to a slow handler for this case. Bug: v8:11485 Change-Id: I01636c6e624562619a216fea5e836ae85c7da93f Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2743882 Reviewed-by: Toon Verwaest Commit-Queue: Sathya Gunasekaran Cr-Commit-Position: refs/heads/master@{#73299} --- src/ic/ic.cc | 7 +++++++ test/cctest/test-accessors.cc | 33 +++++++++++++++++++++++++++++++++ 2 files changed, 40 insertions(+) diff --git a/src/ic/ic.cc b/src/ic/ic.cc index c3f44b614a..408c36f822 100644 --- a/src/ic/ic.cc +++ b/src/ic/ic.cc @@ -943,6 +943,13 @@ Handle LoadIC::ComputeHandler(LookupIterator* lookup) { Handle info = Handle::cast(accessors); + if (info->replace_on_access()) { + set_slow_stub_reason( + "getter needs to be reconfigured to data property"); + TRACE_HANDLER_STATS(isolate(), LoadIC_SlowStub); + return LoadHandler::LoadSlow(isolate()); + } + if (v8::ToCData
(info->getter()) == kNullAddress || !AccessorInfo::IsCompatibleReceiverMap(info, map) || !holder->HasFastProperties() || diff --git a/test/cctest/test-accessors.cc b/test/cctest/test-accessors.cc index d30be37923..4604f5abd7 100644 --- a/test/cctest/test-accessors.cc +++ b/test/cctest/test-accessors.cc @@ -902,3 +902,36 @@ TEST(ObjectSetLazyDataPropertyForIndex) { CHECK_EQ(1, getter_call_count); } } + +TEST(ObjectTemplateSetLazyPropertySurvivesIC) { + i::FLAG_allow_natives_syntax = true; + LocalContext env; + v8::Isolate* isolate = env->GetIsolate(); + v8::HandleScope scope(isolate); + v8::Local context = isolate->GetCurrentContext(); + + v8::Local templ = v8::ObjectTemplate::New(isolate); + static int getter_call_count = 0; + templ->SetLazyDataProperty( + v8_str("foo"), [](v8::Local name, + const v8::PropertyCallbackInfo& info) { + getter_call_count++; + info.GetReturnValue().Set(getter_call_count); + }); + + v8::Local f = CompileRun( + "function f(obj) {" + " obj.foo;" + " obj.foo;" + "};" + "%PrepareFunctionForOptimization(f);" + "f") + .As(); + v8::Local obj = templ->NewInstance(context).ToLocalChecked(); + f->Call(context, context->Global(), 1, &obj).ToLocalChecked(); + CHECK_EQ(getter_call_count, 1); + + obj = templ->NewInstance(context).ToLocalChecked(); + f->Call(context, context->Global(), 1, &obj).ToLocalChecked(); + CHECK_EQ(getter_call_count, 2); +}