mirror of https://github.com/golang/go.git
cmd/link: combine all string data into one symbol
This CL introduces a mergestrings pass after the reachability analysis to combine all reachable go.string."..." character data symbols into a single symbol. Shrinks juju by 1.2mb (1.5%). Shrinks cmd/go by 0.5% when building without DWARF. No noticable effect on linker speed. Change-Id: I2ba3e60bf418f65766bda257f6ca9eea26d895b6 Reviewed-on: https://go-review.googlesource.com/20165 Run-TryBot: David Crawshaw <crawshaw@golang.org> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Ian Lance Taylor <iant@golang.org>
This commit is contained in:
parent
7e92c86df2
commit
0c84c4f19c
|
|
@ -0,0 +1,66 @@
|
|||
// Copyright 2016 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package ld
|
||||
|
||||
import (
|
||||
"cmd/internal/obj"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// mergestrings merges all go.string.* character data into a single symbol.
|
||||
//
|
||||
// Combining string data symbols reduces the total binary size and
|
||||
// makes deduplication possible.
|
||||
func mergestrings() {
|
||||
if Buildmode == BuildmodeShared {
|
||||
return
|
||||
}
|
||||
|
||||
strs := make([]*LSym, 0, 256)
|
||||
seenStr := make(map[string]bool, 256) // symbol name -> in strs slice
|
||||
relocsToStrs := make(map[*LSym][]*Reloc, 256) // string -> relocation to string
|
||||
size := 0 // number of bytes in all strings
|
||||
|
||||
// Collect strings and relocations that point to strings.
|
||||
for _, s := range Ctxt.Allsym {
|
||||
if !s.Attr.Reachable() || s.Attr.Special() {
|
||||
continue
|
||||
}
|
||||
for i := range s.R {
|
||||
r := &s.R[i]
|
||||
if r.Sym == nil {
|
||||
continue
|
||||
}
|
||||
if !seenStr[r.Sym.Name] {
|
||||
if !strings.HasPrefix(r.Sym.Name, "go.string.") {
|
||||
continue
|
||||
}
|
||||
if strings.HasPrefix(r.Sym.Name, "go.string.hdr") {
|
||||
continue
|
||||
}
|
||||
strs = append(strs, r.Sym)
|
||||
seenStr[r.Sym.Name] = true
|
||||
size += len(r.Sym.P)
|
||||
}
|
||||
relocsToStrs[r.Sym] = append(relocsToStrs[r.Sym], r)
|
||||
}
|
||||
}
|
||||
|
||||
// Put all string data into a single symbol and update the relocations.
|
||||
alldata := Linklookup(Ctxt, "go.string.alldata", 0)
|
||||
alldata.Type = obj.SGOSTRING
|
||||
alldata.Attr |= AttrReachable
|
||||
alldata.Size = int64(size)
|
||||
alldata.P = make([]byte, 0, size)
|
||||
for _, str := range strs {
|
||||
off := len(alldata.P)
|
||||
alldata.P = append(alldata.P, str.P...)
|
||||
str.Attr.Set(AttrReachable, false)
|
||||
for _, r := range relocsToStrs[str] {
|
||||
r.Add += int64(off)
|
||||
r.Sym = alldata
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -197,6 +197,7 @@ func Ldmain() {
|
|||
checkstrdata()
|
||||
deadcode()
|
||||
callgraph()
|
||||
mergestrings()
|
||||
|
||||
doelf()
|
||||
if HEADTYPE == obj.Hdarwin {
|
||||
|
|
|
|||
Loading…
Reference in New Issue