]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/compile: make a type-specialized copy of encoding/binary.ReadUvarint
authorDavid Chase <drchase@google.com>
Tue, 27 Sep 2022 18:37:35 +0000 (14:37 -0400)
committerDavid Chase <drchase@google.com>
Tue, 27 Sep 2022 20:58:46 +0000 (20:58 +0000)
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 <khr@golang.org>
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Keith Randall <khr@google.com>
Run-TryBot: David Chase <drchase@google.com>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
src/internal/pkgbits/decoder.go

index 1a18da330148fccfb0cad2045edeef3435915c68..4fe024d4f191031d6a8025afe232558e96c6ae88 100644 (file)
@@ -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)<<s, nil
+               }
+               x |= uint64(b&0x7f) << s
+               s += 7
+       }
+       return x, overflow
+}
+
+var overflow = errors.New("pkgbits: readUvarint overflows a 64-bit integer")
+
 func (r *Decoder) rawVarint() int64 {
        ux := r.rawUvarint()