aboutsummaryrefslogtreecommitdiff
path: root/agent/src/test/java/com/code_intelligence
diff options
context:
space:
mode:
authorFabian Meumertzheim <meumertzheim@code-intelligence.com>2021-02-12 14:18:37 +0100
committerFabian Meumertzheim <fabian@meumertzhe.im>2021-02-22 14:14:52 +0100
commit0677032a0a698c920f02b44fcf7528fc3a6ce448 (patch)
tree370a96ae73a0fb0f0ca0e494f9c578f538d8be06 /agent/src/test/java/com/code_intelligence
parent97942a9f4924ca4c9cad2a2756e44ad29fb44fca (diff)
downloadjazzer-api-0677032a0a698c920f02b44fcf7528fc3a6ce448.tar.gz
Skip instrumentation for known no-throw methods
A method invocation only needs to be instrumented for coverage if the method can throw an exception (including RuntimeException, which is not declared via `throws`). For methods in the Java standard library (in `java.*`), this property is thoroughly documented via Javadoc. This commit adds a doclet, i.e., a Java program that parses Javadoc, for automatically compiling a list of known no-throw methods in `java.*`. The list is loaded lazily at runtime and used to skip calls to these methods in the coverage instrumentation. With OpenJDK 15, the list consists of almost 9000 methods, many of which are used very frequently and in performance-critical parts, e.g., StringBuilder#append(String) and List#size().
Diffstat (limited to 'agent/src/test/java/com/code_intelligence')
-rw-r--r--agent/src/test/java/com/code_intelligence/jazzer/instrumentor/CoverageInstrumentationTarget.java8
-rw-r--r--agent/src/test/java/com/code_intelligence/jazzer/instrumentor/CoverageInstrumentationTest.kt13
2 files changed, 13 insertions, 8 deletions
diff --git a/agent/src/test/java/com/code_intelligence/jazzer/instrumentor/CoverageInstrumentationTarget.java b/agent/src/test/java/com/code_intelligence/jazzer/instrumentor/CoverageInstrumentationTarget.java
index 5725ba23..7502481d 100644
--- a/agent/src/test/java/com/code_intelligence/jazzer/instrumentor/CoverageInstrumentationTarget.java
+++ b/agent/src/test/java/com/code_intelligence/jazzer/instrumentor/CoverageInstrumentationTarget.java
@@ -23,7 +23,7 @@ public class CoverageInstrumentationTarget implements DynamicTestContract {
@Override
public Map<String, Boolean> selfCheck() {
- Map<String, Boolean> results = new HashMap<>();
+ HashMap<String, Boolean> results = new HashMap<>();
results.put("for0", false);
results.put("for1", false);
@@ -50,16 +50,18 @@ public class CoverageInstrumentationTarget implements DynamicTestContract {
return results;
}
- private void foo(Map<String, Boolean> results) {
+ private void foo(HashMap<String, Boolean> results) {
bar(results);
}
+ // The use of Map instead of HashMap is deliberate here: Since Map#put can throw exceptions, the
+ // invocation should be instrumented for coverage.
private void bar(Map<String, Boolean> results) {
results.put("foobar", true);
}
@SuppressWarnings("unused")
- private void baz(Map<String, Boolean> results) {
+ private void baz(HashMap<String, Boolean> results) {
results.put("baz", false);
}
}
diff --git a/agent/src/test/java/com/code_intelligence/jazzer/instrumentor/CoverageInstrumentationTest.kt b/agent/src/test/java/com/code_intelligence/jazzer/instrumentor/CoverageInstrumentationTest.kt
index c689e1ac..31f40575 100644
--- a/agent/src/test/java/com/code_intelligence/jazzer/instrumentor/CoverageInstrumentationTest.kt
+++ b/agent/src/test/java/com/code_intelligence/jazzer/instrumentor/CoverageInstrumentationTest.kt
@@ -55,11 +55,14 @@ class CoverageInstrumentationTest {
private val innerForBodyIfSecondRun = 5
private val innerForIncrementCounter = 7
private val outerForIncrementCounter = 8
- private val selfCheckReturn = 9
- private val fooReturn = 10
- private val barReturn = 11
+ private val fooInvocation = 9
+ private val selfCheckReturn = 10
+ private val barInvocation = 11
+ private val fooReturn = 12
+ private val barMapPutInvocation = 13
+ private val barReturn = 14
@Suppress("unused")
- private val bazReturn = 12
+ private val bazReturn = 15
@Test
fun testOriginal() {
@@ -91,7 +94,7 @@ class CoverageInstrumentationTest {
assertControlFlow(
listOf(constructorReturn, ifFirstBranch, ifEnd) +
outerForControlFlow +
- listOf(barReturn, fooReturn, selfCheckReturn)
+ listOf(fooInvocation, barInvocation, barMapPutInvocation, barReturn, fooReturn, selfCheckReturn)
)
}