mirror of
https://github.com/golang/go
synced 2024-11-19 14:24:47 -07:00
cmd/compile: set itab function pointers at compile time
I noticed that we don't set an itab's function pointers at compile time. Instead, we currently do it at executable startup. Set the function pointers at compile time instead. This shortens startup time. It has no effect on normal binary size. Object files will have more relocations, but that isn't a big deal. For PIE there are additional pointers that will need to be adjusted at load time. There are already other pointers in an itab that need to be adjusted, so the cache line will already be paged in. There might be some binary size overhead to mark these pointers. The "go test -c -buildmode=pie net/http" binary is 0.18% bigger. Update #20505 Change-Id: I267c82489915b509ff66e512fc7319b2dd79b8f7 Reviewed-on: https://go-review.googlesource.com/44341 Run-TryBot: Keith Randall <khr@golang.org> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Martin Möhrmann <moehrmann@google.com>
This commit is contained in:
parent
250a9610a4
commit
89d74f5416
@ -1463,14 +1463,13 @@ func dumptabs() {
|
||||
// }
|
||||
o := dsymptr(i.lsym, 0, dtypesym(i.itype).Linksym(), 0)
|
||||
o = dsymptr(i.lsym, o, dtypesym(i.t).Linksym(), 0)
|
||||
o = duint32(i.lsym, o, typehash(i.t)) // copy of type hash
|
||||
o += 4 // skip unused field
|
||||
o += len(imethods(i.itype)) * Widthptr // skip fun method pointers
|
||||
// at runtime the itab will contain pointers to types, other itabs and
|
||||
// method functions. None are allocated on heap, so we can use obj.NOPTR.
|
||||
ggloblsym(i.lsym, int32(o), int16(obj.DUPOK|obj.NOPTR))
|
||||
// TODO: mark readonly after we pre-add the function pointers
|
||||
|
||||
o = duint32(i.lsym, o, typehash(i.t)) // copy of type hash
|
||||
o += 4 // skip unused field
|
||||
for _, fn := range genfun(i.t, i.itype) {
|
||||
o = dsymptr(i.lsym, o, fn, 0) // method pointer for each method
|
||||
}
|
||||
// Nothing writes static itabs, so they are read only.
|
||||
ggloblsym(i.lsym, int32(o), int16(obj.DUPOK|obj.RODATA))
|
||||
ilink := itablinkpkg.Lookup(i.t.ShortString() + "," + i.itype.ShortString()).Linksym()
|
||||
dsymptr(ilink, 0, i.lsym, 0)
|
||||
ggloblsym(ilink, int32(Widthptr), int16(obj.DUPOK|obj.RODATA))
|
||||
|
@ -167,13 +167,6 @@ func itabAdd(m *itab) {
|
||||
}
|
||||
}
|
||||
|
||||
// Adds m to the set of initial itabs.
|
||||
// itabLock must be held.
|
||||
func itabAddStartup(m *itab) {
|
||||
m.init() // TODO: remove after CL 44341
|
||||
itabAdd(m)
|
||||
}
|
||||
|
||||
// init fills in the m.fun array with all the code pointers for
|
||||
// the m.inter/m._type pair. If the type does not implement the interface,
|
||||
// it sets m.fun[0] to 0 and returns the name of an interface function that is missing.
|
||||
@ -230,7 +223,7 @@ func itabsinit() {
|
||||
lock(&itabLock)
|
||||
for _, md := range activeModules() {
|
||||
for _, i := range md.itablinks {
|
||||
itabAddStartup(i)
|
||||
itabAdd(i)
|
||||
}
|
||||
}
|
||||
unlock(&itabLock)
|
||||
|
@ -56,7 +56,7 @@ func plugin_lastmoduleinit() (path string, syms map[string]interface{}, mismatch
|
||||
|
||||
lock(&itabLock)
|
||||
for _, i := range md.itablinks {
|
||||
itabAddStartup(i)
|
||||
itabAdd(i)
|
||||
}
|
||||
unlock(&itabLock)
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user