v8/test/mjsunit/compiler/context-sensitivity.js

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

578 lines
13 KiB
JavaScript
Raw Normal View History

[turbofan] Introduce the notion of context-sensitivity for JS operators. This change adds predicates to check whether a given JavaScript operator needs the "current context" or if any surrounding context (including the "native context") does it. For example JSAdd doesn't ever need the current context, but actually only the native context. In the BytecodeGraphBuilder we use this predicate to check whether a given operator needs the current context, and if not, we just pass in the native context. Doing so we improve the performance on the benchmarks given in the tracking bug significantly, and go from something around arrayMap: 476 ms. arrayFilter: 312 ms. arrayEvery: 241 ms. arraySome: 152 ms. to arrayMap: 377 ms. arrayFilter: 296 ms. arrayEvery: 191 ms. arraySome: 91 ms. which is an up to 40% improvement. So for idiomatic modern JavaScript which uses higher order functions quite a lot, not just the builtins provided by the JSVM, this is going to improve peak performance noticably. This also makes it possible to completely eliminate all the allocations in the aliased sloppy arguments example ```js function foo(a) { return arguments.length; } ``` concretely we don't allocate the function context anymore and we also don't allocate the arguments object anymore (the JSStackCheck was the reason why we did this in the past, because it was holding on to the current context, which also kept the allocation for the arguments alive). Bug: v8:6200, v8:8060 Change-Id: I1db56d00d6b510ce6337608c0fff16af96e95eef Design-Document: bit.ly/v8-turbofan-context-sensitive-js-operators Reviewed-on: https://chromium-review.googlesource.com/c/1267176 Reviewed-by: Georg Neis <neis@chromium.org> Commit-Queue: Benedikt Meurer <bmeurer@chromium.org> Cr-Commit-Position: refs/heads/master@{#56441}
2018-10-08 10:53:18 +00:00
// 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
const object1 = {[Symbol.toPrimitive]() { return 1; }};
const thrower = {[Symbol.toPrimitive]() { throw new Error(); }};
// Test that JSAdd is not context-sensitive.
(function() {
function bar(fn) {
return fn(1);
}
function foo(x) {
return bar(y => y + x);
}
%PrepareFunctionForOptimization(foo);
[turbofan] Introduce the notion of context-sensitivity for JS operators. This change adds predicates to check whether a given JavaScript operator needs the "current context" or if any surrounding context (including the "native context") does it. For example JSAdd doesn't ever need the current context, but actually only the native context. In the BytecodeGraphBuilder we use this predicate to check whether a given operator needs the current context, and if not, we just pass in the native context. Doing so we improve the performance on the benchmarks given in the tracking bug significantly, and go from something around arrayMap: 476 ms. arrayFilter: 312 ms. arrayEvery: 241 ms. arraySome: 152 ms. to arrayMap: 377 ms. arrayFilter: 296 ms. arrayEvery: 191 ms. arraySome: 91 ms. which is an up to 40% improvement. So for idiomatic modern JavaScript which uses higher order functions quite a lot, not just the builtins provided by the JSVM, this is going to improve peak performance noticably. This also makes it possible to completely eliminate all the allocations in the aliased sloppy arguments example ```js function foo(a) { return arguments.length; } ``` concretely we don't allocate the function context anymore and we also don't allocate the arguments object anymore (the JSStackCheck was the reason why we did this in the past, because it was holding on to the current context, which also kept the allocation for the arguments alive). Bug: v8:6200, v8:8060 Change-Id: I1db56d00d6b510ce6337608c0fff16af96e95eef Design-Document: bit.ly/v8-turbofan-context-sensitive-js-operators Reviewed-on: https://chromium-review.googlesource.com/c/1267176 Reviewed-by: Georg Neis <neis@chromium.org> Commit-Queue: Benedikt Meurer <bmeurer@chromium.org> Cr-Commit-Position: refs/heads/master@{#56441}
2018-10-08 10:53:18 +00:00
assertEquals(1, foo(0));
assertEquals(2, foo(object1));
assertThrows(() => foo(thrower));
%OptimizeFunctionOnNextCall(foo);
assertEquals(1, foo(0));
assertEquals(2, foo(object1));
assertThrows(() => foo(thrower));
})();
// Test that JSSubtract is not context-sensitive.
(function() {
function bar(fn) {
return fn(1);
}
function foo(x) {
return bar(y => y - x);
}
%PrepareFunctionForOptimization(foo);
[turbofan] Introduce the notion of context-sensitivity for JS operators. This change adds predicates to check whether a given JavaScript operator needs the "current context" or if any surrounding context (including the "native context") does it. For example JSAdd doesn't ever need the current context, but actually only the native context. In the BytecodeGraphBuilder we use this predicate to check whether a given operator needs the current context, and if not, we just pass in the native context. Doing so we improve the performance on the benchmarks given in the tracking bug significantly, and go from something around arrayMap: 476 ms. arrayFilter: 312 ms. arrayEvery: 241 ms. arraySome: 152 ms. to arrayMap: 377 ms. arrayFilter: 296 ms. arrayEvery: 191 ms. arraySome: 91 ms. which is an up to 40% improvement. So for idiomatic modern JavaScript which uses higher order functions quite a lot, not just the builtins provided by the JSVM, this is going to improve peak performance noticably. This also makes it possible to completely eliminate all the allocations in the aliased sloppy arguments example ```js function foo(a) { return arguments.length; } ``` concretely we don't allocate the function context anymore and we also don't allocate the arguments object anymore (the JSStackCheck was the reason why we did this in the past, because it was holding on to the current context, which also kept the allocation for the arguments alive). Bug: v8:6200, v8:8060 Change-Id: I1db56d00d6b510ce6337608c0fff16af96e95eef Design-Document: bit.ly/v8-turbofan-context-sensitive-js-operators Reviewed-on: https://chromium-review.googlesource.com/c/1267176 Reviewed-by: Georg Neis <neis@chromium.org> Commit-Queue: Benedikt Meurer <bmeurer@chromium.org> Cr-Commit-Position: refs/heads/master@{#56441}
2018-10-08 10:53:18 +00:00
assertEquals(1, foo(0));
assertEquals(0, foo(object1));
assertThrows(() => foo(thrower));
%OptimizeFunctionOnNextCall(foo);
assertEquals(1, foo(0));
assertEquals(0, foo(object1));
assertThrows(() => foo(thrower));
})();
// Test that JSMultiply is not context-sensitive.
(function() {
function bar(fn) {
return fn(1);
}
function foo(x) {
return bar(y => y * x);
}
%PrepareFunctionForOptimization(foo);
[turbofan] Introduce the notion of context-sensitivity for JS operators. This change adds predicates to check whether a given JavaScript operator needs the "current context" or if any surrounding context (including the "native context") does it. For example JSAdd doesn't ever need the current context, but actually only the native context. In the BytecodeGraphBuilder we use this predicate to check whether a given operator needs the current context, and if not, we just pass in the native context. Doing so we improve the performance on the benchmarks given in the tracking bug significantly, and go from something around arrayMap: 476 ms. arrayFilter: 312 ms. arrayEvery: 241 ms. arraySome: 152 ms. to arrayMap: 377 ms. arrayFilter: 296 ms. arrayEvery: 191 ms. arraySome: 91 ms. which is an up to 40% improvement. So for idiomatic modern JavaScript which uses higher order functions quite a lot, not just the builtins provided by the JSVM, this is going to improve peak performance noticably. This also makes it possible to completely eliminate all the allocations in the aliased sloppy arguments example ```js function foo(a) { return arguments.length; } ``` concretely we don't allocate the function context anymore and we also don't allocate the arguments object anymore (the JSStackCheck was the reason why we did this in the past, because it was holding on to the current context, which also kept the allocation for the arguments alive). Bug: v8:6200, v8:8060 Change-Id: I1db56d00d6b510ce6337608c0fff16af96e95eef Design-Document: bit.ly/v8-turbofan-context-sensitive-js-operators Reviewed-on: https://chromium-review.googlesource.com/c/1267176 Reviewed-by: Georg Neis <neis@chromium.org> Commit-Queue: Benedikt Meurer <bmeurer@chromium.org> Cr-Commit-Position: refs/heads/master@{#56441}
2018-10-08 10:53:18 +00:00
assertEquals(1, foo(1));
assertEquals(1, foo(object1));
assertThrows(() => foo(thrower));
%OptimizeFunctionOnNextCall(foo);
assertEquals(1, foo(1));
assertEquals(1, foo(object1));
assertThrows(() => foo(thrower));
})();
// Test that JSDivide is not context-sensitive.
(function() {
function bar(fn) {
return fn(1);
}
function foo(x) {
return bar(y => y / x);
}
%PrepareFunctionForOptimization(foo);
[turbofan] Introduce the notion of context-sensitivity for JS operators. This change adds predicates to check whether a given JavaScript operator needs the "current context" or if any surrounding context (including the "native context") does it. For example JSAdd doesn't ever need the current context, but actually only the native context. In the BytecodeGraphBuilder we use this predicate to check whether a given operator needs the current context, and if not, we just pass in the native context. Doing so we improve the performance on the benchmarks given in the tracking bug significantly, and go from something around arrayMap: 476 ms. arrayFilter: 312 ms. arrayEvery: 241 ms. arraySome: 152 ms. to arrayMap: 377 ms. arrayFilter: 296 ms. arrayEvery: 191 ms. arraySome: 91 ms. which is an up to 40% improvement. So for idiomatic modern JavaScript which uses higher order functions quite a lot, not just the builtins provided by the JSVM, this is going to improve peak performance noticably. This also makes it possible to completely eliminate all the allocations in the aliased sloppy arguments example ```js function foo(a) { return arguments.length; } ``` concretely we don't allocate the function context anymore and we also don't allocate the arguments object anymore (the JSStackCheck was the reason why we did this in the past, because it was holding on to the current context, which also kept the allocation for the arguments alive). Bug: v8:6200, v8:8060 Change-Id: I1db56d00d6b510ce6337608c0fff16af96e95eef Design-Document: bit.ly/v8-turbofan-context-sensitive-js-operators Reviewed-on: https://chromium-review.googlesource.com/c/1267176 Reviewed-by: Georg Neis <neis@chromium.org> Commit-Queue: Benedikt Meurer <bmeurer@chromium.org> Cr-Commit-Position: refs/heads/master@{#56441}
2018-10-08 10:53:18 +00:00
assertEquals(1, foo(1));
assertEquals(1, foo(object1));
assertThrows(() => foo(thrower));
%OptimizeFunctionOnNextCall(foo);
assertEquals(1, foo(1));
assertEquals(1, foo(object1));
assertThrows(() => foo(thrower));
})();
// Test that JSModulus is not context-sensitive.
(function() {
function bar(fn) {
return fn(1);
}
function foo(x) {
return bar(y => y % x);
}
%PrepareFunctionForOptimization(foo);
[turbofan] Introduce the notion of context-sensitivity for JS operators. This change adds predicates to check whether a given JavaScript operator needs the "current context" or if any surrounding context (including the "native context") does it. For example JSAdd doesn't ever need the current context, but actually only the native context. In the BytecodeGraphBuilder we use this predicate to check whether a given operator needs the current context, and if not, we just pass in the native context. Doing so we improve the performance on the benchmarks given in the tracking bug significantly, and go from something around arrayMap: 476 ms. arrayFilter: 312 ms. arrayEvery: 241 ms. arraySome: 152 ms. to arrayMap: 377 ms. arrayFilter: 296 ms. arrayEvery: 191 ms. arraySome: 91 ms. which is an up to 40% improvement. So for idiomatic modern JavaScript which uses higher order functions quite a lot, not just the builtins provided by the JSVM, this is going to improve peak performance noticably. This also makes it possible to completely eliminate all the allocations in the aliased sloppy arguments example ```js function foo(a) { return arguments.length; } ``` concretely we don't allocate the function context anymore and we also don't allocate the arguments object anymore (the JSStackCheck was the reason why we did this in the past, because it was holding on to the current context, which also kept the allocation for the arguments alive). Bug: v8:6200, v8:8060 Change-Id: I1db56d00d6b510ce6337608c0fff16af96e95eef Design-Document: bit.ly/v8-turbofan-context-sensitive-js-operators Reviewed-on: https://chromium-review.googlesource.com/c/1267176 Reviewed-by: Georg Neis <neis@chromium.org> Commit-Queue: Benedikt Meurer <bmeurer@chromium.org> Cr-Commit-Position: refs/heads/master@{#56441}
2018-10-08 10:53:18 +00:00
assertEquals(0, foo(1));
assertEquals(0, foo(object1));
assertThrows(() => foo(thrower));
%OptimizeFunctionOnNextCall(foo);
assertEquals(0, foo(1));
assertEquals(0, foo(object1));
assertThrows(() => foo(thrower));
})();
// Test that JSExponentiate is not context-sensitive.
(function() {
function bar(fn) {
return fn(1);
}
function foo(x) {
return bar(y => y ** x);
}
%PrepareFunctionForOptimization(foo);
[turbofan] Introduce the notion of context-sensitivity for JS operators. This change adds predicates to check whether a given JavaScript operator needs the "current context" or if any surrounding context (including the "native context") does it. For example JSAdd doesn't ever need the current context, but actually only the native context. In the BytecodeGraphBuilder we use this predicate to check whether a given operator needs the current context, and if not, we just pass in the native context. Doing so we improve the performance on the benchmarks given in the tracking bug significantly, and go from something around arrayMap: 476 ms. arrayFilter: 312 ms. arrayEvery: 241 ms. arraySome: 152 ms. to arrayMap: 377 ms. arrayFilter: 296 ms. arrayEvery: 191 ms. arraySome: 91 ms. which is an up to 40% improvement. So for idiomatic modern JavaScript which uses higher order functions quite a lot, not just the builtins provided by the JSVM, this is going to improve peak performance noticably. This also makes it possible to completely eliminate all the allocations in the aliased sloppy arguments example ```js function foo(a) { return arguments.length; } ``` concretely we don't allocate the function context anymore and we also don't allocate the arguments object anymore (the JSStackCheck was the reason why we did this in the past, because it was holding on to the current context, which also kept the allocation for the arguments alive). Bug: v8:6200, v8:8060 Change-Id: I1db56d00d6b510ce6337608c0fff16af96e95eef Design-Document: bit.ly/v8-turbofan-context-sensitive-js-operators Reviewed-on: https://chromium-review.googlesource.com/c/1267176 Reviewed-by: Georg Neis <neis@chromium.org> Commit-Queue: Benedikt Meurer <bmeurer@chromium.org> Cr-Commit-Position: refs/heads/master@{#56441}
2018-10-08 10:53:18 +00:00
assertEquals(1, foo(1));
assertEquals(1, foo(object1));
assertThrows(() => foo(thrower));
%OptimizeFunctionOnNextCall(foo);
assertEquals(1, foo(1));
assertEquals(1, foo(object1));
assertThrows(() => foo(thrower));
})();
// Test that JSBitwiseOr is not context-sensitive.
(function() {
function bar(fn) {
return fn(1);
}
function foo(x) {
return bar(y => y | x);
}
%PrepareFunctionForOptimization(foo);
[turbofan] Introduce the notion of context-sensitivity for JS operators. This change adds predicates to check whether a given JavaScript operator needs the "current context" or if any surrounding context (including the "native context") does it. For example JSAdd doesn't ever need the current context, but actually only the native context. In the BytecodeGraphBuilder we use this predicate to check whether a given operator needs the current context, and if not, we just pass in the native context. Doing so we improve the performance on the benchmarks given in the tracking bug significantly, and go from something around arrayMap: 476 ms. arrayFilter: 312 ms. arrayEvery: 241 ms. arraySome: 152 ms. to arrayMap: 377 ms. arrayFilter: 296 ms. arrayEvery: 191 ms. arraySome: 91 ms. which is an up to 40% improvement. So for idiomatic modern JavaScript which uses higher order functions quite a lot, not just the builtins provided by the JSVM, this is going to improve peak performance noticably. This also makes it possible to completely eliminate all the allocations in the aliased sloppy arguments example ```js function foo(a) { return arguments.length; } ``` concretely we don't allocate the function context anymore and we also don't allocate the arguments object anymore (the JSStackCheck was the reason why we did this in the past, because it was holding on to the current context, which also kept the allocation for the arguments alive). Bug: v8:6200, v8:8060 Change-Id: I1db56d00d6b510ce6337608c0fff16af96e95eef Design-Document: bit.ly/v8-turbofan-context-sensitive-js-operators Reviewed-on: https://chromium-review.googlesource.com/c/1267176 Reviewed-by: Georg Neis <neis@chromium.org> Commit-Queue: Benedikt Meurer <bmeurer@chromium.org> Cr-Commit-Position: refs/heads/master@{#56441}
2018-10-08 10:53:18 +00:00
assertEquals(1, foo(1));
assertEquals(1, foo(object1));
assertThrows(() => foo(thrower));
%OptimizeFunctionOnNextCall(foo);
assertEquals(1, foo(1));
assertEquals(1, foo(object1));
assertThrows(() => foo(thrower));
})();
// Test that JSBitwiseAnd is not context-sensitive.
(function() {
function bar(fn) {
return fn(1);
}
function foo(x) {
return bar(y => y & x);
}
%PrepareFunctionForOptimization(foo);
[turbofan] Introduce the notion of context-sensitivity for JS operators. This change adds predicates to check whether a given JavaScript operator needs the "current context" or if any surrounding context (including the "native context") does it. For example JSAdd doesn't ever need the current context, but actually only the native context. In the BytecodeGraphBuilder we use this predicate to check whether a given operator needs the current context, and if not, we just pass in the native context. Doing so we improve the performance on the benchmarks given in the tracking bug significantly, and go from something around arrayMap: 476 ms. arrayFilter: 312 ms. arrayEvery: 241 ms. arraySome: 152 ms. to arrayMap: 377 ms. arrayFilter: 296 ms. arrayEvery: 191 ms. arraySome: 91 ms. which is an up to 40% improvement. So for idiomatic modern JavaScript which uses higher order functions quite a lot, not just the builtins provided by the JSVM, this is going to improve peak performance noticably. This also makes it possible to completely eliminate all the allocations in the aliased sloppy arguments example ```js function foo(a) { return arguments.length; } ``` concretely we don't allocate the function context anymore and we also don't allocate the arguments object anymore (the JSStackCheck was the reason why we did this in the past, because it was holding on to the current context, which also kept the allocation for the arguments alive). Bug: v8:6200, v8:8060 Change-Id: I1db56d00d6b510ce6337608c0fff16af96e95eef Design-Document: bit.ly/v8-turbofan-context-sensitive-js-operators Reviewed-on: https://chromium-review.googlesource.com/c/1267176 Reviewed-by: Georg Neis <neis@chromium.org> Commit-Queue: Benedikt Meurer <bmeurer@chromium.org> Cr-Commit-Position: refs/heads/master@{#56441}
2018-10-08 10:53:18 +00:00
assertEquals(1, foo(1));
assertEquals(1, foo(object1));
assertThrows(() => foo(thrower));
%OptimizeFunctionOnNextCall(foo);
assertEquals(1, foo(1));
assertEquals(1, foo(object1));
assertThrows(() => foo(thrower));
})();
// Test that JSBitwiseXor is not context-sensitive.
(function() {
function bar(fn) {
return fn(1);
}
function foo(x) {
return bar(y => y ^ x);
}
%PrepareFunctionForOptimization(foo);
[turbofan] Introduce the notion of context-sensitivity for JS operators. This change adds predicates to check whether a given JavaScript operator needs the "current context" or if any surrounding context (including the "native context") does it. For example JSAdd doesn't ever need the current context, but actually only the native context. In the BytecodeGraphBuilder we use this predicate to check whether a given operator needs the current context, and if not, we just pass in the native context. Doing so we improve the performance on the benchmarks given in the tracking bug significantly, and go from something around arrayMap: 476 ms. arrayFilter: 312 ms. arrayEvery: 241 ms. arraySome: 152 ms. to arrayMap: 377 ms. arrayFilter: 296 ms. arrayEvery: 191 ms. arraySome: 91 ms. which is an up to 40% improvement. So for idiomatic modern JavaScript which uses higher order functions quite a lot, not just the builtins provided by the JSVM, this is going to improve peak performance noticably. This also makes it possible to completely eliminate all the allocations in the aliased sloppy arguments example ```js function foo(a) { return arguments.length; } ``` concretely we don't allocate the function context anymore and we also don't allocate the arguments object anymore (the JSStackCheck was the reason why we did this in the past, because it was holding on to the current context, which also kept the allocation for the arguments alive). Bug: v8:6200, v8:8060 Change-Id: I1db56d00d6b510ce6337608c0fff16af96e95eef Design-Document: bit.ly/v8-turbofan-context-sensitive-js-operators Reviewed-on: https://chromium-review.googlesource.com/c/1267176 Reviewed-by: Georg Neis <neis@chromium.org> Commit-Queue: Benedikt Meurer <bmeurer@chromium.org> Cr-Commit-Position: refs/heads/master@{#56441}
2018-10-08 10:53:18 +00:00
assertEquals(0, foo(1));
assertEquals(0, foo(object1));
assertThrows(() => foo(thrower));
%OptimizeFunctionOnNextCall(foo);
assertEquals(0, foo(1));
assertEquals(0, foo(object1));
assertThrows(() => foo(thrower));
})();
// Test that JSShiftLeft is not context-sensitive.
(function() {
function bar(fn) {
return fn(1);
}
function foo(x) {
return bar(y => y << x);
}
%PrepareFunctionForOptimization(foo);
[turbofan] Introduce the notion of context-sensitivity for JS operators. This change adds predicates to check whether a given JavaScript operator needs the "current context" or if any surrounding context (including the "native context") does it. For example JSAdd doesn't ever need the current context, but actually only the native context. In the BytecodeGraphBuilder we use this predicate to check whether a given operator needs the current context, and if not, we just pass in the native context. Doing so we improve the performance on the benchmarks given in the tracking bug significantly, and go from something around arrayMap: 476 ms. arrayFilter: 312 ms. arrayEvery: 241 ms. arraySome: 152 ms. to arrayMap: 377 ms. arrayFilter: 296 ms. arrayEvery: 191 ms. arraySome: 91 ms. which is an up to 40% improvement. So for idiomatic modern JavaScript which uses higher order functions quite a lot, not just the builtins provided by the JSVM, this is going to improve peak performance noticably. This also makes it possible to completely eliminate all the allocations in the aliased sloppy arguments example ```js function foo(a) { return arguments.length; } ``` concretely we don't allocate the function context anymore and we also don't allocate the arguments object anymore (the JSStackCheck was the reason why we did this in the past, because it was holding on to the current context, which also kept the allocation for the arguments alive). Bug: v8:6200, v8:8060 Change-Id: I1db56d00d6b510ce6337608c0fff16af96e95eef Design-Document: bit.ly/v8-turbofan-context-sensitive-js-operators Reviewed-on: https://chromium-review.googlesource.com/c/1267176 Reviewed-by: Georg Neis <neis@chromium.org> Commit-Queue: Benedikt Meurer <bmeurer@chromium.org> Cr-Commit-Position: refs/heads/master@{#56441}
2018-10-08 10:53:18 +00:00
assertEquals(2, foo(1));
assertEquals(2, foo(object1));
assertThrows(() => foo(thrower));
%OptimizeFunctionOnNextCall(foo);
assertEquals(2, foo(1));
assertEquals(2, foo(object1));
assertThrows(() => foo(thrower));
})();
// Test that JSShiftRight is not context-sensitive.
(function() {
function bar(fn) {
return fn(1);
}
function foo(x) {
return bar(y => y >> x);
}
%PrepareFunctionForOptimization(foo);
[turbofan] Introduce the notion of context-sensitivity for JS operators. This change adds predicates to check whether a given JavaScript operator needs the "current context" or if any surrounding context (including the "native context") does it. For example JSAdd doesn't ever need the current context, but actually only the native context. In the BytecodeGraphBuilder we use this predicate to check whether a given operator needs the current context, and if not, we just pass in the native context. Doing so we improve the performance on the benchmarks given in the tracking bug significantly, and go from something around arrayMap: 476 ms. arrayFilter: 312 ms. arrayEvery: 241 ms. arraySome: 152 ms. to arrayMap: 377 ms. arrayFilter: 296 ms. arrayEvery: 191 ms. arraySome: 91 ms. which is an up to 40% improvement. So for idiomatic modern JavaScript which uses higher order functions quite a lot, not just the builtins provided by the JSVM, this is going to improve peak performance noticably. This also makes it possible to completely eliminate all the allocations in the aliased sloppy arguments example ```js function foo(a) { return arguments.length; } ``` concretely we don't allocate the function context anymore and we also don't allocate the arguments object anymore (the JSStackCheck was the reason why we did this in the past, because it was holding on to the current context, which also kept the allocation for the arguments alive). Bug: v8:6200, v8:8060 Change-Id: I1db56d00d6b510ce6337608c0fff16af96e95eef Design-Document: bit.ly/v8-turbofan-context-sensitive-js-operators Reviewed-on: https://chromium-review.googlesource.com/c/1267176 Reviewed-by: Georg Neis <neis@chromium.org> Commit-Queue: Benedikt Meurer <bmeurer@chromium.org> Cr-Commit-Position: refs/heads/master@{#56441}
2018-10-08 10:53:18 +00:00
assertEquals(0, foo(1));
assertEquals(0, foo(object1));
assertThrows(() => foo(thrower));
%OptimizeFunctionOnNextCall(foo);
assertEquals(0, foo(1));
assertEquals(0, foo(object1));
assertThrows(() => foo(thrower));
})();
// Test that JSShiftRightLogical is not context-sensitive.
(function() {
function bar(fn) {
return fn(1);
}
function foo(x) {
return bar(y => y >>> x);
}
%PrepareFunctionForOptimization(foo);
[turbofan] Introduce the notion of context-sensitivity for JS operators. This change adds predicates to check whether a given JavaScript operator needs the "current context" or if any surrounding context (including the "native context") does it. For example JSAdd doesn't ever need the current context, but actually only the native context. In the BytecodeGraphBuilder we use this predicate to check whether a given operator needs the current context, and if not, we just pass in the native context. Doing so we improve the performance on the benchmarks given in the tracking bug significantly, and go from something around arrayMap: 476 ms. arrayFilter: 312 ms. arrayEvery: 241 ms. arraySome: 152 ms. to arrayMap: 377 ms. arrayFilter: 296 ms. arrayEvery: 191 ms. arraySome: 91 ms. which is an up to 40% improvement. So for idiomatic modern JavaScript which uses higher order functions quite a lot, not just the builtins provided by the JSVM, this is going to improve peak performance noticably. This also makes it possible to completely eliminate all the allocations in the aliased sloppy arguments example ```js function foo(a) { return arguments.length; } ``` concretely we don't allocate the function context anymore and we also don't allocate the arguments object anymore (the JSStackCheck was the reason why we did this in the past, because it was holding on to the current context, which also kept the allocation for the arguments alive). Bug: v8:6200, v8:8060 Change-Id: I1db56d00d6b510ce6337608c0fff16af96e95eef Design-Document: bit.ly/v8-turbofan-context-sensitive-js-operators Reviewed-on: https://chromium-review.googlesource.com/c/1267176 Reviewed-by: Georg Neis <neis@chromium.org> Commit-Queue: Benedikt Meurer <bmeurer@chromium.org> Cr-Commit-Position: refs/heads/master@{#56441}
2018-10-08 10:53:18 +00:00
assertEquals(0, foo(1));
assertEquals(0, foo(object1));
assertThrows(() => foo(thrower));
%OptimizeFunctionOnNextCall(foo);
assertEquals(0, foo(1));
assertEquals(0, foo(object1));
assertThrows(() => foo(thrower));
})();
// Test that JSEqual is not context-sensitive.
(function() {
function bar(fn) {
return fn(1);
}
function foo(x) {
return bar(y => y == x);
}
%PrepareFunctionForOptimization(foo);
[turbofan] Introduce the notion of context-sensitivity for JS operators. This change adds predicates to check whether a given JavaScript operator needs the "current context" or if any surrounding context (including the "native context") does it. For example JSAdd doesn't ever need the current context, but actually only the native context. In the BytecodeGraphBuilder we use this predicate to check whether a given operator needs the current context, and if not, we just pass in the native context. Doing so we improve the performance on the benchmarks given in the tracking bug significantly, and go from something around arrayMap: 476 ms. arrayFilter: 312 ms. arrayEvery: 241 ms. arraySome: 152 ms. to arrayMap: 377 ms. arrayFilter: 296 ms. arrayEvery: 191 ms. arraySome: 91 ms. which is an up to 40% improvement. So for idiomatic modern JavaScript which uses higher order functions quite a lot, not just the builtins provided by the JSVM, this is going to improve peak performance noticably. This also makes it possible to completely eliminate all the allocations in the aliased sloppy arguments example ```js function foo(a) { return arguments.length; } ``` concretely we don't allocate the function context anymore and we also don't allocate the arguments object anymore (the JSStackCheck was the reason why we did this in the past, because it was holding on to the current context, which also kept the allocation for the arguments alive). Bug: v8:6200, v8:8060 Change-Id: I1db56d00d6b510ce6337608c0fff16af96e95eef Design-Document: bit.ly/v8-turbofan-context-sensitive-js-operators Reviewed-on: https://chromium-review.googlesource.com/c/1267176 Reviewed-by: Georg Neis <neis@chromium.org> Commit-Queue: Benedikt Meurer <bmeurer@chromium.org> Cr-Commit-Position: refs/heads/master@{#56441}
2018-10-08 10:53:18 +00:00
assertFalse(foo(0));
assertTrue(foo(object1));
assertThrows(() => foo(thrower));
%OptimizeFunctionOnNextCall(foo);
assertFalse(foo(0));
assertTrue(foo(object1));
assertThrows(() => foo(thrower));
})();
// Test that JSLessThan is not context-sensitive.
(function() {
function bar(fn) {
return fn(1);
}
function foo(x) {
return bar(y => y < x);
}
%PrepareFunctionForOptimization(foo);
[turbofan] Introduce the notion of context-sensitivity for JS operators. This change adds predicates to check whether a given JavaScript operator needs the "current context" or if any surrounding context (including the "native context") does it. For example JSAdd doesn't ever need the current context, but actually only the native context. In the BytecodeGraphBuilder we use this predicate to check whether a given operator needs the current context, and if not, we just pass in the native context. Doing so we improve the performance on the benchmarks given in the tracking bug significantly, and go from something around arrayMap: 476 ms. arrayFilter: 312 ms. arrayEvery: 241 ms. arraySome: 152 ms. to arrayMap: 377 ms. arrayFilter: 296 ms. arrayEvery: 191 ms. arraySome: 91 ms. which is an up to 40% improvement. So for idiomatic modern JavaScript which uses higher order functions quite a lot, not just the builtins provided by the JSVM, this is going to improve peak performance noticably. This also makes it possible to completely eliminate all the allocations in the aliased sloppy arguments example ```js function foo(a) { return arguments.length; } ``` concretely we don't allocate the function context anymore and we also don't allocate the arguments object anymore (the JSStackCheck was the reason why we did this in the past, because it was holding on to the current context, which also kept the allocation for the arguments alive). Bug: v8:6200, v8:8060 Change-Id: I1db56d00d6b510ce6337608c0fff16af96e95eef Design-Document: bit.ly/v8-turbofan-context-sensitive-js-operators Reviewed-on: https://chromium-review.googlesource.com/c/1267176 Reviewed-by: Georg Neis <neis@chromium.org> Commit-Queue: Benedikt Meurer <bmeurer@chromium.org> Cr-Commit-Position: refs/heads/master@{#56441}
2018-10-08 10:53:18 +00:00
assertFalse(foo(0));
assertFalse(foo(object1));
assertThrows(() => foo(thrower));
%OptimizeFunctionOnNextCall(foo);
assertFalse(foo(0));
assertFalse(foo(object1));
assertThrows(() => foo(thrower));
})();
// Test that JSGreaterThan is not context-sensitive.
(function() {
function bar(fn) {
return fn(1);
}
function foo(x) {
return bar(y => x > y);
}
%PrepareFunctionForOptimization(foo);
[turbofan] Introduce the notion of context-sensitivity for JS operators. This change adds predicates to check whether a given JavaScript operator needs the "current context" or if any surrounding context (including the "native context") does it. For example JSAdd doesn't ever need the current context, but actually only the native context. In the BytecodeGraphBuilder we use this predicate to check whether a given operator needs the current context, and if not, we just pass in the native context. Doing so we improve the performance on the benchmarks given in the tracking bug significantly, and go from something around arrayMap: 476 ms. arrayFilter: 312 ms. arrayEvery: 241 ms. arraySome: 152 ms. to arrayMap: 377 ms. arrayFilter: 296 ms. arrayEvery: 191 ms. arraySome: 91 ms. which is an up to 40% improvement. So for idiomatic modern JavaScript which uses higher order functions quite a lot, not just the builtins provided by the JSVM, this is going to improve peak performance noticably. This also makes it possible to completely eliminate all the allocations in the aliased sloppy arguments example ```js function foo(a) { return arguments.length; } ``` concretely we don't allocate the function context anymore and we also don't allocate the arguments object anymore (the JSStackCheck was the reason why we did this in the past, because it was holding on to the current context, which also kept the allocation for the arguments alive). Bug: v8:6200, v8:8060 Change-Id: I1db56d00d6b510ce6337608c0fff16af96e95eef Design-Document: bit.ly/v8-turbofan-context-sensitive-js-operators Reviewed-on: https://chromium-review.googlesource.com/c/1267176 Reviewed-by: Georg Neis <neis@chromium.org> Commit-Queue: Benedikt Meurer <bmeurer@chromium.org> Cr-Commit-Position: refs/heads/master@{#56441}
2018-10-08 10:53:18 +00:00
assertFalse(foo(0));
assertFalse(foo(object1));
assertThrows(() => foo(thrower));
%OptimizeFunctionOnNextCall(foo);
assertFalse(foo(0));
assertFalse(foo(object1));
assertThrows(() => foo(thrower));
})();
// Test that JSLessThanOrEqual is not context-sensitive.
(function() {
function bar(fn) {
return fn(1);
}
function foo(x) {
return bar(y => y <= x);
}
%PrepareFunctionForOptimization(foo);
[turbofan] Introduce the notion of context-sensitivity for JS operators. This change adds predicates to check whether a given JavaScript operator needs the "current context" or if any surrounding context (including the "native context") does it. For example JSAdd doesn't ever need the current context, but actually only the native context. In the BytecodeGraphBuilder we use this predicate to check whether a given operator needs the current context, and if not, we just pass in the native context. Doing so we improve the performance on the benchmarks given in the tracking bug significantly, and go from something around arrayMap: 476 ms. arrayFilter: 312 ms. arrayEvery: 241 ms. arraySome: 152 ms. to arrayMap: 377 ms. arrayFilter: 296 ms. arrayEvery: 191 ms. arraySome: 91 ms. which is an up to 40% improvement. So for idiomatic modern JavaScript which uses higher order functions quite a lot, not just the builtins provided by the JSVM, this is going to improve peak performance noticably. This also makes it possible to completely eliminate all the allocations in the aliased sloppy arguments example ```js function foo(a) { return arguments.length; } ``` concretely we don't allocate the function context anymore and we also don't allocate the arguments object anymore (the JSStackCheck was the reason why we did this in the past, because it was holding on to the current context, which also kept the allocation for the arguments alive). Bug: v8:6200, v8:8060 Change-Id: I1db56d00d6b510ce6337608c0fff16af96e95eef Design-Document: bit.ly/v8-turbofan-context-sensitive-js-operators Reviewed-on: https://chromium-review.googlesource.com/c/1267176 Reviewed-by: Georg Neis <neis@chromium.org> Commit-Queue: Benedikt Meurer <bmeurer@chromium.org> Cr-Commit-Position: refs/heads/master@{#56441}
2018-10-08 10:53:18 +00:00
assertFalse(foo(0));
assertTrue(foo(object1));
assertThrows(() => foo(thrower));
%OptimizeFunctionOnNextCall(foo);
assertFalse(foo(0));
assertTrue(foo(object1));
assertThrows(() => foo(thrower));
})();
// Test that JSGreaterThanOrEqual is not context-sensitive.
(function() {
function bar(fn) {
return fn(1);
}
function foo(x) {
return bar(y => x >= y);
}
%PrepareFunctionForOptimization(foo);
[turbofan] Introduce the notion of context-sensitivity for JS operators. This change adds predicates to check whether a given JavaScript operator needs the "current context" or if any surrounding context (including the "native context") does it. For example JSAdd doesn't ever need the current context, but actually only the native context. In the BytecodeGraphBuilder we use this predicate to check whether a given operator needs the current context, and if not, we just pass in the native context. Doing so we improve the performance on the benchmarks given in the tracking bug significantly, and go from something around arrayMap: 476 ms. arrayFilter: 312 ms. arrayEvery: 241 ms. arraySome: 152 ms. to arrayMap: 377 ms. arrayFilter: 296 ms. arrayEvery: 191 ms. arraySome: 91 ms. which is an up to 40% improvement. So for idiomatic modern JavaScript which uses higher order functions quite a lot, not just the builtins provided by the JSVM, this is going to improve peak performance noticably. This also makes it possible to completely eliminate all the allocations in the aliased sloppy arguments example ```js function foo(a) { return arguments.length; } ``` concretely we don't allocate the function context anymore and we also don't allocate the arguments object anymore (the JSStackCheck was the reason why we did this in the past, because it was holding on to the current context, which also kept the allocation for the arguments alive). Bug: v8:6200, v8:8060 Change-Id: I1db56d00d6b510ce6337608c0fff16af96e95eef Design-Document: bit.ly/v8-turbofan-context-sensitive-js-operators Reviewed-on: https://chromium-review.googlesource.com/c/1267176 Reviewed-by: Georg Neis <neis@chromium.org> Commit-Queue: Benedikt Meurer <bmeurer@chromium.org> Cr-Commit-Position: refs/heads/master@{#56441}
2018-10-08 10:53:18 +00:00
assertFalse(foo(0));
assertTrue(foo(object1));
assertThrows(() => foo(thrower));
%OptimizeFunctionOnNextCall(foo);
assertFalse(foo(0));
assertTrue(foo(object1));
assertThrows(() => foo(thrower));
})();
// Test that JSInstanceOf is not context-sensitive.
(function() {
function bar(fn) {
return fn({});
}
function foo(c) {
return bar(o => o instanceof c);
}
%PrepareFunctionForOptimization(foo);
[turbofan] Introduce the notion of context-sensitivity for JS operators. This change adds predicates to check whether a given JavaScript operator needs the "current context" or if any surrounding context (including the "native context") does it. For example JSAdd doesn't ever need the current context, but actually only the native context. In the BytecodeGraphBuilder we use this predicate to check whether a given operator needs the current context, and if not, we just pass in the native context. Doing so we improve the performance on the benchmarks given in the tracking bug significantly, and go from something around arrayMap: 476 ms. arrayFilter: 312 ms. arrayEvery: 241 ms. arraySome: 152 ms. to arrayMap: 377 ms. arrayFilter: 296 ms. arrayEvery: 191 ms. arraySome: 91 ms. which is an up to 40% improvement. So for idiomatic modern JavaScript which uses higher order functions quite a lot, not just the builtins provided by the JSVM, this is going to improve peak performance noticably. This also makes it possible to completely eliminate all the allocations in the aliased sloppy arguments example ```js function foo(a) { return arguments.length; } ``` concretely we don't allocate the function context anymore and we also don't allocate the arguments object anymore (the JSStackCheck was the reason why we did this in the past, because it was holding on to the current context, which also kept the allocation for the arguments alive). Bug: v8:6200, v8:8060 Change-Id: I1db56d00d6b510ce6337608c0fff16af96e95eef Design-Document: bit.ly/v8-turbofan-context-sensitive-js-operators Reviewed-on: https://chromium-review.googlesource.com/c/1267176 Reviewed-by: Georg Neis <neis@chromium.org> Commit-Queue: Benedikt Meurer <bmeurer@chromium.org> Cr-Commit-Position: refs/heads/master@{#56441}
2018-10-08 10:53:18 +00:00
assertTrue(foo(Object));
assertFalse(foo(Array));
assertThrows(() => foo({[Symbol.hasInstance]() { throw new Error(); }}));
%OptimizeFunctionOnNextCall(foo);
assertTrue(foo(Object));
assertFalse(foo(Array));
assertThrows(() => foo({[Symbol.hasInstance]() { throw new Error(); }}));
})();
// Test that JSBitwiseNot is not context-sensitive.
(function() {
function bar(fn) {
return fn();
}
function foo(x) {
return bar(() => ~x);
}
%PrepareFunctionForOptimization(foo);
[turbofan] Introduce the notion of context-sensitivity for JS operators. This change adds predicates to check whether a given JavaScript operator needs the "current context" or if any surrounding context (including the "native context") does it. For example JSAdd doesn't ever need the current context, but actually only the native context. In the BytecodeGraphBuilder we use this predicate to check whether a given operator needs the current context, and if not, we just pass in the native context. Doing so we improve the performance on the benchmarks given in the tracking bug significantly, and go from something around arrayMap: 476 ms. arrayFilter: 312 ms. arrayEvery: 241 ms. arraySome: 152 ms. to arrayMap: 377 ms. arrayFilter: 296 ms. arrayEvery: 191 ms. arraySome: 91 ms. which is an up to 40% improvement. So for idiomatic modern JavaScript which uses higher order functions quite a lot, not just the builtins provided by the JSVM, this is going to improve peak performance noticably. This also makes it possible to completely eliminate all the allocations in the aliased sloppy arguments example ```js function foo(a) { return arguments.length; } ``` concretely we don't allocate the function context anymore and we also don't allocate the arguments object anymore (the JSStackCheck was the reason why we did this in the past, because it was holding on to the current context, which also kept the allocation for the arguments alive). Bug: v8:6200, v8:8060 Change-Id: I1db56d00d6b510ce6337608c0fff16af96e95eef Design-Document: bit.ly/v8-turbofan-context-sensitive-js-operators Reviewed-on: https://chromium-review.googlesource.com/c/1267176 Reviewed-by: Georg Neis <neis@chromium.org> Commit-Queue: Benedikt Meurer <bmeurer@chromium.org> Cr-Commit-Position: refs/heads/master@{#56441}
2018-10-08 10:53:18 +00:00
assertEquals(0, foo(-1));
assertEquals(~1, foo(object1));
assertThrows(() => foo(thrower));
%OptimizeFunctionOnNextCall(foo);
assertEquals(0, foo(-1));
assertEquals(~1, foo(object1));
assertThrows(() => foo(thrower));
})();
// Test that JSNegate is not context-sensitive.
(function() {
function bar(fn) {
return fn();
}
function foo(x) {
return bar(() => -x);
}
%PrepareFunctionForOptimization(foo);
[turbofan] Introduce the notion of context-sensitivity for JS operators. This change adds predicates to check whether a given JavaScript operator needs the "current context" or if any surrounding context (including the "native context") does it. For example JSAdd doesn't ever need the current context, but actually only the native context. In the BytecodeGraphBuilder we use this predicate to check whether a given operator needs the current context, and if not, we just pass in the native context. Doing so we improve the performance on the benchmarks given in the tracking bug significantly, and go from something around arrayMap: 476 ms. arrayFilter: 312 ms. arrayEvery: 241 ms. arraySome: 152 ms. to arrayMap: 377 ms. arrayFilter: 296 ms. arrayEvery: 191 ms. arraySome: 91 ms. which is an up to 40% improvement. So for idiomatic modern JavaScript which uses higher order functions quite a lot, not just the builtins provided by the JSVM, this is going to improve peak performance noticably. This also makes it possible to completely eliminate all the allocations in the aliased sloppy arguments example ```js function foo(a) { return arguments.length; } ``` concretely we don't allocate the function context anymore and we also don't allocate the arguments object anymore (the JSStackCheck was the reason why we did this in the past, because it was holding on to the current context, which also kept the allocation for the arguments alive). Bug: v8:6200, v8:8060 Change-Id: I1db56d00d6b510ce6337608c0fff16af96e95eef Design-Document: bit.ly/v8-turbofan-context-sensitive-js-operators Reviewed-on: https://chromium-review.googlesource.com/c/1267176 Reviewed-by: Georg Neis <neis@chromium.org> Commit-Queue: Benedikt Meurer <bmeurer@chromium.org> Cr-Commit-Position: refs/heads/master@{#56441}
2018-10-08 10:53:18 +00:00
assertEquals(1, foo(-1));
assertEquals(-1, foo(object1));
assertThrows(() => foo(thrower));
%OptimizeFunctionOnNextCall(foo);
assertEquals(1, foo(-1));
assertEquals(-1, foo(object1));
assertThrows(() => foo(thrower));
})();
// Test that JSIncrement is not context-sensitive.
(function() {
function bar(fn) {
return fn();
}
function foo(x) {
return bar(() => ++x);
}
%PrepareFunctionForOptimization(foo);
[turbofan] Introduce the notion of context-sensitivity for JS operators. This change adds predicates to check whether a given JavaScript operator needs the "current context" or if any surrounding context (including the "native context") does it. For example JSAdd doesn't ever need the current context, but actually only the native context. In the BytecodeGraphBuilder we use this predicate to check whether a given operator needs the current context, and if not, we just pass in the native context. Doing so we improve the performance on the benchmarks given in the tracking bug significantly, and go from something around arrayMap: 476 ms. arrayFilter: 312 ms. arrayEvery: 241 ms. arraySome: 152 ms. to arrayMap: 377 ms. arrayFilter: 296 ms. arrayEvery: 191 ms. arraySome: 91 ms. which is an up to 40% improvement. So for idiomatic modern JavaScript which uses higher order functions quite a lot, not just the builtins provided by the JSVM, this is going to improve peak performance noticably. This also makes it possible to completely eliminate all the allocations in the aliased sloppy arguments example ```js function foo(a) { return arguments.length; } ``` concretely we don't allocate the function context anymore and we also don't allocate the arguments object anymore (the JSStackCheck was the reason why we did this in the past, because it was holding on to the current context, which also kept the allocation for the arguments alive). Bug: v8:6200, v8:8060 Change-Id: I1db56d00d6b510ce6337608c0fff16af96e95eef Design-Document: bit.ly/v8-turbofan-context-sensitive-js-operators Reviewed-on: https://chromium-review.googlesource.com/c/1267176 Reviewed-by: Georg Neis <neis@chromium.org> Commit-Queue: Benedikt Meurer <bmeurer@chromium.org> Cr-Commit-Position: refs/heads/master@{#56441}
2018-10-08 10:53:18 +00:00
assertEquals(1, foo(0));
assertEquals(2, foo(object1));
assertThrows(() => foo(thrower));
%OptimizeFunctionOnNextCall(foo);
assertEquals(1, foo(0));
assertEquals(2, foo(object1));
assertThrows(() => foo(thrower));
})();
// Test that JSDecrement is not context-sensitive.
(function() {
function bar(fn) {
return fn();
}
function foo(x) {
return bar(() => --x);
}
%PrepareFunctionForOptimization(foo);
[turbofan] Introduce the notion of context-sensitivity for JS operators. This change adds predicates to check whether a given JavaScript operator needs the "current context" or if any surrounding context (including the "native context") does it. For example JSAdd doesn't ever need the current context, but actually only the native context. In the BytecodeGraphBuilder we use this predicate to check whether a given operator needs the current context, and if not, we just pass in the native context. Doing so we improve the performance on the benchmarks given in the tracking bug significantly, and go from something around arrayMap: 476 ms. arrayFilter: 312 ms. arrayEvery: 241 ms. arraySome: 152 ms. to arrayMap: 377 ms. arrayFilter: 296 ms. arrayEvery: 191 ms. arraySome: 91 ms. which is an up to 40% improvement. So for idiomatic modern JavaScript which uses higher order functions quite a lot, not just the builtins provided by the JSVM, this is going to improve peak performance noticably. This also makes it possible to completely eliminate all the allocations in the aliased sloppy arguments example ```js function foo(a) { return arguments.length; } ``` concretely we don't allocate the function context anymore and we also don't allocate the arguments object anymore (the JSStackCheck was the reason why we did this in the past, because it was holding on to the current context, which also kept the allocation for the arguments alive). Bug: v8:6200, v8:8060 Change-Id: I1db56d00d6b510ce6337608c0fff16af96e95eef Design-Document: bit.ly/v8-turbofan-context-sensitive-js-operators Reviewed-on: https://chromium-review.googlesource.com/c/1267176 Reviewed-by: Georg Neis <neis@chromium.org> Commit-Queue: Benedikt Meurer <bmeurer@chromium.org> Cr-Commit-Position: refs/heads/master@{#56441}
2018-10-08 10:53:18 +00:00
assertEquals(1, foo(2));
assertEquals(0, foo(object1));
assertThrows(() => foo(thrower));
%OptimizeFunctionOnNextCall(foo);
assertEquals(1, foo(2));
assertEquals(0, foo(object1));
assertThrows(() => foo(thrower));
})();
// Test that JSCreateArguments[UnmappedArguments] is not context-sensitive.
(function() {
function bar(fn) {
return fn();
}
function foo() {
"use strict";
return bar(() => arguments)[0];
}
%PrepareFunctionForOptimization(foo);
[turbofan] Introduce the notion of context-sensitivity for JS operators. This change adds predicates to check whether a given JavaScript operator needs the "current context" or if any surrounding context (including the "native context") does it. For example JSAdd doesn't ever need the current context, but actually only the native context. In the BytecodeGraphBuilder we use this predicate to check whether a given operator needs the current context, and if not, we just pass in the native context. Doing so we improve the performance on the benchmarks given in the tracking bug significantly, and go from something around arrayMap: 476 ms. arrayFilter: 312 ms. arrayEvery: 241 ms. arraySome: 152 ms. to arrayMap: 377 ms. arrayFilter: 296 ms. arrayEvery: 191 ms. arraySome: 91 ms. which is an up to 40% improvement. So for idiomatic modern JavaScript which uses higher order functions quite a lot, not just the builtins provided by the JSVM, this is going to improve peak performance noticably. This also makes it possible to completely eliminate all the allocations in the aliased sloppy arguments example ```js function foo(a) { return arguments.length; } ``` concretely we don't allocate the function context anymore and we also don't allocate the arguments object anymore (the JSStackCheck was the reason why we did this in the past, because it was holding on to the current context, which also kept the allocation for the arguments alive). Bug: v8:6200, v8:8060 Change-Id: I1db56d00d6b510ce6337608c0fff16af96e95eef Design-Document: bit.ly/v8-turbofan-context-sensitive-js-operators Reviewed-on: https://chromium-review.googlesource.com/c/1267176 Reviewed-by: Georg Neis <neis@chromium.org> Commit-Queue: Benedikt Meurer <bmeurer@chromium.org> Cr-Commit-Position: refs/heads/master@{#56441}
2018-10-08 10:53:18 +00:00
assertEquals(0, foo(0, 1));
assertEquals(1, foo(1, 2));
assertEquals(undefined, foo());
%OptimizeFunctionOnNextCall(foo);
assertEquals(0, foo(0, 1));
assertEquals(1, foo(1, 2));
assertEquals(undefined, foo());
})();
// Test that JSCreateArguments[RestParameters] is not context-sensitive.
(function() {
function bar(fn) {
return fn();
}
function foo(...args) {
return bar(() => args)[0];
}
%PrepareFunctionForOptimization(foo);
[turbofan] Introduce the notion of context-sensitivity for JS operators. This change adds predicates to check whether a given JavaScript operator needs the "current context" or if any surrounding context (including the "native context") does it. For example JSAdd doesn't ever need the current context, but actually only the native context. In the BytecodeGraphBuilder we use this predicate to check whether a given operator needs the current context, and if not, we just pass in the native context. Doing so we improve the performance on the benchmarks given in the tracking bug significantly, and go from something around arrayMap: 476 ms. arrayFilter: 312 ms. arrayEvery: 241 ms. arraySome: 152 ms. to arrayMap: 377 ms. arrayFilter: 296 ms. arrayEvery: 191 ms. arraySome: 91 ms. which is an up to 40% improvement. So for idiomatic modern JavaScript which uses higher order functions quite a lot, not just the builtins provided by the JSVM, this is going to improve peak performance noticably. This also makes it possible to completely eliminate all the allocations in the aliased sloppy arguments example ```js function foo(a) { return arguments.length; } ``` concretely we don't allocate the function context anymore and we also don't allocate the arguments object anymore (the JSStackCheck was the reason why we did this in the past, because it was holding on to the current context, which also kept the allocation for the arguments alive). Bug: v8:6200, v8:8060 Change-Id: I1db56d00d6b510ce6337608c0fff16af96e95eef Design-Document: bit.ly/v8-turbofan-context-sensitive-js-operators Reviewed-on: https://chromium-review.googlesource.com/c/1267176 Reviewed-by: Georg Neis <neis@chromium.org> Commit-Queue: Benedikt Meurer <bmeurer@chromium.org> Cr-Commit-Position: refs/heads/master@{#56441}
2018-10-08 10:53:18 +00:00
assertEquals(0, foo(0, 1));
assertEquals(1, foo(1, 2));
assertEquals(undefined, foo());
%OptimizeFunctionOnNextCall(foo);
assertEquals(0, foo(0, 1));
assertEquals(1, foo(1, 2));
assertEquals(undefined, foo());
})();
// Test that JSLoadGlobal/JSStoreGlobal are not context-sensitive.
(function(global) {
var actualValue = 'Some value';
Object.defineProperty(global, 'globalValue', {
configurable: true,
enumerable: true,
get: function() {
return actualValue;
},
set: function(v) {
actualValue = v;
}
});
function bar(fn) {
return fn();
}
function foo(v) {
return bar(() => {
const o = globalValue;
globalValue = v;
return o;
});
}
%PrepareFunctionForOptimization(foo);
[turbofan] Introduce the notion of context-sensitivity for JS operators. This change adds predicates to check whether a given JavaScript operator needs the "current context" or if any surrounding context (including the "native context") does it. For example JSAdd doesn't ever need the current context, but actually only the native context. In the BytecodeGraphBuilder we use this predicate to check whether a given operator needs the current context, and if not, we just pass in the native context. Doing so we improve the performance on the benchmarks given in the tracking bug significantly, and go from something around arrayMap: 476 ms. arrayFilter: 312 ms. arrayEvery: 241 ms. arraySome: 152 ms. to arrayMap: 377 ms. arrayFilter: 296 ms. arrayEvery: 191 ms. arraySome: 91 ms. which is an up to 40% improvement. So for idiomatic modern JavaScript which uses higher order functions quite a lot, not just the builtins provided by the JSVM, this is going to improve peak performance noticably. This also makes it possible to completely eliminate all the allocations in the aliased sloppy arguments example ```js function foo(a) { return arguments.length; } ``` concretely we don't allocate the function context anymore and we also don't allocate the arguments object anymore (the JSStackCheck was the reason why we did this in the past, because it was holding on to the current context, which also kept the allocation for the arguments alive). Bug: v8:6200, v8:8060 Change-Id: I1db56d00d6b510ce6337608c0fff16af96e95eef Design-Document: bit.ly/v8-turbofan-context-sensitive-js-operators Reviewed-on: https://chromium-review.googlesource.com/c/1267176 Reviewed-by: Georg Neis <neis@chromium.org> Commit-Queue: Benedikt Meurer <bmeurer@chromium.org> Cr-Commit-Position: refs/heads/master@{#56441}
2018-10-08 10:53:18 +00:00
assertEquals('Some value', foo('Another value'));
assertEquals('Another value', actualValue);
assertEquals('Another value', foo('Some value'));
assertEquals('Some value', actualValue);
%OptimizeFunctionOnNextCall(foo);
assertEquals('Some value', foo('Another value'));
assertEquals('Another value', actualValue);
assertEquals('Another value', foo('Some value'));
assertEquals('Some value', actualValue);
})(this);
// Test that for..in is not context-sensitive.
(function() {
function bar(fn) {
return fn();
}
function foo(o) {
return bar(() => {
var s = "";
for (var k in o) { s += k; }
return s;
});
}
%PrepareFunctionForOptimization(foo);
[turbofan] Introduce the notion of context-sensitivity for JS operators. This change adds predicates to check whether a given JavaScript operator needs the "current context" or if any surrounding context (including the "native context") does it. For example JSAdd doesn't ever need the current context, but actually only the native context. In the BytecodeGraphBuilder we use this predicate to check whether a given operator needs the current context, and if not, we just pass in the native context. Doing so we improve the performance on the benchmarks given in the tracking bug significantly, and go from something around arrayMap: 476 ms. arrayFilter: 312 ms. arrayEvery: 241 ms. arraySome: 152 ms. to arrayMap: 377 ms. arrayFilter: 296 ms. arrayEvery: 191 ms. arraySome: 91 ms. which is an up to 40% improvement. So for idiomatic modern JavaScript which uses higher order functions quite a lot, not just the builtins provided by the JSVM, this is going to improve peak performance noticably. This also makes it possible to completely eliminate all the allocations in the aliased sloppy arguments example ```js function foo(a) { return arguments.length; } ``` concretely we don't allocate the function context anymore and we also don't allocate the arguments object anymore (the JSStackCheck was the reason why we did this in the past, because it was holding on to the current context, which also kept the allocation for the arguments alive). Bug: v8:6200, v8:8060 Change-Id: I1db56d00d6b510ce6337608c0fff16af96e95eef Design-Document: bit.ly/v8-turbofan-context-sensitive-js-operators Reviewed-on: https://chromium-review.googlesource.com/c/1267176 Reviewed-by: Georg Neis <neis@chromium.org> Commit-Queue: Benedikt Meurer <bmeurer@chromium.org> Cr-Commit-Position: refs/heads/master@{#56441}
2018-10-08 10:53:18 +00:00
assertEquals('abc', foo({a: 1, b: 2, c: 3}));
assertEquals('ab', foo(Object.create({a: 1, b: 2})));
%OptimizeFunctionOnNextCall(foo);
assertEquals('abc', foo({a: 1, b: 2, c: 3}));
assertEquals("ab", foo(Object.create({a:1, b:2})));
})();
// Test that most generator operations are not context-sensitive.
(function() {
function bar(fn) {
let s = undefined;
for (const x of fn()) {
if (s === undefined) s = x;
else s += x;
}
return s;
}
function foo(x, y, z) {
return bar(function*() {
yield x;
yield y;
yield z;
});
}
%PrepareFunctionForOptimization(foo);
[turbofan] Introduce the notion of context-sensitivity for JS operators. This change adds predicates to check whether a given JavaScript operator needs the "current context" or if any surrounding context (including the "native context") does it. For example JSAdd doesn't ever need the current context, but actually only the native context. In the BytecodeGraphBuilder we use this predicate to check whether a given operator needs the current context, and if not, we just pass in the native context. Doing so we improve the performance on the benchmarks given in the tracking bug significantly, and go from something around arrayMap: 476 ms. arrayFilter: 312 ms. arrayEvery: 241 ms. arraySome: 152 ms. to arrayMap: 377 ms. arrayFilter: 296 ms. arrayEvery: 191 ms. arraySome: 91 ms. which is an up to 40% improvement. So for idiomatic modern JavaScript which uses higher order functions quite a lot, not just the builtins provided by the JSVM, this is going to improve peak performance noticably. This also makes it possible to completely eliminate all the allocations in the aliased sloppy arguments example ```js function foo(a) { return arguments.length; } ``` concretely we don't allocate the function context anymore and we also don't allocate the arguments object anymore (the JSStackCheck was the reason why we did this in the past, because it was holding on to the current context, which also kept the allocation for the arguments alive). Bug: v8:6200, v8:8060 Change-Id: I1db56d00d6b510ce6337608c0fff16af96e95eef Design-Document: bit.ly/v8-turbofan-context-sensitive-js-operators Reviewed-on: https://chromium-review.googlesource.com/c/1267176 Reviewed-by: Georg Neis <neis@chromium.org> Commit-Queue: Benedikt Meurer <bmeurer@chromium.org> Cr-Commit-Position: refs/heads/master@{#56441}
2018-10-08 10:53:18 +00:00
assertEquals(6, foo(1, 2, 3));
assertEquals("abc", foo("a", "b", "c"));
%OptimizeFunctionOnNextCall(foo);
assertEquals(6, foo(1, 2, 3));
assertEquals("abc", foo("a", "b", "c"));
})();