-
Notifications
You must be signed in to change notification settings - Fork 18.4k
Closed
Labels
Milestone
Description
This bug is not present in release-branch.go1.8 nor earlier versions of Go. It is the root cause for some failures reported on #19029 (but not the ones using Go 1.7.5).
Here's a source file:
package p
func g()
func h(*error)
func f(err error) error {
defer g()
h(&err)
return err
}
The liveness debugging output begins:
$ go tool compile -live=2 /tmp/xxx.go
/tmp/xxx.go:6: live at entry to f: err
/tmp/xxx.go:6: live at call to newobject: err ~r1
/tmp/xxx.go:6: live at call to writebarrierptr: ~r1 &err
/tmp/xxx.go:7: live at call to deferproc: ~r1 &err
/tmp/xxx.go:8: live at call to h: ~r1 &err
/tmp/xxx.go:9: live at call to deferreturn: ~r1
/tmp/xxx.go:7: live at call to deferreturn: ~r1
liveness: f
bb#0 pred= succ=2,1
00000 (/tmp/xxx.go:6) TEXT "".f(SB)
varkill=err
live=err
00001 (/tmp/xxx.go:6) FUNCDATA $0, "".gcargs·0(SB)
00002 (/tmp/xxx.go:6) FUNCDATA $1, "".gclocals·1(SB)
00003 (/tmp/xxx.go:6) LEAQ type.error(SB), AX
00004 (/tmp/xxx.go:6) MOVQ AX, (SP)
00047 (/tmp/xxx.go:6) PCDATA $0, $1
00005 (/tmp/xxx.go:6) CALL runtime.newobject(SB)
live=err,~r1
00006 (/tmp/xxx.go:6) MOVQ 8(SP), AX
00007 (/tmp/xxx.go:6) MOVQ AX, "".&err-8(SP)
varkill=&err
00008 (/tmp/xxx.go:6) MOVQ "".err(FP), CX
uevar=err
00009 (/tmp/xxx.go:6) MOVQ CX, (AX)
00010 (/tmp/xxx.go:6) MOVL runtime.writeBarrier(SB), CX
00011 (/tmp/xxx.go:6) LEAQ 8(AX), DX
00012 (/tmp/xxx.go:6) TESTL CX, CX
00013 (/tmp/xxx.go:6) JNE $0, 40
end
varkill=err,&err liveout=err,&err
bb#1 pred=0 succ=3
uevar=err livein=err,&err
00014 (/tmp/xxx.go:6) MOVQ "".err+8(FP), CX
uevar=err
00015 (/tmp/xxx.go:6) MOVQ CX, 8(AX)
end
liveout=&err
bb#2 pred=0 succ=3
uevar=err,&err livein=err,&err
00040 (/tmp/xxx.go:6) MOVQ DX, (SP)
00041 (/tmp/xxx.go:6) MOVQ "".err+8(FP), CX
uevar=err
00042 (/tmp/xxx.go:6) MOVQ CX, 8(SP)
00048 (/tmp/xxx.go:6) PCDATA $0, $2
00043 (/tmp/xxx.go:6) CALL runtime.writebarrierptr(SB)
live=~r1,&err
00044 (/tmp/xxx.go:8) MOVQ "".&err-8(SP), AX
uevar=&err
00045 (/tmp/xxx.go:6) JMP 16
end
liveout=&err
bb#3 pred=2,1 succ=5,4
livein=&err
00016 (/tmp/xxx.go:6) VARDEF "".~r1+16(FP)
varkill=~r1
00017 (/tmp/xxx.go:6) MOVQ $0, "".~r1+16(FP)
00018 (/tmp/xxx.go:6) MOVQ $0, "".~r1+24(FP)
00019 (/tmp/xxx.go:7) MOVL $0, (SP)
...
Note that in bb 0~r1 has magically become live between the start of the function and the call to newobject. That's wrong. It is not initialized until bb 3.
My guess is this was introduced by Keith's change to the handling of results in liveness bitmaps, but that's just a guess.
Again, not present in Go 1.8rc3, nor in Go 1.7.5. Those correctly delay ~r1 being live until after it is initialized.
/cc @mdempsky @randall77