843b6646b1
This is a reland of 2b0ac2fb9f
The layout test that caused this revert was fixed with:
https://crrev.com/c/1627386
Original change's description:
> [array] Move Array#sort pre-processing to Torque
>
> This CL removes the "PrepareElementsForSort" runtime function, and
> replaces it with a simpler version in Torque. The biggest difference
> is that certain sparse configurations no longer have a fast-path.
>
> The Torque pre-processing step replaces the existing Torque mechanism that
> copied already pre-processed elements into the "work" FixedArray. The Torque
> compacting works as follows:
> - Iterate all elements from 0 to {length}
> - If the element is the hole: Do nothing.
> - If the element is "undefined": Increment undefined counter.
> - In all other cases, push the element into the "work" FixedArray.
>
> Then the "work" FixedArray is sorted as before. Writing the elements from
> the "work" array back into the receiver, after sorting, has three steps:
> 1. Copy the sorted elements from the "work" FixedArray to the receiver.
> 2. Add previously counted number of "undefined" to the receiver.
> 3. Depending on the backing store either delete properties or
> set them to the Hole up to {length}.
>
> Bug: v8:8714
> Change-Id: I14eccb7cfd2e4618bce2a85cba0689d7e0380ad2
> Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1619756
> Commit-Queue: Simon Zünd <szuend@chromium.org>
> Reviewed-by: Tobias Tebbi <tebbi@chromium.org>
> Reviewed-by: Jakob Gruber <jgruber@chromium.org>
> Cr-Commit-Position: refs/heads/master@{#61812}
TBR: jgruber@chromium.org
Bug: v8:8714
Change-Id: If7613f6e5f37c5e0d649e8192195594bc6c32100
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1627977
Commit-Queue: Simon Zünd <szuend@chromium.org>
Auto-Submit: Simon Zünd <szuend@chromium.org>
Reviewed-by: Tobias Tebbi <tebbi@chromium.org>
Cr-Commit-Position: refs/heads/master@{#61827}
142 lines
3.6 KiB
JavaScript
142 lines
3.6 KiB
JavaScript
// Copyright 2018 the V8 project authors. All rights reserved.
|
|
// Use of this source code is governed by a BSD-style license that can be
|
|
// found in the LICENSE file.
|
|
|
|
const kArraySize = 4000;
|
|
let template_array = [];
|
|
|
|
for (let i = 0; i < kArraySize; ++i) {
|
|
template_array[i] = Math.floor(Math.random() * kArraySize);
|
|
}
|
|
|
|
let array_to_sort = [];
|
|
|
|
function AssertPackedSmiElements() {
|
|
assert(%HasFastPackedElements(array_to_sort) &&
|
|
%HasSmiElements(array_to_sort),
|
|
"Element kind is not PACKED_SMI_ELEMENTS");
|
|
}
|
|
|
|
function AssertPackedDoubleElements() {
|
|
assert(%HasFastPackedElements(array_to_sort) &&
|
|
%HasDoubleElements(array_to_sort),
|
|
"Element kind is not PACKED_DOUBLE_ELEMENTS");
|
|
}
|
|
|
|
function AssertPackedObjectElements() {
|
|
assert(%HasFastPackedElements(array_to_sort) &&
|
|
%HasObjectElements(array_to_sort),
|
|
"Element kind is not PACKED_ELEMENTS");
|
|
}
|
|
|
|
function AssertHoleySmiElements() {
|
|
assert(%HasHoleyElements(array_to_sort) &&
|
|
%HasSmiElements(array_to_sort),
|
|
"Element kind is not HOLEY_SMI_ELEMENTS");
|
|
}
|
|
|
|
function AssertHoleyDoubleElements() {
|
|
assert(%HasHoleyElements(array_to_sort) &&
|
|
%HasDoubleElements(array_to_sort),
|
|
"Element kind is not HOLEY_DOUBLE_ELEMENTS");
|
|
}
|
|
|
|
function AssertHoleyObjectElements() {
|
|
assert(%HasHoleyElements(array_to_sort) &&
|
|
%HasObjectElements(array_to_sort),
|
|
"Element kind is not HOLEY_ELEMENTS");
|
|
}
|
|
|
|
function AssertDictionaryElements() {
|
|
assert(%HasDictionaryElements(array_to_sort),
|
|
"Element kind is not DICTIONARY_ELEMENTS");
|
|
}
|
|
|
|
function CreatePackedSmiArray() {
|
|
array_to_sort = Array.from(template_array);
|
|
AssertPackedSmiElements();
|
|
}
|
|
|
|
function CreatePackedDoubleArray() {
|
|
array_to_sort = Array.from(template_array, (x,_) => x + 0.1);
|
|
AssertPackedDoubleElements();
|
|
}
|
|
|
|
function CreatePackedObjectArray() {
|
|
array_to_sort = Array.from(template_array, (x,_) => `value ${x}`);
|
|
AssertPackedObjectElements();
|
|
}
|
|
|
|
function CreateHoleySmiArray() {
|
|
array_to_sort = Array.from(template_array);
|
|
delete array_to_sort[0];
|
|
AssertHoleySmiElements();
|
|
}
|
|
|
|
function CreateHoleyDoubleArray() {
|
|
array_to_sort = new Array(kArraySize);
|
|
for (let i = 0; i < kArraySize; ++i) {
|
|
array_to_sort[i] = template_array[i] + 0.1;
|
|
}
|
|
|
|
AssertHoleyDoubleElements();
|
|
}
|
|
|
|
function CreateHoleyObjectArray() {
|
|
array_to_sort = new Array(kArraySize);
|
|
for (let i = 0; i < kArraySize; ++i) {
|
|
array_to_sort[i] = `value ${template_array[i]}`;
|
|
}
|
|
|
|
AssertHoleyObjectElements();
|
|
}
|
|
|
|
function CreateDictionaryArray() {
|
|
array_to_sort = Array.from(template_array);
|
|
Object.defineProperty(array_to_sort, kArraySize - 2,
|
|
{ get: () => this.foo,
|
|
set: (v) => this.foo = v });
|
|
|
|
AssertDictionaryElements();
|
|
}
|
|
|
|
function Sort() {
|
|
array_to_sort.sort();
|
|
}
|
|
|
|
function CreateSortFn(comparefns = []) {
|
|
return () => {
|
|
for (let cmpfn of comparefns) {
|
|
array_to_sort.sort(cmpfn);
|
|
}
|
|
}
|
|
}
|
|
|
|
function cmp_smaller(a, b) {
|
|
if (a < b) return -1;
|
|
if (b < a) return 1;
|
|
return 0;
|
|
}
|
|
|
|
function cmp_greater(a, b) { return cmp_smaller(b, a); }
|
|
|
|
// The counter is used in some benchmarks to trigger actions during sorting.
|
|
// To keep benchmarks deterministic, the counter needs to be reset for each
|
|
// iteration.
|
|
let counter = 0;
|
|
|
|
// Sorting benchmarks need to execute setup and tearDown for each iteration.
|
|
// Otherwise the benchmarks would mainly measure sorting already sorted arrays
|
|
// which, depending on the strategy, is either the worst- or best case.
|
|
function createSortSuite(name, reference, run, setup, tearDown = () => {}) {
|
|
let run_fn = () => {
|
|
counter = 0;
|
|
|
|
setup();
|
|
run();
|
|
tearDown();
|
|
};
|
|
|
|
return createSuite(name, reference, run_fn);
|
|
}
|