From: Roland Shoemaker Date: Tue, 27 Apr 2021 19:16:03 +0000 (-0700) Subject: [dev.fuzz] internal/fuzz: don't use temporary buffers X-Git-Tag: go1.18beta1~1282^2~45 X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=5542c10fbf19cb199d1659c18963f9ed83570746;p=gostls13.git [dev.fuzz] internal/fuzz: don't use temporary buffers We're already allocating a huge amount of space at the end of each byte slice, so just use that for scratch space instead of allocating a new temporary buffer. Change-Id: Ie075a199d4ac5dd5789949af2a19815c3025b809 Reviewed-on: https://go-review.googlesource.com/c/go/+/314272 Trust: Roland Shoemaker Trust: Katie Hockman Run-TryBot: Roland Shoemaker TryBot-Result: Go Bot Reviewed-by: Katie Hockman --- diff --git a/src/internal/fuzz/mutator.go b/src/internal/fuzz/mutator.go index d4ca31e6e5..bd8651f806 100644 --- a/src/internal/fuzz/mutator.go +++ b/src/internal/fuzz/mutator.go @@ -31,7 +31,7 @@ func (m *mutator) randByteOrder() binary.ByteOrder { return binary.BigEndian } -// chooseLen chooses length of range mutation in range [0,n]. It gives +// chooseLen chooses length of range mutation in range [1,n]. It gives // preference to shorter ranges. func (m *mutator) chooseLen(n int) int { switch x := m.rand(100); { @@ -292,15 +292,26 @@ func (m *mutator) mutateBytes(ptrB *[]byte) { dst = m.rand(len(b)) } n := m.chooseLen(len(b) - src) - if len(b)+n >= cap(b) { + // Use the end of the slice as scratch space to avoid doing an + // allocation. If the slice is too small abort and try something + // else. + if len(b)+(n*2) >= cap(b) { iter-- continue } - tmp := make([]byte, n) - copy(tmp, b[src:]) - b = b[:len(b)+n] - copy(b[dst+n:], b[dst:]) - copy(b[dst:], tmp) + end := len(b) + // Increase the size of b to fit the duplicated block as well as + // some extra working space + b = b[:end+(n*2)] + // Copy the block of bytes we want to duplicate to the end of the + // slice + copy(b[end+n:], b[src:src+n]) + // Shift the bytes after the splice point n positions to the right + // to make room for the new block + copy(b[dst+n:end+n], b[dst:end]) + // Insert the duplicate block into the splice point + copy(b[dst:], b[end+n:]) + b = b[:end+n] case 3: // Overwrite a range of bytes with a randomly selected // chunk @@ -494,10 +505,19 @@ func (m *mutator) mutateBytes(ptrB *[]byte) { dst = m.rand(len(b)) } n := m.chooseLen(len(b) - src) - tmp := make([]byte, n) - copy(tmp, b[dst:]) + // Use the end of the slice as scratch space to avoid doing an + // allocation. If the slice is too small abort and try something + // else. + if len(b)+n >= cap(b) { + iter-- + continue + } + end := len(b) + b = b[:end+n] + copy(b[end:], b[dst:dst+n]) copy(b[dst:], b[src:src+n]) - copy(b[src:], tmp) + copy(b[src:], b[end:]) + b = b[:end] default: panic("unknown mutator") }