Commit 668513d8 authored by Leszek Swirski's avatar Leszek Swirski Committed by Commit Bot

[sparkplug] Add fuzzer support for CompileBaseline

Robustify %CompileBaseline against fuzzing, and allowlist it in the
fuzzer.

Bug: v8:11420
Change-Id: I44947014c8c9362d80ea98636dbbaa5d07d6a177
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2739643
Auto-Submit: Leszek Swirski <leszeks@chromium.org>
Commit-Queue: Michael Achenbach <machenbach@chromium.org>
Reviewed-by: 's avatarMichael Achenbach <machenbach@chromium.org>
Cr-Commit-Position: refs/heads/master@{#73325}
parent f80b2920
......@@ -311,8 +311,12 @@ bool EnsureFeedbackVector(Isolate* isolate, Handle<JSFunction> function) {
RUNTIME_FUNCTION(Runtime_CompileBaseline) {
HandleScope scope(isolate);
DCHECK_EQ(1, args.length());
CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
if (args.length() != 1) {
return CrashUnlessFuzzing(isolate);
}
CONVERT_ARG_HANDLE_CHECKED(Object, function_object, 0);
if (!function_object->IsJSFunction()) return CrashUnlessFuzzing(isolate);
Handle<JSFunction> function = Handle<JSFunction>::cast(function_object);
IsCompiledScope is_compiled_scope =
function->shared(isolate).is_compiled_scope(isolate);
......
......@@ -215,6 +215,8 @@ bool Runtime::IsAllowListedForFuzzing(FunctionId id) {
case Runtime::kHeapObjectVerify:
case Runtime::kIsBeingInterpreted:
return !FLAG_allow_natives_for_differential_fuzzing;
case Runtime::kCompileBaseline:
return FLAG_sparkplug;
default:
return false;
}
......
......@@ -147,6 +147,7 @@ const DISALLOWED_DIFFERENTIAL_FUZZ_FLAGS = [
const ALLOWED_RUNTIME_FUNCTIONS = new Set([
// List of allowed runtime functions. Others will be replaced with no-ops.
'ArrayBufferDetach',
'CompileBaseline',
'DeoptimizeFunction',
'DeoptimizeNow',
'EnableCodeLoggingForTesting',
......
......@@ -49,7 +49,7 @@ class FunctionCallMutator extends mutator.Mutator {
}
const probability = random.random();
if (probability < 0.5) {
if (probability < 0.4) {
const randFunc = common.randomFunction(path);
if (randFunc) {
thisMutator.annotate(
......@@ -58,7 +58,7 @@ class FunctionCallMutator extends mutator.Mutator {
path.node.callee = randFunc;
}
} else if (probability < 0.7 && thisMutator.settings.engine == 'V8') {
} else if (probability < 0.6 && thisMutator.settings.engine == 'V8') {
const prepareTemplate = babelTemplate(
'__V8BuiltinPrepareFunctionForOptimization(ID)');
const optimizeTemplate = babelTemplate(
......@@ -86,6 +86,28 @@ class FunctionCallMutator extends mutator.Mutator {
thisMutator.insertBeforeSkip(
path, _liftExpressionsToStatements(path, nodes));
}
} else if (probability < 0.75 && thisMutator.settings.engine == 'V8') {
const template = babelTemplate(
'__V8BuiltinCompileBaseline(ID)');
const nodes = [
template({
ID: babelTypes.cloneDeep(path.node.callee),
}).expression,
];
thisMutator.annotate(
nodes[0],
`Compiling baseline ${path.node.callee.name}`);
if (!babelTypes.isExpressionStatement(path.parent)) {
nodes.push(path.node);
thisMutator.replaceWithSkip(
path, babelTypes.sequenceExpression(nodes));
} else {
thisMutator.insertBeforeSkip(
path, _liftExpressionsToStatements(path, nodes));
}
} else if (probability < 0.85 &&
thisMutator.settings.engine == 'V8') {
const template = babelTemplate(
......
......@@ -36,16 +36,14 @@ describe('Mutate functions', () => {
});
it('is robust without available functions', () => {
// This chooses replacing fuctions.
sandbox.stub(random, 'random').callsFake(() => { return 0.4; });
sandbox.stub(random, 'random').callsFake(() => { return 0.3; });
// We just ensure here that mutating this file doesn't throw.
loadAndMutate('mutate_function_call.js');
});
it('optimizes functions in V8', () => {
// This omits function replacement and chooses V8 optimizations.
sandbox.stub(random, 'random').callsFake(() => { return 0.6; });
sandbox.stub(random, 'random').callsFake(() => { return 0.5; });
const source = loadAndMutate('mutate_function_call.js');
const mutated = sourceHelpers.generateCode(source);
......@@ -53,8 +51,16 @@ describe('Mutate functions', () => {
'mutate_function_call_expected.js', mutated);
});
it('compiles functions in V8 to baseline', () => {
sandbox.stub(random, 'random').callsFake(() => { return 0.7; });
const source = loadAndMutate('mutate_function_call.js');
const mutated = sourceHelpers.generateCode(source);
helpers.assertExpectedResult(
'mutate_function_call_baseline_expected.js', mutated);
});
it('deoptimizes functions in V8', () => {
// This chooses V8 deoptimization.
sandbox.stub(random, 'random').callsFake(() => { return 0.8; });
const source = loadAndMutate('mutate_function_call.js');
......
// 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.
/* FunctionCallMutator: Compiling baseline __f_0 */
%CompileBaseline(__f_0);
// Original: mutate_function_call.js
__f_0(1);
a = (
/* FunctionCallMutator: Compiling baseline __f_0 */
%CompileBaseline(__f_0), __f_0(1));
foo(1, (
/* FunctionCallMutator: Compiling baseline __f_0 */
%CompileBaseline(__f_0), __f_0()));
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment