[js-fuzzer] Add optimization template for Maglev

This makes js-fuzzer use %OptimizeMaglevOnNextCall in 30% of the
times when optimization patterns are chosen. Other probabilities
of the function-call mutator are tuned a bit to keep using
%OptimizeFunctionOnNextCall proportionally similarly to before.

(~ some round number preferences... exact choices might not matter
much, since the original probability choices are rater arbitrary
anyways)

Bug: v8:7700
Change-Id: I7727ea27fd956efab6fbee2b4a090213d1d7ff05
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/4124118
Reviewed-by: Almothana Athamneh <almuthanna@chromium.org>
Reviewed-by: Jakob Linke <jgruber@chromium.org>
Commit-Queue: Michael Achenbach <machenbach@chromium.org>
Cr-Commit-Position: refs/heads/main@{#85031}
This commit is contained in:
Michael Achenbach 2022-12-28 10:42:21 +01:00 committed by V8 LUCI CQ
parent be9c39d3d9
commit 48495722ce
4 changed files with 83 additions and 26 deletions

View File

@ -49,7 +49,7 @@ class FunctionCallMutator extends mutator.Mutator {
}
const probability = random.random();
if (probability < 0.4) {
if (probability < 0.3) {
const randFunc = common.randomFunction(path);
if (randFunc) {
thisMutator.annotate(
@ -58,11 +58,12 @@ class FunctionCallMutator extends mutator.Mutator {
path.node.callee = randFunc;
}
} else if (probability < 0.6 && thisMutator.settings.engine == 'V8') {
} else if (probability < 0.7 && thisMutator.settings.engine == 'V8') {
const prepareTemplate = babelTemplate(
'__V8BuiltinPrepareFunctionForOptimization(ID)');
const optimizationMode = random.choose(0.7) ? 'Function' : 'Maglev';
const optimizeTemplate = babelTemplate(
'__V8BuiltinOptimizeFunctionOnNextCall(ID)');
`__V8BuiltinOptimize${optimizationMode}OnNextCall(ID)`);
const nodes = [
prepareTemplate({
@ -86,7 +87,7 @@ class FunctionCallMutator extends mutator.Mutator {
thisMutator.insertBeforeSkip(
path, _liftExpressionsToStatements(path, nodes));
}
} else if (probability < 0.75 && thisMutator.settings.engine == 'V8') {
} else if (probability < 0.8 && thisMutator.settings.engine == 'V8') {
const template = babelTemplate(
'__V8BuiltinCompileBaseline(ID)');
@ -108,7 +109,7 @@ class FunctionCallMutator extends mutator.Mutator {
thisMutator.insertBeforeSkip(
path, _liftExpressionsToStatements(path, nodes));
}
} else if (probability < 0.85 &&
} else if (probability < 0.9 &&
thisMutator.settings.engine == 'V8') {
const template = babelTemplate(
'__V8BuiltinDeoptimizeFunction(ID)');

View File

@ -36,14 +36,15 @@ describe('Mutate functions', () => {
});
it('is robust without available functions', () => {
sandbox.stub(random, 'random').callsFake(() => { return 0.3; });
sandbox.stub(random, 'random').callsFake(() => { return 0.2; });
// We just ensure here that mutating this file doesn't throw.
loadAndMutate('mutate_function_call.js');
});
it('optimizes functions in V8', () => {
it('optimizes functions with turbofan in V8', () => {
sandbox.stub(random, 'random').callsFake(() => { return 0.5; });
sandbox.stub(random, 'choose').callsFake(p => true);
const source = loadAndMutate('mutate_function_call.js');
const mutated = sourceHelpers.generateCode(source);
@ -51,6 +52,18 @@ describe('Mutate functions', () => {
'mutate_function_call_expected.js', mutated);
});
it('optimizes functions with maglev in V8', () => {
sandbox.stub(random, 'random').callsFake(() => { return 0.5; });
// False-path takes 'Maglev'. Other calls to choose should return
// true. It's also used to determine if a mutator should be chosen.
sandbox.stub(random, 'choose').callsFake(p => p == 0.7 ? false : true);
const source = loadAndMutate('mutate_function_call.js');
const mutated = sourceHelpers.generateCode(source);
helpers.assertExpectedResult(
'mutate_function_call_maglev_expected.js', mutated);
});
it('compiles functions in V8 to baseline', () => {
sandbox.stub(random, 'random').callsFake(() => { return 0.7; });

View File

@ -0,0 +1,23 @@
// Copyright 2020 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.
%PrepareFunctionForOptimization(__f_0);
__f_0(1);
__f_0(1);
%OptimizeMaglevOnNextCall(__f_0);
// Original: mutate_function_call.js
/* FunctionCallMutator: Optimizing __f_0 */
__f_0(1);
a = (
/* FunctionCallMutator: Optimizing __f_0 */
%PrepareFunctionForOptimization(__f_0), __f_0(1), __f_0(1), %OptimizeMaglevOnNextCall(__f_0), __f_0(1));
foo(1, (
/* FunctionCallMutator: Optimizing __f_0 */
%PrepareFunctionForOptimization(__f_0), __f_0(), __f_0(), %OptimizeMaglevOnNextCall(__f_0), __f_0()));

View File

@ -11,8 +11,8 @@
// Original: mutation_order/input.js
try {
var __v_0 =
/* NumberMutator: Replaced 1 with 17 */
17;
/* NumberMutator: Replaced 1 with -10 */
-10;
} catch (e) {}
try {
@ -25,10 +25,10 @@ try {
try {
var __v_3 = {
/* NumberMutator: Replaced 0 with 5 */
5:
/* NumberMutator: Replaced 1 with 13 */
13
/* NumberMutator: Replaced 0 with 8 */
8:
/* NumberMutator: Replaced 1 with 3 */
3
};
} catch (e) {}
@ -42,14 +42,14 @@ try {
try {
__f_0(__v_0,
/* NumberMutator: Replaced 3 with -77 */
-77);
/* NumberMutator: Replaced 3 with 5 */
5);
} catch (e) {}
try {
__f_0(__v_0,
/* NumberMutator: Replaced 3 with 12 */
12);
/* NumberMutator: Replaced 3 with NaN */
NaN);
} catch (e) {}
try {
@ -59,8 +59,8 @@ try {
try {
/* FunctionCallMutator: Optimizing __f_0 */
__f_0(__v_0,
/* NumberMutator: Replaced 3 with -7 */
-7);
/* NumberMutator: Replaced 3 with 2 */
2);
} catch (e) {}
function __f_1(__v_6) {
@ -71,7 +71,23 @@ function __f_1(__v_6) {
}
try {
/* FunctionCallMutator: Replaced __f_0 with __f_0 */
%PrepareFunctionForOptimization(__f_0);
} catch (e) {}
try {
__f_0('foo', __v_1);
} catch (e) {}
try {
__f_0('foo', __v_1);
} catch (e) {}
try {
%OptimizeFunctionOnNextCall(__f_0);
} catch (e) {}
try {
/* FunctionCallMutator: Optimizing __f_0 */
__f_0('foo', __v_1);
} catch (e) {}
@ -82,18 +98,22 @@ try {
try {
__f_1(
/* NumberMutator: Replaced 2 with -13 */
-13, __f_0(__v_0, __v_1));
/* NumberMutator: Replaced 2 with -10 */
-10, __f_0(__v_0, __v_1));
} catch (e) {}
try {
/* FunctionCallMutator: Replaced __f_0 with __f_1 */
__f_1(__v_0, __v_1);
/* FunctionCallMutator: Deoptimizing __f_0 */
__f_0(__v_0, __v_1);
} catch (e) {}
try {
%DeoptimizeFunction(__f_0);
} catch (e) {}
try {
/* FunctionCallMutator: Replaced __f_1 with __f_1 */
__f_1(__v_1,
/* NumberMutator: Replaced 3 with 7 */
7);
/* NumberMutator: Replaced 3 with 16 */
16);
} catch (e) {}