Commit d5ab044a authored by Marja Hölttä's avatar Marja Hölttä Committed by Commit Bot

[Promise.any] Make JSAggregateError.errors a FixedArray

There's no reason for it to be a JSArray; it's an internal data member.

We only have a slow version for constructing a FixedArray from an
Iterable, but since this is not a performance critical code path,
it's fine.

BUG=v8:9808

Change-Id: I5bcfac4cc545880966421a96d3aa3d899bbf6cd5
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2157371Reviewed-by: 's avatarIgor Sheludko <ishell@chromium.org>
Commit-Queue: Marja Hölttä <marja@chromium.org>
Cr-Commit-Position: refs/heads/master@{#67321}
parent 09e91e31
...@@ -79,4 +79,13 @@ namespace array { ...@@ -79,4 +79,13 @@ namespace array {
goto Bailout; goto Bailout;
} }
} }
macro CreateJSArrayWithElements(implicit context: Context)(array: FixedArray):
JSArray {
const nativeContext: NativeContext = LoadNativeContext(context);
const map: Map =
LoadJSArrayElementsMap(ElementsKind::PACKED_ELEMENTS, nativeContext);
return AllocateJSArray(map, array, array.length);
}
} }
...@@ -574,7 +574,9 @@ namespace internal { ...@@ -574,7 +574,9 @@ namespace internal {
/* IterableToList */ \ /* IterableToList */ \
/* ES #sec-iterabletolist */ \ /* ES #sec-iterabletolist */ \
TFS(IterableToList, kIterable, kIteratorFn) \ TFS(IterableToList, kIterable, kIteratorFn) \
TFS(IterableToFixedArray, kIterable, kIteratorFn) \
TFS(IterableToListWithSymbolLookup, kIterable) \ TFS(IterableToListWithSymbolLookup, kIterable) \
TFS(IterableToFixedArrayWithSymbolLookupSlow, kIterable) \
TFS(IterableToListMayPreserveHoles, kIterable, kIteratorFn) \ TFS(IterableToListMayPreserveHoles, kIterable, kIteratorFn) \
TFS(IterableToFixedArrayForWasm, kIterable, kExpectedLength) \ TFS(IterableToFixedArrayForWasm, kIterable, kExpectedLength) \
\ \
......
...@@ -183,6 +183,14 @@ TNode<JSArray> IteratorBuiltinsAssembler::IterableToList( ...@@ -183,6 +183,14 @@ TNode<JSArray> IteratorBuiltinsAssembler::IterableToList(
return values.ToJSArray(context); return values.ToJSArray(context);
} }
TNode<FixedArray> IteratorBuiltinsAssembler::IterableToFixedArray(
TNode<Context> context, TNode<Object> iterable, TNode<Object> iterator_fn) {
GrowableFixedArray values(state());
FillFixedArrayFromIterable(context, iterable, iterator_fn, &values);
TNode<FixedArray> new_array = values.ToFixedArray();
return new_array;
}
void IteratorBuiltinsAssembler::FillFixedArrayFromIterable( void IteratorBuiltinsAssembler::FillFixedArrayFromIterable(
TNode<Context> context, TNode<Object> iterable, TNode<Object> iterator_fn, TNode<Context> context, TNode<Object> iterable, TNode<Object> iterator_fn,
GrowableFixedArray* values) { GrowableFixedArray* values) {
...@@ -223,6 +231,14 @@ TF_BUILTIN(IterableToList, IteratorBuiltinsAssembler) { ...@@ -223,6 +231,14 @@ TF_BUILTIN(IterableToList, IteratorBuiltinsAssembler) {
Return(IterableToList(context, iterable, iterator_fn)); Return(IterableToList(context, iterable, iterator_fn));
} }
TF_BUILTIN(IterableToFixedArray, IteratorBuiltinsAssembler) {
TNode<Context> context = CAST(Parameter(Descriptor::kContext));
TNode<Object> iterable = CAST(Parameter(Descriptor::kIterable));
TNode<Object> iterator_fn = CAST(Parameter(Descriptor::kIteratorFn));
Return(IterableToFixedArray(context, iterable, iterator_fn));
}
TF_BUILTIN(IterableToFixedArrayForWasm, IteratorBuiltinsAssembler) { TF_BUILTIN(IterableToFixedArrayForWasm, IteratorBuiltinsAssembler) {
TNode<Context> context = CAST(Parameter(Descriptor::kContext)); TNode<Context> context = CAST(Parameter(Descriptor::kContext));
TNode<Object> iterable = CAST(Parameter(Descriptor::kIterable)); TNode<Object> iterable = CAST(Parameter(Descriptor::kIterable));
...@@ -448,5 +464,17 @@ TF_BUILTIN(GetIteratorWithFeedbackLazyDeoptContinuation, ...@@ -448,5 +464,17 @@ TF_BUILTIN(GetIteratorWithFeedbackLazyDeoptContinuation,
Return(result); Return(result);
} }
// This builtin creates a FixedArray based on an Iterable and doesn't have a
// fast path for anything.
TF_BUILTIN(IterableToFixedArrayWithSymbolLookupSlow,
IteratorBuiltinsAssembler) {
TNode<Context> context = CAST(Parameter(Descriptor::kContext));
TNode<Object> iterable = CAST(Parameter(Descriptor::kIterable));
TNode<Object> iterator_fn = GetIteratorMethod(context, iterable);
TailCallBuiltin(Builtins::kIterableToFixedArray, context, iterable,
iterator_fn);
}
} // namespace internal } // namespace internal
} // namespace v8 } // namespace v8
...@@ -67,6 +67,10 @@ class IteratorBuiltinsAssembler : public CodeStubAssembler { ...@@ -67,6 +67,10 @@ class IteratorBuiltinsAssembler : public CodeStubAssembler {
TNode<JSArray> IterableToList(TNode<Context> context, TNode<Object> iterable, TNode<JSArray> IterableToList(TNode<Context> context, TNode<Object> iterable,
TNode<Object> iterator_fn); TNode<Object> iterator_fn);
TNode<FixedArray> IterableToFixedArray(TNode<Context> context,
TNode<Object> iterable,
TNode<Object> iterator_fn);
void FillFixedArrayFromIterable(TNode<Context> context, void FillFixedArrayFromIterable(TNode<Context> context,
TNode<Object> iterable, TNode<Object> iterable,
TNode<Object> iterator_fn, TNode<Object> iterator_fn,
......
...@@ -33,6 +33,10 @@ void GrowableFixedArray::Push(const TNode<Object> value) { ...@@ -33,6 +33,10 @@ void GrowableFixedArray::Push(const TNode<Object> value) {
} }
} }
TNode<FixedArray> GrowableFixedArray::ToFixedArray() {
return ResizeFixedArray(length(), length());
}
TNode<JSArray> GrowableFixedArray::ToJSArray(const TNode<Context> context) { TNode<JSArray> GrowableFixedArray::ToJSArray(const TNode<Context> context) {
const ElementsKind kind = PACKED_ELEMENTS; const ElementsKind kind = PACKED_ELEMENTS;
......
...@@ -32,6 +32,7 @@ class GrowableFixedArray : public CodeStubAssembler { ...@@ -32,6 +32,7 @@ class GrowableFixedArray : public CodeStubAssembler {
void Push(const TNode<Object> value); void Push(const TNode<Object> value);
TNode<FixedArray> ToFixedArray();
TNode<JSArray> ToJSArray(const TNode<Context> context); TNode<JSArray> ToJSArray(const TNode<Context> context);
private: private:
......
...@@ -50,6 +50,8 @@ namespace iterator { ...@@ -50,6 +50,8 @@ namespace iterator {
Context)(JSAny, JSAny); Context)(JSAny, JSAny);
extern builtin IterableToListWithSymbolLookup(implicit context: extern builtin IterableToListWithSymbolLookup(implicit context:
Context)(JSAny): JSArray; Context)(JSAny): JSArray;
extern builtin IterableToFixedArrayWithSymbolLookupSlow(
implicit context: Context)(JSAny): FixedArray;
transitioning builtin GetIteratorWithFeedback( transitioning builtin GetIteratorWithFeedback(
context: Context, receiver: JSAny, loadSlot: TaggedIndex, context: Context, receiver: JSAny, loadSlot: TaggedIndex,
......
...@@ -3688,6 +3688,17 @@ void CodeStubAssembler::StoreFieldsNoWriteBarrier(TNode<IntPtrT> start_address, ...@@ -3688,6 +3688,17 @@ void CodeStubAssembler::StoreFieldsNoWriteBarrier(TNode<IntPtrT> start_address,
kTaggedSize, IndexAdvanceMode::kPost); kTaggedSize, IndexAdvanceMode::kPost);
} }
void CodeStubAssembler::MakeFixedArrayCOW(TNode<FixedArray> array) {
CSA_ASSERT(this, IsFixedArrayMap(LoadMap(array)));
Label done(this);
// The empty fixed array is not modifiable anyway. And we shouldn't change its
// Map.
GotoIf(TaggedEqual(array, EmptyFixedArrayConstant()), &done);
StoreMap(array, FixedCOWArrayMapConstant());
Goto(&done);
BIND(&done);
}
TNode<BoolT> CodeStubAssembler::IsValidFastJSArrayCapacity( TNode<BoolT> CodeStubAssembler::IsValidFastJSArrayCapacity(
TNode<IntPtrT> capacity) { TNode<IntPtrT> capacity) {
return UintPtrLessThanOrEqual(capacity, return UintPtrLessThanOrEqual(capacity,
......
...@@ -1780,6 +1780,9 @@ class V8_EXPORT_PRIVATE CodeStubAssembler ...@@ -1780,6 +1780,9 @@ class V8_EXPORT_PRIVATE CodeStubAssembler
TNode<IntPtrT> end_address, TNode<IntPtrT> end_address,
TNode<Object> value); TNode<Object> value);
// Marks the FixedArray copy-on-write without moving it.
void MakeFixedArrayCOW(TNode<FixedArray> array);
TNode<Cell> AllocateCellWithValue( TNode<Cell> AllocateCellWithValue(
TNode<Object> value, WriteBarrierMode mode = UPDATE_WRITE_BARRIER); TNode<Object> value, WriteBarrierMode mode = UPDATE_WRITE_BARRIER);
TNode<Cell> AllocateSmiCell(int value = 0) { TNode<Cell> AllocateSmiCell(int value = 0) {
......
...@@ -6,8 +6,10 @@ ...@@ -6,8 +6,10 @@
@generateCppClass @generateCppClass
extern class JSAggregateError extends JSObject { extern class JSAggregateError extends JSObject {
// Only Undefined during AggregateError object creation. // Only Undefined during AggregateError object creation. In order to make the
errors: JSAny|Undefined; // field type FixedArray, we'd need to initialize it in ErrorUtils::Construct
// (after it, it's too late) which we don't want.
errors: FixedArray|Undefined;
} }
namespace error { namespace error {
...@@ -34,7 +36,9 @@ namespace error { ...@@ -34,7 +36,9 @@ namespace error {
// 4. Let errorsList be ? IterableToList(errors). // 4. Let errorsList be ? IterableToList(errors).
const errors: JSAny = arguments.length > 0 ? arguments[0] : Undefined; const errors: JSAny = arguments.length > 0 ? arguments[0] : Undefined;
const errorsArray = iterator::IterableToListWithSymbolLookup(errors); const errorsArray =
iterator::IterableToFixedArrayWithSymbolLookupSlow(errors);
MakeFixedArrayCOW(errorsArray);
// 5. Set O.[[AggregateErrors]] to errorsList. // 5. Set O.[[AggregateErrors]] to errorsList.
obj.errors = errorsArray; obj.errors = errorsArray;
...@@ -54,8 +58,8 @@ namespace error { ...@@ -54,8 +58,8 @@ namespace error {
// 5. Return ! CreateArrayFromList(E.[[AggregateErrors]]). // 5. Return ! CreateArrayFromList(E.[[AggregateErrors]]).
typeswitch (receiver) { typeswitch (receiver) {
case (receiver: JSAggregateError): { case (receiver: JSAggregateError): {
return CloneFastJSArrayFillingHoles( return array::CreateJSArrayWithElements(
context, UnsafeCast<JSArray>(receiver.errors)); UnsafeCast<FixedArray>(receiver.errors));
} }
case (Object): { case (Object): {
ThrowTypeError( ThrowTypeError(
...@@ -68,6 +72,6 @@ namespace error { ...@@ -68,6 +72,6 @@ namespace error {
extern runtime ConstructAggregateErrorHelper( extern runtime ConstructAggregateErrorHelper(
Context, JSFunction, JSAny, JSAny): JSAggregateError; Context, JSFunction, JSAny, JSAny): JSAggregateError;
extern transitioning builtin CloneFastJSArrayFillingHoles(Context, JSArray): extern macro MakeFixedArrayCOW(FixedArray);
JSArray;
} }
...@@ -137,6 +137,33 @@ ...@@ -137,6 +137,33 @@
assertNotSame(errors1, errors2); assertNotSame(errors1, errors2);
})(); })();
(function ErrorsModified(){
let e = new AggregateError([9, 6, 3]);
const errors1 = e.errors;
errors1[0] = 50;
const errors2 = e.errors;
assertEquals([50, 6, 3], errors1);
assertEquals([9, 6, 3], errors2);
})();
(function EmptyErrorsModified1(){
let e = new AggregateError([]);
const errors1 = e.errors;
errors1[0] = 50;
const errors2 = e.errors;
assertEquals([50], errors1);
assertEquals([], errors2);
})();
(function EmptyErrorsModified2(){
let e = new AggregateError([]);
const errors1 = e.errors;
errors1.push(50);
const errors2 = e.errors;
assertEquals([50], errors1);
assertEquals([], errors2);
})();
(function AggregateErrorCreation() { (function AggregateErrorCreation() {
// Verify that we match the spec wrt getting the prototype from the // Verify that we match the spec wrt getting the prototype from the
// newTarget, iterating the errors array and calling toString on the // newTarget, iterating the errors array and calling toString on the
......
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