hello, I found the code in the std source code;
I am confused by the runtime.KeepAlive(x) call;
Can anyone tell me why it needed here;
As far as I know, verifyGCInfo refernces the x by &x; so it’s seems unnecessarily here.
{
var x string
verifyGCInfo(t, "stack string", &x, infoString)
runtime.KeepAlive(x)
}
func verifyGCInfo(t *testing.T, name string, p interface{}, mask0 []byte) {
mask := runtime.GCMask(p)
if !bytes.Equal(mask, mask0) {
t.Errorf("bad GC program for %v:\nwant %+v\ngot %+v", name, mask0, mask)
return
}
}
That’s part of the runtime test code, testing implementation specifics of the GC using undocumented runtime functions… in other words there are dragons here and we (I) don’t understand what is being tested. Maybe the test checks whether the thing is expected to be alive after the function returns.
In normal code you don’t need to call keep alive under the quoted circumstances.
GCMask returns type mask of struct fields (scalar (0) or pointer (1)).
If data of string (string are 2 field struct with data and len) are being unused after its call then GCMask will return scalar type for data otherwise pointer type (always if it heap allocated).
infoString is just []byte{typePointer, typeScalar}
So, data of string is actually unused and stack allocated (it must return scalar type), but runtime.KeepAlive force it be used and GCMask will return []byte{1, 0} (which equals infoString) instead of []byte{0, 0}.