Commit 735fe51a authored by Josh Bleecher Snyder's avatar Josh Bleecher Snyder

cmd/internal/obj: add LookupInit

There are some LSyms that are lazily initialized,
and which cannot be made eagerly initialized,
such as elements of a constant pool.

To avoid needing a mutex to protect the internals of
those LSyms, this CL introduces LookupInit,
which allows an LSym to be initialized only once.

By itself this is not fully concurrency-safe,
but Ctxt.Hash will need mutex protection anyway,
and that will be enough to support one-time LSym initialization.

Passes toolstash-check -all.

Updates #15756

Change-Id: Id7248dfdc4dfbdfe425fa31d0c0045018eeea1fa
Reviewed-on: https://go-review.googlesource.com/39990
Run-TryBot: Josh Bleecher Snyder <josharian@gmail.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: default avatarBrad Fitzpatrick <bradfitz@golang.org>
parent dc243f25
...@@ -68,46 +68,52 @@ func Linknew(arch *LinkArch) *Link { ...@@ -68,46 +68,52 @@ func Linknew(arch *LinkArch) *Link {
return ctxt return ctxt
} }
// Lookup looks up the symbol with name name and version v.
// If it does not exist, it creates it.
func (ctxt *Link) Lookup(name string, v int) *LSym { func (ctxt *Link) Lookup(name string, v int) *LSym {
return ctxt.LookupInit(name, v, nil)
}
// LookupInit looks up the symbol with name name and version v.
// If it does not exist, it creates it and passes it to initfn for one-time initialization.
func (ctxt *Link) LookupInit(name string, v int, init func(s *LSym)) *LSym {
s := ctxt.Hash[SymVer{name, v}] s := ctxt.Hash[SymVer{name, v}]
if s != nil { if s != nil {
return s return s
} }
s = &LSym{ s = &LSym{Name: name, Version: int16(v)}
Name: name,
Type: 0,
Version: int16(v),
Size: 0,
}
ctxt.Hash[SymVer{name, v}] = s ctxt.Hash[SymVer{name, v}] = s
if init != nil {
init(s)
}
return s return s
} }
func (ctxt *Link) Float32Sym(f float32) *LSym { func (ctxt *Link) Float32Sym(f float32) *LSym {
i := math.Float32bits(f) i := math.Float32bits(f)
name := fmt.Sprintf("$f32.%08x", i) name := fmt.Sprintf("$f32.%08x", i)
s := ctxt.Lookup(name, 0) return ctxt.LookupInit(name, 0, func(s *LSym) {
s.Size = 4 s.Size = 4
s.Set(AttrLocal, true) s.Set(AttrLocal, true)
return s })
} }
func (ctxt *Link) Float64Sym(f float64) *LSym { func (ctxt *Link) Float64Sym(f float64) *LSym {
i := math.Float64bits(f) i := math.Float64bits(f)
name := fmt.Sprintf("$f64.%016x", i) name := fmt.Sprintf("$f64.%016x", i)
s := ctxt.Lookup(name, 0) return ctxt.LookupInit(name, 0, func(s *LSym) {
s.Size = 8 s.Size = 8
s.Set(AttrLocal, true) s.Set(AttrLocal, true)
return s })
} }
func (ctxt *Link) Int64Sym(i int64) *LSym { func (ctxt *Link) Int64Sym(i int64) *LSym {
name := fmt.Sprintf("$i64.%016x", uint64(i)) name := fmt.Sprintf("$i64.%016x", uint64(i))
s := ctxt.Lookup(name, 0) return ctxt.LookupInit(name, 0, func(s *LSym) {
s.Size = 8 s.Size = 8
s.Set(AttrLocal, true) s.Set(AttrLocal, true)
return s })
} }
func Linksymfmt(s *LSym) string { func Linksymfmt(s *LSym) string {
......
...@@ -534,10 +534,10 @@ func rewriteToPcrel(ctxt *obj.Link, p *obj.Prog, newprog obj.ProgAlloc) { ...@@ -534,10 +534,10 @@ func rewriteToPcrel(ctxt *obj.Link, p *obj.Prog, newprog obj.ProgAlloc) {
r := obj.Appendp(q, newprog) r := obj.Appendp(q, newprog)
r.RegTo2 = 1 r.RegTo2 = 1
q.As = obj.ACALL q.As = obj.ACALL
q.To.Sym = ctxt.Lookup("__x86.get_pc_thunk."+strings.ToLower(rconv(int(dst))), 0) thunkname := "__x86.get_pc_thunk." + strings.ToLower(rconv(int(dst)))
q.To.Sym = ctxt.LookupInit(thunkname, 0, func(s *obj.LSym) { s.Set(obj.AttrLocal, true) })
q.To.Type = obj.TYPE_MEM q.To.Type = obj.TYPE_MEM
q.To.Name = obj.NAME_EXTERN q.To.Name = obj.NAME_EXTERN
q.To.Sym.Set(obj.AttrLocal, true)
r.As = p.As r.As = p.As
r.Scond = p.Scond r.Scond = p.Scond
r.From = p.From r.From = p.From
......
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