Commit 2b4c6a41 authored by Mike Stanton's avatar Mike Stanton Committed by Commit Bot

[Builtins] Use MoveElements in CSA ArrayPrototypeShift

A new CSA function, MoveElements() does an efficient memmove
operation when the ElementsKind or new-space status allows it.

A few other TNode cleanups applied in the file, for example,
preferring the StoreFixedDoubleArrayHole() function.

Change-Id: Ia0848c066eebbbbe321f81afe0cfa7df7567cbb7
Reviewed-on: https://chromium-review.googlesource.com/c/1268235
Commit-Queue: Michael Stanton <mvstanton@chromium.org>
Reviewed-by: 's avatarTobias Tebbi <tebbi@chromium.org>
Cr-Commit-Position: refs/heads/master@{#56567}
parent 416756b2
...@@ -955,7 +955,7 @@ TF_BUILTIN(ArrayPrototypePop, CodeStubAssembler) { ...@@ -955,7 +955,7 @@ TF_BUILTIN(ArrayPrototypePop, CodeStubAssembler) {
{ {
TNode<JSArray> array_receiver = CAST(receiver); TNode<JSArray> array_receiver = CAST(receiver);
CSA_ASSERT(this, TaggedIsPositiveSmi(LoadJSArrayLength(array_receiver))); CSA_ASSERT(this, TaggedIsPositiveSmi(LoadJSArrayLength(array_receiver)));
Node* length = TNode<IntPtrT> length =
LoadAndUntagObjectField(array_receiver, JSArray::kLengthOffset); LoadAndUntagObjectField(array_receiver, JSArray::kLengthOffset);
Label return_undefined(this), fast_elements(this); Label return_undefined(this), fast_elements(this);
GotoIf(IntPtrEqual(length, IntPtrConstant(0)), &return_undefined); GotoIf(IntPtrEqual(length, IntPtrConstant(0)), &return_undefined);
...@@ -964,15 +964,15 @@ TF_BUILTIN(ArrayPrototypePop, CodeStubAssembler) { ...@@ -964,15 +964,15 @@ TF_BUILTIN(ArrayPrototypePop, CodeStubAssembler) {
EnsureArrayLengthWritable(LoadMap(array_receiver), &runtime); EnsureArrayLengthWritable(LoadMap(array_receiver), &runtime);
// 3) Check that the elements backing store isn't copy-on-write. // 3) Check that the elements backing store isn't copy-on-write.
Node* elements = LoadElements(array_receiver); TNode<FixedArrayBase> elements = LoadElements(array_receiver);
GotoIf(WordEqual(LoadMap(elements), LoadRoot(RootIndex::kFixedCOWArrayMap)), GotoIf(WordEqual(LoadMap(elements), LoadRoot(RootIndex::kFixedCOWArrayMap)),
&runtime); &runtime);
Node* new_length = IntPtrSub(length, IntPtrConstant(1)); TNode<IntPtrT> new_length = IntPtrSub(length, IntPtrConstant(1));
// 4) Check that we're not supposed to shrink the backing store, as // 4) Check that we're not supposed to shrink the backing store, as
// implemented in elements.cc:ElementsAccessorBase::SetLengthImpl. // implemented in elements.cc:ElementsAccessorBase::SetLengthImpl.
Node* capacity = SmiUntag(LoadFixedArrayBaseLength(elements)); TNode<IntPtrT> capacity = SmiUntag(LoadFixedArrayBaseLength(elements));
GotoIf(IntPtrLessThan( GotoIf(IntPtrLessThan(
IntPtrAdd(IntPtrAdd(new_length, new_length), IntPtrAdd(IntPtrAdd(new_length, new_length),
IntPtrConstant(JSObject::kMinAddedElementsCapacity)), IntPtrConstant(JSObject::kMinAddedElementsCapacity)),
...@@ -987,26 +987,10 @@ TF_BUILTIN(ArrayPrototypePop, CodeStubAssembler) { ...@@ -987,26 +987,10 @@ TF_BUILTIN(ArrayPrototypePop, CodeStubAssembler) {
Int32Constant(TERMINAL_FAST_ELEMENTS_KIND)), Int32Constant(TERMINAL_FAST_ELEMENTS_KIND)),
&fast_elements); &fast_elements);
Node* value = LoadFixedDoubleArrayElement( Node* value = LoadFixedDoubleArrayElement(CAST(elements), new_length,
elements, new_length, MachineType::Float64(), 0, INTPTR_PARAMETERS, &return_undefined);
&return_undefined);
StoreFixedDoubleArrayHole(CAST(elements), new_length);
int32_t header_size = FixedDoubleArray::kHeaderSize - kHeapObjectTag;
Node* offset = ElementOffsetFromIndex(new_length, HOLEY_DOUBLE_ELEMENTS,
INTPTR_PARAMETERS, header_size);
if (Is64()) {
Node* double_hole = Int64Constant(kHoleNanInt64);
StoreNoWriteBarrier(MachineRepresentation::kWord64, elements, offset,
double_hole);
} else {
STATIC_ASSERT(kHoleNanLower32 == kHoleNanUpper32);
Node* double_hole = Int32Constant(kHoleNanLower32);
StoreNoWriteBarrier(MachineRepresentation::kWord32, elements, offset,
double_hole);
StoreNoWriteBarrier(MachineRepresentation::kWord32, elements,
IntPtrAdd(offset, IntPtrConstant(kPointerSize)),
double_hole);
}
args.PopAndReturn(AllocateHeapNumberWithValue(value)); args.PopAndReturn(AllocateHeapNumberWithValue(value));
BIND(&fast_elements); BIND(&fast_elements);
...@@ -1532,18 +1516,18 @@ TF_BUILTIN(ArrayPrototypeShift, CodeStubAssembler) { ...@@ -1532,18 +1516,18 @@ TF_BUILTIN(ArrayPrototypeShift, CodeStubAssembler) {
// read-only length. // read-only length.
EnsureArrayLengthWritable(LoadMap(array_receiver), &runtime); EnsureArrayLengthWritable(LoadMap(array_receiver), &runtime);
Node* length = TNode<IntPtrT> length =
LoadAndUntagObjectField(array_receiver, JSArray::kLengthOffset); LoadAndUntagObjectField(array_receiver, JSArray::kLengthOffset);
Label return_undefined(this), fast_elements_tagged(this), Label return_undefined(this), fast_elements_tagged(this),
fast_elements_smi(this); fast_elements_smi(this);
GotoIf(IntPtrEqual(length, IntPtrConstant(0)), &return_undefined); GotoIf(IntPtrEqual(length, IntPtrConstant(0)), &return_undefined);
// 3) Check that the elements backing store isn't copy-on-write. // 3) Check that the elements backing store isn't copy-on-write.
Node* elements = LoadElements(array_receiver); TNode<FixedArrayBase> elements = LoadElements(array_receiver);
GotoIf(WordEqual(LoadMap(elements), LoadRoot(RootIndex::kFixedCOWArrayMap)), GotoIf(WordEqual(LoadMap(elements), LoadRoot(RootIndex::kFixedCOWArrayMap)),
&runtime); &runtime);
Node* new_length = IntPtrSub(length, IntPtrConstant(1)); TNode<IntPtrT> new_length = IntPtrSub(length, IntPtrConstant(1));
// 4) Check that we're not supposed to right-trim the backing store, as // 4) Check that we're not supposed to right-trim the backing store, as
// implemented in elements.cc:ElementsAccessorBase::SetLengthImpl. // implemented in elements.cc:ElementsAccessorBase::SetLengthImpl.
...@@ -1563,6 +1547,8 @@ TF_BUILTIN(ArrayPrototypeShift, CodeStubAssembler) { ...@@ -1563,6 +1547,8 @@ TF_BUILTIN(ArrayPrototypeShift, CodeStubAssembler) {
StoreObjectFieldNoWriteBarrier(array_receiver, JSArray::kLengthOffset, StoreObjectFieldNoWriteBarrier(array_receiver, JSArray::kLengthOffset,
SmiTag(new_length)); SmiTag(new_length));
TNode<IntPtrT> element_zero = IntPtrConstant(0);
TNode<IntPtrT> element_one = IntPtrConstant(1);
TNode<Int32T> elements_kind = LoadElementsKind(array_receiver); TNode<Int32T> elements_kind = LoadElementsKind(array_receiver);
GotoIf( GotoIf(
Int32LessThanOrEqual(elements_kind, Int32Constant(HOLEY_SMI_ELEMENTS)), Int32LessThanOrEqual(elements_kind, Int32Constant(HOLEY_SMI_ELEMENTS)),
...@@ -1580,37 +1566,13 @@ TF_BUILTIN(ArrayPrototypeShift, CodeStubAssembler) { ...@@ -1580,37 +1566,13 @@ TF_BUILTIN(ArrayPrototypeShift, CodeStubAssembler) {
Label move_elements(this); Label move_elements(this);
result.Bind(AllocateHeapNumberWithValue(LoadFixedDoubleArrayElement( result.Bind(AllocateHeapNumberWithValue(LoadFixedDoubleArrayElement(
elements, IntPtrConstant(0), MachineType::Float64(), 0, CAST(elements), element_zero, &move_elements)));
INTPTR_PARAMETERS, &move_elements)));
Goto(&move_elements); Goto(&move_elements);
BIND(&move_elements); BIND(&move_elements);
int32_t header_size = FixedDoubleArray::kHeaderSize - kHeapObjectTag; MoveElements(HOLEY_DOUBLE_ELEMENTS, elements, element_zero, element_one,
Node* memmove = new_length);
ExternalConstant(ExternalReference::libc_memmove_function()); StoreFixedDoubleArrayHole(CAST(elements), new_length);
Node* start = IntPtrAdd(
BitcastTaggedToWord(elements),
ElementOffsetFromIndex(IntPtrConstant(0), HOLEY_DOUBLE_ELEMENTS,
INTPTR_PARAMETERS, header_size));
CallCFunction3(MachineType::AnyTagged(), MachineType::Pointer(),
MachineType::Pointer(), MachineType::UintPtr(), memmove,
start, IntPtrAdd(start, IntPtrConstant(kDoubleSize)),
IntPtrMul(new_length, IntPtrConstant(kDoubleSize)));
Node* offset = ElementOffsetFromIndex(new_length, HOLEY_DOUBLE_ELEMENTS,
INTPTR_PARAMETERS, header_size);
if (Is64()) {
Node* double_hole = Int64Constant(kHoleNanInt64);
StoreNoWriteBarrier(MachineRepresentation::kWord64, elements, offset,
double_hole);
} else {
STATIC_ASSERT(kHoleNanLower32 == kHoleNanUpper32);
Node* double_hole = Int32Constant(kHoleNanLower32);
StoreNoWriteBarrier(MachineRepresentation::kWord32, elements, offset,
double_hole);
StoreNoWriteBarrier(MachineRepresentation::kWord32, elements,
IntPtrAdd(offset, IntPtrConstant(kPointerSize)),
double_hole);
}
args.PopAndReturn(result.value()); args.PopAndReturn(result.value());
} }
...@@ -1618,15 +1580,8 @@ TF_BUILTIN(ArrayPrototypeShift, CodeStubAssembler) { ...@@ -1618,15 +1580,8 @@ TF_BUILTIN(ArrayPrototypeShift, CodeStubAssembler) {
{ {
TNode<FixedArray> elements_fixed_array = CAST(elements); TNode<FixedArray> elements_fixed_array = CAST(elements);
Node* value = LoadFixedArrayElement(elements_fixed_array, 0); Node* value = LoadFixedArrayElement(elements_fixed_array, 0);
BuildFastLoop( MoveElements(HOLEY_ELEMENTS, elements, element_zero, element_one,
IntPtrConstant(0), new_length, new_length);
[&](Node* index) {
StoreFixedArrayElement(
elements_fixed_array, index,
LoadFixedArrayElement(elements_fixed_array,
IntPtrAdd(index, IntPtrConstant(1))));
},
1, ParameterMode::INTPTR_PARAMETERS, IndexAdvanceMode::kPost);
StoreFixedArrayElement(elements_fixed_array, new_length, StoreFixedArrayElement(elements_fixed_array, new_length,
TheHoleConstant()); TheHoleConstant());
GotoIf(WordEqual(value, TheHoleConstant()), &return_undefined); GotoIf(WordEqual(value, TheHoleConstant()), &return_undefined);
...@@ -1637,16 +1592,8 @@ TF_BUILTIN(ArrayPrototypeShift, CodeStubAssembler) { ...@@ -1637,16 +1592,8 @@ TF_BUILTIN(ArrayPrototypeShift, CodeStubAssembler) {
{ {
TNode<FixedArray> elements_fixed_array = CAST(elements); TNode<FixedArray> elements_fixed_array = CAST(elements);
Node* value = LoadFixedArrayElement(elements_fixed_array, 0); Node* value = LoadFixedArrayElement(elements_fixed_array, 0);
BuildFastLoop( MoveElements(HOLEY_SMI_ELEMENTS, elements, element_zero, element_one,
IntPtrConstant(0), new_length, new_length);
[&](Node* index) {
StoreFixedArrayElement(
elements_fixed_array, index,
LoadFixedArrayElement(elements_fixed_array,
IntPtrAdd(index, IntPtrConstant(1))),
SKIP_WRITE_BARRIER);
},
1, ParameterMode::INTPTR_PARAMETERS, IndexAdvanceMode::kPost);
StoreFixedArrayElement(elements_fixed_array, new_length, StoreFixedArrayElement(elements_fixed_array, new_length,
TheHoleConstant()); TheHoleConstant());
GotoIf(WordEqual(value, TheHoleConstant()), &return_undefined); GotoIf(WordEqual(value, TheHoleConstant()), &return_undefined);
......
...@@ -1074,9 +1074,17 @@ class V8_EXPORT_PRIVATE CodeStubAssembler : public compiler::CodeAssembler { ...@@ -1074,9 +1074,17 @@ class V8_EXPORT_PRIVATE CodeStubAssembler : public compiler::CodeAssembler {
Label* if_hole = nullptr); Label* if_hole = nullptr);
Node* LoadFixedDoubleArrayElement(TNode<FixedDoubleArray> object, Node* LoadFixedDoubleArrayElement(TNode<FixedDoubleArray> object,
TNode<Smi> index) { TNode<Smi> index,
Label* if_hole = nullptr) {
return LoadFixedDoubleArrayElement(object, index, MachineType::Float64(), 0,
SMI_PARAMETERS, if_hole);
}
Node* LoadFixedDoubleArrayElement(TNode<FixedDoubleArray> object,
TNode<IntPtrT> index,
Label* if_hole = nullptr) {
return LoadFixedDoubleArrayElement(object, index, MachineType::Float64(), 0, return LoadFixedDoubleArrayElement(object, index, MachineType::Float64(), 0,
SMI_PARAMETERS); INTPTR_PARAMETERS, if_hole);
} }
// Load an array element from a FixedArray, FixedDoubleArray or a // Load an array element from a FixedArray, FixedDoubleArray or a
......
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