ssa: rely on runtime thread defer TLS
This commit is contained in:
@@ -1 +1 @@
|
|||||||
;
|
;
|
||||||
@@ -1 +1 @@
|
|||||||
;
|
;
|
||||||
@@ -29,6 +29,11 @@ func SetThreadDefer(head *Defer) {
|
|||||||
deferTLS.Set(head)
|
deferTLS.Set(head)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetThreadDefer returns the current thread's defer chain head.
|
||||||
|
func GetThreadDefer() *Defer {
|
||||||
|
return deferTLS.Get()
|
||||||
|
}
|
||||||
|
|
||||||
// ClearThreadDefer resets the current thread's defer chain to nil.
|
// ClearThreadDefer resets the current thread's defer chain to nil.
|
||||||
func ClearThreadDefer() {
|
func ClearThreadDefer() {
|
||||||
deferTLS.Clear()
|
deferTLS.Clear()
|
||||||
|
|||||||
36
ssa/eh.go
36
ssa/eh.go
@@ -149,10 +149,6 @@ func (b Builder) Longjmp(jb, retval Expr) {
|
|||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
const (
|
|
||||||
deferKey = "__llgo_defer"
|
|
||||||
)
|
|
||||||
|
|
||||||
func (p Function) deferInitBuilder() (b Builder, next BasicBlock) {
|
func (p Function) deferInitBuilder() (b Builder, next BasicBlock) {
|
||||||
b = p.NewBuilder()
|
b = p.NewBuilder()
|
||||||
next = b.setBlockMoveLast(p.blks[0])
|
next = b.setBlockMoveLast(p.blks[0])
|
||||||
@@ -162,7 +158,6 @@ func (p Function) deferInitBuilder() (b Builder, next BasicBlock) {
|
|||||||
|
|
||||||
type aDefer struct {
|
type aDefer struct {
|
||||||
nextBit int // next defer bit
|
nextBit int // next defer bit
|
||||||
key Expr // pthread TLS key
|
|
||||||
data Expr // pointer to runtime.Defer
|
data Expr // pointer to runtime.Defer
|
||||||
bitsPtr Expr // pointer to defer bits
|
bitsPtr Expr // pointer to defer bits
|
||||||
rethPtr Expr // next block of Rethrow
|
rethPtr Expr // next block of Rethrow
|
||||||
@@ -174,30 +169,6 @@ type aDefer struct {
|
|||||||
stmts []func(bits Expr)
|
stmts []func(bits Expr)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p Package) keyInit(name string) {
|
|
||||||
keyVar := p.VarOf(name)
|
|
||||||
if keyVar == nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
prog := p.Prog
|
|
||||||
keyVar.InitNil()
|
|
||||||
keyVar.impl.SetLinkage(llvm.LinkOnceAnyLinkage)
|
|
||||||
|
|
||||||
b := p.afterBuilder()
|
|
||||||
eq := b.BinOp(token.EQL, b.Load(keyVar.Expr), prog.IntVal(0, prog.CInt()))
|
|
||||||
b.IfThen(eq, func() {
|
|
||||||
b.pthreadKeyCreate(keyVar.Expr, prog.Nil(prog.VoidPtr()))
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p Package) newKey(name string) Global {
|
|
||||||
return p.NewVarEx(name, p.Prog.CIntPtr())
|
|
||||||
}
|
|
||||||
|
|
||||||
func (b Builder) deferKey() Expr {
|
|
||||||
return b.Load(b.Pkg.newKey(deferKey).Expr)
|
|
||||||
}
|
|
||||||
|
|
||||||
const (
|
const (
|
||||||
// 0: addr sigjmpbuf
|
// 0: addr sigjmpbuf
|
||||||
// 1: bits uintptr
|
// 1: bits uintptr
|
||||||
@@ -230,9 +201,8 @@ func (b Builder) getDefer(kind DoAction) *aDefer {
|
|||||||
blks := self.MakeBlocks(2)
|
blks := self.MakeBlocks(2)
|
||||||
procBlk, rethrowBlk := blks[0], blks[1]
|
procBlk, rethrowBlk := blks[0], blks[1]
|
||||||
|
|
||||||
key := b.deferKey()
|
|
||||||
zero := prog.Val(uintptr(0))
|
zero := prog.Val(uintptr(0))
|
||||||
link := Expr{b.pthreadGetspecific(key).impl, prog.DeferPtr()}
|
link := b.Call(b.Pkg.rtFunc("GetThreadDefer"))
|
||||||
jb := b.AllocaSigjmpBuf()
|
jb := b.AllocaSigjmpBuf()
|
||||||
ptr := b.aggregateAllocU(prog.Defer(), jb.impl, zero.impl, link.impl, procBlk.Addr().impl)
|
ptr := b.aggregateAllocU(prog.Defer(), jb.impl, zero.impl, link.impl, procBlk.Addr().impl)
|
||||||
deferData := Expr{ptr, prog.DeferPtr()}
|
deferData := Expr{ptr, prog.DeferPtr()}
|
||||||
@@ -256,7 +226,6 @@ func (b Builder) getDefer(kind DoAction) *aDefer {
|
|||||||
b.If(b.BinOp(token.EQL, retval, czero), next, panicBlk)
|
b.If(b.BinOp(token.EQL, retval, czero), next, panicBlk)
|
||||||
|
|
||||||
self.defer_ = &aDefer{
|
self.defer_ = &aDefer{
|
||||||
key: key,
|
|
||||||
data: deferData,
|
data: deferData,
|
||||||
bitsPtr: bitsPtr,
|
bitsPtr: bitsPtr,
|
||||||
rethPtr: rethPtr,
|
rethPtr: rethPtr,
|
||||||
@@ -281,8 +250,7 @@ func (b Builder) getDefer(kind DoAction) *aDefer {
|
|||||||
|
|
||||||
// DeferData returns the defer data (*runtime.Defer).
|
// DeferData returns the defer data (*runtime.Defer).
|
||||||
func (b Builder) DeferData() Expr {
|
func (b Builder) DeferData() Expr {
|
||||||
key := b.deferKey()
|
return b.Call(b.Pkg.rtFunc("GetThreadDefer"))
|
||||||
return Expr{b.pthreadGetspecific(key).impl, b.Prog.DeferPtr()}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Defer emits a defer instruction.
|
// Defer emits a defer instruction.
|
||||||
|
|||||||
@@ -798,7 +798,6 @@ func (p Package) afterBuilder() Builder {
|
|||||||
|
|
||||||
// AfterInit is called after the package is initialized (init all packages that depends on).
|
// AfterInit is called after the package is initialized (init all packages that depends on).
|
||||||
func (p Package) AfterInit(b Builder, ret BasicBlock) {
|
func (p Package) AfterInit(b Builder, ret BasicBlock) {
|
||||||
p.keyInit(deferKey)
|
|
||||||
doAfterb := p.afterb != nil
|
doAfterb := p.afterb != nil
|
||||||
doPyLoadModSyms := p.pyHasModSyms()
|
doPyLoadModSyms := p.pyHasModSyms()
|
||||||
if doAfterb || doPyLoadModSyms {
|
if doAfterb || doPyLoadModSyms {
|
||||||
|
|||||||
Reference in New Issue
Block a user