[dev.link] cmd/compile: make read-only static temps content-addressable

For now, we only do this for symbols without relocations.

Mark static temps "local", as they are not referenced across DSO
boundaries. And deduplicating a local symbol and a non-local
symbol can be problematic.

Change-Id: I0a3dc4138aaeea7fd4f326998f32ab6305da8e4b
Reviewed-on: https://go-review.googlesource.com/c/go/+/243141
Run-TryBot: Cherry Zhang <cherryyz@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Jeremy Faller <jeremy@golang.org>
This commit is contained in:
Cherry Zhang 2020-07-15 20:01:32 -04:00
parent 3dabaa44e8
commit 289c238a33
5 changed files with 22 additions and 18 deletions

View file

@ -206,8 +206,7 @@ func (o *Order) addrTemp(n *Node) *Node {
// TODO: expand this to all static composite literal nodes? // TODO: expand this to all static composite literal nodes?
n = defaultlit(n, nil) n = defaultlit(n, nil)
dowidth(n.Type) dowidth(n.Type)
vstat := staticname(n.Type) vstat := readonlystaticname(n.Type)
vstat.MarkReadonly()
var s InitSchedule var s InitSchedule
s.staticassign(vstat, n) s.staticassign(vstat, n)
if s.out != nil { if s.out != nil {

View file

@ -356,14 +356,22 @@ func (c initContext) String() string {
var statuniqgen int // name generator for static temps var statuniqgen int // name generator for static temps
// staticname returns a name backed by a static data symbol. // staticname returns a name backed by a (writable) static data symbol.
// Callers should call n.MarkReadonly on the // Use readonlystaticname for read-only node.
// returned node for readonly nodes.
func staticname(t *types.Type) *Node { func staticname(t *types.Type) *Node {
// Don't use lookupN; it interns the resulting string, but these are all unique. // Don't use lookupN; it interns the resulting string, but these are all unique.
n := newname(lookup(fmt.Sprintf("%s%d", obj.StaticNamePref, statuniqgen))) n := newname(lookup(fmt.Sprintf("%s%d", obj.StaticNamePref, statuniqgen)))
statuniqgen++ statuniqgen++
addvar(n, t, PEXTERN) addvar(n, t, PEXTERN)
n.Sym.Linksym().Set(obj.AttrLocal, true)
return n
}
// readonlystaticname returns a name backed by a (writable) static data symbol.
func readonlystaticname(t *types.Type) *Node {
n := staticname(t)
n.MarkReadonly()
n.Sym.Linksym().Set(obj.AttrContentAddressable, true)
return n return n
} }
@ -627,9 +635,10 @@ func slicelit(ctxt initContext, n *Node, var_ *Node, init *Nodes) {
mode := getdyn(n, true) mode := getdyn(n, true)
if mode&initConst != 0 && !isSmallSliceLit(n) { if mode&initConst != 0 && !isSmallSliceLit(n) {
vstat = staticname(t)
if ctxt == inInitFunction { if ctxt == inInitFunction {
vstat.MarkReadonly() vstat = readonlystaticname(t)
} else {
vstat = staticname(t)
} }
fixedlit(ctxt, initKindStatic, n, vstat, init) fixedlit(ctxt, initKindStatic, n, vstat, init)
} }
@ -773,10 +782,8 @@ func maplit(n *Node, m *Node, init *Nodes) {
dowidth(te) dowidth(te)
// make and initialize static arrays // make and initialize static arrays
vstatk := staticname(tk) vstatk := readonlystaticname(tk)
vstatk.MarkReadonly() vstate := readonlystaticname(te)
vstate := staticname(te)
vstate.MarkReadonly()
datak := nod(OARRAYLIT, nil, nil) datak := nod(OARRAYLIT, nil, nil)
datae := nod(OARRAYLIT, nil, nil) datae := nod(OARRAYLIT, nil, nil)
@ -897,8 +904,7 @@ func anylit(n *Node, var_ *Node, init *Nodes) {
if var_.isSimpleName() && n.List.Len() > 4 { if var_.isSimpleName() && n.List.Len() > 4 {
// lay out static data // lay out static data
vstat := staticname(t) vstat := readonlystaticname(t)
vstat.MarkReadonly()
ctxt := inInitFunction ctxt := inInitFunction
if n.Op == OARRAYLIT { if n.Op == OARRAYLIT {

View file

@ -1556,8 +1556,7 @@ opswitch:
if isStaticCompositeLiteral(n) && !canSSAType(n.Type) { if isStaticCompositeLiteral(n) && !canSSAType(n.Type) {
// n can be directly represented in the read-only data section. // n can be directly represented in the read-only data section.
// Make direct reference to the static data. See issue 12841. // Make direct reference to the static data. See issue 12841.
vstat := staticname(n.Type) vstat := readonlystaticname(n.Type)
vstat.MarkReadonly()
fixedlit(inInitFunction, initKindStatic, n, vstat, init) fixedlit(inInitFunction, initKindStatic, n, vstat, init)
n = vstat n = vstat
n = typecheck(n, ctxExpr) n = typecheck(n, ctxExpr)

View file

@ -333,7 +333,7 @@ func (w *writer) Sym(s *LSym) {
} }
func (w *writer) Hash64(s *LSym) { func (w *writer) Hash64(s *LSym) {
if !s.ContentAddressable() { if !s.ContentAddressable() || len(s.R) != 0 {
panic("Hash of non-content-addresable symbol") panic("Hash of non-content-addresable symbol")
} }
var b goobj2.Hash64Type var b goobj2.Hash64Type
@ -342,7 +342,7 @@ func (w *writer) Hash64(s *LSym) {
} }
func (w *writer) Hash(s *LSym) { func (w *writer) Hash(s *LSym) {
if !s.ContentAddressable() { if !s.ContentAddressable() || len(s.R) != 0 { // TODO: currently we don't support content-addressable symbols with relocations
panic("Hash of non-content-addresable symbol") panic("Hash of non-content-addresable symbol")
} }
b := goobj2.HashType(sha1.Sum(s.P)) b := goobj2.HashType(sha1.Sum(s.P))

View file

@ -202,7 +202,7 @@ func (ctxt *Link) NumberSyms() {
var idx, hashedidx, hashed64idx, nonpkgidx int32 var idx, hashedidx, hashed64idx, nonpkgidx int32
ctxt.traverseSyms(traverseDefs, func(s *LSym) { ctxt.traverseSyms(traverseDefs, func(s *LSym) {
if s.ContentAddressable() { if s.ContentAddressable() && len(s.R) == 0 { // TODO: currently we don't support content-addressable symbols with relocations
if len(s.P) <= 8 { if len(s.P) <= 8 {
s.PkgIdx = goobj2.PkgIdxHashed64 s.PkgIdx = goobj2.PkgIdxHashed64
s.SymIdx = hashed64idx s.SymIdx = hashed64idx