1
0
mirror of https://github.com/golang/go synced 2024-11-17 06:04:47 -07:00

cmd: use 128-bit SHA256 & encode in base64 for content hashes

We used to use SHA1 for content hashes, but CL 402595 changed
all the “don't care” hashes to cmd/internal/notsha256 (negated SHA256).
This made object files a little bit bigger: fmt.a on my Mac laptop grows
from 910678 to 937612 bytes (+3%).

To remove that growth, truncate the hash we use for these purposes
to 128 bits (half a SHA256), and also use base64 instead of hex for
encoding it when a string form is needed. This brings fmt.a down to
901706 bytes (-1% from original, -4% from current).

Change-Id: Id81da1cf3ee85ed130b3cda73aa697d8c0053a62
Reviewed-on: https://go-review.googlesource.com/c/go/+/404294
Auto-Submit: Russ Cox <rsc@golang.org>
Run-TryBot: Russ Cox <rsc@golang.org>
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Cherry Mui <cherryyz@google.com>
This commit is contained in:
Russ Cox 2022-05-05 09:41:53 -04:00 committed by Gopher Robot
parent 1926fa5f84
commit 485a572243
3 changed files with 15 additions and 6 deletions

View File

@ -5,6 +5,7 @@
package staticdata
import (
"encoding/base64"
"fmt"
"go/constant"
"io"
@ -61,9 +62,15 @@ func InitSliceBytes(nam *ir.Name, off int64, s string) {
const (
stringSymPrefix = "go.string."
stringSymPattern = ".gostring.%d.%x"
stringSymPattern = ".gostring.%d.%s"
)
// shortHashString converts the hash to a string for use with stringSymPattern.
// We cut it to 16 bytes and then base64-encode to make it even smaller.
func shortHashString(hash []byte) string {
return base64.StdEncoding.EncodeToString(hash[:16])
}
// StringSym returns a symbol containing the string s.
// The symbol contains the string data, not a string header.
func StringSym(pos src.XPos, s string) (data *obj.LSym) {
@ -75,7 +82,7 @@ func StringSym(pos src.XPos, s string) (data *obj.LSym) {
// Same pattern is known to fileStringSym below.
h := notsha256.New()
io.WriteString(h, s)
symname = fmt.Sprintf(stringSymPattern, len(s), h.Sum(nil))
symname = fmt.Sprintf(stringSymPattern, len(s), shortHashString(h.Sum(nil)))
} else {
// Small strings get named directly by their contents.
symname = strconv.Quote(s)
@ -162,7 +169,7 @@ func fileStringSym(pos src.XPos, file string, readonly bool, hash []byte) (*obj.
var symdata *obj.LSym
if readonly {
symname := fmt.Sprintf(stringSymPattern, size, sum)
symname := fmt.Sprintf(stringSymPattern, size, shortHashString(sum))
symdata = base.Ctxt.Lookup(stringSymPrefix + symname)
if !symdata.OnList() {
info := symdata.NewFileInfo()

View File

@ -20,7 +20,6 @@ package goobj
import (
"cmd/internal/bio"
"cmd/internal/notsha256"
"encoding/binary"
"errors"
"fmt"
@ -367,7 +366,7 @@ const Hash64Size = 8
// Hash
type HashType [HashSize]byte
const HashSize = notsha256.Size
const HashSize = 16 // truncated SHA256
// Relocation.
//

View File

@ -35,6 +35,7 @@ import (
"cmd/internal/goobj"
"cmd/internal/notsha256"
"cmd/internal/objabi"
"encoding/base64"
"fmt"
"internal/buildcfg"
"log"
@ -175,7 +176,9 @@ func (ctxt *Link) Int64Sym(i int64) *LSym {
// GCLocalsSym generates a content-addressable sym containing data.
func (ctxt *Link) GCLocalsSym(data []byte) *LSym {
return ctxt.LookupInit(fmt.Sprintf("gclocals·%x", notsha256.Sum256(data)), func(lsym *LSym) {
sum := notsha256.Sum256(data)
str := base64.StdEncoding.EncodeToString(sum[:16])
return ctxt.LookupInit(fmt.Sprintf("gclocals·%s", str), func(lsym *LSym) {
lsym.P = data
lsym.Set(AttrContentAddressable, true)
})