You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
func f(data []byte) {
dataSize := len(data)
g(data)
runtime.GC()
global = dataSize
}
func g([]byte)
var global int
The compiler reports (with -live) that data is live at the runtime.GC call. In fact, only the .len field of data is live at that point. But because we track liveness by variable, if any field of that variable is live whole variable is live. This means data will be retained unnecessarily by the garbage collector.
Even though the code looks like it reads the length first, the compiler postpones that read until after the runtime.GC call (so it doesn't have to issue a pointless spill).
Two solutions come to mind. One is to track liveness of individual pointer fields of variables, instead of whole variables. That would work, but could be expensive for variables which have lots of pointer fields. It also isn't possible to do precisely for variables which are arrays of pointers and have non-constant indexes.
The other solution is to ignore reads of scalars when doing the liveness analysis, as the results of the liveness analysis are only used by the GC. This is more of a hack but would be a simpler fix for the code in this issue.
The text was updated successfully, but these errors were encountered:
It's not trivial to check the scalarness of a read in plive.go.
Usually it's easy, just check the type of the result.
Some reads return value/memory tuples, like MOVQatomicload.
Trickier still is ADDQload, which may be adding a scalar from memory to a pointer and generating a pointer result. Just because the result is a pointer doesn't mean the value being read from the variable is a pointer.
If we could extract the offset+size of the read, we could check in the type of the variable directly.
The compiler reports (with
-live
) thatdata
is live at theruntime.GC
call. In fact, only the.len
field ofdata
is live at that point. But because we track liveness by variable, if any field of that variable is live whole variable is live. This meansdata
will be retained unnecessarily by the garbage collector.The generated code contains:
Even though the code looks like it reads the length first, the compiler postpones that read until after the
runtime.GC
call (so it doesn't have to issue a pointless spill).Two solutions come to mind. One is to track liveness of individual pointer fields of variables, instead of whole variables. That would work, but could be expensive for variables which have lots of pointer fields. It also isn't possible to do precisely for variables which are arrays of pointers and have non-constant indexes.
The other solution is to ignore reads of scalars when doing the liveness analysis, as the results of the liveness analysis are only used by the GC. This is more of a hack but would be a simpler fix for the code in this issue.
The text was updated successfully, but these errors were encountered: