Commit cf5ce194 authored by Joyee Cheung's avatar Joyee Cheung Committed by V8 LUCI CQ

[ic] name Set/Define/Store property operations more consistently pt.2

As a follow-up of
https://chromium-review.googlesource.com/c/v8/v8/+/3481475,
this renames a few more operations related to property stores to keep
them consistent and adds comments to explain about what they do.

Summary of the renamed identifiers:

- SetPropertyInLiteral -> CreateDataProperty: this implements
  [[CreateDataProperty]] in the spec which does [[DefineOwnProperty]]
  instead of [[Set]], so rename for clarity.
- IsStoreIC(), IsStoreICKind() -> IsSetNamedIC(), IsSetNamedICKind():
  these only check whether the feedback kind is kSetNamedSloppy or
  kSetNamedStrict, so the scope can be narrowed.
- StoreMode::kOrdinary -> StoreMode::kSet: this implements [[Set]]
  in the spec and is used by both KeyedStoreIC and
  StoreIC to set the properties when there is no feedback.
- StoreMode::kInLiteral -> StoreMode::kDefineKeyedOwnInLiteral:
  this implements [[CreateDataProperty]] while expecting the receiver
  to be a JSObject created by us (the `InLiteral` part). Prepend
  `DefineKeyedOwn` to it so that it's more aligned with other
  StoreModes - it should be possible to just merge this into the
  more generic StoreMode::kDefineKeyedOwn later.
- KeyedStoreGenericAssembler::SetProperty ->
  KeyedStoreGenericAssembler::StoreProperty: these helpers are used by
  both define and set operations, distinguished with the StoreMode,
  so rename it to the more generic StoreProperty.

Bug: v8:12548
Change-Id: Iccef673c1dc707bbdbf010f02f7db1e9ec32b3e4
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3557690Reviewed-by: 's avatarToon Verwaest <verwaest@chromium.org>
Commit-Queue: Joyee Cheung <joyee@igalia.com>
Cr-Commit-Position: refs/heads/main@{#79694}
parent 8ba70dfe
...@@ -672,7 +672,7 @@ extern transitioning builtin SetProperty(implicit context: Context)( ...@@ -672,7 +672,7 @@ extern transitioning builtin SetProperty(implicit context: Context)(
JSAny, JSAny, JSAny): JSAny; JSAny, JSAny, JSAny): JSAny;
extern transitioning builtin SetPropertyIgnoreAttributes( extern transitioning builtin SetPropertyIgnoreAttributes(
implicit context: Context)(JSObject, String, JSAny, Smi): JSAny; implicit context: Context)(JSObject, String, JSAny, Smi): JSAny;
extern transitioning builtin SetPropertyInLiteral(implicit context: Context)( extern transitioning builtin CreateDataProperty(implicit context: Context)(
JSAny, JSAny, JSAny): JSAny; JSAny, JSAny, JSAny): JSAny;
extern transitioning builtin DeleteProperty(implicit context: Context)( extern transitioning builtin DeleteProperty(implicit context: Context)(
JSAny, JSAny | PrivateSymbol, LanguageModeSmi): Boolean; JSAny, JSAny | PrivateSymbol, LanguageModeSmi): Boolean;
......
...@@ -1062,7 +1062,7 @@ namespace internal { ...@@ -1062,7 +1062,7 @@ namespace internal {
TFC(GetProperty, GetProperty) \ TFC(GetProperty, GetProperty) \
TFS(GetPropertyWithReceiver, kObject, kKey, kReceiver, kOnNonExistent) \ TFS(GetPropertyWithReceiver, kObject, kKey, kReceiver, kOnNonExistent) \
TFS(SetProperty, kReceiver, kKey, kValue) \ TFS(SetProperty, kReceiver, kKey, kValue) \
TFS(SetPropertyInLiteral, kReceiver, kKey, kValue) \ TFS(CreateDataProperty, kReceiver, kKey, kValue) \
ASM(MemCopyUint8Uint8, CCall) \ ASM(MemCopyUint8Uint8, CCall) \
ASM(MemMove, CCall) \ ASM(MemMove, CCall) \
\ \
......
...@@ -839,7 +839,7 @@ class SetOrCopyDataPropertiesAssembler : public CodeStubAssembler { ...@@ -839,7 +839,7 @@ class SetOrCopyDataPropertiesAssembler : public CodeStubAssembler {
1, IndexAdvanceMode::kPost); 1, IndexAdvanceMode::kPost);
} }
CallBuiltin(Builtin::kSetPropertyInLiteral, context, target, key, CallBuiltin(Builtin::kCreateDataProperty, context, target, key,
value); value);
Goto(&skip); Goto(&skip);
Bind(&skip); Bind(&skip);
...@@ -1362,14 +1362,14 @@ TF_BUILTIN(SetProperty, CodeStubAssembler) { ...@@ -1362,14 +1362,14 @@ TF_BUILTIN(SetProperty, CodeStubAssembler) {
// being initialized, and have not yet been made accessible to the user. Thus, // being initialized, and have not yet been made accessible to the user. Thus,
// any operation here should be unobservable until after the object has been // any operation here should be unobservable until after the object has been
// returned. // returned.
TF_BUILTIN(SetPropertyInLiteral, CodeStubAssembler) { TF_BUILTIN(CreateDataProperty, CodeStubAssembler) {
auto context = Parameter<Context>(Descriptor::kContext); auto context = Parameter<Context>(Descriptor::kContext);
auto receiver = Parameter<JSObject>(Descriptor::kReceiver); auto receiver = Parameter<JSObject>(Descriptor::kReceiver);
auto key = Parameter<Object>(Descriptor::kKey); auto key = Parameter<Object>(Descriptor::kKey);
auto value = Parameter<Object>(Descriptor::kValue); auto value = Parameter<Object>(Descriptor::kValue);
KeyedStoreGenericGenerator::SetPropertyInLiteral(state(), context, receiver, KeyedStoreGenericGenerator::CreateDataProperty(state(), context, receiver,
key, value); key, value);
} }
TF_BUILTIN(InstantiateAsmJs, CodeStubAssembler) { TF_BUILTIN(InstantiateAsmJs, CodeStubAssembler) {
......
...@@ -18,20 +18,20 @@ transitioning macro ObjectFromEntriesFastCase(implicit context: Context)( ...@@ -18,20 +18,20 @@ transitioning macro ObjectFromEntriesFastCase(implicit context: Context)(
const pair: KeyValuePair = const pair: KeyValuePair =
collections::LoadKeyValuePairNoSideEffects(value) collections::LoadKeyValuePairNoSideEffects(value)
otherwise IfSlow; otherwise IfSlow;
// StorePropertyInLiteral only handles Names and Numbers. Bail out if // CreateDataProperty only handles Names and Numbers. Bail out if
// the key is not one of those types. Note that JSReceivers should // the key is not one of those types. Note that JSReceivers should
// always bail to the slow path, as calling Symbol.toPrimitive, // always bail to the slow path, as calling Symbol.toPrimitive,
// toString, or valueOf could invalidate assumptions about the // toString, or valueOf could invalidate assumptions about the
// iterable. // iterable.
typeswitch (pair.key) { typeswitch (pair.key) {
case (Name): { case (Name): {
SetPropertyInLiteral(result, pair.key, pair.value); CreateDataProperty(result, pair.key, pair.value);
} }
case (Number): { case (Number): {
SetPropertyInLiteral(result, pair.key, pair.value); CreateDataProperty(result, pair.key, pair.value);
} }
case (oddball: Oddball): { case (oddball: Oddball): {
SetPropertyInLiteral(result, oddball.to_string, pair.value); CreateDataProperty(result, oddball.to_string, pair.value);
} }
case (JSAny): { case (JSAny): {
goto IfSlow; goto IfSlow;
......
...@@ -3229,10 +3229,10 @@ class V8_EXPORT_PRIVATE CodeStubAssembler ...@@ -3229,10 +3229,10 @@ class V8_EXPORT_PRIVATE CodeStubAssembler
return CallBuiltin(Builtin::kSetProperty, context, receiver, key, value); return CallBuiltin(Builtin::kSetProperty, context, receiver, key, value);
} }
TNode<Object> SetPropertyInLiteral(TNode<Context> context, TNode<Object> CreateDataProperty(TNode<Context> context,
TNode<JSObject> receiver, TNode<JSObject> receiver, TNode<Object> key,
TNode<Object> key, TNode<Object> value) { TNode<Object> value) {
return CallBuiltin(Builtin::kSetPropertyInLiteral, context, receiver, key, return CallBuiltin(Builtin::kCreateDataProperty, context, receiver, key,
value); value);
} }
......
...@@ -429,7 +429,7 @@ NamedAccessFeedback::NamedAccessFeedback(NameRef const& name, ...@@ -429,7 +429,7 @@ NamedAccessFeedback::NamedAccessFeedback(NameRef const& name,
ZoneVector<MapRef> const& maps, ZoneVector<MapRef> const& maps,
FeedbackSlotKind slot_kind) FeedbackSlotKind slot_kind)
: ProcessedFeedback(kNamedAccess, slot_kind), name_(name), maps_(maps) { : ProcessedFeedback(kNamedAccess, slot_kind), name_(name), maps_(maps) {
DCHECK(IsLoadICKind(slot_kind) || IsStoreICKind(slot_kind) || DCHECK(IsLoadICKind(slot_kind) || IsSetNamedICKind(slot_kind) ||
IsDefineNamedOwnICKind(slot_kind) || IsKeyedLoadICKind(slot_kind) || IsDefineNamedOwnICKind(slot_kind) || IsKeyedLoadICKind(slot_kind) ||
IsKeyedHasICKind(slot_kind) || IsKeyedStoreICKind(slot_kind) || IsKeyedHasICKind(slot_kind) || IsKeyedStoreICKind(slot_kind) ||
IsStoreInArrayLiteralICKind(slot_kind) || IsStoreInArrayLiteralICKind(slot_kind) ||
......
...@@ -4134,7 +4134,7 @@ void AccessorAssembler::StoreInArrayLiteralIC(const StoreICParameters* p) { ...@@ -4134,7 +4134,7 @@ void AccessorAssembler::StoreInArrayLiteralIC(const StoreICParameters* p) {
BIND(&no_feedback); BIND(&no_feedback);
{ {
Comment("StoreInArrayLiteralIC_NoFeedback"); Comment("StoreInArrayLiteralIC_NoFeedback");
TailCallBuiltin(Builtin::kSetPropertyInLiteral, p->context(), p->receiver(), TailCallBuiltin(Builtin::kCreateDataProperty, p->context(), p->receiver(),
p->name(), p->value()); p->name(), p->value());
} }
...@@ -4782,7 +4782,7 @@ void AccessorAssembler::GenerateCloneObjectIC_Slow() { ...@@ -4782,7 +4782,7 @@ void AccessorAssembler::GenerateCloneObjectIC_Slow() {
ForEachEnumerableOwnProperty( ForEachEnumerableOwnProperty(
context, source_map, CAST(source), kPropertyAdditionOrder, context, source_map, CAST(source), kPropertyAdditionOrder,
[=](TNode<Name> key, TNode<Object> value) { [=](TNode<Name> key, TNode<Object> value) {
SetPropertyInLiteral(context, result, key, value); CreateDataProperty(context, result, key, value);
}, },
&call_runtime); &call_runtime);
Goto(&done); Goto(&done);
......
...@@ -2859,7 +2859,7 @@ RUNTIME_FUNCTION(Runtime_StoreIC_Miss) { ...@@ -2859,7 +2859,7 @@ RUNTIME_FUNCTION(Runtime_StoreIC_Miss) {
kind = vector->GetKind(vector_slot); kind = vector->GetKind(vector_slot);
} }
DCHECK(IsStoreICKind(kind) || IsDefineNamedOwnICKind(kind)); DCHECK(IsSetNamedICKind(kind) || IsDefineNamedOwnICKind(kind));
StoreIC ic(isolate, vector, vector_slot, kind); StoreIC ic(isolate, vector, vector_slot, kind);
ic.UpdateState(receiver, key); ic.UpdateState(receiver, key);
RETURN_RESULT_OR_FAILURE(isolate, ic.Store(receiver, key, value)); RETURN_RESULT_OR_FAILURE(isolate, ic.Store(receiver, key, value));
...@@ -3151,7 +3151,7 @@ RUNTIME_FUNCTION(Runtime_ElementsTransitionAndStoreIC_Miss) { ...@@ -3151,7 +3151,7 @@ RUNTIME_FUNCTION(Runtime_ElementsTransitionAndStoreIC_Miss) {
StoreOwnElement(isolate, Handle<JSArray>::cast(object), key, value); StoreOwnElement(isolate, Handle<JSArray>::cast(object), key, value);
return *value; return *value;
} else { } else {
DCHECK(IsKeyedStoreICKind(kind) || IsStoreICKind(kind) || DCHECK(IsKeyedStoreICKind(kind) || IsSetNamedICKind(kind) ||
IsDefineKeyedOwnICKind(kind)); IsDefineKeyedOwnICKind(kind));
RETURN_RESULT_OR_FAILURE( RETURN_RESULT_OR_FAILURE(
isolate, isolate,
......
...@@ -53,7 +53,7 @@ class IC { ...@@ -53,7 +53,7 @@ class IC {
return IsLoadIC() || IsLoadGlobalIC() || IsKeyedLoadIC(); return IsLoadIC() || IsLoadGlobalIC() || IsKeyedLoadIC();
} }
bool IsAnyStore() const { bool IsAnyStore() const {
return IsStoreIC() || IsDefineNamedOwnIC() || IsStoreGlobalIC() || return IsSetNamedIC() || IsDefineNamedOwnIC() || IsStoreGlobalIC() ||
IsKeyedStoreIC() || IsStoreInArrayLiteralICKind(kind()) || IsKeyedStoreIC() || IsStoreInArrayLiteralICKind(kind()) ||
IsDefineKeyedOwnIC(); IsDefineKeyedOwnIC();
} }
...@@ -121,7 +121,7 @@ class IC { ...@@ -121,7 +121,7 @@ class IC {
bool IsLoadGlobalIC() const { return IsLoadGlobalICKind(kind_); } bool IsLoadGlobalIC() const { return IsLoadGlobalICKind(kind_); }
bool IsKeyedLoadIC() const { return IsKeyedLoadICKind(kind_); } bool IsKeyedLoadIC() const { return IsKeyedLoadICKind(kind_); }
bool IsStoreGlobalIC() const { return IsStoreGlobalICKind(kind_); } bool IsStoreGlobalIC() const { return IsStoreGlobalICKind(kind_); }
bool IsStoreIC() const { return IsStoreICKind(kind_); } bool IsSetNamedIC() const { return IsSetNamedICKind(kind_); }
bool IsDefineNamedOwnIC() const { return IsDefineNamedOwnICKind(kind_); } bool IsDefineNamedOwnIC() const { return IsDefineNamedOwnICKind(kind_); }
bool IsStoreInArrayLiteralIC() const { bool IsStoreInArrayLiteralIC() const {
return IsStoreInArrayLiteralICKind(kind_); return IsStoreInArrayLiteralICKind(kind_);
......
...@@ -17,16 +17,28 @@ namespace v8 { ...@@ -17,16 +17,28 @@ namespace v8 {
namespace internal { namespace internal {
enum class StoreMode { enum class StoreMode {
// TODO(v8:12548): rename to kSet and kDefineKeyedOwnInLiteral // kSet implements [[Set]] in the spec and traverses the prototype
kOrdinary, // chain to invoke setters. it's used by KeyedStoreIC and StoreIC to
kInLiteral, // set the properties when there is no feedback.
kSet,
// kDefineNamedOwn performs an ordinary property store without traversing the // kDefineKeyedOwnInLiteral implements [[CreateDataProperty]] in the spec,
// prototype chain. In the case of private fields, it will throw if the // and it assumes that the receiver is a JSObject that is created by us.
// field does not already exist. // It is used by Object.fromEntries(), CloneObjectIC and
// kDefineKeyedOwn is similar to kDefineNamedOwn, but for private class // StoreInArrayLiteralIC to define a property in an object without
// fields, it will throw if the field does already exist. // traversing the prototype chain.
// TODO(v8:12548): merge this into the more generic kDefineKeyedOwn.
kDefineKeyedOwnInLiteral,
// kDefineNamedOwn implements [[CreateDataProperty]] but it can deal with
// user-defined receivers such as a JSProxy. It also assumes that the key
// is statically known. It's used to initialize named roperties in object
// literals and named public class fields.
kDefineNamedOwn, kDefineNamedOwn,
// kDefineKeyedOwn implements [[CreateDataProperty]], but it can deal with
// user-defined receivers such as a JSProxy, and for private class fields,
// it will throw if the field does already exist. It's different from
// kDefineNamedOwn in that it does not assume the key is statically known.
// It's used to initialized computed public class fields and private
// class fields.
kDefineKeyedOwn kDefineKeyedOwn
}; };
...@@ -44,19 +56,20 @@ class KeyedStoreGenericAssembler : public AccessorAssembler { ...@@ -44,19 +56,20 @@ class KeyedStoreGenericAssembler : public AccessorAssembler {
void StoreIC_NoFeedback(); void StoreIC_NoFeedback();
// Generates code for [[Set]] operation, the |unique_name| is supposed to be // Generates code for [[Set]] or [[CreateDataProperty]] operation,
// unique otherwise this code will always go to runtime. // the |unique_name| is supposed to be unique otherwise this code will
void SetProperty(TNode<Context> context, TNode<JSReceiver> receiver, // always go to runtime.
TNode<BoolT> is_simple_receiver, TNode<Name> unique_name, void StoreProperty(TNode<Context> context, TNode<JSReceiver> receiver,
TNode<Object> value, LanguageMode language_mode); TNode<BoolT> is_simple_receiver, TNode<Name> unique_name,
TNode<Object> value, LanguageMode language_mode);
// [[Set]], but more generic than the above. This impl does essentially the
// same as "KeyedStoreGeneric" but does not use feedback slot and uses a // This does [[Set]] or [[CreateDataProperty]] but it's more generic than
// hardcoded LanguageMode instead of trying to deduce it from the feedback // the above. It is essentially the same as "KeyedStoreGeneric" but does not
// slot's kind. // use feedback slot and uses a hardcoded LanguageMode instead of trying
void SetProperty(TNode<Context> context, TNode<Object> receiver, // to deduce it from the feedback slot's kind.
TNode<Object> key, TNode<Object> value, void StoreProperty(TNode<Context> context, TNode<Object> receiver,
LanguageMode language_mode); TNode<Object> key, TNode<Object> value,
LanguageMode language_mode);
private: private:
StoreMode mode_; StoreMode mode_;
...@@ -69,7 +82,7 @@ class KeyedStoreGenericAssembler : public AccessorAssembler { ...@@ -69,7 +82,7 @@ class KeyedStoreGenericAssembler : public AccessorAssembler {
enum UseStubCache { kUseStubCache, kDontUseStubCache }; enum UseStubCache { kUseStubCache, kDontUseStubCache };
// Helper that is used by the public KeyedStoreGeneric and by SetProperty. // Helper that is used by the public KeyedStoreGeneric and by StoreProperty.
void KeyedStoreGeneric(TNode<Context> context, TNode<Object> receiver, void KeyedStoreGeneric(TNode<Context> context, TNode<Object> receiver,
TNode<Object> key, TNode<Object> value, TNode<Object> key, TNode<Object> value,
Maybe<LanguageMode> language_mode); Maybe<LanguageMode> language_mode);
...@@ -147,31 +160,33 @@ class KeyedStoreGenericAssembler : public AccessorAssembler { ...@@ -147,31 +160,33 @@ class KeyedStoreGenericAssembler : public AccessorAssembler {
TNode<Name> name, TNode<Name> name,
Label* slow); Label* slow);
bool IsKeyedStore() const { return mode_ == StoreMode::kOrdinary; } bool IsSet() const { return mode_ == StoreMode::kSet; }
bool IsStoreInLiteral() const { return mode_ == StoreMode::kInLiteral; } bool IsDefineKeyedOwnInLiteral() const {
return mode_ == StoreMode::kDefineKeyedOwnInLiteral;
}
bool IsDefineNamedOwn() const { return mode_ == StoreMode::kDefineNamedOwn; } bool IsDefineNamedOwn() const { return mode_ == StoreMode::kDefineNamedOwn; }
bool IsDefineKeyedOwn() const { return mode_ == StoreMode::kDefineKeyedOwn; } bool IsDefineKeyedOwn() const { return mode_ == StoreMode::kDefineKeyedOwn; }
bool IsAnyDefineOwn() const { bool IsAnyDefineOwn() const {
return IsDefineNamedOwn() || IsDefineKeyedOwn(); return IsDefineNamedOwn() || IsDefineKeyedOwn();
} }
bool ShouldCheckPrototype() const { return IsKeyedStore(); } bool ShouldCheckPrototype() const { return IsSet(); }
bool ShouldReconfigureExisting() const { return IsStoreInLiteral(); } bool ShouldReconfigureExisting() const { return IsDefineKeyedOwnInLiteral(); }
bool ShouldCallSetter() const { return IsKeyedStore(); } bool ShouldCallSetter() const { return IsSet(); }
bool ShouldCheckPrototypeValidity() const { bool ShouldCheckPrototypeValidity() const {
// We don't do this for "in-literal" stores, because it is impossible for // We don't do this for "in-literal" stores, because it is impossible for
// the target object to be a "prototype". // the target object to be a "prototype".
// We don't need the prototype validity check for "own" stores, because // We don't need the prototype validity check for "own" stores, because
// we don't care about the prototype chain. // we don't care about the prototype chain.
// Thus, we need the prototype check only for ordinary stores. // Thus, we need the prototype check only for ordinary stores.
DCHECK_IMPLIES(!IsKeyedStore(), IsStoreInLiteral() || IsDefineNamedOwn() || DCHECK_IMPLIES(!IsSet(), IsDefineKeyedOwnInLiteral() ||
IsDefineKeyedOwn()); IsDefineNamedOwn() || IsDefineKeyedOwn());
return IsKeyedStore(); return IsSet();
} }
}; };
void KeyedStoreGenericGenerator::Generate(compiler::CodeAssemblerState* state) { void KeyedStoreGenericGenerator::Generate(compiler::CodeAssemblerState* state) {
KeyedStoreGenericAssembler assembler(state, StoreMode::kOrdinary); KeyedStoreGenericAssembler assembler(state, StoreMode::kSet);
assembler.KeyedStoreGeneric(); assembler.KeyedStoreGeneric();
} }
...@@ -182,7 +197,7 @@ void DefineKeyedOwnGenericGenerator::Generate( ...@@ -182,7 +197,7 @@ void DefineKeyedOwnGenericGenerator::Generate(
} }
void StoreICNoFeedbackGenerator::Generate(compiler::CodeAssemblerState* state) { void StoreICNoFeedbackGenerator::Generate(compiler::CodeAssemblerState* state) {
KeyedStoreGenericAssembler assembler(state, StoreMode::kOrdinary); KeyedStoreGenericAssembler assembler(state, StoreMode::kSet);
assembler.StoreIC_NoFeedback(); assembler.StoreIC_NoFeedback();
} }
...@@ -198,24 +213,25 @@ void KeyedStoreGenericGenerator::SetProperty( ...@@ -198,24 +213,25 @@ void KeyedStoreGenericGenerator::SetProperty(
compiler::CodeAssemblerState* state, TNode<Context> context, compiler::CodeAssemblerState* state, TNode<Context> context,
TNode<JSReceiver> receiver, TNode<BoolT> is_simple_receiver, TNode<JSReceiver> receiver, TNode<BoolT> is_simple_receiver,
TNode<Name> name, TNode<Object> value, LanguageMode language_mode) { TNode<Name> name, TNode<Object> value, LanguageMode language_mode) {
KeyedStoreGenericAssembler assembler(state, StoreMode::kOrdinary); KeyedStoreGenericAssembler assembler(state, StoreMode::kSet);
assembler.SetProperty(context, receiver, is_simple_receiver, name, value, assembler.StoreProperty(context, receiver, is_simple_receiver, name, value,
language_mode); language_mode);
} }
void KeyedStoreGenericGenerator::SetProperty( void KeyedStoreGenericGenerator::SetProperty(
compiler::CodeAssemblerState* state, TNode<Context> context, compiler::CodeAssemblerState* state, TNode<Context> context,
TNode<Object> receiver, TNode<Object> key, TNode<Object> value, TNode<Object> receiver, TNode<Object> key, TNode<Object> value,
LanguageMode language_mode) { LanguageMode language_mode) {
KeyedStoreGenericAssembler assembler(state, StoreMode::kOrdinary); KeyedStoreGenericAssembler assembler(state, StoreMode::kSet);
assembler.SetProperty(context, receiver, key, value, language_mode); assembler.StoreProperty(context, receiver, key, value, language_mode);
} }
void KeyedStoreGenericGenerator::SetPropertyInLiteral( void KeyedStoreGenericGenerator::CreateDataProperty(
compiler::CodeAssemblerState* state, TNode<Context> context, compiler::CodeAssemblerState* state, TNode<Context> context,
TNode<JSObject> receiver, TNode<Object> key, TNode<Object> value) { TNode<JSObject> receiver, TNode<Object> key, TNode<Object> value) {
KeyedStoreGenericAssembler assembler(state, StoreMode::kInLiteral); KeyedStoreGenericAssembler assembler(state,
assembler.SetProperty(context, receiver, key, value, LanguageMode::kStrict); StoreMode::kDefineKeyedOwnInLiteral);
assembler.StoreProperty(context, receiver, key, value, LanguageMode::kStrict);
} }
void KeyedStoreGenericAssembler::BranchIfPrototypesMayHaveReadOnlyElements( void KeyedStoreGenericAssembler::BranchIfPrototypesMayHaveReadOnlyElements(
...@@ -381,7 +397,7 @@ void KeyedStoreGenericAssembler::StoreElementWithCapacity( ...@@ -381,7 +397,7 @@ void KeyedStoreGenericAssembler::StoreElementWithCapacity(
{ {
TNode<IntPtrT> offset = TNode<IntPtrT> offset =
ElementOffsetFromIndex(index, PACKED_ELEMENTS, kHeaderSize); ElementOffsetFromIndex(index, PACKED_ELEMENTS, kHeaderSize);
if (!IsStoreInLiteral()) { if (!IsDefineKeyedOwnInLiteral()) {
// Check if we're about to overwrite the hole. We can safely do that // Check if we're about to overwrite the hole. We can safely do that
// only if there can be no setters on the prototype chain. // only if there can be no setters on the prototype chain.
// If we know that we're storing beyond the previous array length, we // If we know that we're storing beyond the previous array length, we
...@@ -484,7 +500,7 @@ void KeyedStoreGenericAssembler::StoreElementWithCapacity( ...@@ -484,7 +500,7 @@ void KeyedStoreGenericAssembler::StoreElementWithCapacity(
{ {
TNode<IntPtrT> offset = TNode<IntPtrT> offset =
ElementOffsetFromIndex(index, PACKED_DOUBLE_ELEMENTS, kHeaderSize); ElementOffsetFromIndex(index, PACKED_DOUBLE_ELEMENTS, kHeaderSize);
if (!IsStoreInLiteral()) { if (!IsDefineKeyedOwnInLiteral()) {
// Check if we're about to overwrite the hole. We can safely do that // Check if we're about to overwrite the hole. We can safely do that
// only if there can be no setters on the prototype chain. // only if there can be no setters on the prototype chain.
{ {
...@@ -1053,7 +1069,7 @@ void KeyedStoreGenericAssembler::EmitGenericPropertyStore( ...@@ -1053,7 +1069,7 @@ void KeyedStoreGenericAssembler::EmitGenericPropertyStore(
} }
} }
// Helper that is used by the public KeyedStoreGeneric and by SetProperty. // Helper that is used by the public KeyedStoreGeneric and by StoreProperty.
void KeyedStoreGenericAssembler::KeyedStoreGeneric( void KeyedStoreGenericAssembler::KeyedStoreGeneric(
TNode<Context> context, TNode<Object> receiver_maybe_smi, TNode<Object> key, TNode<Context> context, TNode<Object> receiver_maybe_smi, TNode<Object> key,
TNode<Object> value, Maybe<LanguageMode> language_mode) { TNode<Object> value, Maybe<LanguageMode> language_mode) {
...@@ -1102,7 +1118,7 @@ void KeyedStoreGenericAssembler::KeyedStoreGeneric( ...@@ -1102,7 +1118,7 @@ void KeyedStoreGenericAssembler::KeyedStoreGeneric(
BIND(&slow); BIND(&slow);
{ {
if (IsKeyedStore() || IsDefineNamedOwn()) { if (IsSet() || IsDefineNamedOwn()) {
// The DefineNamedOwnIC hacky reuse should never reach here. // The DefineNamedOwnIC hacky reuse should never reach here.
CSA_DCHECK(this, BoolConstant(!IsDefineNamedOwn())); CSA_DCHECK(this, BoolConstant(!IsDefineNamedOwn()));
Comment("KeyedStoreGeneric_slow"); Comment("KeyedStoreGeneric_slow");
...@@ -1112,7 +1128,7 @@ void KeyedStoreGenericAssembler::KeyedStoreGeneric( ...@@ -1112,7 +1128,7 @@ void KeyedStoreGenericAssembler::KeyedStoreGeneric(
TailCallRuntime(Runtime::kDefineObjectOwnProperty, context, receiver, key, TailCallRuntime(Runtime::kDefineObjectOwnProperty, context, receiver, key,
value); value);
} else { } else {
DCHECK(IsStoreInLiteral()); DCHECK(IsDefineKeyedOwnInLiteral());
TailCallRuntime(Runtime::kDefineKeyedOwnPropertyInLiteral_Simple, context, TailCallRuntime(Runtime::kDefineKeyedOwnPropertyInLiteral_Simple, context,
receiver, key, value); receiver, key, value);
} }
...@@ -1130,11 +1146,11 @@ void KeyedStoreGenericAssembler::KeyedStoreGeneric() { ...@@ -1130,11 +1146,11 @@ void KeyedStoreGenericAssembler::KeyedStoreGeneric() {
KeyedStoreGeneric(context, receiver, name, value, Nothing<LanguageMode>()); KeyedStoreGeneric(context, receiver, name, value, Nothing<LanguageMode>());
} }
void KeyedStoreGenericAssembler::SetProperty(TNode<Context> context, void KeyedStoreGenericAssembler::StoreProperty(TNode<Context> context,
TNode<Object> receiver, TNode<Object> receiver,
TNode<Object> key, TNode<Object> key,
TNode<Object> value, TNode<Object> value,
LanguageMode language_mode) { LanguageMode language_mode) {
KeyedStoreGeneric(context, receiver, key, value, Just(language_mode)); KeyedStoreGeneric(context, receiver, key, value, Just(language_mode));
} }
...@@ -1177,12 +1193,12 @@ void KeyedStoreGenericAssembler::StoreIC_NoFeedback() { ...@@ -1177,12 +1193,12 @@ void KeyedStoreGenericAssembler::StoreIC_NoFeedback() {
} }
} }
void KeyedStoreGenericAssembler::SetProperty(TNode<Context> context, void KeyedStoreGenericAssembler::StoreProperty(TNode<Context> context,
TNode<JSReceiver> receiver, TNode<JSReceiver> receiver,
TNode<BoolT> is_simple_receiver, TNode<BoolT> is_simple_receiver,
TNode<Name> unique_name, TNode<Name> unique_name,
TNode<Object> value, TNode<Object> value,
LanguageMode language_mode) { LanguageMode language_mode) {
StoreICParameters p(context, receiver, unique_name, value, {}, StoreICParameters p(context, receiver, unique_name, value, {},
UndefinedConstant(), StoreICMode::kDefault); UndefinedConstant(), StoreICMode::kDefault);
...@@ -1200,7 +1216,7 @@ void KeyedStoreGenericAssembler::SetProperty(TNode<Context> context, ...@@ -1200,7 +1216,7 @@ void KeyedStoreGenericAssembler::SetProperty(TNode<Context> context,
BIND(&slow); BIND(&slow);
{ {
if (IsStoreInLiteral()) { if (IsDefineKeyedOwnInLiteral()) {
CallRuntime(Runtime::kDefineKeyedOwnPropertyInLiteral_Simple, context, CallRuntime(Runtime::kDefineKeyedOwnPropertyInLiteral_Simple, context,
receiver, unique_name, value); receiver, unique_name, value);
} else { } else {
......
...@@ -28,10 +28,10 @@ class KeyedStoreGenericGenerator { ...@@ -28,10 +28,10 @@ class KeyedStoreGenericGenerator {
TNode<Object> key, TNode<Object> value, TNode<Object> key, TNode<Object> value,
LanguageMode language_mode); LanguageMode language_mode);
static void SetPropertyInLiteral(compiler::CodeAssemblerState* state, static void CreateDataProperty(compiler::CodeAssemblerState* state,
TNode<Context> context, TNode<Context> context,
TNode<JSObject> receiver, TNode<Object> key, TNode<JSObject> receiver, TNode<Object> key,
TNode<Object> value); TNode<Object> value);
}; };
class DefineKeyedOwnGenericGenerator { class DefineKeyedOwnGenericGenerator {
......
...@@ -1427,7 +1427,7 @@ void FeedbackNexus::ResetTypeProfile() { ...@@ -1427,7 +1427,7 @@ void FeedbackNexus::ResetTypeProfile() {
FeedbackIterator::FeedbackIterator(const FeedbackNexus* nexus) FeedbackIterator::FeedbackIterator(const FeedbackNexus* nexus)
: done_(false), index_(-1), state_(kOther) { : done_(false), index_(-1), state_(kOther) {
DCHECK( DCHECK(
IsLoadICKind(nexus->kind()) || IsStoreICKind(nexus->kind()) || IsLoadICKind(nexus->kind()) || IsSetNamedICKind(nexus->kind()) ||
IsKeyedLoadICKind(nexus->kind()) || IsKeyedStoreICKind(nexus->kind()) || IsKeyedLoadICKind(nexus->kind()) || IsKeyedStoreICKind(nexus->kind()) ||
IsDefineNamedOwnICKind(nexus->kind()) || IsDefineNamedOwnICKind(nexus->kind()) ||
IsDefineKeyedOwnPropertyInLiteralKind(nexus->kind()) || IsDefineKeyedOwnPropertyInLiteralKind(nexus->kind()) ||
......
...@@ -94,7 +94,7 @@ inline bool IsStoreGlobalICKind(FeedbackSlotKind kind) { ...@@ -94,7 +94,7 @@ inline bool IsStoreGlobalICKind(FeedbackSlotKind kind) {
kind == FeedbackSlotKind::kStoreGlobalStrict; kind == FeedbackSlotKind::kStoreGlobalStrict;
} }
inline bool IsStoreICKind(FeedbackSlotKind kind) { inline bool IsSetNamedICKind(FeedbackSlotKind kind) {
return kind == FeedbackSlotKind::kSetNamedSloppy || return kind == FeedbackSlotKind::kSetNamedSloppy ||
kind == FeedbackSlotKind::kSetNamedStrict; kind == FeedbackSlotKind::kSetNamedStrict;
} }
...@@ -140,7 +140,7 @@ inline TypeofMode GetTypeofModeFromSlotKind(FeedbackSlotKind kind) { ...@@ -140,7 +140,7 @@ inline TypeofMode GetTypeofModeFromSlotKind(FeedbackSlotKind kind) {
} }
inline LanguageMode GetLanguageModeFromSlotKind(FeedbackSlotKind kind) { inline LanguageMode GetLanguageModeFromSlotKind(FeedbackSlotKind kind) {
DCHECK(IsStoreICKind(kind) || IsDefineNamedOwnICKind(kind) || DCHECK(IsSetNamedICKind(kind) || IsDefineNamedOwnICKind(kind) ||
IsStoreGlobalICKind(kind) || IsKeyedStoreICKind(kind) || IsStoreGlobalICKind(kind) || IsKeyedStoreICKind(kind) ||
IsDefineKeyedOwnICKind(kind)); IsDefineKeyedOwnICKind(kind));
STATIC_ASSERT(FeedbackSlotKind::kStoreGlobalSloppy <= STATIC_ASSERT(FeedbackSlotKind::kStoreGlobalSloppy <=
...@@ -290,7 +290,7 @@ class FeedbackVector ...@@ -290,7 +290,7 @@ class FeedbackVector
DEFINE_SLOT_KIND_PREDICATE(IsLoadIC) DEFINE_SLOT_KIND_PREDICATE(IsLoadIC)
DEFINE_SLOT_KIND_PREDICATE(IsLoadGlobalIC) DEFINE_SLOT_KIND_PREDICATE(IsLoadGlobalIC)
DEFINE_SLOT_KIND_PREDICATE(IsKeyedLoadIC) DEFINE_SLOT_KIND_PREDICATE(IsKeyedLoadIC)
DEFINE_SLOT_KIND_PREDICATE(IsStoreIC) DEFINE_SLOT_KIND_PREDICATE(IsSetNamedIC)
DEFINE_SLOT_KIND_PREDICATE(IsDefineNamedOwnIC) DEFINE_SLOT_KIND_PREDICATE(IsDefineNamedOwnIC)
DEFINE_SLOT_KIND_PREDICATE(IsStoreGlobalIC) DEFINE_SLOT_KIND_PREDICATE(IsStoreGlobalIC)
DEFINE_SLOT_KIND_PREDICATE(IsKeyedStoreIC) DEFINE_SLOT_KIND_PREDICATE(IsKeyedStoreIC)
......
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