1
0
mirror of https://github.com/golang/go synced 2024-11-19 10:04:56 -07:00

cmd/compile: allow deduplication of long strings

String symbols' names used to appear in the final binary.
Using a string's contents as it's symbol's name
was a thus a bad idea if the string's name was long.
Recent improvements by crawshaw have changed that.

Instead of placing long strings behind opaque names
in local packages, place them in the global string
package and make them content-addressable.
Symbol names still occur in the object files,
so use a hash to avoid needless length there.

Reduces the size of cmd/go by 30k.

Change-Id: Ifdbbaf47bf44352418c90ddd903d5106e48db4f1
Reviewed-on: https://go-review.googlesource.com/20524
Run-TryBot: Josh Bleecher Snyder <josharian@gmail.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: David Crawshaw <crawshaw@golang.org>
This commit is contained in:
Josh Bleecher Snyder 2016-03-10 11:14:22 -08:00
parent 13f74db304
commit a0232ea0dd

View File

@ -6,7 +6,9 @@ package gc
import (
"cmd/internal/obj"
"crypto/sha256"
"fmt"
"io"
"strconv"
)
@ -181,27 +183,22 @@ func duintptr(s *Sym, off int, v uint64) int {
return duintxx(s, off, v, Widthptr)
}
var stringsym_gen int
func stringsym(s string) (hdr, data *Sym) {
var symname string
var pkg *Pkg
if len(s) > 100 {
// huge strings are made static to avoid long names
stringsym_gen++
symname = fmt.Sprintf(".gostring.%d", stringsym_gen)
pkg = localpkg
// Huge strings are hashed to avoid long names in object files.
// Indulge in some paranoia by writing the length of s, too,
// as protection against length extension attacks.
h := sha256.New()
io.WriteString(h, s)
symname = fmt.Sprintf(".gostring.%d.%x", len(s), h.Sum(nil))
} else {
// small strings get named by their contents,
// so that multiple modules using the same string
// can share it.
// Small strings get named directly by their contents.
symname = strconv.Quote(s)
pkg = gostringpkg
}
symhdr := Pkglookup("hdr."+symname, pkg)
symdata := Pkglookup(symname, pkg)
symhdr := Pkglookup("hdr."+symname, gostringpkg)
symdata := Pkglookup(symname, gostringpkg)
// SymUniq flag indicates that data is generated already
if symhdr.Flags&SymUniq != 0 {