[CSA] TNodify ArrayPrototype(Pop|Push)

Bug: v8:6949, v8:9396
Change-Id: Ibb0979979e7092521cacf0931a98b4d5aa39a695
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1758306
Commit-Queue: Santiago Aboy Solanes <solanes@chromium.org>
Reviewed-by: Ross McIlroy <rmcilroy@chromium.org>
Cr-Commit-Position: refs/heads/master@{#63306}
This commit is contained in:
Santiago Aboy Solanes 2019-08-21 11:10:36 +01:00 committed by Commit Bot
parent 688b702eb6
commit 18cdc2f0e8

View File

@ -353,16 +353,24 @@ TF_BUILTIN(ArrayPrototypePop, CodeStubAssembler) {
Int32Constant(TERMINAL_FAST_ELEMENTS_KIND)), Int32Constant(TERMINAL_FAST_ELEMENTS_KIND)),
&fast_elements); &fast_elements);
Node* value = LoadFixedDoubleArrayElement(CAST(elements), new_length, {
&return_undefined); TNode<FixedDoubleArray> elements_known_double_array =
ReinterpretCast<FixedDoubleArray>(elements);
TNode<Float64T> value = LoadFixedDoubleArrayElement(
elements_known_double_array, new_length, &return_undefined);
StoreFixedDoubleArrayHole(CAST(elements), new_length); StoreFixedDoubleArrayHole(elements_known_double_array, new_length);
args.PopAndReturn(AllocateHeapNumberWithValue(value)); args.PopAndReturn(AllocateHeapNumberWithValue(value));
}
BIND(&fast_elements); BIND(&fast_elements);
{ {
Node* value = LoadFixedArrayElement(CAST(elements), new_length); TNode<FixedArray> elements_known_fixed_array =
StoreFixedArrayElement(CAST(elements), new_length, TheHoleConstant()); ReinterpretCast<FixedArray>(elements);
TNode<Object> value =
LoadFixedArrayElement(elements_known_fixed_array, new_length);
StoreFixedArrayElement(elements_known_fixed_array, new_length,
TheHoleConstant());
GotoIf(WordEqual(value, TheHoleConstant()), &return_undefined); GotoIf(WordEqual(value, TheHoleConstant()), &return_undefined);
args.PopAndReturn(value); args.PopAndReturn(value);
} }
@ -426,16 +434,16 @@ TF_BUILTIN(ArrayPrototypePush, CodeStubAssembler) {
// the most generic implementation for the rest of the array. // the most generic implementation for the rest of the array.
BIND(&smi_transition); BIND(&smi_transition);
{ {
Node* arg = args.AtIndex(arg_index.value()); TNode<Object> arg = args.AtIndex(arg_index.value());
GotoIf(TaggedIsSmi(arg), &default_label); GotoIf(TaggedIsSmi(arg), &default_label);
Node* length = LoadJSArrayLength(array_receiver); TNode<Number> length = LoadJSArrayLength(array_receiver);
// TODO(danno): Use the KeyedStoreGeneric stub here when possible, // TODO(danno): Use the KeyedStoreGeneric stub here when possible,
// calling into the runtime to do the elements transition is overkill. // calling into the runtime to do the elements transition is overkill.
SetPropertyStrict(context, array_receiver, CAST(length), CAST(arg)); SetPropertyStrict(context, array_receiver, length, arg);
Increment(&arg_index); Increment(&arg_index);
// The runtime SetProperty call could have converted the array to dictionary // The runtime SetProperty call could have converted the array to dictionary
// mode, which must be detected to abort the fast-path. // mode, which must be detected to abort the fast-path.
Node* kind = LoadElementsKind(array_receiver); TNode<Int32T> kind = LoadElementsKind(array_receiver);
GotoIf(Word32Equal(kind, Int32Constant(DICTIONARY_ELEMENTS)), GotoIf(Word32Equal(kind, Int32Constant(DICTIONARY_ELEMENTS)),
&default_label); &default_label);
@ -451,14 +459,14 @@ TF_BUILTIN(ArrayPrototypePush, CodeStubAssembler) {
BIND(&object_push); BIND(&object_push);
{ {
Node* new_length = BuildAppendJSArray(PACKED_ELEMENTS, array_receiver, TNode<Smi> new_length = BuildAppendJSArray(
&args, &arg_index, &default_label); PACKED_ELEMENTS, array_receiver, &args, &arg_index, &default_label);
args.PopAndReturn(new_length); args.PopAndReturn(new_length);
} }
BIND(&double_push); BIND(&double_push);
{ {
Node* new_length = TNode<Smi> new_length =
BuildAppendJSArray(PACKED_DOUBLE_ELEMENTS, array_receiver, &args, BuildAppendJSArray(PACKED_DOUBLE_ELEMENTS, array_receiver, &args,
&arg_index, &double_transition); &arg_index, &double_transition);
args.PopAndReturn(new_length); args.PopAndReturn(new_length);
@ -470,16 +478,16 @@ TF_BUILTIN(ArrayPrototypePush, CodeStubAssembler) {
// on the most generic implementation for the rest of the array. // on the most generic implementation for the rest of the array.
BIND(&double_transition); BIND(&double_transition);
{ {
Node* arg = args.AtIndex(arg_index.value()); TNode<Object> arg = args.AtIndex(arg_index.value());
GotoIfNumber(arg, &default_label); GotoIfNumber(arg, &default_label);
Node* length = LoadJSArrayLength(array_receiver); TNode<Number> length = LoadJSArrayLength(array_receiver);
// TODO(danno): Use the KeyedStoreGeneric stub here when possible, // TODO(danno): Use the KeyedStoreGeneric stub here when possible,
// calling into the runtime to do the elements transition is overkill. // calling into the runtime to do the elements transition is overkill.
SetPropertyStrict(context, array_receiver, CAST(length), CAST(arg)); SetPropertyStrict(context, array_receiver, length, arg);
Increment(&arg_index); Increment(&arg_index);
// The runtime SetProperty call could have converted the array to dictionary // The runtime SetProperty call could have converted the array to dictionary
// mode, which must be detected to abort the fast-path. // mode, which must be detected to abort the fast-path.
Node* kind = LoadElementsKind(array_receiver); TNode<Int32T> kind = LoadElementsKind(array_receiver);
GotoIf(Word32Equal(kind, Int32Constant(DICTIONARY_ELEMENTS)), GotoIf(Word32Equal(kind, Int32Constant(DICTIONARY_ELEMENTS)),
&default_label); &default_label);
Goto(&object_push); Goto(&object_push);
@ -491,8 +499,8 @@ TF_BUILTIN(ArrayPrototypePush, CodeStubAssembler) {
{ {
args.ForEach( args.ForEach(
[this, array_receiver, context](Node* arg) { [this, array_receiver, context](Node* arg) {
Node* length = LoadJSArrayLength(array_receiver); TNode<Number> length = LoadJSArrayLength(array_receiver);
SetPropertyStrict(context, array_receiver, CAST(length), CAST(arg)); SetPropertyStrict(context, array_receiver, length, CAST(arg));
}, },
arg_index.value()); arg_index.value());
args.PopAndReturn(LoadJSArrayLength(array_receiver)); args.PopAndReturn(LoadJSArrayLength(array_receiver));