Hacker News new | ask | show | jobs
by wahern 2471 days ago
> that's like, global definitions, right?

No, not just global definitions. Closures need linking, too. But the linker is doing much more than linking function entry points. Many automatic (on the stack) variables need linking so the GC can (a) trace the object graph and (b) move them when resizing the stack. Likewise, type definitions require metadata generation for GC tracing. And then there's all the debugging data that needs to be generated, which basically involves everything.

2 comments

Go currently does DWARF generation in the linker, but is in the process of moving that into the compiler. Also, most closures linking problems are relatively easy in Go.

As far as stack variables for the GC, the stack is exactly scanned for all but the last frame (I believe), but conservatively scanned for the last frame. This makes it much easier.

Types -- you're partially right. It is mostly all generated in the compiler, and deduped by the linker.

There's no reason Go's linker couldn't be much simpler and likely even simpler than a standard C linker. You might argue that Go will give up things like LTO, but Go designs out lots of the LTO problem (not PGO) by nature of how packages work, and the fact that there aren't cyclic dependencies.

Overall, the Go linker could be quite simple. It just needs some rework is all. :)

What do you mean by closures, and by linking of closures?

[I've implemented a Scheme before, in C, for context, so I'm wondering if I'm reading what you wrote with common vocabulary.]

The OP was referring to global symbol definitions and the first thing that came to mind were closures, which are generated as implicit global function definitions taking a context argument. Because Go supports lexical closures as first-class objects, they're not uncommon in typical Go code. (Though my experience is limited as I don't use Go regularly.) Point being, there can be hidden, effectively global function definitions. I'm sure that only accounts for a small fraction of the total symbols; it's just the first thing that came to mind, and one of the easiest to understand if your notion of a linker comes from what a Linux runtime linker does for C ABI-based object code.
I read that mostly as making sure capture is handled properly.