Commit 44086602 authored by Ross McIlroy's avatar Ross McIlroy Committed by Commit Bot

[CSA][Cleanup] TNodify EmitElementStore and CheckForCapacityGrow.

One remaining Node* remains in EmitElementStore which will need to wait for
templated versions of StoreElement.

BUG=v8:10021

Change-Id: I6422b8dbfd1989cfc7587c2b180e542fbdb56382
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2007271Reviewed-by: 's avatarSantiago Aboy Solanes <solanes@chromium.org>
Commit-Queue: Ross McIlroy <rmcilroy@chromium.org>
Cr-Commit-Position: refs/heads/master@{#65851}
parent c3e5352a
...@@ -77,7 +77,7 @@ TNode<Object> ArrayBuiltinsAssembler::TypedArrayMapProcessor( ...@@ -77,7 +77,7 @@ TNode<Object> ArrayBuiltinsAssembler::TypedArrayMapProcessor(
// TODO(v8:4153): Consider checking IsDetachedBuffer() and calling // TODO(v8:4153): Consider checking IsDetachedBuffer() and calling
// TypedArrayBuiltinsAssembler::StoreJSTypedArrayElementFromNumeric() here // TypedArrayBuiltinsAssembler::StoreJSTypedArrayElementFromNumeric() here
// instead to avoid converting k_number back to UintPtrT. // instead to avoid converting k_number back to UintPtrT.
EmitElementStore(a(), k_number, num_value, source_elements_kind_, EmitElementStore(CAST(a()), k_number, num_value, source_elements_kind_,
KeyedAccessStoreMode::STANDARD_STORE, &detached, context()); KeyedAccessStoreMode::STANDARD_STORE, &detached, context());
Goto(&done); Goto(&done);
......
...@@ -1653,13 +1653,13 @@ TNode<Smi> CodeStubAssembler::LoadFastJSArrayLength( ...@@ -1653,13 +1653,13 @@ TNode<Smi> CodeStubAssembler::LoadFastJSArrayLength(
LAST_ANY_NONEXTENSIBLE_ELEMENTS_KIND))); LAST_ANY_NONEXTENSIBLE_ELEMENTS_KIND)));
// JSArray length is always a positive Smi for fast arrays. // JSArray length is always a positive Smi for fast arrays.
CSA_SLOW_ASSERT(this, TaggedIsPositiveSmi(length)); CSA_SLOW_ASSERT(this, TaggedIsPositiveSmi(length));
return UncheckedCast<Smi>(length); return CAST(length);
} }
TNode<Smi> CodeStubAssembler::LoadFixedArrayBaseLength( TNode<Smi> CodeStubAssembler::LoadFixedArrayBaseLength(
SloppyTNode<FixedArrayBase> array) { SloppyTNode<FixedArrayBase> array) {
CSA_SLOW_ASSERT(this, IsNotWeakFixedArraySubclass(array)); CSA_SLOW_ASSERT(this, IsNotWeakFixedArraySubclass(array));
return CAST(LoadObjectField(array, FixedArrayBase::kLengthOffset)); return LoadObjectField<Smi>(array, FixedArrayBase::kLengthOffset);
} }
TNode<IntPtrT> CodeStubAssembler::LoadAndUntagFixedArrayBaseLength( TNode<IntPtrT> CodeStubAssembler::LoadAndUntagFixedArrayBaseLength(
...@@ -2908,7 +2908,6 @@ void CodeStubAssembler::StoreFixedArrayOrPropertyArrayElement( ...@@ -2908,7 +2908,6 @@ void CodeStubAssembler::StoreFixedArrayOrPropertyArrayElement(
void CodeStubAssembler::StoreFixedDoubleArrayElement( void CodeStubAssembler::StoreFixedDoubleArrayElement(
TNode<FixedDoubleArray> object, Node* index_node, TNode<Float64T> value, TNode<FixedDoubleArray> object, Node* index_node, TNode<Float64T> value,
ParameterMode parameter_mode, CheckBounds check_bounds) { ParameterMode parameter_mode, CheckBounds check_bounds) {
CSA_ASSERT(this, IsFixedDoubleArray(object));
CSA_SLOW_ASSERT(this, MatchesParameterMode(index_node, parameter_mode)); CSA_SLOW_ASSERT(this, MatchesParameterMode(index_node, parameter_mode));
if (NeedsBoundsCheck(check_bounds)) { if (NeedsBoundsCheck(check_bounds)) {
FixedArrayBoundsCheck(object, index_node, 0, parameter_mode); FixedArrayBoundsCheck(object, index_node, 0, parameter_mode);
...@@ -9753,11 +9752,10 @@ void CodeStubAssembler::BigIntToRawBytes(TNode<BigInt> bigint, ...@@ -9753,11 +9752,10 @@ void CodeStubAssembler::BigIntToRawBytes(TNode<BigInt> bigint,
BIND(&done); BIND(&done);
} }
void CodeStubAssembler::EmitElementStore(Node* object, Node* key, Node* value, void CodeStubAssembler::EmitElementStore(
ElementsKind elements_kind, TNode<JSObject> object, TNode<Object> key, TNode<Object> value,
KeyedAccessStoreMode store_mode, ElementsKind elements_kind, KeyedAccessStoreMode store_mode, Label* bailout,
Label* bailout, Node* context, TNode<Context> context, TVariable<Object>* maybe_converted_value) {
Variable* maybe_converted_value) {
CSA_ASSERT(this, Word32BinaryNot(IsJSProxy(object))); CSA_ASSERT(this, Word32BinaryNot(IsJSProxy(object)));
TNode<FixedArrayBase> elements = LoadElements(object); TNode<FixedArrayBase> elements = LoadElements(object);
...@@ -9773,13 +9771,17 @@ void CodeStubAssembler::EmitElementStore(Node* object, Node* key, Node* value, ...@@ -9773,13 +9771,17 @@ void CodeStubAssembler::EmitElementStore(Node* object, Node* key, Node* value,
ParameterMode parameter_mode = INTPTR_PARAMETERS; ParameterMode parameter_mode = INTPTR_PARAMETERS;
TNode<IntPtrT> intptr_key = TryToIntptr(key, bailout); TNode<IntPtrT> intptr_key = TryToIntptr(key, bailout);
// TODO(rmcilroy): TNodify the converted value once this funciton and
// StoreElement are templated based on the type elements_kind type.
Node* converted_value = value;
if (IsTypedArrayElementsKind(elements_kind)) { if (IsTypedArrayElementsKind(elements_kind)) {
Label done(this), update_value_and_bailout(this, Label::kDeferred); Label done(this), update_value_and_bailout(this, Label::kDeferred);
// IntegerIndexedElementSet converts value to a Number/BigInt prior to the // IntegerIndexedElementSet converts value to a Number/BigInt prior to the
// bounds check. // bounds check.
Node* converted_value = PrepareValueForWriteToTypedArray( converted_value =
CAST(value), elements_kind, CAST(context)); PrepareValueForWriteToTypedArray(value, elements_kind, context);
TNode<JSTypedArray> typed_array = CAST(object);
// There must be no allocations between the buffer load and // There must be no allocations between the buffer load and
// and the actual store to backing store, because GC may decide that // and the actual store to backing store, because GC may decide that
...@@ -9787,7 +9789,7 @@ void CodeStubAssembler::EmitElementStore(Node* object, Node* key, Node* value, ...@@ -9787,7 +9789,7 @@ void CodeStubAssembler::EmitElementStore(Node* object, Node* key, Node* value,
// TODO(ishell): introduce DisallowHeapAllocationCode scope here. // TODO(ishell): introduce DisallowHeapAllocationCode scope here.
// Check if buffer has been detached. // Check if buffer has been detached.
TNode<JSArrayBuffer> buffer = LoadJSArrayBufferViewBuffer(CAST(object)); TNode<JSArrayBuffer> buffer = LoadJSArrayBufferViewBuffer(typed_array);
if (maybe_converted_value) { if (maybe_converted_value) {
GotoIf(IsDetachedBuffer(buffer), &update_value_and_bailout); GotoIf(IsDetachedBuffer(buffer), &update_value_and_bailout);
} else { } else {
...@@ -9795,7 +9797,7 @@ void CodeStubAssembler::EmitElementStore(Node* object, Node* key, Node* value, ...@@ -9795,7 +9797,7 @@ void CodeStubAssembler::EmitElementStore(Node* object, Node* key, Node* value,
} }
// Bounds check. // Bounds check.
TNode<UintPtrT> length = LoadJSTypedArrayLength(CAST(object)); TNode<UintPtrT> length = LoadJSTypedArrayLength(typed_array);
if (store_mode == STORE_IGNORE_OUT_OF_BOUNDS) { if (store_mode == STORE_IGNORE_OUT_OF_BOUNDS) {
// Skip the store if we write beyond the length or // Skip the store if we write beyond the length or
...@@ -9806,7 +9808,7 @@ void CodeStubAssembler::EmitElementStore(Node* object, Node* key, Node* value, ...@@ -9806,7 +9808,7 @@ void CodeStubAssembler::EmitElementStore(Node* object, Node* key, Node* value,
GotoIfNot(UintPtrLessThan(intptr_key, length), &update_value_and_bailout); GotoIfNot(UintPtrLessThan(intptr_key, length), &update_value_and_bailout);
} }
TNode<RawPtrT> data_ptr = LoadJSTypedArrayDataPtr(CAST(object)); TNode<RawPtrT> data_ptr = LoadJSTypedArrayDataPtr(typed_array);
StoreElement(data_ptr, elements_kind, intptr_key, converted_value, StoreElement(data_ptr, elements_kind, intptr_key, converted_value,
parameter_mode); parameter_mode);
Goto(&done); Goto(&done);
...@@ -9826,26 +9828,26 @@ void CodeStubAssembler::EmitElementStore(Node* object, Node* key, Node* value, ...@@ -9826,26 +9828,26 @@ void CodeStubAssembler::EmitElementStore(Node* object, Node* key, Node* value,
case UINT16_ELEMENTS: case UINT16_ELEMENTS:
case INT16_ELEMENTS: case INT16_ELEMENTS:
case UINT8_CLAMPED_ELEMENTS: case UINT8_CLAMPED_ELEMENTS:
maybe_converted_value->Bind(SmiFromInt32(converted_value)); *maybe_converted_value = SmiFromInt32(converted_value);
break; break;
case UINT32_ELEMENTS: case UINT32_ELEMENTS:
maybe_converted_value->Bind(ChangeUint32ToTagged(converted_value)); *maybe_converted_value = ChangeUint32ToTagged(converted_value);
break; break;
case INT32_ELEMENTS: case INT32_ELEMENTS:
maybe_converted_value->Bind(ChangeInt32ToTagged(converted_value)); *maybe_converted_value = ChangeInt32ToTagged(converted_value);
break; break;
case FLOAT32_ELEMENTS: { case FLOAT32_ELEMENTS: {
Label dont_allocate_heap_number(this), end(this); Label dont_allocate_heap_number(this), end(this);
GotoIf(TaggedIsSmi(value), &dont_allocate_heap_number); GotoIf(TaggedIsSmi(value), &dont_allocate_heap_number);
GotoIf(IsHeapNumber(value), &dont_allocate_heap_number); GotoIf(IsHeapNumber(CAST(value)), &dont_allocate_heap_number);
{ {
maybe_converted_value->Bind(AllocateHeapNumberWithValue( *maybe_converted_value = AllocateHeapNumberWithValue(
ChangeFloat32ToFloat64(converted_value))); ChangeFloat32ToFloat64(converted_value));
Goto(&end); Goto(&end);
} }
BIND(&dont_allocate_heap_number); BIND(&dont_allocate_heap_number);
{ {
maybe_converted_value->Bind(value); *maybe_converted_value = value;
Goto(&end); Goto(&end);
} }
BIND(&end); BIND(&end);
...@@ -9854,15 +9856,15 @@ void CodeStubAssembler::EmitElementStore(Node* object, Node* key, Node* value, ...@@ -9854,15 +9856,15 @@ void CodeStubAssembler::EmitElementStore(Node* object, Node* key, Node* value,
case FLOAT64_ELEMENTS: { case FLOAT64_ELEMENTS: {
Label dont_allocate_heap_number(this), end(this); Label dont_allocate_heap_number(this), end(this);
GotoIf(TaggedIsSmi(value), &dont_allocate_heap_number); GotoIf(TaggedIsSmi(value), &dont_allocate_heap_number);
GotoIf(IsHeapNumber(value), &dont_allocate_heap_number); GotoIf(IsHeapNumber(CAST(value)), &dont_allocate_heap_number);
{ {
maybe_converted_value->Bind( *maybe_converted_value =
AllocateHeapNumberWithValue(converted_value)); AllocateHeapNumberWithValue(converted_value);
Goto(&end); Goto(&end);
} }
BIND(&dont_allocate_heap_number); BIND(&dont_allocate_heap_number);
{ {
maybe_converted_value->Bind(value); *maybe_converted_value = value;
Goto(&end); Goto(&end);
} }
BIND(&end); BIND(&end);
...@@ -9870,7 +9872,7 @@ void CodeStubAssembler::EmitElementStore(Node* object, Node* key, Node* value, ...@@ -9870,7 +9872,7 @@ void CodeStubAssembler::EmitElementStore(Node* object, Node* key, Node* value,
} }
case BIGINT64_ELEMENTS: case BIGINT64_ELEMENTS:
case BIGUINT64_ELEMENTS: case BIGUINT64_ELEMENTS:
maybe_converted_value->Bind(converted_value); *maybe_converted_value = CAST(converted_value);
break; break;
default: default:
UNREACHABLE(); UNREACHABLE();
...@@ -9885,33 +9887,31 @@ void CodeStubAssembler::EmitElementStore(Node* object, Node* key, Node* value, ...@@ -9885,33 +9887,31 @@ void CodeStubAssembler::EmitElementStore(Node* object, Node* key, Node* value,
IsSealedElementsKind(elements_kind) || IsSealedElementsKind(elements_kind) ||
IsNonextensibleElementsKind(elements_kind)); IsNonextensibleElementsKind(elements_kind));
TNode<Smi> smi_length = Select<Smi>(
IsJSArray(object),
[=]() {
// This is casting Number -> Smi which may not actually be safe.
return CAST(LoadJSArrayLength(CAST(object)));
},
[=]() { return LoadFixedArrayBaseLength(elements); });
Node* length = TaggedToParameter(smi_length, parameter_mode);
// In case value is stored into a fast smi array, assure that the value is // In case value is stored into a fast smi array, assure that the value is
// a smi before manipulating the backing store. Otherwise the backing store // a smi before manipulating the backing store. Otherwise the backing store
// may be left in an invalid state. // may be left in an invalid state.
if (IsSmiElementsKind(elements_kind)) { if (IsSmiElementsKind(elements_kind)) {
GotoIfNot(TaggedIsSmi(value), bailout); GotoIfNot(TaggedIsSmi(value), bailout);
} else if (IsDoubleElementsKind(elements_kind)) { } else if (IsDoubleElementsKind(elements_kind)) {
value = TryTaggedToFloat64(CAST(value), bailout); converted_value = TryTaggedToFloat64(value, bailout);
} }
TNode<Smi> smi_length = Select<Smi>(
IsJSArray(object),
[=]() {
// This is casting Number -> Smi which may not actually be safe.
return CAST(LoadJSArrayLength(CAST(object)));
},
[=]() { return LoadFixedArrayBaseLength(elements); });
TNode<UintPtrT> length = Unsigned(SmiUntag(smi_length));
if (IsGrowStoreMode(store_mode) && if (IsGrowStoreMode(store_mode) &&
!(IsSealedElementsKind(elements_kind) || !(IsSealedElementsKind(elements_kind) ||
IsNonextensibleElementsKind(elements_kind))) { IsNonextensibleElementsKind(elements_kind))) {
elements = elements = CAST(CheckForCapacityGrow(object, elements, elements_kind,
CAST(CheckForCapacityGrow(object, elements, elements_kind, length, length, intptr_key, bailout));
intptr_key, parameter_mode, bailout));
} else { } else {
GotoIfNot(UintPtrLessThan(intptr_key, length), bailout); GotoIfNot(UintPtrLessThan(Unsigned(intptr_key), length), bailout);
} }
// Cannot store to a hole in holey sealed elements so bailout. // Cannot store to a hole in holey sealed elements so bailout.
...@@ -9934,15 +9934,13 @@ void CodeStubAssembler::EmitElementStore(Node* object, Node* key, Node* value, ...@@ -9934,15 +9934,13 @@ void CodeStubAssembler::EmitElementStore(Node* object, Node* key, Node* value,
} }
CSA_ASSERT(this, Word32BinaryNot(IsFixedCOWArrayMap(LoadMap(elements)))); CSA_ASSERT(this, Word32BinaryNot(IsFixedCOWArrayMap(LoadMap(elements))));
StoreElement(elements, elements_kind, intptr_key, value, parameter_mode); StoreElement(elements, elements_kind, intptr_key, converted_value,
parameter_mode);
} }
Node* CodeStubAssembler::CheckForCapacityGrow(Node* object, Node* elements, Node* CodeStubAssembler::CheckForCapacityGrow(
ElementsKind kind, TNode<JSObject> object, TNode<FixedArrayBase> elements, ElementsKind kind,
SloppyTNode<UintPtrT> length, TNode<UintPtrT> length, TNode<IntPtrT> key, Label* bailout) {
TNode<IntPtrT> key,
ParameterMode mode,
Label* bailout) {
DCHECK(IsFastElementsKind(kind)); DCHECK(IsFastElementsKind(kind));
VARIABLE(checked_elements, MachineRepresentation::kTagged); VARIABLE(checked_elements, MachineRepresentation::kTagged);
Label grow_case(this), no_grow_case(this), done(this), Label grow_case(this), no_grow_case(this), done(this),
...@@ -9959,27 +9957,25 @@ Node* CodeStubAssembler::CheckForCapacityGrow(Node* object, Node* elements, ...@@ -9959,27 +9957,25 @@ Node* CodeStubAssembler::CheckForCapacityGrow(Node* object, Node* elements,
BIND(&grow_case); BIND(&grow_case);
{ {
Node* current_capacity = TNode<IntPtrT> current_capacity =
TaggedToParameter(LoadFixedArrayBaseLength(elements), mode); SmiUntag(LoadFixedArrayBaseLength(elements));
checked_elements.Bind(elements); checked_elements.Bind(elements);
Label fits_capacity(this); Label fits_capacity(this);
// If key is negative, we will notice in Runtime::kGrowArrayElements. // If key is negative, we will notice in Runtime::kGrowArrayElements.
GotoIf(UintPtrLessThan(key, current_capacity), &fits_capacity); GotoIf(UintPtrLessThan(key, current_capacity), &fits_capacity);
{ {
Node* new_elements = TryGrowElementsCapacity( Node* new_elements =
object, elements, kind, key, current_capacity, mode, &grow_bailout); TryGrowElementsCapacity(object, elements, kind, key, current_capacity,
INTPTR_PARAMETERS, &grow_bailout);
checked_elements.Bind(new_elements); checked_elements.Bind(new_elements);
Goto(&fits_capacity); Goto(&fits_capacity);
} }
BIND(&grow_bailout); BIND(&grow_bailout);
{ {
GotoIf(IntPtrOrSmiLessThan(key, IntPtrOrSmiConstant(0, mode), mode), GotoIf(IntPtrLessThan(key, IntPtrConstant(0)), bailout);
bailout); TNode<Number> tagged_key = ChangeUintPtrToTagged(Unsigned(key));
Node* tagged_key = mode == SMI_PARAMETERS
? static_cast<Node*>(key)
: ChangeUintPtrToTagged(Unsigned(key));
TNode<Object> maybe_elements = CallRuntime( TNode<Object> maybe_elements = CallRuntime(
Runtime::kGrowArrayElements, NoContextConstant(), object, tagged_key); Runtime::kGrowArrayElements, NoContextConstant(), object, tagged_key);
GotoIf(TaggedIsSmi(maybe_elements), bailout); GotoIf(TaggedIsSmi(maybe_elements), bailout);
...@@ -9991,9 +9987,9 @@ Node* CodeStubAssembler::CheckForCapacityGrow(Node* object, Node* elements, ...@@ -9991,9 +9987,9 @@ Node* CodeStubAssembler::CheckForCapacityGrow(Node* object, Node* elements,
BIND(&fits_capacity); BIND(&fits_capacity);
GotoIfNot(IsJSArray(object), &done); GotoIfNot(IsJSArray(object), &done);
TNode<WordT> new_length = IntPtrAdd(key, IntPtrOrSmiConstant(1, mode)); TNode<IntPtrT> new_length = IntPtrAdd(key, IntPtrConstant(1));
StoreObjectFieldNoWriteBarrier(CAST(object), JSArray::kLengthOffset, StoreObjectFieldNoWriteBarrier(object, JSArray::kLengthOffset,
ParameterToTagged(new_length, mode)); SmiTag(new_length));
Goto(&done); Goto(&done);
} }
......
...@@ -3336,15 +3336,16 @@ class V8_EXPORT_PRIVATE CodeStubAssembler ...@@ -3336,15 +3336,16 @@ class V8_EXPORT_PRIVATE CodeStubAssembler
void BigIntToRawBytes(TNode<BigInt> bigint, TVariable<UintPtrT>* var_low, void BigIntToRawBytes(TNode<BigInt> bigint, TVariable<UintPtrT>* var_low,
TVariable<UintPtrT>* var_high); TVariable<UintPtrT>* var_high);
void EmitElementStore(Node* object, Node* key, Node* value, void EmitElementStore(TNode<JSObject> object, TNode<Object> key,
ElementsKind elements_kind, TNode<Object> value, ElementsKind elements_kind,
KeyedAccessStoreMode store_mode, Label* bailout, KeyedAccessStoreMode store_mode, Label* bailout,
Node* context, TNode<Context> context,
Variable* maybe_converted_value = nullptr); TVariable<Object>* maybe_converted_value = nullptr);
Node* CheckForCapacityGrow(Node* object, Node* elements, ElementsKind kind, Node* CheckForCapacityGrow(TNode<JSObject> object,
SloppyTNode<UintPtrT> length, TNode<IntPtrT> key, TNode<FixedArrayBase> elements, ElementsKind kind,
ParameterMode mode, Label* bailout); TNode<UintPtrT> length, TNode<IntPtrT> key,
Label* bailout);
Node* CopyElementsOnWrite(Node* object, Node* elements, ElementsKind kind, Node* CopyElementsOnWrite(Node* object, Node* elements, ElementsKind kind,
Node* length, ParameterMode mode, Label* bailout); Node* length, ParameterMode mode, Label* bailout);
......
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