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() { ...@@ -926,10 +926,11 @@ void BaselineCompiler::VisitStaNamedProperty() {
} }
void BaselineCompiler::VisitStaNamedOwnProperty() { void BaselineCompiler::VisitStaNamedOwnProperty() {
// TODO(v8:11429,ishell): Currently we use StoreOwnIC only for storing CallBuiltin<Builtin::kStoreOwnICBaseline>(
// properties that already exist in the boilerplate therefore we can use RegisterOperand(0), // object
// StoreIC. Constant<Name>(1), // name
VisitStaNamedProperty(); kInterpreterAccumulatorRegister, // value
IndexAsTagged(2)); // slot
} }
void BaselineCompiler::VisitStaKeyedProperty() { void BaselineCompiler::VisitStaKeyedProperty() {
......
...@@ -445,7 +445,7 @@ namespace internal { ...@@ -445,7 +445,7 @@ namespace internal {
T(InvalidPrivateBrand, "Object must be an instance of class %") \ T(InvalidPrivateBrand, "Object must be an instance of class %") \
T(InvalidPrivateBrandReinitialization, \ T(InvalidPrivateBrandReinitialization, \
"Cannot initialize private methods of class % twice on the same object") \ "Cannot initialize private methods of class % twice on the same object") \
T(InvalidPrivateFieldReitialization, \ T(InvalidPrivateFieldReinitialization, \
"Cannot initialize % twice on the same object") \ "Cannot initialize % twice on the same object") \
T(InvalidPrivateFieldResolution, \ T(InvalidPrivateFieldResolution, \
"Private field '%' must be declared in an enclosing class") \ "Private field '%' must be declared in an enclosing class") \
......
...@@ -1291,9 +1291,13 @@ void AccessorAssembler::HandleStoreICHandlerCase( ...@@ -1291,9 +1291,13 @@ void AccessorAssembler::HandleStoreICHandlerCase(
if (ic_mode == ICMode::kGlobalIC) { if (ic_mode == ICMode::kGlobalIC) {
TailCallRuntime(Runtime::kStoreGlobalIC_Slow, p->context(), p->value(), TailCallRuntime(Runtime::kStoreGlobalIC_Slow, p->context(), p->value(),
p->slot(), p->vector(), p->receiver(), p->name()); p->slot(), p->vector(), p->receiver(), p->name());
} else if (p->IsStoreOwn()) {
TailCallRuntime(Runtime::kStoreDataPropertyInLiteral, p->context(),
p->receiver(), p->name(), p->value());
} else { } else {
TailCallRuntime(Runtime::kKeyedStoreIC_Slow, p->context(), p->value(), TailCallRuntime(p->IsDefineOwn() ? Runtime::kKeyedDefineOwnIC_Slow
p->receiver(), p->name()); : 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, ...@@ -1765,7 +1765,7 @@ MaybeHandle<Object> StoreIC::Store(Handle<Object> object, Handle<Name> name,
Handle<String> name_string( Handle<String> name_string(
String::cast(Symbol::cast(*name).description()), isolate()); String::cast(Symbol::cast(*name).description()), isolate());
if (exists) { if (exists) {
return TypeError(MessageTemplate::kInvalidPrivateFieldReitialization, return TypeError(MessageTemplate::kInvalidPrivateFieldReinitialization,
object, name_string); object, name_string);
} else { } else {
return TypeError(MessageTemplate::kInvalidPrivateMemberWrite, object, return TypeError(MessageTemplate::kInvalidPrivateMemberWrite, object,
...@@ -2922,6 +2922,18 @@ RUNTIME_FUNCTION(Runtime_KeyedStoreIC_Slow) { ...@@ -2922,6 +2922,18 @@ RUNTIME_FUNCTION(Runtime_KeyedStoreIC_Slow) {
StoreOrigin::kMaybeKeyed)); 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) { RUNTIME_FUNCTION(Runtime_StoreInArrayLiteralIC_Slow) {
HandleScope scope(isolate); HandleScope scope(isolate);
DCHECK_EQ(3, args.length()); DCHECK_EQ(3, args.length());
......
...@@ -570,7 +570,7 @@ MaybeHandle<Object> Runtime::DefineObjectOwnProperty( ...@@ -570,7 +570,7 @@ MaybeHandle<Object> Runtime::DefineObjectOwnProperty(
DCHECK(name_string->IsString()); DCHECK(name_string->IsString());
THROW_NEW_ERROR( THROW_NEW_ERROR(
isolate, isolate,
NewTypeError(MessageTemplate::kInvalidPrivateFieldReitialization, NewTypeError(MessageTemplate::kInvalidPrivateFieldReinitialization,
name_string), name_string),
Object); Object);
} }
...@@ -1480,7 +1480,8 @@ RUNTIME_FUNCTION(Runtime_AddPrivateField) { ...@@ -1480,7 +1480,8 @@ RUNTIME_FUNCTION(Runtime_AddPrivateField) {
if (it.IsFound()) { if (it.IsFound()) {
THROW_NEW_ERROR_RETURN_FAILURE( THROW_NEW_ERROR_RETURN_FAILURE(
isolate, isolate,
NewTypeError(MessageTemplate::kInvalidPrivateFieldReitialization, key)); NewTypeError(MessageTemplate::kInvalidPrivateFieldReinitialization,
key));
} }
CHECK(Object::AddDataProperty(&it, value, NONE, Just(kDontThrow), CHECK(Object::AddDataProperty(&it, value, NONE, Just(kDontThrow),
......
...@@ -640,6 +640,7 @@ namespace internal { ...@@ -640,6 +640,7 @@ namespace internal {
F(KeyedDefineOwnIC_Miss, 5, 1) \ F(KeyedDefineOwnIC_Miss, 5, 1) \
F(StoreInArrayLiteralIC_Miss, 5, 1) \ F(StoreInArrayLiteralIC_Miss, 5, 1) \
F(KeyedStoreIC_Slow, 3, 1) \ F(KeyedStoreIC_Slow, 3, 1) \
F(KeyedDefineOwnIC_Slow, 3, 1) \
F(LoadElementWithInterceptor, 2, 1) \ F(LoadElementWithInterceptor, 2, 1) \
F(LoadGlobalIC_Miss, 4, 1) \ F(LoadGlobalIC_Miss, 4, 1) \
F(LoadGlobalIC_Slow, 3, 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