hybrid write barrier 为什么能消除 stack rescanning?

这两天看了一下 eliminate stack rescanning 那个 proposal,感觉很困惑。

stack rescanning 的初衷是因为 write barrier 太重,所以栈上变量的读写是不会加 write barrier 的,所以自然需要在 mark termination STW 时重扫一遍栈。但是现在,栈上变量读写仍然不加 hybrid write barrier,那么与 mark 并发的栈上变量的修改还是无法被 GC 观测到。考虑一下例子:

a 和 b 均为栈上变量,类型为指针,c 为堆上内存。

a = c mark start, a 和 b 作为根对象入队 a = nil a 出队,被染黑 b 出队,被染黑 b = c mark termination

至此,c 还是白的,会被回收。

我想了一下,hybrid write barrier 有效的前提是,逃逸分析百分百可靠,堆上内存一定会有一个堆上的引用,这样在堆上引用被移动到栈上时 deletion barrier 就会发挥作用。问题在于现在 Go 的逃逸分析并不是百分百准确的。所以我很困惑。

ref:

https://golang.org/src/cmd/compile/internal/ssa/writebarrier.go#L16 的 needwb 函数中展示了在何时添加 barrier,显然栈上读写是不加 barrier 的。

那个 proposal: https://github.com/golang/proposal/blob/master/design/17503-eliminate-rescan.md

已邀请:

goyif

赞同来自:

漏了一步,第三步不是a出队,而是scan这个栈,这样c就是灰色的了,而不是白色

要回复问题请先登录注册