Commit e8c82376 authored by Shu-yu Guo's avatar Shu-yu Guo Committed by V8 LUCI CQ

[ic,baseline] Add KeyedDefineOwnIC_Slow and use StoreOwnICBaseline in baseline

A "store own" slow runtime was missing, and the slow handler on the
StoreOwnIC was using the non-own slow runtime function, incorrectly
causing setters to be called.

For baseline, [1] invalidates the invariant that StoreOwnIC is only used
for storing properties already in the literal boilerplate, since it's
also used when the new literal is cloned from an object spread.

[1] https://chromium-review.googlesource.com/c/v8/v8/+/3224666

Bug: chromium:1263389, v8:11429
Change-Id: I0284396f306f937d1b8ff96adda6cc133c19726a
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3244308Reviewed-by: 's avatarIgor Sheludko <ishell@chromium.org>
Commit-Queue: Shu-yu Guo <syg@chromium.org>
Cr-Commit-Position: refs/heads/main@{#77591}
parent 5cbd1eed
......@@ -926,10 +926,11 @@ void BaselineCompiler::VisitStaNamedProperty() {
}
void BaselineCompiler::VisitStaNamedOwnProperty() {
// TODO(v8:11429,ishell): Currently we use StoreOwnIC only for storing
// properties that already exist in the boilerplate therefore we can use
// StoreIC.
VisitStaNamedProperty();
CallBuiltin<Builtin::kStoreOwnICBaseline>(
RegisterOperand(0), // object
Constant<Name>(1), // name
kInterpreterAccumulatorRegister, // value
IndexAsTagged(2)); // slot
}
void BaselineCompiler::VisitStaKeyedProperty() {
......
......@@ -445,7 +445,7 @@ namespace internal {
T(InvalidPrivateBrand, "Object must be an instance of class %") \
T(InvalidPrivateBrandReinitialization, \
"Cannot initialize private methods of class % twice on the same object") \
T(InvalidPrivateFieldReitialization, \
T(InvalidPrivateFieldReinitialization, \
"Cannot initialize % twice on the same object") \
T(InvalidPrivateFieldResolution, \
"Private field '%' must be declared in an enclosing class") \
......
......@@ -1291,9 +1291,13 @@ void AccessorAssembler::HandleStoreICHandlerCase(
if (ic_mode == ICMode::kGlobalIC) {
TailCallRuntime(Runtime::kStoreGlobalIC_Slow, p->context(), p->value(),
p->slot(), p->vector(), p->receiver(), p->name());
} else if (p->IsStoreOwn()) {
TailCallRuntime(Runtime::kStoreDataPropertyInLiteral, p->context(),
p->receiver(), p->name(), p->value());
} else {
TailCallRuntime(Runtime::kKeyedStoreIC_Slow, p->context(), p->value(),
p->receiver(), p->name());
TailCallRuntime(p->IsDefineOwn() ? Runtime::kKeyedDefineOwnIC_Slow
: Runtime::kKeyedStoreIC_Slow,
p->context(), p->value(), p->receiver(), p->name());
}
}
}
......
......@@ -1765,7 +1765,7 @@ MaybeHandle<Object> StoreIC::Store(Handle<Object> object, Handle<Name> name,
Handle<String> name_string(
String::cast(Symbol::cast(*name).description()), isolate());
if (exists) {
return TypeError(MessageTemplate::kInvalidPrivateFieldReitialization,
return TypeError(MessageTemplate::kInvalidPrivateFieldReinitialization,
object, name_string);
} else {
return TypeError(MessageTemplate::kInvalidPrivateMemberWrite, object,
......@@ -2922,6 +2922,18 @@ RUNTIME_FUNCTION(Runtime_KeyedStoreIC_Slow) {
StoreOrigin::kMaybeKeyed));
}
RUNTIME_FUNCTION(Runtime_KeyedDefineOwnIC_Slow) {
HandleScope scope(isolate);
DCHECK_EQ(3, args.length());
// Runtime functions don't follow the IC's calling convention.
Handle<Object> value = args.at(0);
Handle<Object> object = args.at(1);
Handle<Object> key = args.at(2);
RETURN_RESULT_OR_FAILURE(
isolate, Runtime::DefineObjectOwnProperty(isolate, object, key, value,
StoreOrigin::kMaybeKeyed));
}
RUNTIME_FUNCTION(Runtime_StoreInArrayLiteralIC_Slow) {
HandleScope scope(isolate);
DCHECK_EQ(3, args.length());
......
......@@ -570,7 +570,7 @@ MaybeHandle<Object> Runtime::DefineObjectOwnProperty(
DCHECK(name_string->IsString());
THROW_NEW_ERROR(
isolate,
NewTypeError(MessageTemplate::kInvalidPrivateFieldReitialization,
NewTypeError(MessageTemplate::kInvalidPrivateFieldReinitialization,
name_string),
Object);
}
......@@ -1480,7 +1480,8 @@ RUNTIME_FUNCTION(Runtime_AddPrivateField) {
if (it.IsFound()) {
THROW_NEW_ERROR_RETURN_FAILURE(
isolate,
NewTypeError(MessageTemplate::kInvalidPrivateFieldReitialization, key));
NewTypeError(MessageTemplate::kInvalidPrivateFieldReinitialization,
key));
}
CHECK(Object::AddDataProperty(&it, value, NONE, Just(kDontThrow),
......
......@@ -640,6 +640,7 @@ namespace internal {
F(KeyedDefineOwnIC_Miss, 5, 1) \
F(StoreInArrayLiteralIC_Miss, 5, 1) \
F(KeyedStoreIC_Slow, 3, 1) \
F(KeyedDefineOwnIC_Slow, 3, 1) \
F(LoadElementWithInterceptor, 2, 1) \
F(LoadGlobalIC_Miss, 4, 1) \
F(LoadGlobalIC_Slow, 3, 1) \
......
// Copyright 2021 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// This is testing a regression a slow store IC handler, so force allocation of
// type feedback vectors.
//
// Flags: --no-lazy-feedback-allocation
function crash() { assertTrue(false); }
Object.prototype.__defineSetter__("crashOnSet", crash);
function test() {
const o = { a: 1 };
return { ...o, crashOnSet: 42 };
}
// Run once to install the slow IC handler.
test();
// Hit the slow handler.
test();
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