mirror of https://github.com/golang/go.git
Merge 1ea6cf68ec into 49cdf0c42e
This commit is contained in:
commit
b6a8e50167
|
|
@ -984,19 +984,20 @@ func stacksplit(ctxt *obj.Link, p *obj.Prog, cursym *obj.LSym, newprog obj.ProgA
|
|||
// unnecessarily. See issue #35470.
|
||||
p = ctxt.StartUnsafePoint(p, newprog)
|
||||
|
||||
var to_done, to_more *obj.Prog
|
||||
var to_more *obj.Prog
|
||||
to_more_big := (*obj.Prog)(nil)
|
||||
|
||||
if framesize <= abi.StackSmall {
|
||||
// small stack
|
||||
// // if SP > stackguard { goto done }
|
||||
// BLTU stackguard, SP, done
|
||||
// // if SP <= stackguard { goto label-of-call-to-morestack }
|
||||
// BGEU stackguard, SP, label-of-call-to-morestack
|
||||
p = obj.Appendp(p, newprog)
|
||||
p.As = ABLTU
|
||||
p.As = ABGEU
|
||||
p.From.Type = obj.TYPE_REG
|
||||
p.From.Reg = REG_X6
|
||||
p.Reg = REG_SP
|
||||
p.To.Type = obj.TYPE_BRANCH
|
||||
to_done = p
|
||||
to_more = p
|
||||
} else {
|
||||
// large stack: SP-framesize < stackguard-StackSmall
|
||||
offset := int64(framesize) - abi.StackSmall
|
||||
|
|
@ -1024,13 +1025,13 @@ func stacksplit(ctxt *obj.Link, p *obj.Prog, cursym *obj.LSym, newprog obj.ProgA
|
|||
p.From.Reg = REG_SP
|
||||
p.Reg = REG_X7
|
||||
p.To.Type = obj.TYPE_BRANCH
|
||||
to_more = p
|
||||
to_more_big = p
|
||||
}
|
||||
|
||||
// Check against the stack guard. We've ensured this won't underflow.
|
||||
// ADD $-(framesize-StackSmall), SP, X7
|
||||
// // if X7 > stackguard { goto done }
|
||||
// BLTU stackguard, X7, done
|
||||
// // if X7 <= stackguard { goto label-of-call-to-morestack }
|
||||
// BLTU stackguard, X7, label-of-call-to-morestack
|
||||
p = obj.Appendp(p, newprog)
|
||||
p.As = AADDI
|
||||
p.From.Type = obj.TYPE_CONST
|
||||
|
|
@ -1040,53 +1041,65 @@ func stacksplit(ctxt *obj.Link, p *obj.Prog, cursym *obj.LSym, newprog obj.ProgA
|
|||
p.To.Reg = REG_X7
|
||||
|
||||
p = obj.Appendp(p, newprog)
|
||||
p.As = ABLTU
|
||||
p.As = ABGEU
|
||||
p.From.Type = obj.TYPE_REG
|
||||
p.From.Reg = REG_X6
|
||||
p.Reg = REG_X7
|
||||
p.To.Type = obj.TYPE_BRANCH
|
||||
to_done = p
|
||||
to_more = p
|
||||
}
|
||||
|
||||
end := ctxt.EndUnsafePoint(p, newprog, -1)
|
||||
|
||||
var last *obj.Prog
|
||||
for last = cursym.Func().Text; last.Link != nil; last = last.Link {
|
||||
}
|
||||
|
||||
// Now we are at the end of the function, but logically
|
||||
// we are still in function prologue. We need to fix the
|
||||
// SP data and PCDATA.
|
||||
spfix := obj.Appendp(last, newprog)
|
||||
spfix.As = obj.ANOP
|
||||
spfix.Spadj = -int32(framesize)
|
||||
|
||||
pcdata := ctxt.EmitEntryStackMap(cursym, spfix, newprog)
|
||||
pcdata = ctxt.StartUnsafePoint(pcdata, newprog)
|
||||
|
||||
if to_more_big != nil {
|
||||
to_more_big.To.SetTarget(pcdata)
|
||||
}
|
||||
to_more.To.SetTarget(pcdata)
|
||||
|
||||
// Spill the register args that could be clobbered by the
|
||||
// morestack code
|
||||
p = ctxt.EmitEntryStackMap(cursym, p, newprog)
|
||||
p = cursym.Func().SpillRegisterArgs(p, newprog)
|
||||
spill := cursym.Func().SpillRegisterArgs(pcdata, newprog)
|
||||
|
||||
// CALL runtime.morestack(SB)
|
||||
p = obj.Appendp(p, newprog)
|
||||
p.As = obj.ACALL
|
||||
p.To.Type = obj.TYPE_BRANCH
|
||||
call := obj.Appendp(spill, newprog)
|
||||
call.As = obj.ACALL
|
||||
call.To.Type = obj.TYPE_BRANCH
|
||||
|
||||
if cursym.CFunc() {
|
||||
p.To.Sym = ctxt.Lookup("runtime.morestackc")
|
||||
call.To.Sym = ctxt.Lookup("runtime.morestackc")
|
||||
} else if !cursym.Func().Text.From.Sym.NeedCtxt() {
|
||||
p.To.Sym = ctxt.Lookup("runtime.morestack_noctxt")
|
||||
call.To.Sym = ctxt.Lookup("runtime.morestack_noctxt")
|
||||
} else {
|
||||
p.To.Sym = ctxt.Lookup("runtime.morestack")
|
||||
call.To.Sym = ctxt.Lookup("runtime.morestack")
|
||||
}
|
||||
if to_more != nil {
|
||||
to_more.To.SetTarget(p)
|
||||
}
|
||||
jalToSym(ctxt, p, REG_X5)
|
||||
jalToSym(ctxt, call, REG_X5)
|
||||
|
||||
// The instructions which unspill regs should be preemptible.
|
||||
p = ctxt.EndUnsafePoint(p, newprog, -1)
|
||||
p = cursym.Func().UnspillRegisterArgs(p, newprog)
|
||||
pcdata = ctxt.EndUnsafePoint(call, newprog, -1)
|
||||
unspill := cursym.Func().UnspillRegisterArgs(pcdata, newprog)
|
||||
|
||||
// JMP start
|
||||
p = obj.Appendp(p, newprog)
|
||||
p.As = AJAL
|
||||
p.To = obj.Addr{Type: obj.TYPE_BRANCH}
|
||||
p.From = obj.Addr{Type: obj.TYPE_REG, Reg: REG_ZERO}
|
||||
p.To.SetTarget(startPred.Link)
|
||||
jmp := obj.Appendp(unspill, newprog)
|
||||
jmp.As = AJAL
|
||||
jmp.To = obj.Addr{Type: obj.TYPE_BRANCH}
|
||||
jmp.From = obj.Addr{Type: obj.TYPE_REG, Reg: REG_ZERO}
|
||||
jmp.To.SetTarget(startPred.Link)
|
||||
jmp.Spadj = +int32(framesize)
|
||||
|
||||
// placeholder for to_done's jump target
|
||||
p = obj.Appendp(p, newprog)
|
||||
p.As = obj.ANOP // zero-width place holder
|
||||
to_done.To.SetTarget(p)
|
||||
|
||||
return p
|
||||
return end
|
||||
}
|
||||
|
||||
// signExtend sign extends val starting at bit bit.
|
||||
|
|
|
|||
Loading…
Reference in New Issue