s := Ctxt.Lookup("type..importpath." + p.Prefix + ".")
ot := dnameData(s, 0, str, "", nil, false)
ggloblsym(s, int32(ot), obj.DUPOK|obj.RODATA)
+ s.Set(obj.AttrContentAddressable, true)
p.Pathsym = s
}
}
ot := dnameData(s, 0, name, tag, pkg, exported)
ggloblsym(s, int32(ot), obj.DUPOK|obj.RODATA)
+ s.Set(obj.AttrContentAddressable, true)
return s
}
// hashed symbols.
func (w *writer) contentHash(s *LSym) goobj.HashType {
h := sha1.New()
+ // Don't dedup type symbols with others, as they are in a different
+ // section.
+ if strings.HasPrefix(s.Name, "type.") {
+ h.Write([]byte{'T'})
+ } else {
+ h.Write([]byte{0})
+ }
// The compiler trims trailing zeros _sometimes_. We just do
// it always.
h.Write(bytes.TrimRight(s.P, "\x00"))
"log"
"math"
"sort"
+ "strings"
)
func Linknew(arch *LinkArch) *Link {
// if Pkgpath is unknown, cannot hash symbols with relocations, as it
// may reference named symbols whose names are not fully expanded.
if s.ContentAddressable() && (ctxt.Pkgpath != "" || len(s.R) == 0) {
- if len(s.P) <= 8 && len(s.R) == 0 { // we can use short hash only for symbols without relocations
+ if len(s.P) <= 8 && len(s.R) == 0 && !strings.HasPrefix(s.Name, "type.") {
+ // We can use short hash only for symbols without relocations.
+ // Don't use short hash for type symbols, as they need special handling.
s.PkgIdx = goobj.PkgIdxHashed64
s.SymIdx = hashed64idx
if hashed64idx != int32(len(ctxt.hashed64defs)) {
l.npkgsyms = l.NSym()
// Preallocate some space (a few hundreds KB) for some symbols.
// As of Go 1.15, linking cmd/compile has ~8000 hashed64 symbols and
- // ~13000 hashed symbols.
+ // ~27000 hashed symbols.
st := loadState{
l: l,
hashed64Syms: make(map[uint64]symAndSize, 10000),
- hashedSyms: make(map[goobj.HashType]symAndSize, 15000),
+ hashedSyms: make(map[goobj.HashType]symAndSize, 30000),
}
for _, o := range l.objs[goObjStart:] {
st.preloadSyms(o.r, hashed64Def)