Skip to content

Commit 9b3c1ae

Browse files
committed
mutation: Simplify ArgumentsMutator by not storing the instance
1 parent 04ced4e commit 9b3c1ae

File tree

4 files changed

+23
-62
lines changed

4 files changed

+23
-62
lines changed

src/jmh/java/com/code_intelligence/jazzer/mutation/MutatorBenchmark.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ public static class BenchmarkState {
5858
@Setup(Level.Iteration)
5959
public void setUp() throws NoSuchMethodException {
6060
mutator =
61-
ArgumentsMutator.forStaticMethodOrThrow(
61+
ArgumentsMutator.forMethodOrThrow(
6262
MutatorBenchmark.class.getMethod("fuzzMinimal", List.class));
6363
}
6464
}
@@ -70,7 +70,7 @@ public void mutateDetachInvoke(BenchmarkState state) throws Throwable {
7070
mutator.init(prng);
7171
for (int i = 0; i < state.mutations; i++) {
7272
mutator.mutate(prng);
73-
mutator.invoke(true);
73+
mutator.invoke(null, true);
7474
}
7575
}
7676

@@ -88,7 +88,7 @@ public void mutateReadInvokeWrite(BenchmarkState state) throws Throwable {
8888
out.reset();
8989
mutator.write(out);
9090
buffer = out.toByteArray();
91-
mutator.invoke(false);
91+
mutator.invoke(null, false);
9292
}
9393
}
9494
}

src/main/java/com/code_intelligence/jazzer/driver/FuzzTargetRunner.java

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,6 @@
3838
import java.io.IOException;
3939
import java.lang.invoke.MethodHandle;
4040
import java.lang.invoke.MethodHandles;
41-
import java.lang.reflect.Modifier;
4241
import java.math.BigInteger;
4342
import java.nio.charset.StandardCharsets;
4443
import java.security.MessageDigest;
@@ -159,11 +158,7 @@ public final class FuzzTargetRunner {
159158
}
160159

161160
if (useExperimentalMutator) {
162-
if (Modifier.isStatic(fuzzTarget.method.getModifiers())) {
163-
mutator = ArgumentsMutator.forStaticMethodOrThrow(fuzzTarget.method);
164-
} else {
165-
mutator = ArgumentsMutator.forInstanceMethodOrThrow(fuzzTargetInstance, fuzzTarget.method);
166-
}
161+
mutator = ArgumentsMutator.forMethodOrThrow(fuzzTarget.method);
167162
Log.info("Using experimental mutator: " + mutator);
168163
} else {
169164
mutator = null;
@@ -242,7 +237,7 @@ private static int runOne(long dataPtr, int dataLength) {
242237
if (useExperimentalMutator) {
243238
// No need to detach as we are currently reading in the mutator state from bytes in every
244239
// iteration.
245-
mutator.invoke(false);
240+
mutator.invoke(fuzzTargetInstance, false);
246241
} else if (fuzzTargetInstance == null) {
247242
fuzzTargetMethod.invoke(argument);
248243
} else {

src/main/java/com/code_intelligence/jazzer/mutation/ArgumentsMutator.java

Lines changed: 9 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@
2222
import static com.code_intelligence.jazzer.mutation.support.StreamSupport.toArrayOrEmpty;
2323
import static java.lang.String.format;
2424
import static java.util.Arrays.stream;
25-
import static java.util.Objects.requireNonNull;
2625
import static java.util.stream.Collectors.joining;
2726

2827
import com.code_intelligence.jazzer.mutation.api.MutatorFactory;
@@ -42,11 +41,9 @@
4241
import java.lang.reflect.AnnotatedType;
4342
import java.lang.reflect.InvocationTargetException;
4443
import java.lang.reflect.Method;
45-
import java.lang.reflect.Modifier;
4644
import java.util.Optional;
4745

4846
public final class ArgumentsMutator {
49-
private final Object instance;
5047
private final Method method;
5148
private final ProductMutator productMutator;
5249
private Object[] arguments;
@@ -60,8 +57,7 @@ public final class ArgumentsMutator {
6057
*/
6158
private boolean argumentsExposed;
6259

63-
private ArgumentsMutator(Object instance, Method method, ProductMutator productMutator) {
64-
this.instance = instance;
60+
private ArgumentsMutator(Method method, ProductMutator productMutator) {
6561
this.method = method;
6662
this.productMutator = productMutator;
6763
}
@@ -74,44 +70,19 @@ private static String prettyPrintMethod(Method method) {
7470
stream(method.getAnnotatedParameterTypes()).map(Object::toString).collect(joining(", ")));
7571
}
7672

77-
public static ArgumentsMutator forInstanceMethodOrThrow(Object instance, Method method) {
78-
return forInstanceMethod(Mutators.newFactory(), instance, method)
79-
.orElseThrow(
80-
() ->
81-
new IllegalArgumentException(
82-
"Failed to construct mutator for " + prettyPrintMethod(method)));
83-
}
84-
85-
public static ArgumentsMutator forStaticMethodOrThrow(Method method) {
86-
return forStaticMethod(Mutators.newFactory(), method)
73+
public static ArgumentsMutator forMethodOrThrow(Method method) {
74+
return forMethod(Mutators.newFactory(), method)
8775
.orElseThrow(
8876
() ->
8977
new IllegalArgumentException(
9078
"Failed to construct mutator for " + prettyPrintMethod(method)));
9179
}
9280

9381
public static Optional<ArgumentsMutator> forMethod(Method method) {
94-
return forMethod(Mutators.newFactory(), null, method);
82+
return forMethod(Mutators.newFactory(), method);
9583
}
9684

97-
public static Optional<ArgumentsMutator> forInstanceMethod(
98-
MutatorFactory mutatorFactory, Object instance, Method method) {
99-
require(!isStatic(method), "method must not be static");
100-
requireNonNull(instance, "instance must not be null");
101-
require(
102-
method.getDeclaringClass().isInstance(instance),
103-
format("instance is a %s, expected %s", instance.getClass(), method.getDeclaringClass()));
104-
return forMethod(mutatorFactory, instance, method);
105-
}
106-
107-
public static Optional<ArgumentsMutator> forStaticMethod(
108-
MutatorFactory mutatorFactory, Method method) {
109-
require(isStatic(method), "method must be static");
110-
return forMethod(mutatorFactory, null, method);
111-
}
112-
113-
public static Optional<ArgumentsMutator> forMethod(
114-
MutatorFactory mutatorFactory, Object instance, Method method) {
85+
public static Optional<ArgumentsMutator> forMethod(MutatorFactory mutatorFactory, Method method) {
11586
require(method.getParameterCount() > 0, "Can't fuzz method without parameters: " + method);
11687
for (AnnotatedType parameter : method.getAnnotatedParameterTypes()) {
11788
validateAnnotationUsage(parameter);
@@ -120,18 +91,13 @@ public static Optional<ArgumentsMutator> forMethod(
12091
stream(method.getAnnotatedParameterTypes()).map(mutatorFactory::tryCreate),
12192
SerializingMutator<?>[]::new)
12293
.map(MutatorCombinators::mutateProduct)
123-
.map(productMutator -> ArgumentsMutator.create(instance, method, productMutator));
94+
.map(productMutator -> ArgumentsMutator.create(method, productMutator));
12495
}
12596

126-
private static ArgumentsMutator create(
127-
Object instance, Method method, ProductMutator productMutator) {
97+
private static ArgumentsMutator create(Method method, ProductMutator productMutator) {
12898
method.setAccessible(true);
12999

130-
return new ArgumentsMutator(instance, method, productMutator);
131-
}
132-
133-
private static boolean isStatic(Method method) {
134-
return Modifier.isStatic(method.getModifiers());
100+
return new ArgumentsMutator(method, productMutator);
135101
}
136102

137103
/**
@@ -203,7 +169,7 @@ void mutate(PseudoRandom prng) {
203169
productMutator.mutateInPlace(arguments, prng);
204170
}
205171

206-
public void invoke(boolean detach) throws Throwable {
172+
public void invoke(Object instance, boolean detach) throws Throwable {
207173
Object[] invokeArguments;
208174
if (detach) {
209175
invokeArguments = productMutator.detach(arguments);

src/test/java/com/code_intelligence/jazzer/mutation/ArgumentsMutatorTest.java

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ void testStaticMethod() throws Throwable {
4848
Method method =
4949
ArgumentsMutatorTest.class.getMethod("fuzzThisFunction", List.class, List.class);
5050
Optional<ArgumentsMutator> maybeMutator =
51-
ArgumentsMutator.forStaticMethod(Mutators.newFactory(), method);
51+
ArgumentsMutator.forMethod(Mutators.newFactory(), method);
5252
assertThat(maybeMutator).isPresent();
5353
ArgumentsMutator mutator = maybeMutator.get();
5454

@@ -77,7 +77,7 @@ void testStaticMethod() throws Throwable {
7777

7878
fuzzThisFunctionArgument1 = null;
7979
fuzzThisFunctionArgument2 = null;
80-
mutator.invoke(true);
80+
mutator.invoke(this, true);
8181
assertThat(fuzzThisFunctionArgument1).containsExactly(singletonList(true));
8282
assertThat(fuzzThisFunctionArgument2).containsExactly(false);
8383

@@ -106,7 +106,7 @@ void testStaticMethod() throws Throwable {
106106

107107
fuzzThisFunctionArgument1 = null;
108108
fuzzThisFunctionArgument2 = null;
109-
mutator.invoke(true);
109+
mutator.invoke(this, true);
110110
assertThat(fuzzThisFunctionArgument1).containsExactly(singletonList(false));
111111
assertThat(fuzzThisFunctionArgument2).containsExactly(false);
112112

@@ -139,7 +139,7 @@ void testStaticMethod() throws Throwable {
139139

140140
fuzzThisFunctionArgument1 = null;
141141
fuzzThisFunctionArgument2 = null;
142-
mutator.invoke(false);
142+
mutator.invoke(this, false);
143143
assertThat(fuzzThisFunctionArgument1).containsExactly(singletonList(true));
144144
assertThat(fuzzThisFunctionArgument2).containsExactly(false);
145145
}
@@ -157,7 +157,7 @@ void testInstanceMethod() throws Throwable {
157157
Method method =
158158
ArgumentsMutatorTest.class.getMethod("mutableFuzzThisFunction", List.class, List.class);
159159
Optional<ArgumentsMutator> maybeMutator =
160-
ArgumentsMutator.forInstanceMethod(Mutators.newFactory(), this, method);
160+
ArgumentsMutator.forMethod(Mutators.newFactory(), method);
161161
assertThat(maybeMutator).isPresent();
162162
ArgumentsMutator mutator = maybeMutator.get();
163163

@@ -186,7 +186,7 @@ void testInstanceMethod() throws Throwable {
186186

187187
mutableFuzzThisFunctionArgument1 = null;
188188
mutableFuzzThisFunctionArgument2 = null;
189-
mutator.invoke(true);
189+
mutator.invoke(this, true);
190190
assertThat(mutableFuzzThisFunctionArgument1).containsExactly(singletonList(true));
191191
assertThat(mutableFuzzThisFunctionArgument2).containsExactly(false);
192192

@@ -215,7 +215,7 @@ void testInstanceMethod() throws Throwable {
215215

216216
mutableFuzzThisFunctionArgument1 = null;
217217
mutableFuzzThisFunctionArgument2 = null;
218-
mutator.invoke(true);
218+
mutator.invoke(this, true);
219219
assertThat(mutableFuzzThisFunctionArgument1).containsExactly(singletonList(false));
220220
assertThat(mutableFuzzThisFunctionArgument2).containsExactly(false);
221221

@@ -248,7 +248,7 @@ void testInstanceMethod() throws Throwable {
248248

249249
mutableFuzzThisFunctionArgument1 = null;
250250
mutableFuzzThisFunctionArgument2 = null;
251-
mutator.invoke(false);
251+
mutator.invoke(this, false);
252252
assertThat(mutableFuzzThisFunctionArgument1).containsExactly(singletonList(true));
253253
assertThat(mutableFuzzThisFunctionArgument2).containsExactly(false);
254254
}
@@ -261,7 +261,7 @@ public void crossOverFunction(List<Boolean> list) {}
261261
void testCrossOver() throws Throwable {
262262
Method method = ArgumentsMutatorTest.class.getMethod("crossOverFunction", List.class);
263263
Optional<ArgumentsMutator> maybeMutator =
264-
ArgumentsMutator.forInstanceMethod(Mutators.newFactory(), this, method);
264+
ArgumentsMutator.forMethod(Mutators.newFactory(), method);
265265
assertThat(maybeMutator).isPresent();
266266
ArgumentsMutator mutator = maybeMutator.get();
267267

0 commit comments

Comments
 (0)