if fn := s.Func(); fn != nil {
align = uint32(fn.Align)
}
- if s.ContentAddressable() {
- // We generally assume data symbols are natually aligned,
- // except for strings. If we dedup a string symbol and a
- // non-string symbol with the same content, we should keep
+ if s.ContentAddressable() && s.Size != 0 {
+ // We generally assume data symbols are natually aligned
+ // (e.g. integer constants), except for strings and a few
+ // compiler-emitted funcdata. If we dedup a string symbol and
+ // a non-string symbol with the same content, we should keep
// the largest alignment.
// TODO: maybe the compiler could set the alignment for all
// data symbols more carefully.
- if s.Size != 0 && !strings.HasPrefix(s.Name, "go.string.") {
+ switch {
+ case strings.HasPrefix(s.Name, "go.string."),
+ strings.HasPrefix(name, "type..namedata."),
+ strings.HasPrefix(name, "type..importpath."),
+ strings.HasSuffix(name, ".opendefer"),
+ strings.HasSuffix(name, ".arginfo0"),
+ strings.HasSuffix(name, ".arginfo1"):
+ // These are just bytes, or varints.
+ align = 1
+ case strings.HasPrefix(name, "gclocals·"):
+ // It has 32-bit fields.
+ align = 4
+ default:
switch {
case w.ctxt.Arch.PtrSize == 8 && s.Size%8 == 0:
align = 8
align = 4
case s.Size%2 == 0:
align = 2
+ default:
+ align = 1
}
- // don't bother setting align to 1.
}
}
if s.Size > cutoff {
continue
}
- align := int32(1)
name := ldr.SymName(s)
switch {
case strings.HasPrefix(name, "go.string."):
symGroupType[s] = sym.SGOSTRING
ldr.SetAttrNotInSymbolTable(s, true)
ldr.SetCarrierSym(s, symgostring)
- if ldr.SymAlign(s) == 0 {
- ldr.SetSymAlign(s, 1) // String data is just bytes, no padding.
- }
case strings.HasPrefix(name, "runtime.gcbits."):
symGroupType[s] = sym.SGCBITS
case strings.HasPrefix(name, "gcargs."),
strings.HasPrefix(name, "gclocals."),
strings.HasPrefix(name, "gclocals·"),
- ldr.SymType(s) == sym.SGOFUNC && s != symgofunc: // inltree, see pcln.go
- // GC stack maps and inltrees have 32-bit fields.
- align = 4
- fallthrough
- case strings.HasSuffix(name, ".opendefer"),
+ ldr.SymType(s) == sym.SGOFUNC && s != symgofunc, // inltree, see pcln.go
+ strings.HasSuffix(name, ".opendefer"),
strings.HasSuffix(name, ".arginfo0"),
strings.HasSuffix(name, ".arginfo1"):
- // These are just bytes, or varints, use align 1 (set before the switch).
symGroupType[s] = sym.SGOFUNC
ldr.SetAttrNotInSymbolTable(s, true)
ldr.SetCarrierSym(s, symgofunc)
- if a := ldr.SymAlign(s); a < align {
- ldr.SetSymAlign(s, align)
- } else {
- align = a
+ if ctxt.Debugvlog != 0 {
+ align := ldr.SymAlign(s)
+ liveness += (ldr.SymSize(s) + int64(align) - 1) &^ (int64(align) - 1)
}
- liveness += (ldr.SymSize(s) + int64(align) - 1) &^ (int64(align) - 1)
// Note: Check for "type." prefix after checking for .arginfo1 suffix.
// That way symbols like "type..eq.[2]interface {}.arginfo1" that belong
ldr.SetCarrierSym(s, symtype)
}
}
- if (strings.HasPrefix(name, "type..namedata.") || strings.HasPrefix(name, "type..importpath.")) && ldr.SymAlign(s) == 0 {
- ldr.SetSymAlign(s, 1) // String data is just bytes, no padding.
- }
}
}