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