Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
bytecodealliance
GitHub Repository: bytecodealliance/wasmtime
Path: blob/main/cranelift/fuzzgen/src/config.rs
1692 views
1
use std::collections::HashMap;
2
use std::ops::RangeInclusive;
3
4
/// Holds the range of acceptable values to use during the generation of testcases
5
pub struct Config {
6
/// Maximum allowed test case inputs.
7
/// We build test case inputs from the rest of the bytes that the fuzzer provides us
8
/// so we allow the fuzzer to control this by feeding us more or less bytes.
9
/// The upper bound here is to prevent too many inputs that cause long test times
10
pub max_test_case_inputs: usize,
11
// Number of functions that we generate per testcase
12
pub testcase_funcs: RangeInclusive<usize>,
13
pub signature_params: RangeInclusive<usize>,
14
pub signature_rets: RangeInclusive<usize>,
15
pub instructions_per_block: RangeInclusive<usize>,
16
/// Number of variables that we allocate per function
17
/// This value does not include the signature params
18
pub vars_per_function: RangeInclusive<usize>,
19
/// Number of blocks that we generate per function.
20
/// This value does not include the entry block
21
pub blocks_per_function: RangeInclusive<usize>,
22
/// Number of params a block should take
23
/// This value does not apply to block0 which takes the function params
24
/// and is thus governed by `signature_params`
25
pub block_signature_params: RangeInclusive<usize>,
26
/// Max number of jump tables entries to generate
27
pub jump_table_entries: RangeInclusive<usize>,
28
29
/// The Switch API specializes either individual blocks or contiguous ranges.
30
/// In `switch_cases` we decide to produce either a single block or a range.
31
/// The size of the range is controlled by `switch_max_range_size`.
32
pub switch_cases: RangeInclusive<usize>,
33
pub switch_max_range_size: RangeInclusive<usize>,
34
35
/// Stack slots.
36
/// The combination of these two determines stack usage per function
37
pub static_stack_slots_per_function: RangeInclusive<usize>,
38
/// Size in bytes
39
pub static_stack_slot_size: RangeInclusive<usize>,
40
/// Stack slot alignment as a power of 2
41
pub stack_slot_alignment_log2: RangeInclusive<usize>,
42
/// Allowed stack probe sizes
43
pub stack_probe_size_log2: RangeInclusive<usize>,
44
45
/// Determines how often we generate a backwards branch
46
/// Backwards branches are prone to infinite loops, and thus cause timeouts.
47
pub backwards_branch_ratio: (usize, usize),
48
49
/// How often should we allow integer division by zero traps.
50
///
51
/// Some instructions such as Srem and Udiv can cause a `int_divz` trap
52
/// under some inputs. We almost always insert a sequence of instructions
53
/// that avoids these issues. However we can allow some `int_divz` traps
54
/// by controlling this config.
55
pub allowed_int_divz_ratio: (usize, usize),
56
57
/// How often should we allow fcvt related traps.
58
///
59
/// `Fcvt*` instructions fail under some inputs, most commonly NaN's.
60
/// We insert a checking sequence to guarantee that those inputs never make
61
/// it to the instruction, but sometimes we want to allow them.
62
pub allowed_fcvt_traps_ratio: (usize, usize),
63
64
/// Some flags really impact compile performance, we still want to test
65
/// them, but probably at a lower rate, so that overall execution time isn't
66
/// impacted as much
67
pub compile_flag_ratio: HashMap<&'static str, (usize, usize)>,
68
69
/// Range of values for the padding between basic blocks. Larger values will
70
/// generate larger functions.
71
pub bb_padding_log2_size: RangeInclusive<usize>,
72
}
73
74
impl Default for Config {
75
fn default() -> Self {
76
Config {
77
max_test_case_inputs: 100,
78
testcase_funcs: 1..=8,
79
signature_params: 0..=16,
80
signature_rets: 0..=16,
81
instructions_per_block: 0..=64,
82
vars_per_function: 0..=16,
83
blocks_per_function: 0..=16,
84
block_signature_params: 0..=16,
85
jump_table_entries: 0..=16,
86
switch_cases: 0..=64,
87
// Ranges smaller than 2 don't make sense.
88
switch_max_range_size: 2..=32,
89
static_stack_slots_per_function: 0..=8,
90
static_stack_slot_size: 0..=128,
91
stack_slot_alignment_log2: 0..=10,
92
// We need the mix of sizes that allows us to:
93
// * not generates any stack probes
94
// * generate unrolled stack probes
95
// * generate loop stack probes
96
//
97
// This depends on the total amount of stack space that we have for this function
98
// (controlled by `static_stack_slots_per_function` and `static_stack_slot_size`)
99
//
100
// 1<<6 = 64 and 1<<14 = 16384
101
//
102
// This range allows us to generate all 3 cases within the current allowed
103
// stack size range.
104
stack_probe_size_log2: 6..=14,
105
// 0.1% allows us to explore this, while not causing enough timeouts to significantly
106
// impact execs/s
107
backwards_branch_ratio: (1, 1000),
108
allowed_int_divz_ratio: (1, 1_000_000),
109
allowed_fcvt_traps_ratio: (1, 1_000_000),
110
compile_flag_ratio: [("regalloc_checker", (1usize, 1000))].into_iter().collect(),
111
// Generate up to 4KiB of padding between basic blocks. Although we only
112
// explicitly generate up to 16 blocks, after SSA construction we can
113
// end up with way more blocks than that (Seeing 400 blocks is not uncommon).
114
// At 4KiB we end up at around 1.5MiB of padding per function, which seems reasonable.
115
bb_padding_log2_size: 0..=12,
116
}
117
}
118
}
119
120