summaryrefslogtreecommitdiff
path: root/deps/v8/src/ic/accessor-assembler.cc
diff options
context:
space:
mode:
Diffstat (limited to 'deps/v8/src/ic/accessor-assembler.cc')
-rw-r--r--deps/v8/src/ic/accessor-assembler.cc205
1 files changed, 145 insertions, 60 deletions
diff --git a/deps/v8/src/ic/accessor-assembler.cc b/deps/v8/src/ic/accessor-assembler.cc
index 7aff16b9da..4542f4af42 100644
--- a/deps/v8/src/ic/accessor-assembler.cc
+++ b/deps/v8/src/ic/accessor-assembler.cc
@@ -225,8 +225,7 @@ void AccessorAssembler::HandleLoadICHandlerCase(
BIND(&call_handler);
{
- // TODO(v8:11880): call CodeT directly.
- TNode<Code> code_handler = FromCodeT(CAST(handler));
+ TNode<CodeT> code_handler = CAST(handler);
exit_point->ReturnCallStub(LoadWithVectorDescriptor{}, code_handler,
p->context(), p->lookup_start_object(),
p->name(), p->slot(), p->vector());
@@ -1187,6 +1186,37 @@ void AccessorAssembler::HandleStoreICNativeDataProperty(
holder, accessor_info, p->name(), p->value());
}
+void AccessorAssembler::HandleStoreICSmiHandlerJSSharedStructFieldCase(
+ TNode<Context> context, TNode<Word32T> handler_word, TNode<JSObject> holder,
+ TNode<Object> value) {
+ CSA_DCHECK(this,
+ Word32Equal(DecodeWord32<StoreHandler::KindBits>(handler_word),
+ STORE_KIND(kSharedStructField)));
+ CSA_DCHECK(
+ this,
+ Word32Equal(DecodeWord32<StoreHandler::RepresentationBits>(handler_word),
+ Int32Constant(Representation::kTagged)));
+
+ TVARIABLE(Object, shared_value, value);
+ SharedValueBarrier(context, &shared_value);
+
+ TNode<BoolT> is_inobject =
+ IsSetWord32<StoreHandler::IsInobjectBits>(handler_word);
+ TNode<HeapObject> property_storage = Select<HeapObject>(
+ is_inobject, [&]() { return holder; },
+ [&]() { return LoadFastProperties(holder); });
+
+ TNode<UintPtrT> index =
+ DecodeWordFromWord32<StoreHandler::FieldIndexBits>(handler_word);
+ TNode<IntPtrT> offset = Signed(TimesTaggedSize(index));
+
+ StoreJSSharedStructInObjectField(property_storage, offset,
+ shared_value.value());
+
+ // Return the original value.
+ Return(value);
+}
+
void AccessorAssembler::HandleStoreICHandlerCase(
const StoreICParameters* p, TNode<MaybeObject> handler, Label* miss,
ICMode ic_mode, ElementSupport support_elements) {
@@ -1233,7 +1263,7 @@ void AccessorAssembler::HandleStoreICHandlerCase(
properties, CAST(p->name()), &dictionary_found, &var_name_index, miss);
BIND(&dictionary_found);
{
- if (p->IsDefineOwn()) {
+ if (p->IsDefineKeyedOwn()) {
// Take slow path to throw if a private name already exists.
GotoIf(IsPrivateSymbol(CAST(p->name())), &if_slow);
}
@@ -1270,10 +1300,13 @@ void AccessorAssembler::HandleStoreICHandlerCase(
BIND(&if_fast_smi);
{
- Label data(this), accessor(this), native_data_property(this);
+ Label data(this), accessor(this), shared_struct_field(this),
+ native_data_property(this);
GotoIf(Word32Equal(handler_kind, STORE_KIND(kAccessor)), &accessor);
- Branch(Word32Equal(handler_kind, STORE_KIND(kNativeDataProperty)),
- &native_data_property, &data);
+ GotoIf(Word32Equal(handler_kind, STORE_KIND(kNativeDataProperty)),
+ &native_data_property);
+ Branch(Word32Equal(handler_kind, STORE_KIND(kSharedStructField)),
+ &shared_struct_field, &data);
BIND(&accessor);
HandleStoreAccessor(p, CAST(holder), handler_word);
@@ -1281,6 +1314,10 @@ void AccessorAssembler::HandleStoreICHandlerCase(
BIND(&native_data_property);
HandleStoreICNativeDataProperty(p, CAST(holder), handler_word);
+ BIND(&shared_struct_field);
+ HandleStoreICSmiHandlerJSSharedStructFieldCase(p->context(), handler_word,
+ CAST(holder), p->value());
+
BIND(&data);
// Handle non-transitioning field stores.
HandleStoreICSmiHandlerCase(handler_word, CAST(holder), p->value(), miss);
@@ -1307,10 +1344,10 @@ void AccessorAssembler::HandleStoreICHandlerCase(
p->slot(), p->vector(), p->receiver(), p->name());
} else {
Runtime::FunctionId id;
- if (p->IsStoreOwn()) {
- id = Runtime::kStoreOwnIC_Slow;
- } else if (p->IsDefineOwn()) {
- id = Runtime::kKeyedDefineOwnIC_Slow;
+ if (p->IsDefineNamedOwn()) {
+ id = Runtime::kDefineNamedOwnIC_Slow;
+ } else if (p->IsDefineKeyedOwn()) {
+ id = Runtime::kDefineKeyedOwnIC_Slow;
} else {
id = Runtime::kKeyedStoreIC_Slow;
}
@@ -1335,8 +1372,7 @@ void AccessorAssembler::HandleStoreICHandlerCase(
// |handler| is a heap object. Must be code, call it.
BIND(&call_handler);
{
- // TODO(v8:11880): call CodeT directly.
- TNode<Code> code_handler = FromCodeT(CAST(strong_handler));
+ TNode<CodeT> code_handler = CAST(strong_handler);
TailCallStub(StoreWithVectorDescriptor{}, code_handler, p->context(),
p->receiver(), p->name(), p->value(), p->slot(),
p->vector());
@@ -1359,7 +1395,7 @@ void AccessorAssembler::HandleStoreICHandlerCase(
ExitPoint direct_exit(this);
// StoreGlobalIC_PropertyCellCase doesn't properly handle private names
// but they are not expected here anyway.
- CSA_DCHECK(this, BoolConstant(!p->IsDefineOwn()));
+ CSA_DCHECK(this, BoolConstant(!p->IsDefineKeyedOwn()));
StoreGlobalIC_PropertyCellCase(property_cell, p->value(), &direct_exit,
miss);
}
@@ -1367,7 +1403,7 @@ void AccessorAssembler::HandleStoreICHandlerCase(
{
TNode<Map> map = CAST(map_or_property_cell);
HandleStoreICTransitionMapHandlerCase(p, map, miss,
- p->IsAnyStoreOwn()
+ p->IsAnyDefineOwn()
? kDontCheckPrototypeValidity
: kCheckPrototypeValidity);
Return(p->value());
@@ -1665,6 +1701,55 @@ void AccessorAssembler::OverwriteExistingFastDataProperty(
BIND(&done);
}
+void AccessorAssembler::StoreJSSharedStructField(
+ TNode<Context> context, TNode<HeapObject> shared_struct,
+ TNode<Map> shared_struct_map, TNode<DescriptorArray> descriptors,
+ TNode<IntPtrT> descriptor_name_index, TNode<Uint32T> details,
+ TNode<Object> maybe_local_value) {
+ CSA_DCHECK(this, IsJSSharedStruct(shared_struct));
+
+ Label done(this);
+
+ TNode<UintPtrT> field_index =
+ DecodeWordFromWord32<PropertyDetails::FieldIndexField>(details);
+ field_index = Unsigned(IntPtrAdd(
+ field_index,
+ Unsigned(LoadMapInobjectPropertiesStartInWords(shared_struct_map))));
+
+ TNode<IntPtrT> instance_size_in_words =
+ LoadMapInstanceSizeInWords(shared_struct_map);
+
+ TVARIABLE(Object, shared_value, maybe_local_value);
+ SharedValueBarrier(context, &shared_value);
+
+ Label inobject(this), backing_store(this);
+ Branch(UintPtrLessThan(field_index, instance_size_in_words), &inobject,
+ &backing_store);
+
+ BIND(&inobject);
+ {
+ TNode<IntPtrT> field_offset = Signed(TimesTaggedSize(field_index));
+ StoreJSSharedStructInObjectField(shared_struct, field_offset,
+ shared_value.value());
+ Goto(&done);
+ }
+
+ BIND(&backing_store);
+ {
+ TNode<IntPtrT> backing_store_index =
+ Signed(IntPtrSub(field_index, instance_size_in_words));
+
+ Label tagged_rep(this), double_rep(this);
+ TNode<PropertyArray> properties =
+ CAST(LoadFastProperties(CAST(shared_struct)));
+ StoreJSSharedStructPropertyArrayElement(properties, backing_store_index,
+ shared_value.value());
+ Goto(&done);
+ }
+
+ BIND(&done);
+}
+
void AccessorAssembler::CheckPrototypeValidityCell(
TNode<Object> maybe_validity_cell, Label* miss) {
Label done(this);
@@ -1712,10 +1797,9 @@ void AccessorAssembler::HandleStoreICProtoHandler(
&if_transitioning_element_store);
BIND(&if_element_store);
{
- // TODO(v8:11880): call CodeT directly.
- TailCallStub(StoreWithVectorDescriptor{}, FromCodeT(code_handler),
- p->context(), p->receiver(), p->name(), p->value(),
- p->slot(), p->vector());
+ TailCallStub(StoreWithVectorDescriptor{}, code_handler, p->context(),
+ p->receiver(), p->name(), p->value(), p->slot(),
+ p->vector());
}
BIND(&if_transitioning_element_store);
@@ -1727,10 +1811,9 @@ void AccessorAssembler::HandleStoreICProtoHandler(
GotoIf(IsDeprecatedMap(transition_map), miss);
- // TODO(v8:11880): call CodeT directly.
- TailCallStub(StoreTransitionDescriptor{}, FromCodeT(code_handler),
- p->context(), p->receiver(), p->name(), transition_map,
- p->value(), p->slot(), p->vector());
+ TailCallStub(StoreTransitionDescriptor{}, code_handler, p->context(),
+ p->receiver(), p->name(), transition_map, p->value(),
+ p->slot(), p->vector());
}
};
}
@@ -1795,10 +1878,10 @@ void AccessorAssembler::HandleStoreICProtoHandler(
if (ic_mode == ICMode::kGlobalIC) {
TailCallRuntime(Runtime::kStoreGlobalIC_Slow, p->context(), p->value(),
p->slot(), p->vector(), p->receiver(), p->name());
- } else if (p->IsAnyStoreOwn()) {
- // DefineOwnIC and StoreOwnIC shouldn't be using slow proto handlers,
- // otherwise proper slow function must be called.
- CSA_DCHECK(this, BoolConstant(!p->IsAnyStoreOwn()));
+ } else if (p->IsAnyDefineOwn()) {
+ // DefineKeyedOwnIC and DefineNamedOwnIC shouldn't be using slow proto
+ // handlers, otherwise proper slow function must be called.
+ CSA_DCHECK(this, BoolConstant(!p->IsAnyDefineOwn()));
Unreachable();
} else {
TailCallRuntime(Runtime::kKeyedStoreIC_Slow, p->context(), p->value(),
@@ -1881,7 +1964,7 @@ void AccessorAssembler::HandleStoreICProtoHandler(
ExitPoint direct_exit(this);
// StoreGlobalIC_PropertyCellCase doesn't properly handle private names
// but they are not expected here anyway.
- CSA_DCHECK(this, BoolConstant(!p->IsDefineOwn()));
+ CSA_DCHECK(this, BoolConstant(!p->IsDefineKeyedOwn()));
StoreGlobalIC_PropertyCellCase(CAST(holder), p->value(), &direct_exit,
miss);
}
@@ -2950,7 +3033,7 @@ void AccessorAssembler::LoadIC_BytecodeHandler(const LazyLoadICParameters* p,
// Call into the stub that implements the non-inlined parts of LoadIC.
Callable ic = Builtins::CallableFor(isolate(), Builtin::kLoadIC_Noninlined);
- TNode<Code> code_target = HeapConstant(ic.code());
+ TNode<CodeT> code_target = HeapConstant(ic.code());
exit_point->ReturnCallStub(ic.descriptor(), code_target, p->context(),
p->receiver_and_lookup_start_object(), p->name(),
p->slot(), p->vector());
@@ -3648,16 +3731,18 @@ void AccessorAssembler::StoreIC(const StoreICParameters* p) {
BIND(&no_feedback);
{
- auto builtin = p->IsStoreOwn() ? Builtin::kStoreOwnIC_NoFeedback
- : Builtin::kStoreIC_NoFeedback;
+ // TODO(v8:12548): refactor SetNamedIC as a subclass of StoreIC, which can
+ // be called here and below when !p->IsDefineNamedOwn().
+ auto builtin = p->IsDefineNamedOwn() ? Builtin::kDefineNamedOwnIC_NoFeedback
+ : Builtin::kStoreIC_NoFeedback;
TailCallBuiltin(builtin, p->context(), p->receiver(), p->name(), p->value(),
p->slot());
}
BIND(&miss);
{
- auto runtime =
- p->IsStoreOwn() ? Runtime::kStoreOwnIC_Miss : Runtime::kStoreIC_Miss;
+ auto runtime = p->IsDefineNamedOwn() ? Runtime::kDefineNamedOwnIC_Miss
+ : Runtime::kStoreIC_Miss;
TailCallRuntime(runtime, p->context(), p->value(), p->slot(), p->vector(),
p->receiver(), p->name());
}
@@ -3870,7 +3955,7 @@ void AccessorAssembler::KeyedStoreIC(const StoreICParameters* p) {
}
}
-void AccessorAssembler::KeyedDefineOwnIC(const StoreICParameters* p) {
+void AccessorAssembler::DefineKeyedOwnIC(const StoreICParameters* p) {
Label miss(this, Label::kDeferred);
{
TVARIABLE(MaybeObject, var_handler);
@@ -3892,7 +3977,7 @@ void AccessorAssembler::KeyedDefineOwnIC(const StoreICParameters* p) {
&if_handler, &var_handler, &try_polymorphic);
BIND(&if_handler);
{
- Comment("KeyedDefineOwnIC_if_handler");
+ Comment("DefineKeyedOwnIC_if_handler");
HandleStoreICHandlerCase(p, var_handler.value(), &miss,
ICMode::kNonGlobalIC, kSupportElements);
}
@@ -3901,7 +3986,7 @@ void AccessorAssembler::KeyedDefineOwnIC(const StoreICParameters* p) {
TNode<HeapObject> strong_feedback = GetHeapObjectIfStrong(feedback, &miss);
{
// CheckPolymorphic case.
- Comment("KeyedDefineOwnIC_try_polymorphic");
+ Comment("DefineKeyedOwnIC_try_polymorphic");
GotoIfNot(IsWeakFixedArrayMap(LoadMap(strong_feedback)),
&try_megamorphic);
HandlePolymorphicCase(receiver_map, CAST(strong_feedback), &if_handler,
@@ -3911,21 +3996,21 @@ void AccessorAssembler::KeyedDefineOwnIC(const StoreICParameters* p) {
BIND(&try_megamorphic);
{
// Check megamorphic case.
- Comment("KeyedDefineOwnIC_try_megamorphic");
+ Comment("DefineKeyedOwnIC_try_megamorphic");
Branch(TaggedEqual(strong_feedback, MegamorphicSymbolConstant()),
&no_feedback, &try_polymorphic_name);
}
BIND(&no_feedback);
{
- TailCallBuiltin(Builtin::kKeyedDefineOwnIC_Megamorphic, p->context(),
+ TailCallBuiltin(Builtin::kDefineKeyedOwnIC_Megamorphic, p->context(),
p->receiver(), p->name(), p->value(), p->slot());
}
BIND(&try_polymorphic_name);
{
// We might have a name in feedback, and a fixed array in the next slot.
- Comment("KeyedDefineOwnIC_try_polymorphic_name");
+ Comment("DefineKeyedOwnIC_try_polymorphic_name");
GotoIfNot(TaggedEqual(strong_feedback, p->name()), &miss);
// If the name comparison succeeded, we know we have a feedback vector
// with at least one map/handler pair.
@@ -3938,8 +4023,8 @@ void AccessorAssembler::KeyedDefineOwnIC(const StoreICParameters* p) {
}
BIND(&miss);
{
- Comment("KeyedDefineOwnIC_miss");
- TailCallRuntime(Runtime::kKeyedDefineOwnIC_Miss, p->context(), p->value(),
+ Comment("DefineKeyedOwnIC_miss");
+ TailCallRuntime(Runtime::kDefineKeyedOwnIC_Miss, p->context(), p->value(),
p->slot(), p->vector(), p->receiver(), p->name());
}
}
@@ -3977,8 +4062,7 @@ void AccessorAssembler::StoreInArrayLiteralIC(const StoreICParameters* p) {
{
// Call the handler.
- // TODO(v8:11880): call CodeT directly.
- TNode<Code> code_handler = FromCodeT(CAST(handler));
+ TNode<CodeT> code_handler = CAST(handler);
TailCallStub(StoreWithVectorDescriptor{}, code_handler, p->context(),
p->receiver(), p->name(), p->value(), p->slot(),
p->vector());
@@ -3991,9 +4075,8 @@ void AccessorAssembler::StoreInArrayLiteralIC(const StoreICParameters* p) {
TNode<Map> transition_map =
CAST(GetHeapObjectAssumeWeak(maybe_transition_map, &miss));
GotoIf(IsDeprecatedMap(transition_map), &miss);
- // TODO(v8:11880): call CodeT directly.
- TNode<Code> code = FromCodeT(
- CAST(LoadObjectField(handler, StoreHandler::kSmiHandlerOffset)));
+ TNode<CodeT> code =
+ CAST(LoadObjectField(handler, StoreHandler::kSmiHandlerOffset));
TailCallStub(StoreTransitionDescriptor{}, code, p->context(),
p->receiver(), p->name(), transition_map, p->value(),
p->slot(), p->vector());
@@ -4489,7 +4572,7 @@ void AccessorAssembler::GenerateStoreICBaseline() {
vector);
}
-void AccessorAssembler::GenerateStoreOwnIC() {
+void AccessorAssembler::GenerateDefineNamedOwnIC() {
using Descriptor = StoreWithVectorDescriptor;
auto receiver = Parameter<Object>(Descriptor::kReceiver);
@@ -4500,11 +4583,13 @@ void AccessorAssembler::GenerateStoreOwnIC() {
auto context = Parameter<Context>(Descriptor::kContext);
StoreICParameters p(context, receiver, name, value, slot, vector,
- StoreICMode::kStoreOwn);
+ StoreICMode::kDefineNamedOwn);
+ // StoreIC is a generic helper than handle both set and define own
+ // named stores.
StoreIC(&p);
}
-void AccessorAssembler::GenerateStoreOwnICTrampoline() {
+void AccessorAssembler::GenerateDefineNamedOwnICTrampoline() {
using Descriptor = StoreDescriptor;
auto receiver = Parameter<Object>(Descriptor::kReceiver);
@@ -4514,11 +4599,11 @@ void AccessorAssembler::GenerateStoreOwnICTrampoline() {
auto context = Parameter<Context>(Descriptor::kContext);
TNode<FeedbackVector> vector = LoadFeedbackVectorForStub();
- TailCallBuiltin(Builtin::kStoreOwnIC, context, receiver, name, value, slot,
- vector);
+ TailCallBuiltin(Builtin::kDefineNamedOwnIC, context, receiver, name, value,
+ slot, vector);
}
-void AccessorAssembler::GenerateStoreOwnICBaseline() {
+void AccessorAssembler::GenerateDefineNamedOwnICBaseline() {
using Descriptor = StoreWithVectorDescriptor;
auto receiver = Parameter<Object>(Descriptor::kReceiver);
@@ -4528,8 +4613,8 @@ void AccessorAssembler::GenerateStoreOwnICBaseline() {
TNode<FeedbackVector> vector = LoadFeedbackVectorFromBaseline();
TNode<Context> context = LoadContextFromBaseline();
- TailCallBuiltin(Builtin::kStoreOwnIC, context, receiver, name, value, slot,
- vector);
+ TailCallBuiltin(Builtin::kDefineNamedOwnIC, context, receiver, name, value,
+ slot, vector);
}
void AccessorAssembler::GenerateKeyedStoreIC() {
@@ -4575,7 +4660,7 @@ void AccessorAssembler::GenerateKeyedStoreICBaseline() {
vector);
}
-void AccessorAssembler::GenerateKeyedDefineOwnIC() {
+void AccessorAssembler::GenerateDefineKeyedOwnIC() {
using Descriptor = StoreWithVectorDescriptor;
auto receiver = Parameter<Object>(Descriptor::kReceiver);
@@ -4586,11 +4671,11 @@ void AccessorAssembler::GenerateKeyedDefineOwnIC() {
auto context = Parameter<Context>(Descriptor::kContext);
StoreICParameters p(context, receiver, name, value, slot, vector,
- StoreICMode::kDefineOwn);
- KeyedDefineOwnIC(&p);
+ StoreICMode::kDefineKeyedOwn);
+ DefineKeyedOwnIC(&p);
}
-void AccessorAssembler::GenerateKeyedDefineOwnICTrampoline() {
+void AccessorAssembler::GenerateDefineKeyedOwnICTrampoline() {
using Descriptor = StoreDescriptor;
auto receiver = Parameter<Object>(Descriptor::kReceiver);
@@ -4600,11 +4685,11 @@ void AccessorAssembler::GenerateKeyedDefineOwnICTrampoline() {
auto context = Parameter<Context>(Descriptor::kContext);
TNode<FeedbackVector> vector = LoadFeedbackVectorForStub();
- TailCallBuiltin(Builtin::kKeyedDefineOwnIC, context, receiver, name, value,
+ TailCallBuiltin(Builtin::kDefineKeyedOwnIC, context, receiver, name, value,
slot, vector);
}
-void AccessorAssembler::GenerateKeyedDefineOwnICBaseline() {
+void AccessorAssembler::GenerateDefineKeyedOwnICBaseline() {
using Descriptor = StoreBaselineDescriptor;
auto receiver = Parameter<Object>(Descriptor::kReceiver);
@@ -4614,7 +4699,7 @@ void AccessorAssembler::GenerateKeyedDefineOwnICBaseline() {
TNode<FeedbackVector> vector = LoadFeedbackVectorFromBaseline();
TNode<Context> context = LoadContextFromBaseline();
- TailCallBuiltin(Builtin::kKeyedDefineOwnIC, context, receiver, name, value,
+ TailCallBuiltin(Builtin::kDefineKeyedOwnIC, context, receiver, name, value,
slot, vector);
}