v8/test/mjsunit/compiler/array-push-2.js
Benedikt Meurer 68e4d86c6e [turbofan] Inline multi-parameter Array#push.
TurboFan wasn't able to inline calls to Array.prototype.push which
didn't have exactly one parameter. This was a rather artifical
limitation and was mostly due to the way the MaybeGrowFastElements
operator was implemented (which was not ideal by itself). Refactoring
this a bit, allows us to inline the operation in general, independent
of the number of values to push.

Array#push with multiple parameters is used quite a lot inside Ember (as
discovered by Apple, i.e. https://bugs.webkit.org/show_bug.cgi?id=175823)
and is also dominating the Six-Speed/SpreadLiterals/ES5 benchmark (see
https://twitter.com/SpiderMonkeyJS/status/906528938452832257 from the
SpiderMonkey folks). The micro-benchmark mentioned in the tracking bug
(v8:6808) improves from

  arrayPush0: 2422 ms.
  arrayPush1: 2567 ms.
  arrayPush2: 4092 ms.
  arrayPush3: 4308 ms.

to

  arrayPush0: 798 ms.
  arrayPush1: 2563 ms.
  arrayPush2: 2623 ms.
  arrayPush3: 2773 ms.

with this change, effectively removing the odd 50-60% performance
cliff that was associated with going from one parameter to two or
more.

Bug: v8:2229, v8:6808
Change-Id: Iffe4c1233903c04c3dc2062aad39d99769c8ab57
Reviewed-on: https://chromium-review.googlesource.com/657582
Reviewed-by: Jaroslav Sevcik <jarin@chromium.org>
Commit-Queue: Benedikt Meurer <bmeurer@chromium.org>
Cr-Commit-Position: refs/heads/master@{#47940}
2017-09-11 10:52:29 +00:00

66 lines
1.5 KiB
JavaScript

// Copyright 2017 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.
// Flags: --allow-natives-syntax --opt
// Test elements transition from SMI to DOUBLE.
(function() {
const a = [];
const foo = (x, y) => a.push(x, y);
foo(1, 2);
foo(3, 4);
%OptimizeFunctionOnNextCall(foo);
foo(5, 6.6);
assertEquals([1, 2, 3, 4, 5, 6.6], a);
})();
(function() {
const a = [];
const foo = (x, y) => a.push(x, y);
foo(1, 2);
foo(3, 4);
%OptimizeFunctionOnNextCall(foo);
foo(5.5, 6.6);
assertEquals([1, 2, 3, 4, 5.5, 6.6], a);
})();
// Test elements transition from SMI to OBJECT.
(function() {
const a = [];
const foo = (x, y) => a.push(x, y);
foo(1, 2);
foo(3, 4);
%OptimizeFunctionOnNextCall(foo);
foo(5, '6');
assertEquals([1, 2, 3, 4, 5, '6'], a);
})();
(function() {
const a = [];
const foo = (x, y) => a.push(x, y);
foo(1, 2);
foo(3, 4);
%OptimizeFunctionOnNextCall(foo);
foo('5', '6');
assertEquals([1, 2, 3, 4, '5', '6'], a);
})();
// Test elements transition from DOUBLE to OBJECT.
(function() {
const a = [0.5];
const foo = (x, y) => a.push(x, y);
foo(1, 2);
foo(3, 4);
%OptimizeFunctionOnNextCall(foo);
foo(5, '6');
assertEquals([0.5, 1, 2, 3, 4, 5, '6'], a);
})();
(function() {
const a = [0.5];
const foo = (x, y) => a.push(x, y);
foo(1, 2);
foo(3, 4);
%OptimizeFunctionOnNextCall(foo);
foo('5', '6');
assertEquals([0.5, 1, 2, 3, 4, '5', '6'], a);
})();