diff --git a/src/ic/accessor-assembler.cc b/src/ic/accessor-assembler.cc index 7a1f49d09a..83b296423d 100644 --- a/src/ic/accessor-assembler.cc +++ b/src/ic/accessor-assembler.cc @@ -1296,13 +1296,16 @@ 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(p->IsDefineOwn() ? Runtime::kKeyedDefineOwnIC_Slow - : Runtime::kKeyedStoreIC_Slow, - p->context(), p->value(), p->receiver(), p->name()); + Runtime::FunctionId id; + if (p->IsStoreOwn()) { + id = Runtime::kStoreOwnIC_Slow; + } else if (p->IsDefineOwn()) { + id = Runtime::kKeyedDefineOwnIC_Slow; + } else { + id = Runtime::kKeyedStoreIC_Slow; + } + TailCallRuntime(id, p->context(), p->value(), p->receiver(), p->name()); } } } diff --git a/src/ic/ic.cc b/src/ic/ic.cc index 983cd9423b..6141377bfe 100644 --- a/src/ic/ic.cc +++ b/src/ic/ic.cc @@ -2751,6 +2751,27 @@ RUNTIME_FUNCTION(Runtime_StoreOwnIC_Miss) { RETURN_RESULT_OR_FAILURE(isolate, ic.Store(receiver, key, value)); } +RUNTIME_FUNCTION(Runtime_StoreOwnIC_Slow) { + HandleScope scope(isolate); + DCHECK_EQ(3, args.length()); + + Handle value = args.at(0); + Handle object = args.at(1); + Handle key = args.at(2); + + // Unlike DefineOwn, StoreOwn doesn't handle private fields and is used for + // defining data properties in object literals and defining public class + // fields. + DCHECK(!key->IsSymbol() || !Symbol::cast(*key).is_private_name()); + + PropertyKey lookup_key(isolate, key); + LookupIterator it(isolate, object, lookup_key, LookupIterator::OWN); + MAYBE_RETURN(JSObject::DefineOwnPropertyIgnoreAttributes( + &it, value, NONE, Nothing()), + ReadOnlyRoots(isolate).exception()); + return *value; +} + RUNTIME_FUNCTION(Runtime_StoreGlobalIC_Miss) { HandleScope scope(isolate); DCHECK_EQ(4, args.length()); diff --git a/src/runtime/runtime.h b/src/runtime/runtime.h index b50d481e82..96b404f95d 100644 --- a/src/runtime/runtime.h +++ b/src/runtime/runtime.h @@ -638,6 +638,7 @@ namespace internal { F(KeyedStoreIC_Miss, 5, 1) \ F(KeyedDefineOwnIC_Miss, 5, 1) \ F(StoreInArrayLiteralIC_Miss, 5, 1) \ + F(StoreOwnIC_Slow, 3, 1) \ F(KeyedStoreIC_Slow, 3, 1) \ F(KeyedDefineOwnIC_Slow, 3, 1) \ F(LoadElementWithInterceptor, 2, 1) \ diff --git a/test/mjsunit/regress/regress-crbug-1264828.js b/test/mjsunit/regress/regress-crbug-1264828.js new file mode 100644 index 0000000000..ce33cd6f8a --- /dev/null +++ b/test/mjsunit/regress/regress-crbug-1264828.js @@ -0,0 +1,15 @@ +// 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. + +// Flags: --no-lazy-feedback-allocation + +{ + class C { + x = Object.freeze(this); + } + // Call once to install slow handler. + assertThrows(() => { new C(); }); + // Hit the slow handler. + assertThrows(() => { new C(); }); +}