mirror of
https://github.com/golang/go.git
synced 2025-05-06 08:03:03 +00:00
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: Matthew Dempsky <mdempsky@google.com>
This commit is contained in:
parent
ac4a86523c
commit
ac7761e1a4
@ -30,7 +30,7 @@ func testEndToEnd(t *testing.T, goarch, file string) {
|
|||||||
architecture, ctxt := setArch(goarch)
|
architecture, ctxt := setArch(goarch)
|
||||||
lexer := lex.NewLexer(input)
|
lexer := lex.NewLexer(input)
|
||||||
parser := NewParser(ctxt, architecture, lexer)
|
parser := NewParser(ctxt, architecture, lexer)
|
||||||
pList := obj.Linknewplist(ctxt)
|
pList := new(obj.Plist)
|
||||||
var ok bool
|
var ok bool
|
||||||
testOut = new(bytes.Buffer) // The assembler writes test output to this buffer.
|
testOut = new(bytes.Buffer) // The assembler writes test output to this buffer.
|
||||||
ctxt.Bso = bufio.NewWriter(os.Stdout)
|
ctxt.Bso = bufio.NewWriter(os.Stdout)
|
||||||
@ -179,7 +179,7 @@ Diff:
|
|||||||
t.Errorf(format, args...)
|
t.Errorf(format, args...)
|
||||||
ok = false
|
ok = false
|
||||||
}
|
}
|
||||||
obj.FlushplistNoFree(ctxt)
|
obj.FlushplistNoFree(ctxt, pList)
|
||||||
|
|
||||||
for p := top; p != nil; p = p.Link {
|
for p := top; p != nil; p = p.Link {
|
||||||
if p.As == obj.ATEXT {
|
if p.As == obj.ATEXT {
|
||||||
@ -267,7 +267,7 @@ func testErrors(t *testing.T, goarch, file string) {
|
|||||||
architecture, ctxt := setArch(goarch)
|
architecture, ctxt := setArch(goarch)
|
||||||
lexer := lex.NewLexer(input)
|
lexer := lex.NewLexer(input)
|
||||||
parser := NewParser(ctxt, architecture, lexer)
|
parser := NewParser(ctxt, architecture, lexer)
|
||||||
pList := obj.Linknewplist(ctxt)
|
pList := new(obj.Plist)
|
||||||
var ok bool
|
var ok bool
|
||||||
testOut = new(bytes.Buffer) // The assembler writes test output to this buffer.
|
testOut = new(bytes.Buffer) // The assembler writes test output to this buffer.
|
||||||
ctxt.Bso = bufio.NewWriter(os.Stdout)
|
ctxt.Bso = bufio.NewWriter(os.Stdout)
|
||||||
@ -283,7 +283,7 @@ func testErrors(t *testing.T, goarch, file string) {
|
|||||||
errBuf.WriteString(s)
|
errBuf.WriteString(s)
|
||||||
}
|
}
|
||||||
pList.Firstpc, ok = parser.Parse()
|
pList.Firstpc, ok = parser.Parse()
|
||||||
obj.Flushplist(ctxt)
|
obj.Flushplist(ctxt, pList)
|
||||||
if ok && !failed {
|
if ok && !failed {
|
||||||
t.Errorf("asm: %s had no errors", goarch)
|
t.Errorf("asm: %s had no errors", goarch)
|
||||||
}
|
}
|
||||||
|
@ -62,16 +62,17 @@ func main() {
|
|||||||
diag = true
|
diag = true
|
||||||
log.Printf(format, args...)
|
log.Printf(format, args...)
|
||||||
}
|
}
|
||||||
pList := obj.Linknewplist(ctxt)
|
pList := new(obj.Plist)
|
||||||
pList.Firstpc, ok = parser.Parse()
|
pList.Firstpc, ok = parser.Parse()
|
||||||
if !ok {
|
if !ok {
|
||||||
failedFile = f
|
failedFile = f
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
// reports errors to parser.Errorf
|
||||||
|
obj.Flushplist(ctxt, pList)
|
||||||
}
|
}
|
||||||
if ok {
|
if ok {
|
||||||
// reports errors to parser.Errorf
|
obj.WriteObjFile(ctxt, buf)
|
||||||
obj.Writeobjdirect(ctxt, buf)
|
|
||||||
}
|
}
|
||||||
if !ok || diag {
|
if !ok || diag {
|
||||||
if failedFile != "" {
|
if failedFile != "" {
|
||||||
|
@ -5,7 +5,6 @@
|
|||||||
package gc
|
package gc
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"cmd/internal/obj"
|
|
||||||
"cmd/internal/src"
|
"cmd/internal/src"
|
||||||
"fmt"
|
"fmt"
|
||||||
"sort"
|
"sort"
|
||||||
@ -1228,11 +1227,6 @@ func funccompile(n *Node) {
|
|||||||
pc = nil
|
pc = nil
|
||||||
funcdepth = 0
|
funcdepth = 0
|
||||||
dclcontext = PEXTERN
|
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 {
|
func funcsym(s *Sym) *Sym {
|
||||||
|
@ -161,16 +161,6 @@ func Addrconst(a *obj.Addr, v int64) {
|
|||||||
a.Offset = v
|
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,
|
// 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)
|
// 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).
|
// 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)
|
ggloblsym(zero, int32(zerosize), obj.DUPOK|obj.RODATA)
|
||||||
}
|
}
|
||||||
|
|
||||||
obj.Writeobjdirect(Ctxt, bout.Writer)
|
obj.WriteObjFile(Ctxt, bout.Writer)
|
||||||
|
|
||||||
if writearchive {
|
if writearchive {
|
||||||
bout.Flush()
|
bout.Flush()
|
||||||
|
@ -368,7 +368,10 @@ func compile(fn *Node) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
newplist()
|
plist := new(obj.Plist)
|
||||||
|
pc = Ctxt.NewProg()
|
||||||
|
Clearp(pc)
|
||||||
|
plist.Firstpc = pc
|
||||||
|
|
||||||
setlineno(Curfn)
|
setlineno(Curfn)
|
||||||
|
|
||||||
@ -430,6 +433,7 @@ func compile(fn *Node) {
|
|||||||
|
|
||||||
genssa(ssafn, ptxt, gcargs, gclocals)
|
genssa(ssafn, ptxt, gcargs, gclocals)
|
||||||
ssafn.Free()
|
ssafn.Free()
|
||||||
|
obj.Flushplist(Ctxt, plist) // convert from Prog list to machine code
|
||||||
}
|
}
|
||||||
|
|
||||||
func gendebug(fn *obj.LSym, decls []*Node) {
|
func gendebug(fn *obj.LSym, decls []*Node) {
|
||||||
|
@ -729,7 +729,6 @@ type Link struct {
|
|||||||
Hash map[SymVer]*LSym
|
Hash map[SymVer]*LSym
|
||||||
PosTable src.PosTable
|
PosTable src.PosTable
|
||||||
Imports []string
|
Imports []string
|
||||||
Plists []*Plist
|
|
||||||
Sym_div *LSym
|
Sym_div *LSym
|
||||||
Sym_divu *LSym
|
Sym_divu *LSym
|
||||||
Sym_mod *LSym
|
Sym_mod *LSym
|
||||||
|
@ -119,14 +119,6 @@ import (
|
|||||||
"sort"
|
"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.
|
// objWriter writes Go object files.
|
||||||
type objWriter struct {
|
type objWriter struct {
|
||||||
wr *bufio.Writer
|
wr *bufio.Writer
|
||||||
|
@ -14,96 +14,83 @@ type Plist struct {
|
|||||||
Firstpc *Prog
|
Firstpc *Prog
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
func Flushplist(ctxt *Link, plist *Plist) {
|
||||||
* start a new Prog list.
|
flushplist(ctxt, plist, ctxt.Debugasm == 0)
|
||||||
*/
|
|
||||||
func Linknewplist(ctxt *Link) *Plist {
|
|
||||||
pl := new(Plist)
|
|
||||||
ctxt.Plists = append(ctxt.Plists, pl)
|
|
||||||
return pl
|
|
||||||
}
|
}
|
||||||
|
func FlushplistNoFree(ctxt *Link, plist *Plist) {
|
||||||
func Flushplist(ctxt *Link) {
|
flushplist(ctxt, plist, false)
|
||||||
flushplist(ctxt, ctxt.Debugasm == 0)
|
|
||||||
}
|
}
|
||||||
func FlushplistNoFree(ctxt *Link) {
|
func flushplist(ctxt *Link, plist *Plist, freeProgs bool) {
|
||||||
flushplist(ctxt, false)
|
|
||||||
}
|
|
||||||
func flushplist(ctxt *Link, freeProgs bool) {
|
|
||||||
// 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,
|
|
||||||
// and the assemblers just use one big list.
|
|
||||||
var curtext *LSym
|
var curtext *LSym
|
||||||
var etext *Prog
|
var etext *Prog
|
||||||
var text []*LSym
|
var text []*LSym
|
||||||
|
|
||||||
for _, pl := range ctxt.Plists {
|
var plink *Prog
|
||||||
var plink *Prog
|
for p := plist.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 {
|
fmt.Printf("obj: %v\n", p)
|
||||||
fmt.Printf("obj: %v\n", p)
|
|
||||||
}
|
|
||||||
plink = p.Link
|
|
||||||
p.Link = nil
|
|
||||||
|
|
||||||
switch p.As {
|
|
||||||
case AEND:
|
|
||||||
continue
|
|
||||||
|
|
||||||
case ATEXT:
|
|
||||||
s := p.From.Sym
|
|
||||||
if s == nil {
|
|
||||||
// func _() { }
|
|
||||||
curtext = nil
|
|
||||||
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
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 curtext == nil {
|
|
||||||
etext = nil
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
etext.Link = p
|
|
||||||
etext = p
|
|
||||||
}
|
}
|
||||||
|
plink = p.Link
|
||||||
|
p.Link = nil
|
||||||
|
|
||||||
|
switch p.As {
|
||||||
|
case AEND:
|
||||||
|
continue
|
||||||
|
|
||||||
|
case ATEXT:
|
||||||
|
s := p.From.Sym
|
||||||
|
if s == nil {
|
||||||
|
// func _() { }
|
||||||
|
curtext = nil
|
||||||
|
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
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 curtext == nil {
|
||||||
|
etext = nil
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
etext.Link = p
|
||||||
|
etext = p
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add reference to Go arguments for C or assembly functions without them.
|
// 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.
|
// Add to running list in ctxt.
|
||||||
ctxt.Text = append(ctxt.Text, text...)
|
ctxt.Text = append(ctxt.Text, text...)
|
||||||
ctxt.Data = append(ctxt.Data, gendwarf(ctxt, text)...)
|
ctxt.Data = append(ctxt.Data, gendwarf(ctxt, text)...)
|
||||||
ctxt.Plists = nil
|
|
||||||
ctxt.Curp = nil
|
ctxt.Curp = nil
|
||||||
if freeProgs {
|
if freeProgs {
|
||||||
ctxt.freeProgs()
|
ctxt.freeProgs()
|
||||||
|
Loading…
x
Reference in New Issue
Block a user