aboutsummaryrefslogtreecommitdiff
path: root/src/internal/fuzz/coverage.go
diff options
context:
space:
mode:
Diffstat (limited to 'src/internal/fuzz/coverage.go')
-rw-r--r--src/internal/fuzz/coverage.go63
1 files changed, 54 insertions, 9 deletions
diff --git a/src/internal/fuzz/coverage.go b/src/internal/fuzz/coverage.go
index bd1ff8690d..2468e70fa4 100644
--- a/src/internal/fuzz/coverage.go
+++ b/src/internal/fuzz/coverage.go
@@ -6,6 +6,7 @@ package fuzz
import (
"internal/unsafeheader"
+ "math/bits"
"unsafe"
)
@@ -36,26 +37,70 @@ func ResetCoverage() {
}
// SnapshotCoverage copies the current counter values into coverageSnapshot,
-// preserving them for later inspection.
+// preserving them for later inspection. SnapshotCoverage also rounds each
+// counter down to the nearest power of two. This lets the coordinator store
+// multiple values for each counter by OR'ing them together.
func SnapshotCoverage() {
cov := coverage()
- if coverageSnapshot == nil {
- coverageSnapshot = make([]byte, len(cov))
+ for i, b := range cov {
+ b |= b >> 1
+ b |= b >> 2
+ b |= b >> 4
+ b -= b >> 1
+ coverageSnapshot[i] = b
}
- copy(coverageSnapshot, cov)
}
-func countEdges(cov []byte) int {
+// diffCoverage returns a set of bits set in snapshot but not in base.
+// If there are no new bits set, diffCoverage returns nil.
+func diffCoverage(base, snapshot []byte) []byte {
+ found := false
+ for i := range snapshot {
+ if snapshot[i]&^base[i] != 0 {
+ found = true
+ break
+ }
+ }
+ if !found {
+ return nil
+ }
+ diff := make([]byte, len(snapshot))
+ for i := range diff {
+ diff[i] = snapshot[i] &^ base[i]
+ }
+ return diff
+}
+
+// countNewCoverageBits returns the number of bits set in snapshot that are not
+// set in base.
+func countNewCoverageBits(base, snapshot []byte) int {
n := 0
- for _, c := range cov {
- if c > 0 {
- n++
+ for i := range snapshot {
+ n += bits.OnesCount8(snapshot[i] &^ base[i])
+ }
+ return n
+}
+
+// hasCoverageBit returns true if snapshot has at least one bit set that is
+// also set in base.
+func hasCoverageBit(base, snapshot []byte) bool {
+ for i := range snapshot {
+ if snapshot[i]&base[i] != 0 {
+ return true
}
}
+ return false
+}
+
+func countBits(cov []byte) int {
+ n := 0
+ for _, c := range cov {
+ n += bits.OnesCount8(c)
+ }
return n
}
-var coverageSnapshot []byte
+var coverageSnapshot = make([]byte, len(coverage()))
// _counters and _ecounters mark the start and end, respectively, of where
// the 8-bit coverage counters reside in memory. They're known to cmd/link,