简体   繁体   中英

how a pointer to a struct member keeps the struct alive in Go

Given the following golang code:

type Pointer struct { x, y int }

func foo(p *Pointer) *int {
    return &p.y
}

CompilerExplorer shows that return &p.y compiles to

TESTB   AL, (AX)
ADDQ    $8, AX
RET

It's easy to understand. TESTB is a null check, then ADDQ produce a pointer to py by adding offset of Pointer::y to p .

What I don't understand is, given a pointer to py , how does the garbage collector knows it's not just an arbitrary *int , but a pointer to a Pointer::y , so p must remain alive as long as a pointer to py is still alive?

After reading the source code I found the answer.

  1. Go use arena / span based allocation.
  2. Arenas and spans are aligned with pages, so it's trivial to calculate which arena is the pointer pointing to.
  3. There's a global vector stores metadata of all arenas and spans.
  4. Each span has a fixed "element size". All objects in the same span have the same size.
  5. Given the pointer p , base address of span b and element size of span s , we know the pointer is pointing n-th element in the span, where n = (p - b) / s .
  6. So the address of n-th object in the span b + s * n , which needs to be marked as alive.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM