From 1fdf5ba50cf67d28dffb4a4f0e29fcb053d660ad Mon Sep 17 00:00:00 2001 From: Jeremy Faller Date: Mon, 22 Jun 2020 11:11:12 -0400 Subject: [PATCH] [dev.link] cmd/link: move findfunctab to a generated symbol MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Basically removes all allocation from findfunctab: Findfunctab_GC 172kB ± 0% 0kB ± 0% ~ (p=1.000 n=1+1) Change-Id: I246f7d2751317886b658f7ef672fb30b3c519668 Reviewed-on: https://go-review.googlesource.com/c/go/+/239281 Run-TryBot: Jeremy Faller TryBot-Result: Gobot Gobot Reviewed-by: Cherry Zhang Reviewed-by: Than McIntosh --- src/cmd/link/internal/ld/pcln.go | 110 ++++++++++++++++--------------- 1 file changed, 57 insertions(+), 53 deletions(-) diff --git a/src/cmd/link/internal/ld/pcln.go b/src/cmd/link/internal/ld/pcln.go index 81f1a2d40b..5bbfbb02c1 100644 --- a/src/cmd/link/internal/ld/pcln.go +++ b/src/cmd/link/internal/ld/pcln.go @@ -585,9 +585,6 @@ const ( // a given text symbols is a container (outer sym). func (ctxt *Link) findfunctab(container loader.Bitmap) { ldr := ctxt.loader - t := ldr.CreateSymForUpdate("runtime.findfunctab", 0) - t.SetType(sym.SRODATA) - ldr.SetAttrLocal(t.Sym(), true) // find min and max address min := ldr.SymValue(ctxt.Textp[0]) @@ -598,67 +595,74 @@ func (ctxt *Link) findfunctab(container loader.Bitmap) { // that map to that subbucket. n := int32((max - min + SUBBUCKETSIZE - 1) / SUBBUCKETSIZE) - indexes := make([]int32, n) - for i := int32(0); i < n; i++ { - indexes[i] = NOIDX - } - idx := int32(0) - for i, s := range ctxt.Textp { - if !emitPcln(ctxt, s, container) { - continue - } - p := ldr.SymValue(s) - var e loader.Sym - i++ - if i < len(ctxt.Textp) { - e = ctxt.Textp[i] + nbuckets := int32((max - min + BUCKETSIZE - 1) / BUCKETSIZE) + + size := 4*int64(nbuckets) + int64(n) + + writeFindFuncTab := func(_ *Link, s loader.Sym) { + t := ldr.MakeSymbolUpdater(s) + + indexes := make([]int32, n) + for i := int32(0); i < n; i++ { + indexes[i] = NOIDX } - for e != 0 && !emitPcln(ctxt, e, container) && i < len(ctxt.Textp) { - e = ctxt.Textp[i] + idx := int32(0) + for i, s := range ctxt.Textp { + if !emitPcln(ctxt, s, container) { + continue + } + p := ldr.SymValue(s) + var e loader.Sym i++ - } - q := max - if e != 0 { - q = ldr.SymValue(e) - } + if i < len(ctxt.Textp) { + e = ctxt.Textp[i] + } + for e != 0 && !emitPcln(ctxt, e, container) && i < len(ctxt.Textp) { + e = ctxt.Textp[i] + i++ + } + q := max + if e != 0 { + q = ldr.SymValue(e) + } + + //print("%d: [%lld %lld] %s\n", idx, p, q, s->name); + for ; p < q; p += SUBBUCKETSIZE { + i = int((p - min) / SUBBUCKETSIZE) + if indexes[i] > idx { + indexes[i] = idx + } + } - //print("%d: [%lld %lld] %s\n", idx, p, q, s->name); - for ; p < q; p += SUBBUCKETSIZE { - i = int((p - min) / SUBBUCKETSIZE) + i = int((q - 1 - min) / SUBBUCKETSIZE) if indexes[i] > idx { indexes[i] = idx } + idx++ } - i = int((q - 1 - min) / SUBBUCKETSIZE) - if indexes[i] > idx { - indexes[i] = idx - } - idx++ - } - - // allocate table - nbuckets := int32((max - min + BUCKETSIZE - 1) / BUCKETSIZE) - - t.Grow(4*int64(nbuckets) + int64(n)) - - // fill in table - for i := int32(0); i < nbuckets; i++ { - base := indexes[i*SUBBUCKETS] - if base == NOIDX { - Errorf(nil, "hole in findfunctab") - } - t.SetUint32(ctxt.Arch, int64(i)*(4+SUBBUCKETS), uint32(base)) - for j := int32(0); j < SUBBUCKETS && i*SUBBUCKETS+j < n; j++ { - idx = indexes[i*SUBBUCKETS+j] - if idx == NOIDX { + // fill in table + for i := int32(0); i < nbuckets; i++ { + base := indexes[i*SUBBUCKETS] + if base == NOIDX { Errorf(nil, "hole in findfunctab") } - if idx-base >= 256 { - Errorf(nil, "too many functions in a findfunc bucket! %d/%d %d %d", i, nbuckets, j, idx-base) - } + t.SetUint32(ctxt.Arch, int64(i)*(4+SUBBUCKETS), uint32(base)) + for j := int32(0); j < SUBBUCKETS && i*SUBBUCKETS+j < n; j++ { + idx = indexes[i*SUBBUCKETS+j] + if idx == NOIDX { + Errorf(nil, "hole in findfunctab") + } + if idx-base >= 256 { + Errorf(nil, "too many functions in a findfunc bucket! %d/%d %d %d", i, nbuckets, j, idx-base) + } - t.SetUint8(ctxt.Arch, int64(i)*(4+SUBBUCKETS)+4+int64(j), uint8(idx-base)) + t.SetUint8(ctxt.Arch, int64(i)*(4+SUBBUCKETS)+4+int64(j), uint8(idx-base)) + } } } + + s := ctxt.createGeneratorSymbol("runtime.findfunctab", 0, sym.SRODATA, size, writeFindFuncTab) + ldr.SetAttrReachable(s, true) + ldr.SetAttrLocal(s, true) } -- 2.50.0