diff options
| author | Dmitry Vyukov <dvyukov@google.com> | 2022-11-25 12:50:29 +0100 |
|---|---|---|
| committer | Dmitry Vyukov <dvyukov@google.com> | 2022-11-25 13:14:53 +0100 |
| commit | 70393e5d05ae78166599755b835f0d465c815f48 (patch) | |
| tree | f674c69030c296100885d68d65c3c9f20b062bcf /prog | |
| parent | 0d68fcb4879b7f76e4242bfa0b0004c9a0eb9b5e (diff) | |
prog: don't materialize uncompressed image in Deserialize
Currently we uncompress all images in Deserialize to check that the data is valid.
As the result deserializing all seeds we have takes ~40 seconds of real time
and ~125 seconds of CPU time. And we do this during every syz-manager start.
Don't materialize the uncompressed image.
This reduces real time to ~15 seconds and CPU time to 18 seconds (no garbage collections).
In syz-manager the benefit is even larger since garbage collections take longer (larger heap).
Diffstat (limited to 'prog')
| -rw-r--r-- | prog/compression.go | 16 | ||||
| -rw-r--r-- | prog/encoding.go | 6 |
2 files changed, 13 insertions, 9 deletions
diff --git a/prog/compression.go b/prog/compression.go index 07c3bd02c..87820b5ee 100644 --- a/prog/compression.go +++ b/prog/compression.go @@ -29,18 +29,22 @@ func Compress(rawData []byte) []byte { } func Decompress(compressedData []byte) ([]byte, error) { + buf := new(bytes.Buffer) + err := DecompressWriter(buf, compressedData) + return buf.Bytes(), err +} + +func DecompressWriter(w io.Writer, compressedData []byte) error { zlibReader, err := zlib.NewReader(bytes.NewReader(compressedData)) if err != nil { - return nil, fmt.Errorf("could not initialise zlib: %v", err) + return fmt.Errorf("could not initialise zlib: %v", err) } - data, err := io.ReadAll(zlibReader) - if err != nil { - return nil, fmt.Errorf("could not read data with zlib: %v", err) + if _, err := io.Copy(w, zlibReader); err != nil { + return fmt.Errorf("could not read data with zlib: %v", err) } - err = zlibReader.Close() - return data, err + return zlibReader.Close() } func DecodeB64(b64Data []byte) ([]byte, error) { diff --git a/prog/encoding.go b/prog/encoding.go index 5c4be432e..6b9fbe501 100644 --- a/prog/encoding.go +++ b/prog/encoding.go @@ -7,6 +7,7 @@ import ( "bytes" "encoding/hex" "fmt" + "io/ioutil" "reflect" "strconv" "strings" @@ -603,11 +604,10 @@ func (p *parser) parseArgString(t Type, dir Dir) (Arg, error) { } // Check compressed data for validity. if typ.IsCompressed() { - _, err = Decompress(data) - if err != nil { + if err := DecompressWriter(ioutil.Discard, data); err != nil { p.strictFailf("invalid compressed data in arg: %v", err) // In non-strict mode, empty the data slice. - data = Compress([]byte{}) + data = Compress(nil) } } size := ^uint64(0) |
