0c296cb229
This change introduces the necessary conversion operators to convert from Word64 to other representations (Tagged, Word32, Float64, etc.), and plugs in the Word64 representation for NumberAdd/NumberSubtract, such that TurboFan will go to Int64Add/Sub on 64-bit architectures when the inputs and the output of the operation is in safe integer range. This includes the necessary changes to the Deoptimizer to be able to rematerialize Int64 values as Smi/HeapNumber when going back to Ignition later. This change might affect performance, although measurements indicate that there should be no noticable performance impact. The goal is to have TurboFan support Word64 representation to a degree that changing the TypedArray length to an uint64_t (for 64-bit archs) becomes viable and doesn't have any negative performance implications. Independent of that we might get performance improvements in other areas such as for crypto code later. Bug: v8:4153, v8:7881, v8:8171, v8:8178 Design-Document: bit.ly/turbofan-word64 Change-Id: I29d56e2a31c1bae61d04a89d29ea73f21fd49c59 Cq-Include-Trybots: luci.chromium.try:linux_chromium_headless_rel Reviewed-on: https://chromium-review.googlesource.com/1225709 Commit-Queue: Benedikt Meurer <bmeurer@chromium.org> Reviewed-by: Jaroslav Sevcik <jarin@chromium.org> Cr-Commit-Position: refs/heads/master@{#55937}
92 lines
2.4 KiB
JavaScript
92 lines
2.4 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.
|
|
|
|
// Flags: --allow-natives-syntax
|
|
|
|
// Test NumberAdd with PositiveSafeInteger -> PositiveSafeInteger (as Tagged).
|
|
(function() {
|
|
function foo(x) {
|
|
const i = x ? 0xFFFFFFFF : 0;
|
|
return i + 1;
|
|
}
|
|
|
|
assertEquals(0x000000001, foo(false));
|
|
assertEquals(0x000000001, foo(false));
|
|
assertEquals(0x100000000, foo(true));
|
|
assertEquals(0x100000000, foo(true));
|
|
%OptimizeFunctionOnNextCall(foo);
|
|
assertEquals(0x000000001, foo(false));
|
|
assertEquals(0x100000000, foo(true));
|
|
})();
|
|
|
|
// Test NumberAdd with SafeInteger -> SafeInteger (as Tagged).
|
|
(function() {
|
|
function foo(x) {
|
|
const i = x ? 0xFFFFFFFF : -1;
|
|
return i + 1;
|
|
}
|
|
|
|
assertEquals(0x000000000, foo(false));
|
|
assertEquals(0x000000000, foo(false));
|
|
assertEquals(0x100000000, foo(true));
|
|
assertEquals(0x100000000, foo(true));
|
|
%OptimizeFunctionOnNextCall(foo);
|
|
assertEquals(0x000000000, foo(false));
|
|
assertEquals(0x100000000, foo(true));
|
|
})();
|
|
|
|
// NumberAdd: Smi x Unsigned32 -> SafeInteger (as Float64).
|
|
(function() {
|
|
const a = new Float64Array(1);
|
|
|
|
function foo(o) {
|
|
a[0] = o.x + 0xFFFFFFFF;
|
|
return a[0];
|
|
}
|
|
|
|
assertEquals(0x0FFFFFFFF, foo({x:0}));
|
|
assertEquals(0x100000000, foo({x:1}));
|
|
%OptimizeFunctionOnNextCall(foo);
|
|
assertEquals(0x100000000, foo({x:1}));
|
|
})();
|
|
|
|
// NumberAdd: Smi x Unsigned32 -> SafeInteger (as TaggedSigned).
|
|
(function() {
|
|
function foo(o) {
|
|
return {x: Math.floor((o.x + 11123456789) + -11123456788)}.x;
|
|
}
|
|
|
|
assertEquals(1, foo({x:0}));
|
|
assertEquals(2, foo({x:1}));
|
|
%OptimizeFunctionOnNextCall(foo);
|
|
assertEquals(2, foo({x:1}));
|
|
})();
|
|
|
|
// NumberSubtract: Unsigned32 x Unsigned32 -> SafeInteger (as Word32).
|
|
(function() {
|
|
function foo(a, i) {
|
|
i = ((i >>> 0)) - 0xFFFFFFFF;
|
|
return a[i];
|
|
}
|
|
|
|
assertEquals(1, foo([1], 0xFFFFFFFF));
|
|
assertEquals(2, foo([2], 0xFFFFFFFF));
|
|
%OptimizeFunctionOnNextCall(foo);
|
|
assertEquals(3, foo([3], 0xFFFFFFFF));
|
|
})();
|
|
|
|
// Test that the Deoptimizer can handle Word64 properly.
|
|
(function() {
|
|
function foo(b) {
|
|
const i = ((b >>> 0)) - 0xFFFFFFFF;
|
|
%DeoptimizeFunction(foo);
|
|
return i;
|
|
}
|
|
|
|
assertEquals(0, foo(0xFFFFFFFF));
|
|
assertEquals(0, foo(0xFFFFFFFF));
|
|
%OptimizeFunctionOnNextCall(foo);
|
|
assertEquals(0, foo(0xFFFFFFFF));
|
|
})();
|