mirror of
https://github.com/golang/go.git
synced 2025-12-08 06:10:04 +00:00
cmd/compile: use getcallersp for gorecover "fp" arg
Currently, the compiler synthesize a special ".fp" node, which points to the FP of the current frame, be to used to call gorecover. Later that node turns to an Arg in SSA that is not really an arg, causing problems for the new ABI work which changes the handling of Args, so we have to special-case that node. This CL changes the compiler to get the FP by using getcallersp, which is an intrinsic in SSA and works on all platforms. As we need the FP, not the caller SP, one drawback is that we have to add FixedFrameSize for LR machines. But it does allow us to remove that special node. Change-Id: Ie721d51efca8116c9d23cc4f79738fffcf847df8 Reviewed-on: https://go-review.googlesource.com/c/go/+/297930 Trust: Cherry Zhang <cherryyz@google.com> Reviewed-by: David Chase <drchase@google.com>
This commit is contained in:
parent
a22bd3dc73
commit
fb03be9d55
7 changed files with 11 additions and 18 deletions
|
|
@ -509,5 +509,3 @@ func NewPkgName(pos src.XPos, sym *types.Sym, pkg *types.Pkg) *PkgName {
|
||||||
p.pos = pos
|
p.pos = pos
|
||||||
return p
|
return p
|
||||||
}
|
}
|
||||||
|
|
||||||
var RegFP *Name
|
|
||||||
|
|
|
||||||
|
|
@ -93,12 +93,7 @@ func (s *ssafn) AllocFrame(f *ssa.Func) {
|
||||||
for _, v := range b.Values {
|
for _, v := range b.Values {
|
||||||
if n, ok := v.Aux.(*ir.Name); ok {
|
if n, ok := v.Aux.(*ir.Name); ok {
|
||||||
switch n.Class {
|
switch n.Class {
|
||||||
case ir.PPARAM, ir.PPARAMOUT:
|
case ir.PPARAM, ir.PPARAMOUT, ir.PAUTO:
|
||||||
// Don't modify RegFP; it is a global.
|
|
||||||
if n != ir.RegFP {
|
|
||||||
n.SetUsed(true)
|
|
||||||
}
|
|
||||||
case ir.PAUTO:
|
|
||||||
n.SetUsed(true)
|
n.SetUsed(true)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -5176,10 +5176,6 @@ func (s *state) addr(n ir.Node) *ssa.Value {
|
||||||
if v != nil {
|
if v != nil {
|
||||||
return v
|
return v
|
||||||
}
|
}
|
||||||
if n == ir.RegFP {
|
|
||||||
// Special arg that points to the frame pointer (Used by ORECOVER).
|
|
||||||
return s.entryNewValue2A(ssa.OpLocalAddr, t, n, s.sp, s.startmem)
|
|
||||||
}
|
|
||||||
s.Fatalf("addr of undeclared ONAME %v. declared: %v", n, s.decladdrs)
|
s.Fatalf("addr of undeclared ONAME %v. declared: %v", n, s.decladdrs)
|
||||||
return nil
|
return nil
|
||||||
case ir.PAUTO:
|
case ir.PAUTO:
|
||||||
|
|
|
||||||
|
|
@ -178,6 +178,7 @@ var runtimeDecls = [...]struct {
|
||||||
{"uint32tofloat64", funcTag, 117},
|
{"uint32tofloat64", funcTag, 117},
|
||||||
{"complex128div", funcTag, 118},
|
{"complex128div", funcTag, 118},
|
||||||
{"getcallerpc", funcTag, 119},
|
{"getcallerpc", funcTag, 119},
|
||||||
|
{"getcallersp", funcTag, 119},
|
||||||
{"racefuncenter", funcTag, 31},
|
{"racefuncenter", funcTag, 31},
|
||||||
{"racefuncexit", funcTag, 9},
|
{"racefuncexit", funcTag, 9},
|
||||||
{"raceread", funcTag, 31},
|
{"raceread", funcTag, 31},
|
||||||
|
|
|
||||||
|
|
@ -226,6 +226,7 @@ func uint32tofloat64(uint32) float64
|
||||||
func complex128div(num complex128, den complex128) (quo complex128)
|
func complex128div(num complex128, den complex128) (quo complex128)
|
||||||
|
|
||||||
func getcallerpc() uintptr
|
func getcallerpc() uintptr
|
||||||
|
func getcallersp() uintptr
|
||||||
|
|
||||||
// race detection
|
// race detection
|
||||||
func racefuncenter(uintptr)
|
func racefuncenter(uintptr)
|
||||||
|
|
|
||||||
|
|
@ -354,9 +354,4 @@ func DeclareUniverse() {
|
||||||
s1.Def = s.Def
|
s1.Def = s.Def
|
||||||
s1.Block = s.Block
|
s1.Block = s.Block
|
||||||
}
|
}
|
||||||
|
|
||||||
ir.RegFP = NewName(Lookup(".fp"))
|
|
||||||
ir.RegFP.SetType(types.Types[types.TINT32])
|
|
||||||
ir.RegFP.Class = ir.PPARAM
|
|
||||||
ir.RegFP.SetUsed(true)
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -158,7 +158,14 @@ func walkExpr1(n ir.Node, init *ir.Nodes) ir.Node {
|
||||||
|
|
||||||
case ir.ORECOVER:
|
case ir.ORECOVER:
|
||||||
n := n.(*ir.CallExpr)
|
n := n.(*ir.CallExpr)
|
||||||
return mkcall("gorecover", n.Type(), init, typecheck.NodAddr(ir.RegFP))
|
// Call gorecover with the FP of this frame.
|
||||||
|
// FP is equal to caller's SP plus FixedFrameSize().
|
||||||
|
var fp ir.Node = mkcall("getcallersp", types.Types[types.TUINTPTR], init)
|
||||||
|
if off := base.Ctxt.FixedFrameSize(); off != 0 {
|
||||||
|
fp = ir.NewBinaryExpr(fp.Pos(), ir.OADD, fp, ir.NewInt(off))
|
||||||
|
}
|
||||||
|
fp = ir.NewConvExpr(fp.Pos(), ir.OCONVNOP, types.NewPtr(types.Types[types.TINT32]), fp)
|
||||||
|
return mkcall("gorecover", n.Type(), init, fp)
|
||||||
|
|
||||||
case ir.OCFUNC:
|
case ir.OCFUNC:
|
||||||
return n
|
return n
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue