Commit d4452d2e authored by Mythri A's avatar Mythri A Committed by Commit Bot

[ic] Add fast path for StaInArrayLiteral with no feedback

We could use StorePropertyInLiteral builtin to handle StaInArrayLiteral
when there is no feedback vector.

Change-Id: I38cae322cc1901582e570f996c6ffd270501245f
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1862559Reviewed-by: 's avatarToon Verwaest <verwaest@chromium.org>
Reviewed-by: 's avatarIgor Sheludko <ishell@chromium.org>
Commit-Queue: Mythri Alle <mythria@chromium.org>
Cr-Commit-Position: refs/heads/master@{#64379}
parent 6f265b7c
......@@ -3397,7 +3397,7 @@ void AccessorAssembler::KeyedStoreIC(const StoreICParameters* p) {
}
void AccessorAssembler::StoreInArrayLiteralIC(const StoreICParameters* p) {
Label miss(this, Label::kDeferred);
Label miss(this, Label::kDeferred), no_feedback(this, Label::kDeferred);
{
TVARIABLE(MaybeObject, var_handler);
......@@ -3408,7 +3408,7 @@ void AccessorAssembler::StoreInArrayLiteralIC(const StoreICParameters* p) {
TNode<Map> array_map = LoadReceiverMap(p->receiver());
GotoIf(IsDeprecatedMap(array_map), &miss);
GotoIf(IsUndefined(p->vector()), &miss);
GotoIf(IsUndefined(p->vector()), &no_feedback);
TNode<MaybeObject> feedback =
TryMonomorphicCase(p->slot(), CAST(p->vector()), array_map, &if_handler,
......@@ -3485,6 +3485,13 @@ void AccessorAssembler::StoreInArrayLiteralIC(const StoreICParameters* p) {
}
}
BIND(&no_feedback);
{
Comment("StoreInArrayLiteralIC_NoFeedback");
TailCallBuiltin(Builtins::kSetPropertyInLiteral, p->context(),
p->receiver(), p->name(), p->value());
}
BIND(&miss);
{
Comment("StoreInArrayLiteralIC_miss");
......
......@@ -340,20 +340,23 @@ void KeyedStoreGenericAssembler::StoreElementWithCapacity(
{
TNode<IntPtrT> offset =
ElementOffsetFromIndex(index, PACKED_ELEMENTS, kHeaderSize);
// 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
// can skip the hole check (and always assume the hole).
{
Label hole_check_passed(this);
if (update_length == kDontChangeLength) {
TNode<Object> element =
CAST(Load(MachineType::AnyTagged(), elements, offset));
GotoIf(TaggedNotEqual(element, TheHoleConstant()), &hole_check_passed);
if (!IsStoreInLiteral()) {
// 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
// can skip the hole check (and always assume the hole).
{
Label hole_check_passed(this);
if (update_length == kDontChangeLength) {
TNode<Object> element =
CAST(Load(MachineType::AnyTagged(), elements, offset));
GotoIf(TaggedNotEqual(element, TheHoleConstant()),
&hole_check_passed);
}
BranchIfPrototypesHaveNonFastElements(receiver_map, slow,
&hole_check_passed);
BIND(&hole_check_passed);
}
BranchIfPrototypesHaveNonFastElements(receiver_map, slow,
&hole_check_passed);
BIND(&hole_check_passed);
}
// Check if the value we're storing matches the elements_kind. Smis
......@@ -443,22 +446,25 @@ void KeyedStoreGenericAssembler::StoreElementWithCapacity(
{
TNode<IntPtrT> offset =
ElementOffsetFromIndex(index, PACKED_DOUBLE_ELEMENTS, kHeaderSize);
// 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.
{
Label hole_check_passed(this);
// If we know that we're storing beyond the previous array length, we
// can skip the hole check (and always assume the hole).
if (update_length == kDontChangeLength) {
Label found_hole(this);
LoadDoubleWithHoleCheck(elements, offset, &found_hole,
MachineType::None());
Goto(&hole_check_passed);
BIND(&found_hole);
if (!IsStoreInLiteral()) {
// 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.
{
Label hole_check_passed(this);
// If we know that we're storing beyond the previous array length, we
// can skip the hole check (and always assume the hole).
if (update_length == kDontChangeLength) {
Label found_hole(this);
LoadDoubleWithHoleCheck(elements, offset, &found_hole,
MachineType::None());
Goto(&hole_check_passed);
BIND(&found_hole);
}
BranchIfPrototypesHaveNonFastElements(receiver_map, slow,
&hole_check_passed);
BIND(&hole_check_passed);
}
BranchIfPrototypesHaveNonFastElements(receiver_map, slow,
&hole_check_passed);
BIND(&hole_check_passed);
}
// Try to store the value as a double.
......@@ -541,13 +547,15 @@ void KeyedStoreGenericAssembler::EmitGenericElementStore(
}
BIND(&if_out_of_bounds);
{
if (!IsStoreInLiteral()) {
// Integer indexed out-of-bounds accesses to typed arrays are simply
// ignored, since we never look up integer indexed properties on the
// prototypes of typed arrays. For all other types, we may need to
// grow the backing store.
GotoIfNot(InstanceTypeEqual(instance_type, JS_TYPED_ARRAY_TYPE), &if_grow);
Return(value);
} else {
Goto(&if_grow);
}
BIND(&if_increment_length_by_one);
......
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