in internal/gocore/object.go [280:325]
func edges1(p *Process, r *Root, off int64, t *Type, fn func(int64, Object, int64) bool) bool {
switch t.Kind {
case KindBool, KindInt, KindUint, KindFloat, KindComplex:
// no edges here
case KindIface, KindEface:
// The first word is a type or itab.
// Itabs are never in the heap.
// Types might be, though.
a := r.Addr.Add(off)
if r.Frame == nil || r.Frame.Live[a] {
dst, off2 := p.FindObject(p.proc.ReadPtr(a))
if dst != 0 {
if !fn(off, dst, off2) {
return false
}
}
}
// Treat second word like a pointer.
off += p.proc.PtrSize()
fallthrough
case KindPtr, KindString, KindSlice, KindFunc:
a := r.Addr.Add(off)
if r.Frame == nil || r.Frame.Live[a] {
dst, off2 := p.FindObject(p.proc.ReadPtr(a))
if dst != 0 {
if !fn(off, dst, off2) {
return false
}
}
}
case KindArray:
s := t.Elem.Size
for i := int64(0); i < t.Count; i++ {
if !edges1(p, r, off+i*s, t.Elem, fn) {
return false
}
}
case KindStruct:
for _, f := range t.Fields {
if !edges1(p, r, off+f.Off, f.Type, fn) {
return false
}
}
}
return true
}