Don't accumulate a massive list of Prog structs during
compilation and write them all out at the end of compilation.
Instead, convert them to code+relocs (or data+relocs) after each
function is compiled.
Track down a few other places that were keeping Progs alive
and nil them out so the Progs get GCd promptly.
Saves ~20% in peak memory usage for the compiler. Surprisingly not much
help speed-wise (only because we end up doing more GCs. With a
compensating GOGC=120, it does help a bit), but this provides a base for
more changes (e.g. reusing a cache of Progs).
Change-Id: I838e01017c228995a687a8110d0cd67bf8596407
Reviewed-on: https://go-review.googlesource.com/19867
Run-TryBot: Keith Randall <khr@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Josh Bleecher Snyder <josharian@gmail.com>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
Funcdepth = n.Func.Depth + 1
compile(n)
Curfn = nil
+ Pc = nil
+ continpc = nil
+ breakpc = nil
Funcdepth = 0
dclcontext = PEXTERN
+ flushdata()
+ obj.Flushplist(Ctxt) // convert from Prog list to machine code
}
func funcsym(s *Sym) *Sym {
Clearp(Pc)
}
+func flushdata() {
+ if dfirst == nil {
+ return
+ }
+ newplist()
+ *Pc = *dfirst
+ Pc = dpc
+ Clearp(Pc)
+ dfirst = nil
+ dpc = nil
+}
+
// Fixup instructions after allocauto (formerly compactframe) has moved all autos around.
func fixautoused(p *obj.Prog) {
for lp := &p; ; {
ctxt.Arch.Assemble(ctxt, s)
fieldtrack(ctxt, s)
linkpcln(ctxt, s)
+ s.Text = nil
+ s.Etext = nil
}
// Add to running list in ctxt.
- if ctxt.Etext == nil {
- ctxt.Text = text
- } else {
- ctxt.Etext.Next = text
+ if text != nil {
+ if ctxt.Text == nil {
+ ctxt.Text = text
+ } else {
+ ctxt.Etext.Next = text
+ }
+ ctxt.Etext = etext
}
- ctxt.Etext = etext
ctxt.Plist = nil
+ ctxt.Plast = nil
+ ctxt.Curp = nil
}
func Writeobjfile(ctxt *Link, b *Biobuf) {