Commit ab557544 authored by Igor Sheludko's avatar Igor Sheludko Committed by Commit Bot

[builtins] Use uintptr for iteration in TypedArray builtins, pt.3

The CL fixes the following builtins:
  %TypedArray%.prototype.map

Bug: v8:4153
Change-Id: I1db5716d5044788da8a792e4449d501ac7507823
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1876047
Commit-Queue: Igor Sheludko <ishell@chromium.org>
Reviewed-by: 's avatarJakob Kummerow <jkummerow@chromium.org>
Cr-Commit-Position: refs/heads/master@{#64515}
parent 17d6b5bb
......@@ -32,15 +32,13 @@ ArrayBuiltinsAssembler::ArrayBuiltinsAssembler(
void ArrayBuiltinsAssembler::TypedArrayMapResultGenerator() {
// 6. Let A be ? TypedArraySpeciesCreate(O, len).
TNode<JSTypedArray> original_array = CAST(o());
// TODO(v8:4153): Consider making |len_| an UintPtrT.
TNode<UintPtrT> length = ChangeNonnegativeNumberToUintPtr(len_);
const char* method_name = "%TypedArray%.prototype.map";
TNode<JSTypedArray> a = TypedArraySpeciesCreateByLength(
context(), method_name, original_array, length);
context(), method_name, original_array, len());
// In the Spec and our current implementation, the length check is already
// performed in TypedArraySpeciesCreate.
CSA_ASSERT(this, UintPtrLessThanOrEqual(length, LoadJSTypedArrayLength(a)));
CSA_ASSERT(this, UintPtrLessThanOrEqual(len(), LoadJSTypedArrayLength(a)));
fast_typed_array_target_ =
Word32Equal(LoadElementsKind(original_array), LoadElementsKind(a));
a_ = a;
......@@ -48,11 +46,12 @@ void ArrayBuiltinsAssembler::TypedArrayMapResultGenerator() {
// See tc39.github.io/ecma262/#sec-%typedarray%.prototype.map.
TNode<Object> ArrayBuiltinsAssembler::TypedArrayMapProcessor(
TNode<Object> k_value, TNode<Object> k) {
TNode<Object> k_value, TNode<UintPtrT> k) {
// 8. c. Let mapped_value be ? Call(callbackfn, T, « kValue, k, O »).
TNode<Number> k_number = ChangeUintPtrToTagged(k);
TNode<Object> mapped_value =
CallJS(CodeFactory::Call(isolate()), context(), callbackfn(), this_arg(),
k_value, k, o());
k_value, k_number, o());
Label fast(this), slow(this), done(this), detached(this, Label::kDeferred);
// 8. d. Perform ? Set(A, Pk, mapped_value, true).
......@@ -73,14 +72,20 @@ TNode<Object> ArrayBuiltinsAssembler::TypedArrayMapProcessor(
} else {
num_value = ToNumber_Inline(context(), mapped_value);
}
// The only way how this can bailout is because of a detached buffer.
EmitElementStore(a(), k, num_value, source_elements_kind_,
// TODO(v8:4153): Consider checking IsDetachedBuffer() and calling
// TypedArrayBuiltinsAssembler::StoreJSTypedArrayElementFromTagged() here
// instead to avoid converting k_number back to UintPtrT.
EmitElementStore(a(), k_number, num_value, source_elements_kind_,
KeyedAccessStoreMode::STANDARD_STORE, &detached, context());
Goto(&done);
BIND(&slow);
SetPropertyStrict(context(), a(), k, mapped_value);
Goto(&done);
{
SetPropertyStrict(context(), a(), k_number, mapped_value);
Goto(&done);
}
BIND(&detached);
// tc39.github.io/ecma262/#sec-integerindexedelementset
......@@ -130,7 +135,7 @@ void ArrayBuiltinsAssembler::GenerateIteratingTypedArrayBuiltinBody(
TNode<JSArrayBuffer> array_buffer = LoadJSArrayBufferViewBuffer(typed_array);
ThrowIfArrayBufferIsDetached(context_, array_buffer, name_);
len_ = ChangeUintPtrToTagged(LoadJSTypedArrayLength(typed_array));
len_ = LoadJSTypedArrayLength(typed_array);
Label throw_not_callable(this, Label::kDeferred);
Label distinguish_types(this);
......@@ -166,12 +171,6 @@ void ArrayBuiltinsAssembler::GenerateIteratingTypedArrayBuiltinBody(
generator(this);
if (direction == ForEachDirection::kForward) {
k_ = SmiConstant(0);
} else {
k_ = NumberDec(len());
}
CSA_ASSERT(this, IsSafeInteger(k()));
TNode<Int32T> elements_kind = LoadMapElementsKind(typed_array_map);
Switch(elements_kind, &unexpected_instance_type, elements_kinds.data(),
label_ptrs.data(), labels.size());
......@@ -199,8 +198,8 @@ void ArrayBuiltinsAssembler::VisitAllTypedArrayElements(
TNode<JSTypedArray> typed_array) {
VariableList list({&a_, &k_}, zone());
TNode<Smi> start = SmiConstant(0);
TNode<Smi> end = CAST(len_);
TNode<UintPtrT> start = UintPtrConstant(0);
TNode<UintPtrT> end = len_;
IndexAdvanceMode advance_mode = IndexAdvanceMode::kPost;
int incr = 1;
if (direction == ForEachDirection::kReverse) {
......@@ -208,13 +207,14 @@ void ArrayBuiltinsAssembler::VisitAllTypedArrayElements(
advance_mode = IndexAdvanceMode::kPre;
incr = -1;
}
BuildFastLoop<Smi>(
k_ = start;
BuildFastLoop<UintPtrT>(
list, start, end,
[&](TNode<Smi> index) {
[&](TNode<UintPtrT> index) {
GotoIf(IsDetachedBuffer(array_buffer), detached);
TNode<RawPtrT> data_ptr = LoadJSTypedArrayDataPtr(typed_array);
TNode<Numeric> value = LoadFixedTypedArrayElementAsTagged(
data_ptr, index, source_elements_kind_, SMI_PARAMETERS);
data_ptr, index, source_elements_kind_);
k_ = index;
a_ = processor(this, value, index);
},
......@@ -1530,7 +1530,7 @@ TF_BUILTIN(ArrayIteratorPrototypeNext, CodeStubAssembler) {
{
// If {array} is a JSTypedArray, the {index} must always be a Smi.
// TODO(v8:4153): Update this and the relevant TurboFan code.
CSA_ASSERT(this, TaggedIsSmi(index));
TNode<UintPtrT> index_uintptr = Unsigned(SmiUntag(CAST(index)));
// Check that the {array}s buffer wasn't detached.
ThrowIfArrayBufferViewBufferIsDetached(context, CAST(array), method_name);
......@@ -1540,8 +1540,10 @@ TF_BUILTIN(ArrayIteratorPrototypeNext, CodeStubAssembler) {
// length cannot change anymore, so this {iterator} will never
// produce values again anyways.
TNode<UintPtrT> length = LoadJSTypedArrayLength(CAST(array));
GotoIfNot(UintPtrLessThan(SmiUntag(CAST(index)), length),
GotoIfNot(UintPtrLessThan(index_uintptr, length),
&allocate_iterator_result);
// TODO(v8:4153): Consider storing next index as uintptr. Update this and
// the relevant TurboFan code.
StoreObjectFieldNoWriteBarrier(iterator, JSArrayIterator::kNextIndexOffset,
SmiInc(CAST(index)));
......@@ -1555,7 +1557,7 @@ TF_BUILTIN(ArrayIteratorPrototypeNext, CodeStubAssembler) {
TNode<Int32T> elements_kind = LoadMapElementsKind(array_map);
TNode<RawPtrT> data_ptr = LoadJSTypedArrayDataPtr(CAST(array));
var_value = LoadFixedTypedArrayElementAsTagged(data_ptr, CAST(index),
var_value = LoadFixedTypedArrayElementAsTagged(data_ptr, index_uintptr,
elements_kind);
Goto(&allocate_entry_if_needed);
}
......
......@@ -18,12 +18,13 @@ class ArrayBuiltinsAssembler : public CodeStubAssembler {
std::function<void(ArrayBuiltinsAssembler* masm)>;
using CallResultProcessor = std::function<TNode<Object>(
ArrayBuiltinsAssembler* masm, TNode<Object> k_value, TNode<Object> k)>;
ArrayBuiltinsAssembler* masm, TNode<Object> k_value, TNode<UintPtrT> k)>;
void TypedArrayMapResultGenerator();
// See tc39.github.io/ecma262/#sec-%typedarray%.prototype.map.
TNode<Object> TypedArrayMapProcessor(TNode<Object> k_value, TNode<Object> k);
TNode<Object> TypedArrayMapProcessor(TNode<Object> k_value,
TNode<UintPtrT> k);
TNode<String> CallJSArrayArrayJoinConcatToSequentialString(
TNode<FixedArray> fixed_array, TNode<IntPtrT> length, TNode<String> sep,
......@@ -47,10 +48,10 @@ class ArrayBuiltinsAssembler : public CodeStubAssembler {
TNode<Object> receiver() { return receiver_; }
TNode<IntPtrT> argc() { return argc_; }
TNode<JSReceiver> o() { return o_; }
TNode<Number> len() { return len_; }
TNode<UintPtrT> len() { return len_; }
TNode<Object> callbackfn() { return callbackfn_; }
TNode<Object> this_arg() { return this_arg_; }
TNode<Number> k() { return k_.value(); }
TNode<UintPtrT> k() { return k_.value(); }
TNode<Object> a() { return a_.value(); }
void ReturnFromBuiltin(TNode<Object> value);
......@@ -109,13 +110,13 @@ class ArrayBuiltinsAssembler : public CodeStubAssembler {
TNode<Object> callbackfn_;
TNode<JSReceiver> o_;
TNode<Object> this_arg_;
TNode<Number> len_;
TNode<UintPtrT> len_;
TNode<Context> context_;
TNode<Object> receiver_;
TNode<IntPtrT> argc_;
TNode<BoolT> fast_typed_array_target_;
const char* name_ = nullptr;
TVariable<Number> k_;
TVariable<UintPtrT> k_;
TVariable<Object> a_;
Label fully_spec_compliant_;
ElementsKind source_elements_kind_ = ElementsKind::NO_ELEMENTS;
......
......@@ -413,6 +413,11 @@ TNode<IntPtrT> CodeStubAssembler::IntPtrOrSmiConstant<IntPtrT>(int value) {
return IntPtrConstant(value);
}
template <>
TNode<UintPtrT> CodeStubAssembler::IntPtrOrSmiConstant<UintPtrT>(int value) {
return Unsigned(IntPtrConstant(value));
}
template <>
TNode<RawPtrT> CodeStubAssembler::IntPtrOrSmiConstant<RawPtrT>(int value) {
return ReinterpretCast<RawPtrT>(IntPtrConstant(value));
......@@ -2395,10 +2400,10 @@ TNode<BigInt> CodeStubAssembler::BigIntFromUint64(TNode<UintPtrT> value) {
}
TNode<Numeric> CodeStubAssembler::LoadFixedTypedArrayElementAsTagged(
TNode<RawPtrT> data_pointer, Node* index_node, ElementsKind elements_kind,
ParameterMode parameter_mode) {
TNode<RawPtrT> data_pointer, TNode<UintPtrT> index,
ElementsKind elements_kind) {
TNode<IntPtrT> offset =
ElementOffsetFromIndex(index_node, elements_kind, parameter_mode, 0);
ElementOffsetFromIndex(Signed(index), elements_kind, 0);
switch (elements_kind) {
case UINT8_ELEMENTS: /* fall through */
case UINT8_CLAMPED_ELEMENTS:
......@@ -2431,7 +2436,7 @@ TNode<Numeric> CodeStubAssembler::LoadFixedTypedArrayElementAsTagged(
}
TNode<Numeric> CodeStubAssembler::LoadFixedTypedArrayElementAsTagged(
TNode<RawPtrT> data_pointer, TNode<Smi> index,
TNode<RawPtrT> data_pointer, TNode<UintPtrT> index,
TNode<Int32T> elements_kind) {
TVARIABLE(Numeric, var_result);
Label done(this), if_unknown_type(this, Label::kDeferred);
......@@ -2458,12 +2463,12 @@ TNode<Numeric> CodeStubAssembler::LoadFixedTypedArrayElementAsTagged(
BIND(&if_unknown_type);
Unreachable();
#define TYPED_ARRAY_CASE(Type, type, TYPE, ctype) \
BIND(&if_##type##array); \
{ \
var_result = LoadFixedTypedArrayElementAsTagged( \
data_pointer, index, TYPE##_ELEMENTS, SMI_PARAMETERS); \
Goto(&done); \
#define TYPED_ARRAY_CASE(Type, type, TYPE, ctype) \
BIND(&if_##type##array); \
{ \
var_result = LoadFixedTypedArrayElementAsTagged(data_pointer, index, \
TYPE##_ELEMENTS); \
Goto(&done); \
}
TYPED_ARRAYS(TYPED_ARRAY_CASE)
#undef TYPED_ARRAY_CASE
......@@ -10770,6 +10775,10 @@ template TNode<IntPtrT> CodeStubAssembler::BuildFastLoop<IntPtrT>(
const VariableList& vars, TNode<IntPtrT> start_index,
TNode<IntPtrT> end_index, const FastLoopBody<IntPtrT>& body, int increment,
IndexAdvanceMode advance_mode);
template TNode<UintPtrT> CodeStubAssembler::BuildFastLoop<UintPtrT>(
const VariableList& vars, TNode<UintPtrT> start_index,
TNode<UintPtrT> end_index, const FastLoopBody<UintPtrT>& body,
int increment, IndexAdvanceMode advance_mode);
void CodeStubAssembler::BuildFastFixedArrayForEach(
const CodeStubAssembler::VariableList& vars, Node* fixed_array,
......
......@@ -468,6 +468,9 @@ class V8_EXPORT_PRIVATE CodeStubAssembler
TNode<IntPtrT> OpName(TNode<IntPtrT> a, TNode<IntPtrT> b) { \
return IntPtrOpName(a, b); \
} \
TNode<UintPtrT> OpName(TNode<UintPtrT> a, TNode<UintPtrT> b) { \
return Unsigned(IntPtrOpName(Signed(a), Signed(b))); \
} \
TNode<RawPtrT> OpName(TNode<RawPtrT> a, TNode<RawPtrT> b) { \
return ReinterpretCast<RawPtrT>(IntPtrOpName( \
ReinterpretCast<IntPtrT>(a), ReinterpretCast<IntPtrT>(b))); \
......@@ -493,6 +496,9 @@ class V8_EXPORT_PRIVATE CodeStubAssembler
TNode<BoolT> OpName(TNode<IntPtrT> a, TNode<IntPtrT> b) { \
return IntPtrOpName(a, b); \
} \
TNode<BoolT> OpName(TNode<UintPtrT> a, TNode<UintPtrT> b) { \
return IntPtrOpName(Signed(a), Signed(b)); \
} \
TNode<BoolT> OpName(TNode<RawPtrT> a, TNode<RawPtrT> b) { \
return IntPtrOpName(a, b); \
}
......@@ -1419,17 +1425,11 @@ class V8_EXPORT_PRIVATE CodeStubAssembler
TNode<Float64T> LoadDoubleWithHoleCheck(
SloppyTNode<Object> base, SloppyTNode<IntPtrT> offset, Label* if_hole,
MachineType machine_type = MachineType::Float64());
TNode<Numeric> LoadFixedTypedArrayElementAsTagged(TNode<RawPtrT> data_pointer,
TNode<UintPtrT> index,
ElementsKind elements_kind);
TNode<Numeric> LoadFixedTypedArrayElementAsTagged(
TNode<RawPtrT> data_pointer, Node* index_node, ElementsKind elements_kind,
ParameterMode parameter_mode = INTPTR_PARAMETERS);
TNode<Numeric> LoadFixedTypedArrayElementAsTagged(
TNode<RawPtrT> data_pointer, TNode<Smi> index_node,
ElementsKind elements_kind) {
return LoadFixedTypedArrayElementAsTagged(data_pointer, index_node,
elements_kind, SMI_PARAMETERS);
}
TNode<Numeric> LoadFixedTypedArrayElementAsTagged(
TNode<RawPtrT> data_pointer, TNode<Smi> index,
TNode<RawPtrT> data_pointer, TNode<UintPtrT> index,
TNode<Int32T> elements_kind);
// Parts of the above, factored out for readability:
TNode<BigInt> LoadFixedBigInt64ArrayElementAsTagged(
......
......@@ -2220,13 +2220,13 @@ void AccessorAssembler::EmitElementLoad(
{
Comment("BIGINT64_ELEMENTS");
exit_point->Return(LoadFixedTypedArrayElementAsTagged(
data_ptr, intptr_index, BIGINT64_ELEMENTS, INTPTR_PARAMETERS));
data_ptr, Unsigned(intptr_index), BIGINT64_ELEMENTS));
}
BIND(&biguint64_elements);
{
Comment("BIGUINT64_ELEMENTS");
exit_point->Return(LoadFixedTypedArrayElementAsTagged(
data_ptr, intptr_index, BIGUINT64_ELEMENTS, INTPTR_PARAMETERS));
data_ptr, Unsigned(intptr_index), BIGUINT64_ELEMENTS));
}
}
}
......
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