Join GitHub today
GitHub is home to over 31 million developers working together to host and review code, manage projects, and build software together.Sign up
runtime, cmd/compile: remove all pointers from type information #17724
For Go 1.7 I started replacing the pointers in Go's run time type information with offsets from the beginning of the type section. (The motivation was significantly reduced binary size, as 8-bytes for the pointer + 32-bytes for the dynamic relocation is significantly more than a 4-byte offset multiplied through by several pointers in each type and thousands of types.)
This work is not yet complete, and in its partial state it leads to subtle bugs like #17709. When using a binary built with -buildmode=shared or -buildmode=plugin, there are multiple type information sections, one for each module. An offset into this region (represented by either a
This can lead to an offset from one module being resolved against the wrong type region, meaning garbage data is used for the type. This will manifest as subtle bugs: types incorrectly mapping (or not) onto interfaces, the reflect package returning wrong results, or bad garbage collection.
The likelihood of misplacing an offset decreases significantly if we remove the pointers, as we will not have to consider the interaction of two separate relocation systems. Let's do that.
I have perhaps overstated the risk: this only applies to parts of the runtime that have access to non-canonical *_type values. Almost all of the runtime receives a *_type via module lookup, and moduledata.typemap ensures that the type is canonical.
Because the canonical *_type is the version of it from the earliest loaded moduledata, and because ld.so always resolves to the earliest loaded module, the pointers in a typical *_type point to the module that *_type originates from. It is definitely not an issue outside the runtime as all *_type values are canonical there, and even relatively high-level runtime code like iface.go only sees canonical *_type values.
In fact, runtime.typesEqual is one of the only functions that is exposed to non-canonical *_type values. Even so, I'd hate for someone else to have to debug something like this.