Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 19 additions & 17 deletions src/tools/fuzzing/fuzzing.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -82,37 +82,40 @@ TranslateToFuzzReader::TranslateToFuzzReader(Module& wasm,
// the process creation overhead of all the things we run from python), and
// the defaults are tuned to that. This corresponds to INPUT_SIZE_MEAN in
// scripts/fuzz_opt.py
const double MEAN_SIZE = 40 * 1024;
const uint64_t MEAN_SIZE = 40 * 1024;

// As we have not read anything from the input, the remaining size is its
// size.
double size = random.remaining();
auto ratio = size / MEAN_SIZE;
uint64_t size = random.remaining();

auto bits = random.get();
if (bits & 1) {
fuzzParams->MAX_NEW_GC_TYPES *= ratio;
fuzzParams->MAX_NEW_GC_TYPES =
(uint64_t(fuzzParams->MAX_NEW_GC_TYPES) * size) / MEAN_SIZE;
}
if (bits & 2) {
fuzzParams->MAX_GLOBALS *= ratio;
fuzzParams->MAX_GLOBALS =
(uint64_t(fuzzParams->MAX_GLOBALS) * size) / MEAN_SIZE;
}
if (bits & 4) {
// Only adjust the limit if there is one.
if (fuzzParams->HANG_LIMIT) {
fuzzParams->HANG_LIMIT *= ratio;
fuzzParams->HANG_LIMIT =
(uint64_t(fuzzParams->HANG_LIMIT) * size) / MEAN_SIZE;
// There is a limit, so keep it non-zero to actually prevent hangs.
fuzzParams->HANG_LIMIT = std::max(fuzzParams->HANG_LIMIT, 1);
}
}
if (bits & 8) {
// Only increase the number of tries. Trying fewer times does not help
// find more interesting patterns.
if (ratio > 1) {
fuzzParams->TRIES *= ratio;
if (size > MEAN_SIZE) {
fuzzParams->TRIES = (uint64_t(fuzzParams->TRIES) * size) / MEAN_SIZE;
}
}
if (bits & 16) {
fuzzParams->MAX_ARRAY_SIZE *= ratio;
fuzzParams->MAX_ARRAY_SIZE =
(uint64_t(fuzzParams->MAX_ARRAY_SIZE) * size) / MEAN_SIZE;
}
}

Expand Down Expand Up @@ -1972,10 +1975,9 @@ void TranslateToFuzzReader::mutate(Function* func) {
// \integral_0^1 t^9 dx = 0.1 * t^10 |_0^1 = 0.1
// As a result, we get a value in the range of 0-100%. (Note that 100% is ok
// since we can't replace everything anyhow, see below.)
double t = r;
t = t / 100;
t = pow(t, 9);
Index percentChance = t * 100;
uint64_t r3 = uint64_t(r) * r * r;
uint64_t r9 = r3 * r3 * r3;
Index percentChance = r9 / 10000000000000000ULL;
// Adjust almost-zero frequencies to at least a few %, just so we have some
// reasonable chance of making some changes.
percentChance = std::max(percentChance, Index(3));
Expand Down Expand Up @@ -2419,7 +2421,7 @@ void TranslateToFuzzReader::mutateJSBoundary() {
std::vector<Call*> callImports;
};

using NameInfoMap = std::unordered_map<Name, FunctionInfo>;
using NameInfoMap = std::map<Name, FunctionInfo>;

struct FunctionInfoScanner
: public WalkerPass<PostWalker<FunctionInfoScanner>> {
Expand Down Expand Up @@ -2535,9 +2537,9 @@ void TranslateToFuzzReader::mutateJSBoundary() {

// First, refine params sent to imports. Gather the LUB sent to each import,
// and then refine.
std::unordered_map<Name, LUBFinder> paramLUBs;
for (auto& [_, info] : map) {
for (auto* call : info.callImports) {
std::map<Name, LUBFinder> paramLUBs;
for (const auto& [_, info] : map) {
for (const auto* call : info.callImports) {
auto declaredParams = wasm.getFunction(call->target)->getParams();
std::vector<Type> sent;
for (Index i = 0; i < call->operands.size(); i++) {
Expand Down
120 changes: 71 additions & 49 deletions test/passes/translate-to-fuzz_all-features_metrics_noprint.txt
Original file line number Diff line number Diff line change
@@ -1,55 +1,77 @@
Metrics
total
[exports] : 10
[funcs] : 5
[globals] : 2
[exports] : 63
[funcs] : 93
[globals] : 1
[imports] : 13
[memories] : 1
[memory-data] : 16
[table-data] : 2
[table-data] : 44
[tables] : 2
[tags] : 3
[total] : 704
[vars] : 26
ArrayNewFixed : 6
AtomicFence : 3
Binary : 30
Block : 130
BrOn : 6
Break : 23
Call : 30
CallRef : 2
Const : 103
Drop : 10
GlobalGet : 44
GlobalSet : 42
I31Get : 3
If : 39
Load : 6
LocalGet : 25
LocalSet : 27
Loop : 16
MemoryInit : 1
Nop : 7
Pop : 6
RefEq : 1
RefFunc : 11
RefI31 : 10
RefNull : 10
RefTest : 7
Return : 3
Select : 1
Store : 2
StringConst : 7
StringEq : 1
StringMeasure : 2
StringWTF16Get : 2
StructNew : 8
TableSet : 2
Throw : 2
Try : 6
TryTable : 6
TupleExtract : 3
TupleMake : 5
Unary : 35
Unreachable : 21
[tags] : 2
[total] : 5682
[vars] : 449
ArrayCmpxchg : 1
ArrayFill : 4
ArrayGet : 2
ArrayLen : 13
ArrayNew : 62
ArrayNewFixed : 21
ArraySet : 9
AtomicCmpxchg : 3
AtomicFence : 8
AtomicNotify : 3
AtomicRMW : 7
Binary : 357
Block : 873
BrOn : 26
Break : 97
Call : 192
CallIndirect : 27
CallRef : 12
Const : 950
Drop : 83
GlobalGet : 342
GlobalSet : 340
I31Get : 9
If : 266
Load : 43
LocalGet : 213
LocalSet : 190
Loop : 77
MemoryCopy : 2
MemoryInit : 3
Nop : 67
Pop : 16
RefAs : 78
RefCast : 12
RefEq : 23
RefFunc : 142
RefI31 : 27
RefIsNull : 13
RefNull : 145
RefTest : 4
Return : 48
SIMDExtract : 14
Select : 29
Store : 13
StringConst : 49
StringEncode : 4
StringEq : 8
StringMeasure : 9
StringWTF16Get : 5
StructCmpxchg : 5
StructGet : 15
StructNew : 128
StructRMW : 4
StructSet : 5
Switch : 4
TableSet : 3
Throw : 11
ThrowRef : 4
Try : 19
TryTable : 45
TupleExtract : 26
TupleMake : 24
Unary : 276
Unreachable : 172
Loading
Loading