Commit a0232ea0 authored by Josh Bleecher Snyder's avatar Josh Bleecher Snyder

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: 's avatarDavid Crawshaw <crawshaw@golang.org>
parent 13f74db3
...@@ -6,7 +6,9 @@ package gc ...@@ -6,7 +6,9 @@ package gc
import ( import (
"cmd/internal/obj" "cmd/internal/obj"
"crypto/sha256"
"fmt" "fmt"
"io"
"strconv" "strconv"
) )
...@@ -181,27 +183,22 @@ func duintptr(s *Sym, off int, v uint64) int { ...@@ -181,27 +183,22 @@ func duintptr(s *Sym, off int, v uint64) int {
return duintxx(s, off, v, Widthptr) return duintxx(s, off, v, Widthptr)
} }
var stringsym_gen int
func stringsym(s string) (hdr, data *Sym) { func stringsym(s string) (hdr, data *Sym) {
var symname string var symname string
var pkg *Pkg
if len(s) > 100 { if len(s) > 100 {
// huge strings are made static to avoid long names // Huge strings are hashed to avoid long names in object files.
stringsym_gen++ // Indulge in some paranoia by writing the length of s, too,
symname = fmt.Sprintf(".gostring.%d", stringsym_gen) // as protection against length extension attacks.
h := sha256.New()
pkg = localpkg io.WriteString(h, s)
symname = fmt.Sprintf(".gostring.%d.%x", len(s), h.Sum(nil))
} else { } else {
// small strings get named by their contents, // Small strings get named directly by their contents.
// so that multiple modules using the same string
// can share it.
symname = strconv.Quote(s) symname = strconv.Quote(s)
pkg = gostringpkg
} }
symhdr := Pkglookup("hdr."+symname, pkg) symhdr := Pkglookup("hdr."+symname, gostringpkg)
symdata := Pkglookup(symname, pkg) symdata := Pkglookup(symname, gostringpkg)
// SymUniq flag indicates that data is generated already // SymUniq flag indicates that data is generated already
if symhdr.Flags&SymUniq != 0 { if symhdr.Flags&SymUniq != 0 {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment