Commit ac7761e1 authored by Heschi Kreinick's avatar Heschi Kreinick

cmd/compile, cmd/asm: remove Link.Plists

Link.Plists never contained more than one Plist, and sometimes none.
Passing around the Plist being worked on is straightforward and makes
the data flow easier to follow.

Change-Id: I79cb30cb2bd3d319fdbb1dfa5d35b27fcb748e5c
Reviewed-on: https://go-review.googlesource.com/37169
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: 's avatarMatthew Dempsky <mdempsky@google.com>
parent ac4a8652
......@@ -30,7 +30,7 @@ func testEndToEnd(t *testing.T, goarch, file string) {
architecture, ctxt := setArch(goarch)
lexer := lex.NewLexer(input)
parser := NewParser(ctxt, architecture, lexer)
pList := obj.Linknewplist(ctxt)
pList := new(obj.Plist)
var ok bool
testOut = new(bytes.Buffer) // The assembler writes test output to this buffer.
ctxt.Bso = bufio.NewWriter(os.Stdout)
......@@ -179,7 +179,7 @@ Diff:
t.Errorf(format, args...)
ok = false
}
obj.FlushplistNoFree(ctxt)
obj.FlushplistNoFree(ctxt, pList)
for p := top; p != nil; p = p.Link {
if p.As == obj.ATEXT {
......@@ -267,7 +267,7 @@ func testErrors(t *testing.T, goarch, file string) {
architecture, ctxt := setArch(goarch)
lexer := lex.NewLexer(input)
parser := NewParser(ctxt, architecture, lexer)
pList := obj.Linknewplist(ctxt)
pList := new(obj.Plist)
var ok bool
testOut = new(bytes.Buffer) // The assembler writes test output to this buffer.
ctxt.Bso = bufio.NewWriter(os.Stdout)
......@@ -283,7 +283,7 @@ func testErrors(t *testing.T, goarch, file string) {
errBuf.WriteString(s)
}
pList.Firstpc, ok = parser.Parse()
obj.Flushplist(ctxt)
obj.Flushplist(ctxt, pList)
if ok && !failed {
t.Errorf("asm: %s had no errors", goarch)
}
......
......@@ -62,16 +62,17 @@ func main() {
diag = true
log.Printf(format, args...)
}
pList := obj.Linknewplist(ctxt)
pList := new(obj.Plist)
pList.Firstpc, ok = parser.Parse()
if !ok {
failedFile = f
break
}
// reports errors to parser.Errorf
obj.Flushplist(ctxt, pList)
}
if ok {
// reports errors to parser.Errorf
obj.Writeobjdirect(ctxt, buf)
obj.WriteObjFile(ctxt, buf)
}
if !ok || diag {
if failedFile != "" {
......
......@@ -5,7 +5,6 @@
package gc
import (
"cmd/internal/obj"
"cmd/internal/src"
"fmt"
"sort"
......@@ -1228,11 +1227,6 @@ func funccompile(n *Node) {
pc = nil
funcdepth = 0
dclcontext = PEXTERN
if nerrors != 0 {
// If we have compile errors, ignore any assembler/linker errors.
Ctxt.DiagFunc = func(string, ...interface{}) {}
}
obj.Flushplist(Ctxt) // convert from Prog list to machine code
}
func funcsym(s *Sym) *Sym {
......
......@@ -161,16 +161,6 @@ func Addrconst(a *obj.Addr, v int64) {
a.Offset = v
}
func newplist() *obj.Plist {
pl := obj.Linknewplist(Ctxt)
pc = Ctxt.NewProg()
Clearp(pc)
pl.Firstpc = pc
return pl
}
// nodarg returns a Node for the function argument denoted by t,
// which is either the entire function argument or result struct (t is a struct *Type)
// or a specific argument (t is a *Field within a struct *Type).
......
......@@ -151,7 +151,7 @@ func dumpobj1(outfile string, mode int) {
ggloblsym(zero, int32(zerosize), obj.DUPOK|obj.RODATA)
}
obj.Writeobjdirect(Ctxt, bout.Writer)
obj.WriteObjFile(Ctxt, bout.Writer)
if writearchive {
bout.Flush()
......
......@@ -368,7 +368,10 @@ func compile(fn *Node) {
return
}
newplist()
plist := new(obj.Plist)
pc = Ctxt.NewProg()
Clearp(pc)
plist.Firstpc = pc
setlineno(Curfn)
......@@ -430,6 +433,7 @@ func compile(fn *Node) {
genssa(ssafn, ptxt, gcargs, gclocals)
ssafn.Free()
obj.Flushplist(Ctxt, plist) // convert from Prog list to machine code
}
func gendebug(fn *obj.LSym, decls []*Node) {
......
......@@ -729,7 +729,6 @@ type Link struct {
Hash map[SymVer]*LSym
PosTable src.PosTable
Imports []string
Plists []*Plist
Sym_div *LSym
Sym_divu *LSym
Sym_mod *LSym
......
......@@ -119,14 +119,6 @@ import (
"sort"
)
// The Go and C compilers, and the assembler, call writeobj to write
// out a Go object file. The linker does not call this; the linker
// does not write out object files.
func Writeobjdirect(ctxt *Link, b *bufio.Writer) {
Flushplist(ctxt)
WriteObjFile(ctxt, b)
}
// objWriter writes Go object files.
type objWriter struct {
wr *bufio.Writer
......
......@@ -14,96 +14,83 @@ type Plist struct {
Firstpc *Prog
}
/*
* start a new Prog list.
*/
func Linknewplist(ctxt *Link) *Plist {
pl := new(Plist)
ctxt.Plists = append(ctxt.Plists, pl)
return pl
func Flushplist(ctxt *Link, plist *Plist) {
flushplist(ctxt, plist, ctxt.Debugasm == 0)
}
func Flushplist(ctxt *Link) {
flushplist(ctxt, ctxt.Debugasm == 0)
}
func FlushplistNoFree(ctxt *Link) {
flushplist(ctxt, false)
func FlushplistNoFree(ctxt *Link, plist *Plist) {
flushplist(ctxt, plist, false)
}
func flushplist(ctxt *Link, freeProgs bool) {
func flushplist(ctxt *Link, plist *Plist, freeProgs bool) {
// Build list of symbols, and assign instructions to lists.
// Ignore ctxt->plist boundaries. There are no guarantees there,
// and the assemblers just use one big list.
var curtext *LSym
var etext *Prog
var text []*LSym
for _, pl := range ctxt.Plists {
var plink *Prog
for p := pl.Firstpc; p != nil; p = plink {
if ctxt.Debugasm != 0 && ctxt.Debugvlog != 0 {
fmt.Printf("obj: %v\n", p)
}
plink = p.Link
p.Link = nil
switch p.As {
case AEND:
continue
var plink *Prog
for p := plist.Firstpc; p != nil; p = plink {
if ctxt.Debugasm != 0 && ctxt.Debugvlog != 0 {
fmt.Printf("obj: %v\n", p)
}
plink = p.Link
p.Link = nil
case ATEXT:
s := p.From.Sym
if s == nil {
// func _() { }
curtext = nil
switch p.As {
case AEND:
continue
continue
}
case ATEXT:
s := p.From.Sym
if s == nil {
// func _() { }
curtext = nil
if s.Text != nil {
log.Fatalf("duplicate TEXT for %s", s.Name)
}
if s.OnList() {
log.Fatalf("symbol %s listed multiple times", s.Name)
}
s.Set(AttrOnList, true)
text = append(text, s)
flag := int(p.From3Offset())
if flag&DUPOK != 0 {
s.Set(AttrDuplicateOK, true)
}
if flag&NOSPLIT != 0 {
s.Set(AttrNoSplit, true)
}
if flag&REFLECTMETHOD != 0 {
s.Set(AttrReflectMethod, true)
}
s.Type = STEXT
s.Text = p
etext = p
curtext = s
continue
}
case AFUNCDATA:
// Rewrite reference to go_args_stackmap(SB) to the Go-provided declaration information.
if curtext == nil { // func _() {}
continue
}
if p.To.Sym.Name == "go_args_stackmap" {
if p.From.Type != TYPE_CONST || p.From.Offset != FUNCDATA_ArgsPointerMaps {
ctxt.Diag("FUNCDATA use of go_args_stackmap(SB) without FUNCDATA_ArgsPointerMaps")
}
p.To.Sym = Linklookup(ctxt, fmt.Sprintf("%s.args_stackmap", curtext.Name), int(curtext.Version))
}
if s.Text != nil {
log.Fatalf("duplicate TEXT for %s", s.Name)
}
if s.OnList() {
log.Fatalf("symbol %s listed multiple times", s.Name)
}
s.Set(AttrOnList, true)
text = append(text, s)
flag := int(p.From3Offset())
if flag&DUPOK != 0 {
s.Set(AttrDuplicateOK, true)
}
if flag&NOSPLIT != 0 {
s.Set(AttrNoSplit, true)
}
if flag&REFLECTMETHOD != 0 {
s.Set(AttrReflectMethod, true)
}
s.Type = STEXT
s.Text = p
etext = p
curtext = s
continue
if curtext == nil {
etext = nil
case AFUNCDATA:
// Rewrite reference to go_args_stackmap(SB) to the Go-provided declaration information.
if curtext == nil { // func _() {}
continue
}
etext.Link = p
etext = p
if p.To.Sym.Name == "go_args_stackmap" {
if p.From.Type != TYPE_CONST || p.From.Offset != FUNCDATA_ArgsPointerMaps {
ctxt.Diag("FUNCDATA use of go_args_stackmap(SB) without FUNCDATA_ArgsPointerMaps")
}
p.To.Sym = Linklookup(ctxt, fmt.Sprintf("%s.args_stackmap", curtext.Name), int(curtext.Version))
}
}
if curtext == nil {
etext = nil
continue
}
etext.Link = p
etext = p
}
// Add reference to Go arguments for C or assembly functions without them.
......@@ -147,7 +134,6 @@ func flushplist(ctxt *Link, freeProgs bool) {
// Add to running list in ctxt.
ctxt.Text = append(ctxt.Text, text...)
ctxt.Data = append(ctxt.Data, gendwarf(ctxt, text)...)
ctxt.Plists = nil
ctxt.Curp = nil
if freeProgs {
ctxt.freeProgs()
......
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