From: David Chase Date: Tue, 27 Sep 2022 18:37:35 +0000 (-0400) Subject: cmd/compile: make a type-specialized copy of encoding/binary.ReadUvarint X-Git-Tag: go1.20rc1~894 X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=caa8e1f97788d4276276d68610fadc6179a022ee;p=gostls13.git cmd/compile: make a type-specialized copy of encoding/binary.ReadUvarint This is to get better escape analysis for a frequently-allocated object. Change-Id: I1942a4e1c3cd1f0fa870bc8433a0165c18ce9c75 Reviewed-on: https://go-review.googlesource.com/c/go/+/435336 Reviewed-by: Keith Randall TryBot-Result: Gopher Robot Reviewed-by: Keith Randall Run-TryBot: David Chase Reviewed-by: Matthew Dempsky --- diff --git a/src/internal/pkgbits/decoder.go b/src/internal/pkgbits/decoder.go index 1a18da3301..4fe024d4f1 100644 --- a/src/internal/pkgbits/decoder.go +++ b/src/internal/pkgbits/decoder.go @@ -6,6 +6,7 @@ package pkgbits import ( "encoding/binary" + "errors" "fmt" "go/constant" "go/token" @@ -246,11 +247,39 @@ func (r *Decoder) checkErr(err error) { } func (r *Decoder) rawUvarint() uint64 { - x, err := binary.ReadUvarint(&r.Data) + x, err := readUvarint(&r.Data) r.checkErr(err) return x } +// readUvarint is a type-specialized copy of encoding/binary.ReadUvarint. +// This avoids the interface conversion and thus has better escape properties, +// which flows up the stack. +func readUvarint(r *strings.Reader) (uint64, error) { + var x uint64 + var s uint + for i := 0; i < binary.MaxVarintLen64; i++ { + b, err := r.ReadByte() + if err != nil { + if i > 0 && err == io.EOF { + err = io.ErrUnexpectedEOF + } + return x, err + } + if b < 0x80 { + if i == binary.MaxVarintLen64-1 && b > 1 { + return x, overflow + } + return x | uint64(b)<