简体   繁体   English

指向结构成员的指针如何使结构在 Go 中保持活动状态

[英]how a pointer to a struct member keeps the struct alive in Go

Given the following golang code:给定以下 golang 代码:

type Pointer struct { x, y int }

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

CompilerExplorer shows that return &p.y compiles to CompilerExplorer显示return &p.y编译为

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 . TESTB是一个空检查,然后ADDQ通过将Pointer::y的偏移量添加到p来生成指向py的指针。

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?我不明白的是,给定一个指向py的指针,垃圾收集器如何知道它不仅仅是一个任意的*int ,而是一个指向Pointer::y的指针,所以只要指向py的指针p就必须保持活动状态还活着?

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. Arenas 和 spans 与页面对齐,因此计算指针指向的 arena 很简单。
  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 .给定指针p 、 span b的基地址和 span s元素大小,我们知道指针指向 span 中的第 n 个元素,其中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.所以跨度b + s * n中第 n 个对象的地址,需要标记为活动的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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