[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 <verwaest@chromium.org>
Commit-Queue: Sathya Gunasekaran  <gsathya@chromium.org>
Cr-Commit-Position: refs/heads/master@{#73299}
This commit is contained in:
Sathya Gunasekaran 2021-03-09 14:48:00 +00:00 committed by Commit Bot
parent cd48a91276
commit 5bbcfd1859
2 changed files with 40 additions and 0 deletions

View File

@ -943,6 +943,13 @@ Handle<Object> LoadIC::ComputeHandler(LookupIterator* lookup) {
Handle<AccessorInfo> info = Handle<AccessorInfo>::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<Address>(info->getter()) == kNullAddress ||
!AccessorInfo::IsCompatibleReceiverMap(info, map) ||
!holder->HasFastProperties() ||

View File

@ -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<v8::Context> context = isolate->GetCurrentContext();
v8::Local<v8::ObjectTemplate> templ = v8::ObjectTemplate::New(isolate);
static int getter_call_count = 0;
templ->SetLazyDataProperty(
v8_str("foo"), [](v8::Local<v8::Name> name,
const v8::PropertyCallbackInfo<v8::Value>& info) {
getter_call_count++;
info.GetReturnValue().Set(getter_call_count);
});
v8::Local<v8::Function> f = CompileRun(
"function f(obj) {"
" obj.foo;"
" obj.foo;"
"};"
"%PrepareFunctionForOptimization(f);"
"f")
.As<v8::Function>();
v8::Local<v8::Value> 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);
}