mirror of
https://github.com/golang/go.git
synced 2025-12-08 06:10:04 +00:00
cmd/internal/obj: stop storing Text flags in From3
Prior to this CL, flags such as NOSPLIT on ATEXT Progs were stored in From3.Offset. Some but not all of those flags were also duplicated into From.Sym.Attribute. This CL migrates all of those flags into From.Sym.Attribute and stops creating a From3. A side-effect of this is that printing an ATEXT Prog can no longer simply dump From3.Offset. That's kind of good, since the raw flag value wasn't very informative anyway, but it did necessitate a bunch of updates to the cmd/asm tests. The reason I'm doing this work now is that avoiding storing flags in both From.Sym and From3.Offset simplifies some other changes to fix the data race first described in CL 40254. This CL almost passes toolstash-check -all. The only changes are in cases where the assembler has decided that a function's flags may be altered, e.g. to make a function with no calls in it NOSPLIT. Prior to this CL, that information was not printed. Sample before: "".Ctz64 t=1 size=63 args=0x10 locals=0x0 0x0000 00000 (/Users/josh/go/tip/src/runtime/internal/sys/intrinsics.go:35) TEXT "".Ctz64(SB), $0-16 0x0000 00000 (/Users/josh/go/tip/src/runtime/internal/sys/intrinsics.go:35) FUNCDATA $0, gclocals·f207267fbf96a0178e8758c6e3e0ce28(SB) Sample after: "".Ctz64 t=1 nosplit size=63 args=0x10 locals=0x0 0x0000 00000 (/Users/josh/go/tip/src/runtime/internal/sys/intrinsics.go:35) TEXT "".Ctz64(SB), NOSPLIT, $0-16 0x0000 00000 (/Users/josh/go/tip/src/runtime/internal/sys/intrinsics.go:35) FUNCDATA $0, gclocals·f207267fbf96a0178e8758c6e3e0ce28(SB) Observe the additional "nosplit" in the first line and the additional "NOSPLIT" in the second line. Updates #15756 Change-Id: I5c59bd8f3bdc7c780361f801d94a261f0aef3d13 Reviewed-on: https://go-review.googlesource.com/40495 Run-TryBot: Josh Bleecher Snyder <josharian@gmail.com> Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org> TryBot-Result: Gobot Gobot <gobot@golang.org>
This commit is contained in:
parent
4eb48a336e
commit
ce3ee7cdae
22 changed files with 145 additions and 83 deletions
|
|
@ -162,6 +162,8 @@ go src=..
|
|||
regexp
|
||||
testdata
|
||||
+
|
||||
runtime
|
||||
textflag.h
|
||||
strconv
|
||||
testdata
|
||||
+
|
||||
|
|
|
|||
|
|
@ -165,10 +165,6 @@ func (p *Parser) asmText(word string, operands [][]lex.Token) {
|
|||
As: obj.ATEXT,
|
||||
Pos: p.pos(),
|
||||
From: nameAddr,
|
||||
From3: &obj.Addr{
|
||||
Type: obj.TYPE_CONST,
|
||||
Offset: flag,
|
||||
},
|
||||
To: obj.Addr{
|
||||
Type: obj.TYPE_TEXTSIZE,
|
||||
Offset: frameSize,
|
||||
|
|
@ -176,7 +172,7 @@ func (p *Parser) asmText(word string, operands [][]lex.Token) {
|
|||
},
|
||||
}
|
||||
prog.To.Val = int32(argSize)
|
||||
p.ctxt.InitTextSym(prog)
|
||||
p.ctxt.InitTextSym(prog, int(flag))
|
||||
|
||||
p.append(prog, "", true)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -62,6 +62,11 @@ Diff:
|
|||
for _, line := range lines {
|
||||
lineno++
|
||||
|
||||
// Ignore include of textflag.h.
|
||||
if strings.HasPrefix(line, "#include ") {
|
||||
continue
|
||||
}
|
||||
|
||||
// The general form of a test input line is:
|
||||
// // comment
|
||||
// INST args [// printed form] [// hex encoding]
|
||||
|
|
|
|||
4
src/cmd/asm/internal/asm/testdata/386.s
vendored
4
src/cmd/asm/internal/asm/testdata/386.s
vendored
|
|
@ -2,7 +2,9 @@
|
|||
// the old assembler's (8a's) grammar and hand-writing complete
|
||||
// instructions for each rule, to guarantee we cover the same space.
|
||||
|
||||
TEXT foo(SB), 7, $0
|
||||
#include "../../../../../runtime/textflag.h"
|
||||
|
||||
TEXT foo(SB), DUPOK|NOSPLIT, $0
|
||||
|
||||
// LTYPE1 nonrem { outcode(int($1), &$2); }
|
||||
SETCC AX
|
||||
|
|
|
|||
4
src/cmd/asm/internal/asm/testdata/amd64.s
vendored
4
src/cmd/asm/internal/asm/testdata/amd64.s
vendored
|
|
@ -6,7 +6,9 @@
|
|||
// the old assembler's (6a's) grammar and hand-writing complete
|
||||
// instructions for each rule, to guarantee we cover the same space.
|
||||
|
||||
TEXT foo(SB), 7, $0
|
||||
#include "../../../../../runtime/textflag.h"
|
||||
|
||||
TEXT foo(SB), DUPOK|NOSPLIT, $0
|
||||
|
||||
// LTYPE1 nonrem { outcode($1, &$2); }
|
||||
NEGQ R11
|
||||
|
|
|
|||
4
src/cmd/asm/internal/asm/testdata/amd64enc.s
vendored
4
src/cmd/asm/internal/asm/testdata/amd64enc.s
vendored
|
|
@ -1,7 +1,9 @@
|
|||
// generated by x86test -amd64
|
||||
// DO NOT EDIT
|
||||
|
||||
TEXT asmtest(SB),7,$0
|
||||
#include "../../../../../runtime/textflag.h"
|
||||
|
||||
TEXT asmtest(SB),DUPOK|NOSPLIT,$0
|
||||
ADCB $7, AL // 1407
|
||||
ADCW $61731, AX // 661523f1
|
||||
ADCL $4045620583, AX // 15674523f1
|
||||
|
|
|
|||
4
src/cmd/asm/internal/asm/testdata/arm.s
vendored
4
src/cmd/asm/internal/asm/testdata/arm.s
vendored
|
|
@ -6,7 +6,9 @@
|
|||
// the old assembler's (5a's) grammar and hand-writing complete
|
||||
// instructions for each rule, to guarantee we cover the same space.
|
||||
|
||||
TEXT foo(SB), 7, $0
|
||||
#include "../../../../../runtime/textflag.h"
|
||||
|
||||
TEXT foo(SB), DUPOK|NOSPLIT, $0
|
||||
|
||||
// ADD
|
||||
//
|
||||
|
|
|
|||
4
src/cmd/asm/internal/asm/testdata/arm64.s
vendored
4
src/cmd/asm/internal/asm/testdata/arm64.s
vendored
|
|
@ -6,7 +6,9 @@
|
|||
// the old assembler's (7a's) grammar and hand-writing complete
|
||||
// instructions for each rule, to guarantee we cover the same space.
|
||||
|
||||
TEXT foo(SB), 7, $-8
|
||||
#include "../../../../../runtime/textflag.h"
|
||||
|
||||
TEXT foo(SB), DUPOK|NOSPLIT, $-8
|
||||
|
||||
//
|
||||
// ADD
|
||||
|
|
|
|||
4
src/cmd/asm/internal/asm/testdata/mips.s
vendored
4
src/cmd/asm/internal/asm/testdata/mips.s
vendored
|
|
@ -5,7 +5,9 @@
|
|||
// This input was created by taking the mips64 testcase and modified
|
||||
// by hand.
|
||||
|
||||
TEXT foo(SB),7,$0
|
||||
#include "../../../../../runtime/textflag.h"
|
||||
|
||||
TEXT foo(SB),DUPOK|NOSPLIT,$0
|
||||
|
||||
//inst:
|
||||
//
|
||||
|
|
|
|||
4
src/cmd/asm/internal/asm/testdata/mips64.s
vendored
4
src/cmd/asm/internal/asm/testdata/mips64.s
vendored
|
|
@ -5,7 +5,9 @@
|
|||
// This input was created by taking the ppc64 testcase and modified
|
||||
// by hand.
|
||||
|
||||
TEXT foo(SB),7,$0
|
||||
#include "../../../../../runtime/textflag.h"
|
||||
|
||||
TEXT foo(SB),DUPOK|NOSPLIT,$0
|
||||
|
||||
//inst:
|
||||
//
|
||||
|
|
|
|||
4
src/cmd/asm/internal/asm/testdata/ppc64.s
vendored
4
src/cmd/asm/internal/asm/testdata/ppc64.s
vendored
|
|
@ -6,7 +6,9 @@
|
|||
// the old assembler's (9a's) grammar and hand-writing complete
|
||||
// instructions for each rule, to guarantee we cover the same space.
|
||||
|
||||
TEXT foo(SB),7,$0
|
||||
#include "../../../../../runtime/textflag.h"
|
||||
|
||||
TEXT foo(SB),DUPOK|NOSPLIT,$0
|
||||
|
||||
//inst:
|
||||
//
|
||||
|
|
|
|||
8
src/cmd/asm/internal/asm/testdata/s390x.s
vendored
8
src/cmd/asm/internal/asm/testdata/s390x.s
vendored
|
|
@ -2,7 +2,9 @@
|
|||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
TEXT main·foo(SB),7,$16-0 // TEXT main.foo(SB), 7, $16-0
|
||||
#include "../../../../../runtime/textflag.h"
|
||||
|
||||
TEXT main·foo(SB),DUPOK|NOSPLIT,$16-0 // TEXT main.foo(SB), DUPOK|NOSPLIT, $16-0
|
||||
MOVD R1, R2 // b9040021
|
||||
MOVW R3, R4 // b9140043
|
||||
MOVH R5, R6 // b9070065
|
||||
|
|
@ -350,9 +352,9 @@ TEXT main·foo(SB),7,$16-0 // TEXT main.foo(SB), 7, $16-0
|
|||
|
||||
RET
|
||||
|
||||
TEXT main·init(SB),7,$0 // TEXT main.init(SB), 7, $0
|
||||
TEXT main·init(SB),DUPOK|NOSPLIT,$0 // TEXT main.init(SB), DUPOK|NOSPLIT, $0
|
||||
RET
|
||||
|
||||
TEXT main·main(SB),7,$0 // TEXT main.main(SB), 7, $0
|
||||
TEXT main·main(SB),DUPOK|NOSPLIT,$0 // TEXT main.main(SB), DUPOK|NOSPLIT, $0
|
||||
BL main·foo(SB) // CALL main.foo(SB)
|
||||
RET
|
||||
|
|
|
|||
|
|
@ -155,24 +155,24 @@ func (pp *Progs) settext(fn *Node) {
|
|||
}
|
||||
}
|
||||
|
||||
ptxt.From3 = new(obj.Addr)
|
||||
var flag int
|
||||
if fn.Func.Dupok() {
|
||||
ptxt.From3.Offset |= obj.DUPOK
|
||||
flag |= obj.DUPOK
|
||||
}
|
||||
if fn.Func.Wrapper() {
|
||||
ptxt.From3.Offset |= obj.WRAPPER
|
||||
flag |= obj.WRAPPER
|
||||
}
|
||||
if fn.Func.NoFramePointer() {
|
||||
ptxt.From3.Offset |= obj.NOFRAME
|
||||
flag |= obj.NOFRAME
|
||||
}
|
||||
if fn.Func.Needctxt() {
|
||||
ptxt.From3.Offset |= obj.NEEDCTXT
|
||||
flag |= obj.NEEDCTXT
|
||||
}
|
||||
if fn.Func.Pragma&Nosplit != 0 {
|
||||
ptxt.From3.Offset |= obj.NOSPLIT
|
||||
flag |= obj.NOSPLIT
|
||||
}
|
||||
if fn.Func.ReflectMethod() {
|
||||
ptxt.From3.Offset |= obj.REFLECTMETHOD
|
||||
flag |= obj.REFLECTMETHOD
|
||||
}
|
||||
|
||||
// Clumsy but important.
|
||||
|
|
@ -181,11 +181,11 @@ func (pp *Progs) settext(fn *Node) {
|
|||
if myimportpath == "reflect" {
|
||||
switch fn.Func.Nname.Sym.Name {
|
||||
case "callReflect", "callMethod":
|
||||
ptxt.From3.Offset |= obj.WRAPPER
|
||||
flag |= obj.WRAPPER
|
||||
}
|
||||
}
|
||||
|
||||
Ctxt.InitTextSym(ptxt)
|
||||
Ctxt.InitTextSym(ptxt, flag)
|
||||
|
||||
pp.Text = ptxt
|
||||
}
|
||||
|
|
|
|||
|
|
@ -357,7 +357,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) {
|
|||
}
|
||||
}
|
||||
|
||||
if p.From3.Offset&obj.NOSPLIT == 0 {
|
||||
if !p.From.Sym.NoSplit() {
|
||||
p = c.stacksplit(p, autosize) // emit split check
|
||||
}
|
||||
|
||||
|
|
@ -373,7 +373,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) {
|
|||
p.To.Reg = REGSP
|
||||
p.Spadj = autosize
|
||||
|
||||
if cursym.Text.From3.Offset&obj.WRAPPER != 0 {
|
||||
if cursym.Text.From.Sym.Wrapper() {
|
||||
// if(g->panic != nil && g->panic->argp == FP) g->panic->argp = bottom-of-frame
|
||||
//
|
||||
// MOVW g_panic(g), R1
|
||||
|
|
@ -534,7 +534,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) {
|
|||
}
|
||||
|
||||
case ADIV, ADIVU, AMOD, AMODU:
|
||||
if cursym.Text.From3.Offset&obj.NOSPLIT != 0 {
|
||||
if cursym.Text.From.Sym.NoSplit() {
|
||||
ctxt.Diag("cannot divide in NOSPLIT function")
|
||||
}
|
||||
const debugdivmod = false
|
||||
|
|
@ -842,7 +842,7 @@ func (c *ctxt5) stacksplit(p *obj.Prog, framesize int32) *obj.Prog {
|
|||
switch {
|
||||
case c.cursym.CFunc():
|
||||
morestack = "runtime.morestackc"
|
||||
case c.cursym.Text.From3.Offset&obj.NEEDCTXT == 0:
|
||||
case !c.cursym.Text.From.Sym.NeedCtxt():
|
||||
morestack = "runtime.morestack_noctxt"
|
||||
}
|
||||
call.To.Sym = c.ctxt.Lookup(morestack, 0)
|
||||
|
|
|
|||
|
|
@ -204,7 +204,7 @@ func (c *ctxt7) stacksplit(p *obj.Prog, framesize int32) *obj.Prog {
|
|||
switch {
|
||||
case c.cursym.CFunc():
|
||||
morestack = "runtime.morestackc"
|
||||
case c.cursym.Text.From3.Offset&obj.NEEDCTXT == 0:
|
||||
case !c.cursym.Text.From.Sym.NeedCtxt():
|
||||
morestack = "runtime.morestack_noctxt"
|
||||
}
|
||||
call.To.Sym = c.ctxt.Lookup(morestack, 0)
|
||||
|
|
@ -552,7 +552,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) {
|
|||
c.cursym.Text.Mark |= LEAF
|
||||
}
|
||||
|
||||
if !(p.From3.Offset&obj.NOSPLIT != 0) {
|
||||
if !p.From.Sym.NoSplit() {
|
||||
p = c.stacksplit(p, c.autosize) // emit split check
|
||||
}
|
||||
|
||||
|
|
@ -614,7 +614,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) {
|
|||
q1.Spadj = aoffset
|
||||
}
|
||||
|
||||
if c.cursym.Text.From3.Offset&obj.WRAPPER != 0 {
|
||||
if c.cursym.Text.From.Sym.Wrapper() {
|
||||
// if(g->panic != nil && g->panic->argp == FP) g->panic->argp = bottom-of-frame
|
||||
//
|
||||
// MOV g_panic(g), R1
|
||||
|
|
|
|||
|
|
@ -261,14 +261,6 @@ func (p *Prog) From3Type() AddrType {
|
|||
return p.From3.Type
|
||||
}
|
||||
|
||||
// From3Offset returns From3.Offset, or 0 when From3 is nil.
|
||||
func (p *Prog) From3Offset() int64 {
|
||||
if p.From3 == nil {
|
||||
return 0
|
||||
}
|
||||
return p.From3.Offset
|
||||
}
|
||||
|
||||
// An As denotes an assembler opcode.
|
||||
// There are some portable opcodes, declared here in package obj,
|
||||
// that are common to all architectures.
|
||||
|
|
@ -347,6 +339,9 @@ const (
|
|||
AttrCFunc
|
||||
AttrNoSplit
|
||||
AttrLeaf
|
||||
AttrWrapper
|
||||
AttrNeedCtxt
|
||||
AttrNoFrame
|
||||
AttrSeenGlobl
|
||||
AttrOnList
|
||||
|
||||
|
|
@ -379,6 +374,9 @@ func (a Attribute) SeenGlobl() bool { return a&AttrSeenGlobl != 0 }
|
|||
func (a Attribute) OnList() bool { return a&AttrOnList != 0 }
|
||||
func (a Attribute) ReflectMethod() bool { return a&AttrReflectMethod != 0 }
|
||||
func (a Attribute) Local() bool { return a&AttrLocal != 0 }
|
||||
func (a Attribute) Wrapper() bool { return a&AttrWrapper != 0 }
|
||||
func (a Attribute) NeedCtxt() bool { return a&AttrNeedCtxt != 0 }
|
||||
func (a Attribute) NoFrame() bool { return a&AttrNoFrame != 0 }
|
||||
|
||||
func (a *Attribute) Set(flag Attribute, value bool) {
|
||||
if value {
|
||||
|
|
@ -388,6 +386,45 @@ func (a *Attribute) Set(flag Attribute, value bool) {
|
|||
}
|
||||
}
|
||||
|
||||
var textAttrStrings = [...]struct {
|
||||
bit Attribute
|
||||
s string
|
||||
}{
|
||||
{bit: AttrDuplicateOK, s: "DUPOK"},
|
||||
{bit: AttrMakeTypelink, s: ""},
|
||||
{bit: AttrCFunc, s: "CFUNC"},
|
||||
{bit: AttrNoSplit, s: "NOSPLIT"},
|
||||
{bit: AttrLeaf, s: "LEAF"},
|
||||
{bit: AttrSeenGlobl, s: ""},
|
||||
{bit: AttrOnList, s: ""},
|
||||
{bit: AttrReflectMethod, s: "REFLECTMETHOD"},
|
||||
{bit: AttrLocal, s: "LOCAL"},
|
||||
{bit: AttrWrapper, s: "WRAPPER"},
|
||||
{bit: AttrNeedCtxt, s: "NEEDCTXT"},
|
||||
{bit: AttrNoFrame, s: "NOFRAME"},
|
||||
}
|
||||
|
||||
// TextAttrString formats a for printing in as part of a TEXT prog.
|
||||
func (a Attribute) TextAttrString() string {
|
||||
var s string
|
||||
for _, x := range textAttrStrings {
|
||||
if a&x.bit != 0 {
|
||||
if x.s != "" {
|
||||
s += x.s + "|"
|
||||
}
|
||||
a &^= x.bit
|
||||
}
|
||||
}
|
||||
if a != 0 {
|
||||
s += fmt.Sprintf("UnknownAttribute(%d)|", a)
|
||||
}
|
||||
// Chop off trailing |, if present.
|
||||
if len(s) > 0 {
|
||||
s = s[:len(s)-1]
|
||||
}
|
||||
return s
|
||||
}
|
||||
|
||||
// The compiler needs LSym to satisfy fmt.Stringer, because it stores
|
||||
// an LSym in ssa.ExternSymbol.
|
||||
func (s *LSym) String() string {
|
||||
|
|
|
|||
|
|
@ -286,7 +286,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) {
|
|||
|
||||
p.To.Offset = int64(autosize) - ctxt.FixedFrameSize()
|
||||
|
||||
if p.From3.Offset&obj.NOSPLIT == 0 {
|
||||
if !p.From.Sym.NoSplit() {
|
||||
p = c.stacksplit(p, autosize) // emit split check
|
||||
}
|
||||
|
||||
|
|
@ -316,7 +316,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) {
|
|||
q.To.Reg = REGSP
|
||||
q.Spadj = +autosize
|
||||
} else if c.cursym.Text.Mark&LEAF == 0 {
|
||||
if c.cursym.Text.From3.Offset&obj.NOSPLIT != 0 {
|
||||
if c.cursym.Text.From.Sym.NoSplit() {
|
||||
if ctxt.Debugvlog {
|
||||
ctxt.Logf("save suppressed in: %s\n", c.cursym.Name)
|
||||
}
|
||||
|
|
@ -330,7 +330,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) {
|
|||
break
|
||||
}
|
||||
|
||||
if c.cursym.Text.From3.Offset&obj.WRAPPER != 0 {
|
||||
if c.cursym.Text.From.Sym.Wrapper() {
|
||||
// if(g->panic != nil && g->panic->argp == FP) g->panic->argp = bottom-of-frame
|
||||
//
|
||||
// MOV g_panic(g), R1
|
||||
|
|
@ -759,7 +759,7 @@ func (c *ctxt0) stacksplit(p *obj.Prog, framesize int32) *obj.Prog {
|
|||
p.To.Type = obj.TYPE_BRANCH
|
||||
if c.cursym.CFunc() {
|
||||
p.To.Sym = c.ctxt.Lookup("runtime.morestackc", 0)
|
||||
} else if c.cursym.Text.From3.Offset&obj.NEEDCTXT == 0 {
|
||||
} else if !c.cursym.Text.From.Sym.NeedCtxt() {
|
||||
p.To.Sym = c.ctxt.Lookup("runtime.morestack_noctxt", 0)
|
||||
} else {
|
||||
p.To.Sym = c.ctxt.Lookup("runtime.morestack", 0)
|
||||
|
|
|
|||
|
|
@ -112,7 +112,7 @@ func Flushplist(ctxt *Link, plist *Plist, newprog ProgAlloc) {
|
|||
ctxt.Text = append(ctxt.Text, text...)
|
||||
}
|
||||
|
||||
func (ctxt *Link) InitTextSym(p *Prog) {
|
||||
func (ctxt *Link) InitTextSym(p *Prog, flag int) {
|
||||
if p.As != ATEXT {
|
||||
ctxt.Diag("InitTextSym non-ATEXT: %v", p)
|
||||
}
|
||||
|
|
@ -132,16 +132,12 @@ func (ctxt *Link) InitTextSym(p *Prog) {
|
|||
ctxt.Diag("symbol %s listed multiple times", s.Name)
|
||||
}
|
||||
s.Set(AttrOnList, true)
|
||||
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.Set(AttrDuplicateOK, flag&DUPOK != 0)
|
||||
s.Set(AttrNoSplit, flag&NOSPLIT != 0)
|
||||
s.Set(AttrReflectMethod, flag&REFLECTMETHOD != 0)
|
||||
s.Set(AttrWrapper, flag&WRAPPER != 0)
|
||||
s.Set(AttrNeedCtxt, flag&NEEDCTXT != 0)
|
||||
s.Set(AttrNoFrame, flag&NOFRAME != 0)
|
||||
s.Type = STEXT
|
||||
s.Text = p
|
||||
}
|
||||
|
|
|
|||
|
|
@ -240,13 +240,13 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) {
|
|||
textstksiz := p.To.Offset
|
||||
if textstksiz == -8 {
|
||||
// Compatibility hack.
|
||||
p.From3.Offset |= obj.NOFRAME
|
||||
p.From.Sym.Set(obj.AttrNoFrame, true)
|
||||
textstksiz = 0
|
||||
}
|
||||
if textstksiz%8 != 0 {
|
||||
c.ctxt.Diag("frame size %d not a multiple of 8", textstksiz)
|
||||
}
|
||||
if p.From3.Offset&obj.NOFRAME != 0 {
|
||||
if p.From.Sym.NoFrame() {
|
||||
if textstksiz != 0 {
|
||||
c.ctxt.Diag("NOFRAME functions must have a frame size of 0, not %d", textstksiz)
|
||||
}
|
||||
|
|
@ -439,10 +439,10 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) {
|
|||
|
||||
if p.Mark&LEAF != 0 && autosize == 0 {
|
||||
// A leaf function with no locals has no frame.
|
||||
p.From3.Offset |= obj.NOFRAME
|
||||
p.From.Sym.Set(obj.AttrNoFrame, true)
|
||||
}
|
||||
|
||||
if p.From3.Offset&obj.NOFRAME == 0 {
|
||||
if !p.From.Sym.NoFrame() {
|
||||
// If there is a stack frame at all, it includes
|
||||
// space to save the LR.
|
||||
autosize += int32(c.ctxt.FixedFrameSize())
|
||||
|
|
@ -451,7 +451,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) {
|
|||
if p.Mark&LEAF != 0 && autosize < obj.StackSmall {
|
||||
// A leaf function with a small stack can be marked
|
||||
// NOSPLIT, avoiding a stack check.
|
||||
p.From3.Offset |= obj.NOSPLIT
|
||||
p.From.Sym.Set(obj.AttrNoSplit, true)
|
||||
}
|
||||
|
||||
p.To.Offset = int64(autosize)
|
||||
|
|
@ -492,7 +492,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) {
|
|||
rel.Type = obj.R_ADDRPOWER_PCREL
|
||||
}
|
||||
|
||||
if c.cursym.Text.From3.Offset&obj.NOSPLIT == 0 {
|
||||
if !c.cursym.Text.From.Sym.NoSplit() {
|
||||
q = c.stacksplit(q, autosize) // emit split check
|
||||
}
|
||||
|
||||
|
|
@ -572,7 +572,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) {
|
|||
q.To.Offset = 24
|
||||
}
|
||||
|
||||
if c.cursym.Text.From3.Offset&obj.WRAPPER != 0 {
|
||||
if c.cursym.Text.From.Sym.Wrapper() {
|
||||
// if(g->panic != nil && g->panic->argp == FP) g->panic->argp = bottom-of-frame
|
||||
//
|
||||
// MOVD g_panic(g), R3
|
||||
|
|
@ -950,7 +950,7 @@ func (c *ctxt9) stacksplit(p *obj.Prog, framesize int32) *obj.Prog {
|
|||
var morestacksym *obj.LSym
|
||||
if c.cursym.CFunc() {
|
||||
morestacksym = c.ctxt.Lookup("runtime.morestackc", 0)
|
||||
} else if c.cursym.Text.From3.Offset&obj.NEEDCTXT == 0 {
|
||||
} else if !c.cursym.Text.From.Sym.NeedCtxt() {
|
||||
morestacksym = c.ctxt.Lookup("runtime.morestack_noctxt", 0)
|
||||
} else {
|
||||
morestacksym = c.ctxt.Lookup("runtime.morestack", 0)
|
||||
|
|
|
|||
|
|
@ -204,13 +204,13 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) {
|
|||
textstksiz := p.To.Offset
|
||||
if textstksiz == -8 {
|
||||
// Compatibility hack.
|
||||
p.From3.Offset |= obj.NOFRAME
|
||||
p.From.Sym.Set(obj.AttrNoFrame, true)
|
||||
textstksiz = 0
|
||||
}
|
||||
if textstksiz%8 != 0 {
|
||||
c.ctxt.Diag("frame size %d not a multiple of 8", textstksiz)
|
||||
}
|
||||
if p.From3.Offset&obj.NOFRAME != 0 {
|
||||
if p.From.Sym.NoFrame() {
|
||||
if textstksiz != 0 {
|
||||
c.ctxt.Diag("NOFRAME functions must have a frame size of 0, not %d", textstksiz)
|
||||
}
|
||||
|
|
@ -293,10 +293,10 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) {
|
|||
|
||||
if p.Mark&LEAF != 0 && autosize == 0 {
|
||||
// A leaf function with no locals has no frame.
|
||||
p.From3.Offset |= obj.NOFRAME
|
||||
p.From.Sym.Set(obj.AttrNoFrame, true)
|
||||
}
|
||||
|
||||
if p.From3.Offset&obj.NOFRAME == 0 {
|
||||
if !p.From.Sym.NoFrame() {
|
||||
// If there is a stack frame at all, it includes
|
||||
// space to save the LR.
|
||||
autosize += int32(c.ctxt.FixedFrameSize())
|
||||
|
|
@ -305,14 +305,14 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) {
|
|||
if p.Mark&LEAF != 0 && autosize < obj.StackSmall {
|
||||
// A leaf function with a small stack can be marked
|
||||
// NOSPLIT, avoiding a stack check.
|
||||
p.From3.Offset |= obj.NOSPLIT
|
||||
p.From.Sym.Set(obj.AttrNoSplit, true)
|
||||
}
|
||||
|
||||
p.To.Offset = int64(autosize)
|
||||
|
||||
q := p
|
||||
|
||||
if p.From3.Offset&obj.NOSPLIT == 0 {
|
||||
if !p.From.Sym.NoSplit() {
|
||||
p, pPreempt = c.stacksplitPre(p, autosize) // emit pre part of split check
|
||||
pPre = p
|
||||
wasSplit = true //need post part of split
|
||||
|
|
@ -352,7 +352,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) {
|
|||
break
|
||||
}
|
||||
|
||||
if c.cursym.Text.From3.Offset&obj.WRAPPER != 0 {
|
||||
if c.cursym.Text.From.Sym.Wrapper() {
|
||||
// if(g->panic != nil && g->panic->argp == FP) g->panic->argp = bottom-of-frame
|
||||
//
|
||||
// MOVD g_panic(g), R3
|
||||
|
|
@ -682,7 +682,7 @@ func (c *ctxtz) stacksplitPost(p *obj.Prog, pPre *obj.Prog, pPreempt *obj.Prog,
|
|||
p.To.Type = obj.TYPE_BRANCH
|
||||
if c.cursym.CFunc() {
|
||||
p.To.Sym = c.ctxt.Lookup("runtime.morestackc", 0)
|
||||
} else if c.cursym.Text.From3.Offset&obj.NEEDCTXT == 0 {
|
||||
} else if !c.cursym.Text.From.Sym.NeedCtxt() {
|
||||
p.To.Sym = c.ctxt.Lookup("runtime.morestack_noctxt", 0)
|
||||
} else {
|
||||
p.To.Sym = c.ctxt.Lookup("runtime.morestack", 0)
|
||||
|
|
|
|||
|
|
@ -143,16 +143,24 @@ func (p *Prog) String() string {
|
|||
sep = ", "
|
||||
}
|
||||
if p.From3Type() != TYPE_NONE {
|
||||
if p.From3.Type == TYPE_CONST && p.As == ATEXT {
|
||||
// Special case - omit $.
|
||||
fmt.Fprintf(&buf, "%s%d", sep, p.From3.Offset)
|
||||
} else if quadOpAmd64 {
|
||||
if quadOpAmd64 {
|
||||
fmt.Fprintf(&buf, "%s%v", sep, Rconv(int(p.From3.Reg)))
|
||||
} else {
|
||||
fmt.Fprintf(&buf, "%s%v", sep, Dconv(p, p.From3))
|
||||
}
|
||||
sep = ", "
|
||||
}
|
||||
if p.As == ATEXT {
|
||||
// If there are attributes, print them. Otherwise, skip the comma.
|
||||
// In short, print one of these two:
|
||||
// TEXT foo(SB), DUPOK|NOSPLIT, $0
|
||||
// TEXT foo(SB), $0
|
||||
s := p.From.Sym.Attribute.TextAttrString()
|
||||
if s != "" {
|
||||
fmt.Fprintf(&buf, "%s%s", sep, s)
|
||||
sep = ", "
|
||||
}
|
||||
}
|
||||
if p.To.Type != TYPE_NONE {
|
||||
fmt.Fprintf(&buf, "%s%v", sep, Dconv(p, &p.To))
|
||||
}
|
||||
|
|
|
|||
|
|
@ -609,8 +609,8 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) {
|
|||
|
||||
var bpsize int
|
||||
if ctxt.Arch.Family == sys.AMD64 && ctxt.Framepointer_enabled &&
|
||||
p.From3.Offset&obj.NOFRAME == 0 && // (1) below
|
||||
!(autoffset == 0 && p.From3.Offset&obj.NOSPLIT != 0) && // (2) below
|
||||
!p.From.Sym.NoFrame() && // (1) below
|
||||
!(autoffset == 0 && p.From.Sym.NoSplit()) && // (2) below
|
||||
!(autoffset == 0 && !hasCall) { // (3) below
|
||||
// Make room to save a base pointer.
|
||||
// There are 2 cases we must avoid:
|
||||
|
|
@ -637,7 +637,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) {
|
|||
}
|
||||
|
||||
// TODO(rsc): Remove 'ctxt.Arch.Family == sys.AMD64 &&'.
|
||||
if ctxt.Arch.Family == sys.AMD64 && autoffset < obj.StackSmall && p.From3Offset()&obj.NOSPLIT == 0 {
|
||||
if ctxt.Arch.Family == sys.AMD64 && autoffset < obj.StackSmall && !p.From.Sym.NoSplit() {
|
||||
leaf := true
|
||||
LeafSearch:
|
||||
for q := p; q != nil; q = q.Link {
|
||||
|
|
@ -659,16 +659,16 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) {
|
|||
}
|
||||
|
||||
if leaf {
|
||||
p.From3.Offset |= obj.NOSPLIT
|
||||
p.From.Sym.Set(obj.AttrNoSplit, true)
|
||||
}
|
||||
}
|
||||
|
||||
if p.From3Offset()&obj.NOSPLIT == 0 || p.From3Offset()&obj.WRAPPER != 0 {
|
||||
if !p.From.Sym.NoSplit() || p.From.Sym.Wrapper() {
|
||||
p = obj.Appendp(p, newprog)
|
||||
p = load_g_cx(ctxt, p, newprog) // load g into CX
|
||||
}
|
||||
|
||||
if cursym.Text.From3Offset()&obj.NOSPLIT == 0 {
|
||||
if !cursym.Text.From.Sym.NoSplit() {
|
||||
p = stacksplit(ctxt, cursym, p, newprog, autoffset, int32(textarg)) // emit split check
|
||||
}
|
||||
|
||||
|
|
@ -709,7 +709,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) {
|
|||
p.To.Reg = REG_BP
|
||||
}
|
||||
|
||||
if cursym.Text.From3Offset()&obj.WRAPPER != 0 {
|
||||
if cursym.Text.From.Sym.Wrapper() {
|
||||
// if g._panic != nil && g._panic.argp == FP {
|
||||
// g._panic.argp = bottom-of-frame
|
||||
// }
|
||||
|
|
@ -1150,7 +1150,7 @@ func stacksplit(ctxt *obj.Link, cursym *obj.LSym, p *obj.Prog, newprog obj.ProgA
|
|||
switch {
|
||||
case cursym.CFunc():
|
||||
morestack = "runtime.morestackc"
|
||||
case cursym.Text.From3Offset()&obj.NEEDCTXT == 0:
|
||||
case !cursym.Text.From.Sym.NeedCtxt():
|
||||
morestack = "runtime.morestack_noctxt"
|
||||
}
|
||||
call.To.Sym = ctxt.Lookup(morestack, 0)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue