cmd/internal/obj: separate code layout from object writing

This will allow the compiler to crunch Prog lists down to code as each
function is compiled, instead of waiting until the end, which should
reduce the working set of the compiler. But not until Go 1.7.

This also makes it easier to write some machine code output tests
for the assembler, which is why it's being done now.

For #13822.

Change-Id: I0811123bc6e5717cebb8948f9cea18e1b9baf6f7
Reviewed-on: https://go-review.googlesource.com/18311
Reviewed-by: Ian Lance Taylor <iant@golang.org>
This commit is contained in:
Russ Cox 2016-01-05 09:27:40 -05:00
parent 1ac637c766
commit ed03dab853
2 changed files with 31 additions and 11 deletions

View file

@ -610,6 +610,12 @@ type Link struct {
Version int Version int
Textp *LSym Textp *LSym
Etextp *LSym Etextp *LSym
// state for writing objects
Text *LSym
Data *LSym
Etext *LSym
Edata *LSym
} }
// The smallest possible offset from the hardware stack pointer to a local // The smallest possible offset from the hardware stack pointer to a local

View file

@ -111,6 +111,11 @@ import (
// out a Go object file. The linker does not call this; the linker // out a Go object file. The linker does not call this; the linker
// does not write out object files. // does not write out object files.
func Writeobjdirect(ctxt *Link, b *Biobuf) { func Writeobjdirect(ctxt *Link, b *Biobuf) {
Flushplist(ctxt)
Writeobjfile(ctxt, b)
}
func Flushplist(ctxt *Link) {
var flag int var flag int
var s *LSym var s *LSym
var p *Prog var p *Prog
@ -119,13 +124,11 @@ func Writeobjdirect(ctxt *Link, b *Biobuf) {
// Build list of symbols, and assign instructions to lists. // Build list of symbols, and assign instructions to lists.
// Ignore ctxt->plist boundaries. There are no guarantees there, // Ignore ctxt->plist boundaries. There are no guarantees there,
// and the C compilers and assemblers just use one big list. // and the assemblers just use one big list.
var text *LSym
var curtext *LSym var curtext *LSym
var data *LSym var text *LSym
var etext *LSym var etext *LSym
var edata *LSym
for pl := ctxt.Plist; pl != nil; pl = pl.Link { for pl := ctxt.Plist; pl != nil; pl = pl.Link {
for p = pl.Firstpc; p != nil; p = plink { for p = pl.Firstpc; p != nil; p = plink {
if ctxt.Debugasm != 0 && ctxt.Debugvlog != 0 { if ctxt.Debugasm != 0 && ctxt.Debugvlog != 0 {
@ -174,10 +177,10 @@ func Writeobjdirect(ctxt *Link, b *Biobuf) {
log.Fatalf("symbol %s listed multiple times", s.Name) log.Fatalf("symbol %s listed multiple times", s.Name)
} }
s.Onlist = 1 s.Onlist = 1
if data == nil { if ctxt.Data == nil {
data = s ctxt.Data = s
} else { } else {
edata.Next = s ctxt.Edata.Next = s
} }
s.Next = nil s.Next = nil
s.Size = p.To.Offset s.Size = p.To.Offset
@ -195,7 +198,7 @@ func Writeobjdirect(ctxt *Link, b *Biobuf) {
} else if flag&TLSBSS != 0 { } else if flag&TLSBSS != 0 {
s.Type = STLSBSS s.Type = STLSBSS
} }
edata = s ctxt.Edata = s
continue continue
} }
@ -298,6 +301,17 @@ func Writeobjdirect(ctxt *Link, b *Biobuf) {
linkpcln(ctxt, s) linkpcln(ctxt, s)
} }
// Add to running list in ctxt.
if ctxt.Etext == nil {
ctxt.Text = text
} else {
ctxt.Etext.Next = text
}
ctxt.Etext = etext
ctxt.Plist = nil
}
func Writeobjfile(ctxt *Link, b *Biobuf) {
// Emit header. // Emit header.
Bputc(b, 0) Bputc(b, 0)
@ -312,10 +326,10 @@ func Writeobjdirect(ctxt *Link, b *Biobuf) {
wrstring(b, "") wrstring(b, "")
// Emit symbols. // Emit symbols.
for s := text; s != nil; s = s.Next { for s := ctxt.Text; s != nil; s = s.Next {
writesym(ctxt, b, s) writesym(ctxt, b, s)
} }
for s := data; s != nil; s = s.Next { for s := ctxt.Data; s != nil; s = s.Next {
writesym(ctxt, b, s) writesym(ctxt, b, s)
} }