diff options
Diffstat (limited to 'deps/v8/src/builtins/array-filter.tq')
-rw-r--r-- | deps/v8/src/builtins/array-filter.tq | 150 |
1 files changed, 56 insertions, 94 deletions
diff --git a/deps/v8/src/builtins/array-filter.tq b/deps/v8/src/builtins/array-filter.tq index 222e4e291b..4bf175a787 100644 --- a/deps/v8/src/builtins/array-filter.tq +++ b/deps/v8/src/builtins/array-filter.tq @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -namespace array { +namespace array_filter { transitioning javascript builtin ArrayFilterLoopEagerDeoptContinuation(implicit context: Context)( receiver: Object, callback: Object, thisArg: Object, array: Object, @@ -14,14 +14,12 @@ namespace array { // Also, this great mass of casts is necessary because the signature // of Torque javascript builtins requires Object type for all parameters // other than {context}. - const jsreceiver: JSReceiver = - Cast<JSReceiver>(receiver) otherwise unreachable; - const callbackfn: Callable = Cast<Callable>(callback) otherwise unreachable; - const outputArray: JSReceiver = - Cast<JSReceiver>(array) otherwise unreachable; - const numberK: Number = Cast<Number>(initialK) otherwise unreachable; - const numberTo: Number = Cast<Number>(initialTo) otherwise unreachable; - const numberLength: Number = Cast<Number>(length) otherwise unreachable; + const jsreceiver = Cast<JSReceiver>(receiver) otherwise unreachable; + const callbackfn = Cast<Callable>(callback) otherwise unreachable; + const outputArray = Cast<JSReceiver>(array) otherwise unreachable; + const numberK = Cast<Number>(initialK) otherwise unreachable; + const numberTo = Cast<Number>(initialTo) otherwise unreachable; + const numberLength = Cast<Number>(length) otherwise unreachable; return ArrayFilterLoopContinuation( jsreceiver, callbackfn, thisArg, outputArray, jsreceiver, numberK, @@ -36,21 +34,19 @@ namespace array { // All continuation points in the optimized filter implementation are // after the ToObject(O) call that ensures we are dealing with a // JSReceiver. - const jsreceiver: JSReceiver = - Cast<JSReceiver>(receiver) otherwise unreachable; - const callbackfn: Callable = Cast<Callable>(callback) otherwise unreachable; - const outputArray: JSReceiver = - Cast<JSReceiver>(array) otherwise unreachable; - let numberK: Number = Cast<Number>(initialK) otherwise unreachable; - let numberTo: Number = Cast<Number>(initialTo) otherwise unreachable; - const numberLength: Number = Cast<Number>(length) otherwise unreachable; + const jsreceiver = Cast<JSReceiver>(receiver) otherwise unreachable; + const callbackfn = Cast<Callable>(callback) otherwise unreachable; + const outputArray = Cast<JSReceiver>(array) otherwise unreachable; + let numberK = Cast<Number>(initialK) otherwise unreachable; + let numberTo = Cast<Number>(initialTo) otherwise unreachable; + const numberLength = Cast<Number>(length) otherwise unreachable; // This custom lazy deopt point is right after the callback. filter() needs // to pick up at the next step, which is setting the callback result in // the output array. After incrementing k and to, we can glide into the loop // continuation builtin. if (ToBoolean(result)) { - CreateDataProperty(outputArray, numberTo, valueK); + FastCreateDataProperty(outputArray, numberTo, valueK); numberTo = numberTo + 1; } @@ -87,7 +83,7 @@ namespace array { // iii. If selected is true, then... if (ToBoolean(result)) { // 1. Perform ? CreateDataPropertyOrThrow(A, ToString(to), kValue). - CreateDataProperty(array, to, kValue); + FastCreateDataProperty(array, to, kValue); // 2. Increase to by 1. to = to + 1; } @@ -98,80 +94,42 @@ namespace array { return array; } - transitioning macro - FilterVisitAllElements<FixedArrayType: type>(implicit context: Context)( - kind: constexpr ElementsKind, o: JSArray, len: Smi, callbackfn: Callable, - thisArg: Object, a: JSArray) labels Bailout(Smi, Smi) { + transitioning macro FastArrayFilter(implicit context: Context)( + fastO: FastJSArray, len: Smi, callbackfn: Callable, thisArg: Object, + output: FastJSArray) labels Bailout(Number, Number) { let k: Smi = 0; let to: Smi = 0; - const fastOWitness: FastJSArrayWitness = - MakeWitness(Cast<FastJSArray>(o) otherwise goto Bailout(k, to)); - const fastAWitness: FastJSArrayWitness = - MakeWitness(Cast<FastJSArray>(a) otherwise goto Bailout(k, to)); + let fastOW = NewFastJSArrayWitness(fastO); + let fastOutputW = NewFastJSArrayWitness(output); + + fastOutputW.EnsureArrayPushable() otherwise goto Bailout(k, to); - // Build a fast loop over the smi array. + // Build a fast loop over the array. for (; k < len; k++) { - let fastO: FastJSArray = - Testify(fastOWitness) otherwise goto Bailout(k, to); + fastOW.Recheck() otherwise goto Bailout(k, to); // Ensure that we haven't walked beyond a possibly updated length. - if (k >= fastO.length) goto Bailout(k, to); - - try { - const value: Object = - LoadElementNoHole<FixedArrayType>(fastO, k) otherwise FoundHole; - const result: Object = - Call(context, callbackfn, thisArg, value, k, fastO); - if (ToBoolean(result)) { - try { - // Since the call to {callbackfn} is observable, we can't - // use the Bailout label until we've successfully stored. - // Hence the {SlowStore} label. - const fastA: FastJSArray = - Testify(fastAWitness) otherwise SlowStore; - if (fastA.length != to) goto SlowStore; - BuildAppendJSArray(kind, fastA, value) - otherwise SlowStore; - } - label SlowStore { - CreateDataProperty(a, to, value); - } - to = to + 1; + if (k >= fastOW.Get().length) goto Bailout(k, to); + const value: Object = fastOW.LoadElementNoHole(k) otherwise continue; + const result: Object = + Call(context, callbackfn, thisArg, value, k, fastOW.Get()); + if (ToBoolean(result)) { + try { + // Since the call to {callbackfn} is observable, we can't + // use the Bailout label until we've successfully stored. + // Hence the {SlowStore} label. + fastOutputW.Recheck() otherwise SlowStore; + if (fastOutputW.Get().length != to) goto SlowStore; + fastOutputW.Push(value) otherwise SlowStore; + } + label SlowStore { + FastCreateDataProperty(fastOutputW.stable, to, value); } + to = to + 1; } - label FoundHole {} } } - transitioning macro FastArrayFilter(implicit context: Context)( - o: JSReceiver, len: Number, callbackfn: Callable, thisArg: Object, - array: JSReceiver): Object - labels Bailout(Smi, Smi) { - let k: Smi = 0; - let to: Smi = 0; - const smiLen: Smi = Cast<Smi>(len) otherwise goto Bailout(k, to); - const fastArray: FastJSArray = - Cast<FastJSArray>(array) otherwise goto Bailout(k, to); - let fastO: FastJSArray = Cast<FastJSArray>(o) otherwise goto Bailout(k, to); - EnsureArrayPushable(fastArray.map) otherwise goto Bailout(k, to); - const elementsKind: ElementsKind = fastO.map.elements_kind; - if (IsElementsKindLessThanOrEqual(elementsKind, HOLEY_SMI_ELEMENTS)) { - FilterVisitAllElements<FixedArray>( - HOLEY_SMI_ELEMENTS, fastO, smiLen, callbackfn, thisArg, fastArray) - otherwise Bailout; - } else if (IsElementsKindLessThanOrEqual(elementsKind, HOLEY_ELEMENTS)) { - FilterVisitAllElements<FixedArray>( - HOLEY_ELEMENTS, fastO, smiLen, callbackfn, thisArg, fastArray) - otherwise Bailout; - } else { - assert(IsDoubleElementsKind(elementsKind)); - FilterVisitAllElements<FixedDoubleArray>( - HOLEY_DOUBLE_ELEMENTS, fastO, smiLen, callbackfn, thisArg, fastArray) - otherwise Bailout; - } - return array; - } - // This method creates a 0-length array with the ElementsKind of the // receiver if possible, otherwise, bails out. It makes sense for the // caller to know that the slow case needs to be invoked. @@ -179,7 +137,7 @@ namespace array { receiver: JSReceiver): JSReceiver labels Slow { const len: Smi = 0; if (IsArraySpeciesProtectorCellInvalid()) goto Slow; - const o: FastJSArray = Cast<FastJSArray>(receiver) otherwise Slow; + const o = Cast<FastJSArray>(receiver) otherwise Slow; const newMap: Map = LoadJSArrayElementsMap(o.map.elements_kind, LoadNativeContext(context)); return AllocateJSArray(PACKED_SMI_ELEMENTS, newMap, len, len); @@ -204,41 +162,45 @@ namespace array { if (arguments.length == 0) { goto TypeError; } - const callbackfn: Callable = - Cast<Callable>(arguments[0]) otherwise TypeError; + const callbackfn = Cast<Callable>(arguments[0]) otherwise TypeError; // 4. If thisArg is present, let T be thisArg; else let T be undefined. const thisArg: Object = arguments.length > 1 ? arguments[1] : Undefined; - let array: JSReceiver; + let output: JSReceiver; // Special cases. let k: Number = 0; let to: Number = 0; try { - array = FastFilterSpeciesCreate(o) otherwise SlowSpeciesCreate; + output = FastFilterSpeciesCreate(o) otherwise SlowSpeciesCreate; try { - return FastArrayFilter(o, len, callbackfn, thisArg, array) + const smiLen: Smi = Cast<Smi>(len) otherwise goto Bailout(k, to); + const fastOutput = + Cast<FastJSArray>(output) otherwise goto Bailout(k, to); + const fastO = Cast<FastJSArray>(o) otherwise goto Bailout(k, to); + + FastArrayFilter(fastO, smiLen, callbackfn, thisArg, fastOutput) otherwise Bailout; + return output; } - label Bailout(kValue: Smi, toValue: Smi) deferred { + label Bailout(kValue: Number, toValue: Number) deferred { k = kValue; to = toValue; } } label SlowSpeciesCreate { - array = ArraySpeciesCreate(context, receiver, 0); + output = ArraySpeciesCreate(context, receiver, 0); } return ArrayFilterLoopContinuation( - o, callbackfn, thisArg, array, o, k, len, to); + o, callbackfn, thisArg, output, o, k, len, to); } label TypeError deferred { - ThrowTypeError(context, kCalledNonCallable, arguments[0]); + ThrowTypeError(kCalledNonCallable, arguments[0]); } label NullOrUndefinedError deferred { - ThrowTypeError( - context, kCalledOnNullOrUndefined, 'Array.prototype.filter'); + ThrowTypeError(kCalledOnNullOrUndefined, 'Array.prototype.filter'); } } } |