Commit 9c5a4abc authored by Ulan Degenbaev's avatar Ulan Degenbaev Committed by Commit Bot

[csa] Make LoadArrayElement generic.

Previosly, LoadArrayElement assumed that the array is a FixedArray.
The PropertyArray and WeakFixedArray pretended to be a FixedArray and
had static asserts about length offsets.

This patch make LoadArrayElement generic and uses a new LoadArrayLength
function to fetch the length of the array without hard-coding the length
offset.

Bug: v8:8486
Change-Id: Ib27132bf3fcecc135ad632c4227c57ca0a05036f
Reviewed-on: https://chromium-review.googlesource.com/c/1346498
Commit-Queue: Ulan Degenbaev <ulan@chromium.org>
Reviewed-by: 's avatarCamillo Bruni <cbruni@chromium.org>
Cr-Commit-Position: refs/heads/master@{#57723}
parent b2a7292c
......@@ -1936,8 +1936,36 @@ TNode<MaybeObject> CodeStubAssembler::MakeWeak(TNode<HeapObject> value) {
WordOr(BitcastTaggedToWord(value), IntPtrConstant(kWeakHeapObjectTag))));
}
template <>
TNode<IntPtrT> CodeStubAssembler::LoadArrayLength(TNode<FixedArray> array) {
return LoadAndUntagFixedArrayBaseLength(array);
}
template <>
TNode<IntPtrT> CodeStubAssembler::LoadArrayLength(TNode<WeakFixedArray> array) {
return LoadAndUntagWeakFixedArrayLength(array);
}
template <>
TNode<IntPtrT> CodeStubAssembler::LoadArrayLength(TNode<PropertyArray> array) {
return LoadPropertyArrayLength(array);
}
template <>
TNode<IntPtrT> CodeStubAssembler::LoadArrayLength(
TNode<DescriptorArray> array) {
return LoadAndUntagWeakFixedArrayLength(array);
}
template <>
TNode<IntPtrT> CodeStubAssembler::LoadArrayLength(
TNode<TransitionArray> array) {
return LoadAndUntagWeakFixedArrayLength(array);
}
template <typename Array>
TNode<MaybeObject> CodeStubAssembler::LoadArrayElement(
SloppyTNode<HeapObject> array, int array_header_size, Node* index_node,
TNode<Array> array, int array_header_size, Node* index_node,
int additional_offset, ParameterMode parameter_mode,
LoadSensitivity needs_poisoning) {
CSA_ASSERT(this, IntPtrGreaterThanOrEqual(
......@@ -1947,32 +1975,24 @@ TNode<MaybeObject> CodeStubAssembler::LoadArrayElement(
int32_t header_size = array_header_size + additional_offset - kHeapObjectTag;
TNode<IntPtrT> offset = ElementOffsetFromIndex(index_node, HOLEY_ELEMENTS,
parameter_mode, header_size);
STATIC_ASSERT(FixedArrayBase::kLengthOffset == WeakFixedArray::kLengthOffset);
STATIC_ASSERT(FixedArrayBase::kLengthOffset ==
PropertyArray::kLengthAndHashOffset);
// Check that index_node + additional_offset <= object.length.
// TODO(cbruni): Use proper LoadXXLength helpers
CSA_ASSERT(
this,
IsOffsetInBounds(
offset,
Select<IntPtrT>(
IsPropertyArray(array),
[=] {
TNode<IntPtrT> length_and_hash = LoadAndUntagObjectField(
array, PropertyArray::kLengthAndHashOffset);
return TNode<IntPtrT>::UncheckedCast(
DecodeWord<PropertyArray::LengthField>(length_and_hash));
},
[=] {
return LoadAndUntagObjectField(array,
FixedArrayBase::kLengthOffset);
}),
FixedArray::kHeaderSize));
CSA_ASSERT(this, IsOffsetInBounds(offset, LoadArrayLength(array),
array_header_size));
return UncheckedCast<MaybeObject>(
Load(MachineType::AnyTagged(), array, offset, needs_poisoning));
}
template TNode<MaybeObject>
CodeStubAssembler::LoadArrayElement<TransitionArray>(TNode<TransitionArray>,
int, Node*, int,
ParameterMode,
LoadSensitivity);
template TNode<MaybeObject>
CodeStubAssembler::LoadArrayElement<DescriptorArray>(TNode<DescriptorArray>,
int, Node*, int,
ParameterMode,
LoadSensitivity);
void CodeStubAssembler::FixedArrayBoundsCheck(TNode<FixedArrayBase> array,
Node* index,
int additional_offset,
......@@ -2016,12 +2036,10 @@ TNode<Object> CodeStubAssembler::LoadFixedArrayElement(
}
TNode<Object> CodeStubAssembler::LoadPropertyArrayElement(
SloppyTNode<PropertyArray> object, SloppyTNode<IntPtrT> index) {
TNode<PropertyArray> object, SloppyTNode<IntPtrT> index) {
int additional_offset = 0;
ParameterMode parameter_mode = INTPTR_PARAMETERS;
LoadSensitivity needs_poisoning = LoadSensitivity::kSafe;
STATIC_ASSERT(PropertyArray::kHeaderSize == FixedArray::kHeaderSize);
return CAST(LoadArrayElement(object, PropertyArray::kHeaderSize, index,
additional_offset, parameter_mode,
needs_poisoning));
......@@ -2378,8 +2396,9 @@ TNode<MaybeObject> CodeStubAssembler::LoadFeedbackVectorSlot(
Load(MachineType::AnyTagged(), object, offset));
}
template <typename Array>
TNode<Int32T> CodeStubAssembler::LoadAndUntagToWord32ArrayElement(
SloppyTNode<HeapObject> object, int array_header_size, Node* index_node,
TNode<Array> object, int array_header_size, Node* index_node,
int additional_offset, ParameterMode parameter_mode) {
CSA_SLOW_ASSERT(this, MatchesParameterMode(index_node, parameter_mode));
DCHECK_EQ(additional_offset % kPointerSize, 0);
......@@ -2391,14 +2410,8 @@ TNode<Int32T> CodeStubAssembler::LoadAndUntagToWord32ArrayElement(
endian_correction;
Node* offset = ElementOffsetFromIndex(index_node, HOLEY_ELEMENTS,
parameter_mode, header_size);
STATIC_ASSERT(FixedArrayBase::kLengthOffset == WeakFixedArray::kLengthOffset);
// Check that index_node + additional_offset <= object.length.
// TODO(cbruni): Use proper LoadXXLength helpers
CSA_ASSERT(this,
IsOffsetInBounds(
offset,
LoadAndUntagObjectField(object, FixedArrayBase::kLengthOffset),
FixedArray::kHeaderSize + endian_correction));
CSA_ASSERT(this, IsOffsetInBounds(offset, LoadArrayLength(object),
array_header_size + endian_correction));
if (SmiValuesAre32Bits()) {
return UncheckedCast<Int32T>(Load(MachineType::Int32(), object, offset));
} else {
......@@ -2407,7 +2420,7 @@ TNode<Int32T> CodeStubAssembler::LoadAndUntagToWord32ArrayElement(
}
TNode<Int32T> CodeStubAssembler::LoadAndUntagToWord32FixedArrayElement(
SloppyTNode<HeapObject> object, Node* index_node, int additional_offset,
TNode<FixedArray> object, Node* index_node, int additional_offset,
ParameterMode parameter_mode) {
CSA_SLOW_ASSERT(this, IsFixedArraySubclass(object));
return LoadAndUntagToWord32ArrayElement(object, FixedArray::kHeaderSize,
......@@ -9159,9 +9172,9 @@ void CodeStubAssembler::LoadPropertyFromFastObject(
BIND(&if_backing_store);
{
Comment("if_backing_store");
Node* properties = LoadFastProperties(object);
TNode<HeapObject> properties = LoadFastProperties(object);
field_index = IntPtrSub(field_index, instance_size_in_words);
Node* value = LoadPropertyArrayElement(properties, field_index);
Node* value = LoadPropertyArrayElement(CAST(properties), field_index);
Label if_double(this), if_tagged(this);
Branch(Word32NotEqual(representation,
......
......@@ -1014,14 +1014,20 @@ class V8_EXPORT_PRIVATE CodeStubAssembler
int additional_offset = 0,
ParameterMode parameter_mode = INTPTR_PARAMETERS);
// Load an array element from a FixedArray / WeakFixedArray / PropertyArray.
// Array is any array-like type that has a fixed header followed by
// tagged elements.
template <typename Array>
TNode<IntPtrT> LoadArrayLength(TNode<Array> array);
// Array is any array-like type that has a fixed header followed by
// tagged elements.
template <typename Array>
TNode<MaybeObject> LoadArrayElement(
SloppyTNode<HeapObject> object, int array_header_size, Node* index,
TNode<Array> array, int array_header_size, Node* index,
int additional_offset = 0,
ParameterMode parameter_mode = INTPTR_PARAMETERS,
LoadSensitivity needs_poisoning = LoadSensitivity::kSafe);
// Load an array element from a FixedArray.
TNode<Object> LoadFixedArrayElement(
TNode<FixedArray> object, Node* index, int additional_offset = 0,
ParameterMode parameter_mode = INTPTR_PARAMETERS,
......@@ -1053,24 +1059,26 @@ class V8_EXPORT_PRIVATE CodeStubAssembler
return LoadFixedArrayElement(object, index, 0, SMI_PARAMETERS);
}
TNode<Object> LoadPropertyArrayElement(SloppyTNode<PropertyArray> object,
TNode<Object> LoadPropertyArrayElement(TNode<PropertyArray> object,
SloppyTNode<IntPtrT> index);
TNode<IntPtrT> LoadPropertyArrayLength(TNode<PropertyArray> object);
// Load an array element from a FixedArray / WeakFixedArray, untag it and
// return it as Word32.
// Load an element from an array and untag it and return it as Word32.
// Array is any array-like type that has a fixed header followed by
// tagged elements.
template <typename Array>
TNode<Int32T> LoadAndUntagToWord32ArrayElement(
SloppyTNode<HeapObject> object, int array_header_size, Node* index,
TNode<Array> array, int array_header_size, Node* index,
int additional_offset = 0,
ParameterMode parameter_mode = INTPTR_PARAMETERS);
// Load an array element from a FixedArray, untag it and return it as Word32.
TNode<Int32T> LoadAndUntagToWord32FixedArrayElement(
SloppyTNode<HeapObject> object, Node* index, int additional_offset = 0,
TNode<FixedArray> object, Node* index, int additional_offset = 0,
ParameterMode parameter_mode = INTPTR_PARAMETERS);
TNode<Int32T> LoadAndUntagToWord32FixedArrayElement(
SloppyTNode<HeapObject> object, int index, int additional_offset = 0) {
TNode<FixedArray> object, int index, int additional_offset = 0) {
return LoadAndUntagToWord32FixedArrayElement(
object, IntPtrConstant(index), additional_offset, INTPTR_PARAMETERS);
}
......
......@@ -130,7 +130,7 @@ Handle<Code> BuildSetupFunction(Isolate* isolate,
__ Int32Constant(0));
for (int lane = 0; lane < 4; lane++) {
TNode<Int32T> lane_value = __ LoadAndUntagToWord32FixedArrayElement(
element, __ IntPtrConstant(lane));
__ CAST(element), __ IntPtrConstant(lane));
vector = tester.raw_assembler_for_testing()->AddNode(
tester.raw_assembler_for_testing()->machine()->I32x4ReplaceLane(
lane),
......
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