Go: A Documentary

Design docs and discussions

556 links on 226 of 436 threads: design docs (golang/proposal, Google Docs, go.dev/s short links), proposal and tracking issues, and mailing-list and GitHub discussions. They were found by following each thread's own commits to the issues they reference, and those issues to the documents and discussions they link, plus the curated links of Go: A Documentary. Each link says where it was found. Threads without an entry had no design document or discussion that could be traced.

Memory management

Stop-the-world mark-sweep, then the parallel collector · Go 1.0–1.17

Concurrent sweep and proportional sweep · Go 1.0–1.17

Concurrent mark: write barriers and the dev.garbage collector · Go 1.0–1.17

Decentralized GC state machine and mark termination simplification · Go 1.0–1.17

GC pacer: trigger controller, assists and background utilisation · Go 1.0–1.17

Stack scanning: conservative, precise by frames, stack barriers, hybrid barrier, async safe points · Go 1.0–1.17

Hybrid write barrier and buffered write barrier · Go 1.0–1.17

Allocating from mark bits: allocBits, freeindex and ctz · Go 1.0–1.17

Size classes, tiny allocator and mcache/mcentral · Go 1.0–1.17

The bitmap page allocator · Go 1.0–1.17

Scavenger: returning memory to the OS · Go 1.0–1.17

Heap address space: contiguous arena to sparse arenas · Go 1.0–1.17

Memory statistics and accounting · Go 1.0–1.17

GC pacer redesign · Go 1.18–1.28

Soft memory limit and GC CPU limiter · Go 1.18–1.28

Green Tea: span-based marking with vector scan kernels · Go 1.18–1.28

mallocgc decomposition and size-specialized malloc · Go 1.18–1.28

Scavenger redesign · Go 1.18–1.28

Transparent huge page management · Go 1.18–1.28

Finalizers, runtime.AddCleanup and the cleanup queue · Go 1.18–1.28

Weak pointers and the unique package · Go 1.18–1.28

Object pinning (runtime.Pinner) · Go 1.18–1.28

Memory arenas experiment · Go 1.18–1.28

runtime.freegc: compiler-directed explicit freeing · Go 1.18–1.28

Mark worker scheduling and GC work queues · Go 1.18–1.28

Allocation publication, zeroing and preemptibility · Go 1.18–1.28

Sweeper termination and pacing · Go 1.18–1.28

Heap base address randomization · Go 1.18–1.28

Scheduler and concurrency

The G-M-P scheduler: from global-lock M:N to per-P run queues, spinning Ms and work stealing · Go 1.0–1.17

Preemption: cooperative stack-check preemption (1.2) to signal-based asynchronous preemption (1.14) · Go 1.0–1.17

Timers: timerproc goroutine → per-bucket heaps → timers on Ps · Go 1.0–1.17

Channels and select · Go 1.0–1.17

sync.Mutex, RWMutex, WaitGroup, Cond, Once · Go 1.0–1.17

sync.Pool · Go 1.0–1.17

sync.Map, atomic.Value and sync/atomic · Go 1.0–1.17

Runtime lock ranking (static lock order checking) · Go 1.0–1.17

Runtime from C to Go: scheduler, channels, semaphores, timers, netpoll · Go 1.0–1.17

Goroutine and M lifecycle: caches, ids, LockOSThread, Goexit, cgo extra Ms, deadlock detection · Go 1.0–1.17

Scheduler diagnostics: schedtrace, GODEBUG, execution tracer, block/mutex profiles · Go 1.0–1.17

Fast random numbers for the scheduler · Go 1.0–1.17

GOMAXPROCS, thread and resource limits · Go 1.0–1.17

Timer rewrite: per-P timer heap, timer.lock, and GC-able synchronous timer channels · Go 1.18–1.28

Runtime mutex: tri-state futex/sema locks → "spinbit" mutex · Go 1.18–1.28

Contended runtime-lock profiling (mutex profile for runtime-internal locks) · Go 1.18–1.28

Scheduler core: spinning Ms, work conservation, stealing, STW interaction · Go 1.18–1.28

Syscall path: eliminating _Psyscall, _Gdeadextra, and goroutine states · Go 1.18–1.28

GOMAXPROCS container awareness and dynamic updates · Go 1.18–1.28

testing/synctest bubbles · Go 1.18–1.28

Coroutines (iter.Pull runtime support) · Go 1.18–1.28

Asynchronous preemption: extended register state · Go 1.18–1.28

sync package API evolution · Go 1.18–1.28

sync/atomic and runtime atomics · Go 1.18–1.28

Runtime lock ranking · Go 1.18–1.28

Goroutine lifecycle and identity · Go 1.18–1.28

Data structures and type metadata

Hash map core: from the first hashmap.c to the 8-entry bucket design · Go 1.0–1.17

Hash functions and algorithm tables: memhash, AES hash, fallback hash · Go 1.0–1.17

Runtime type descriptors: layout, shrinking and name encoding · Go 1.0–1.17

Interface values, itabs and type assertions · Go 1.0–1.17

Register ABI support in reflect and runtime assembly (Go 1.17) · Go 1.0–1.17

C-to-Go conversion of runtime data-structure code · Go 1.0–1.17

internal/reflectlite and checkptr · Go 1.0–1.17

Swiss-table maps (GOEXPERIMENT=swissmap → only implementation) · Go 1.18–1.28

Interface conversion: itabs, type switch and assertion caches · Go 1.18–1.28

Register ABI completion for reflect, memmove/memclr and bytealg across architectures · Go 1.18–1.28

Slice growth, string building and allocation-free bytes/strings helpers · Go 1.18–1.28

Runtime randomness: fastrand, chacha8rand and math/rand/v2 · Go 1.18–1.28

iter.Pull and range-over-func iterator types · Go 1.18–1.28

Diagnostics and knobs

Execution tracer (trace v1): events, per-goroutine sequencing, annotations · Go 1.0–1.17

CPU profiler and runtime/pprof writers (legacy format to compressed protobuf) · Go 1.0–1.17

Profile labels · Go 1.0–1.17

runtime/metrics · Go 1.0–1.17

The new execution tracer (trace v2): generations, per-M buffers, new parser · Go 1.18–1.28

Mutex and block profiles, including runtime-internal lock contention · Go 1.18–1.28

Flight recorder and trace subscribers · Go 1.18–1.28

CPU profiling, goroutine profiling, pprof labels and the protobuf writer · Go 1.18–1.28

Goroutine leak profile (GC-based leak detection) · Go 1.18–1.28

runtime/metrics and MemStats · Go 1.18–1.28

Coverage redesign: runtime/coverage, internal/coverage, covdata · Go 1.18–1.28

Race detector, ASan, MSan and Valgrind integration · Go 1.18–1.28

Crash output, runtime/debug, BuildInfo and debuglog · Go 1.18–1.28

OS layer, stacks and panics

Segmented stacks to contiguous (copied) stacks · Go 1.0–1.4

Goroutine preemption (stackguard0, 10 ms and GC preemption) · Go 1.0–1.4

C-to-Go conversion of the runtime's OS, arch and signal layers ([dev.cc]) · Go 1.5–1.17

Goroutine stack growth, shrinking, GC stack barriers and stack objects · Go 1.5–1.17

Defer, panic, recover and Goexit (runtime side) · Go 1.5–1.17

Asynchronous preemption: signal plumbing, injected calls and per-arch support · Go 1.5–1.17

cgo runtime support: pointer checks, callbacks, extra Ms, C-to-Go call path · Go 1.5–1.17

Shared-library and buildmode entry points (c-archive, c-shared, plugin, shared) · Go 1.5–1.17

vDSO, time sources and process-wide randomness · Go 1.5–1.17

Darwin and OpenBSD move to libc; Solaris and AIX libcall; syscall wrapper layer · Go 1.5–1.17

CPU feature detection (internal/cpu), auxv parsing and GODEBUG=cpu.* · Go 1.5–1.17

Assembly-level runtime entry points: memequal/cmp/IndexByte, hashing, atomics and ABI wrappers · Go 1.5–1.17

Debugger function calls and conservative preemption frames · Go 1.5–1.17

Plan 9 and NaCl ports · Go 1.5–1.17

Unwinder: gentraceback → unwinder iterator, inline unwinder, pcvalue cache · Go 1.18–1.28

Frame pointers: explicit NOFRAME, FP maintenance and FP unwinding · Go 1.18–1.28

runtime/secret and data-independent timing (DIT) · Go 1.18–1.28

vDSO, vgetrandom and fast clocks · Go 1.18–1.28

Syscall layer: AllThreadsSyscall, internal/runtime/syscall, libc and Windows SyscallN · Go 1.18–1.28

CPU feature detection, GOAMD64 checks and cpu GODEBUG options · Go 1.18–1.28

Compiler frontend

Escape analysis and heap allocation · Go 1.0: 2008–2012

The C-to-Go translation of the compiler (cmd/gc → cmd/internal/gc → cmd/compile/internal/gc) · Go 1.1–1.9

Binary export data and the object-file split · Go 1.1–1.9

Escape analysis and stack allocation · Go 1.1–1.9

Type aliases (the => experiment and type A = B) · Go 1.1–1.9

Compiler data structures: Node, Nodes, Type, and the types package · Go 1.1–1.9

Compiler performance, formatting and concurrency · Go 1.1–1.9

Generics bring-up in the compiler (dev.typeparams): parser, -G, types2, irgen, first stenciling · Go 1.10–1.17

Constants: Go 2 number literals, evconst, untyped conversion and go/constant · Go 1.10–1.17

Language version gating (-lang) and language changes implemented in the frontend · Go 1.10–1.17

Package initialization order, static initialisation and init functions · Go 1.10–1.17

Inlining-related frontend work: export of bodies, type switches, closures, devirtualization · Go 1.10–1.17

checkptr instrumentation and compiler debugging flags · Go 1.10–1.17

Register-ABI plumbing in the frontend · Go 1.10–1.17

Bringing up generics in types2 (type-parameter operands, core/structural types, tparam-as-interface) · Go 1.18–1.28

Type sets, union terms, interfaces and constraint satisfaction · Go 1.18–1.28

Instantiation, Named types, Context deduplication and lazy expansion · Go 1.18–1.28

Type inference and unification · Go 1.18–1.28

Generic type aliases and Alias type nodes · Go 1.18–1.28

Per-file language versions and version gating · Go 1.18–1.28

Composite-literal type elision via target types (#12854) · Go 1.18–1.28

Method receiver checking · Go 1.18–1.28

Error reporting: codes, messages, and sub-errors · Go 1.18–1.28

Sharing code between go/types and types2 · Go 1.18–1.28

Checker performance, memory and API ergonomics · Go 1.18–1.28

Generics via GC-shape stenciling and runtime dictionaries · Go 1.18–1.28

Unified IR: one serialization for noding, stenciling, inlining and export · Go 1.18–1.28

Old typechecker and IR node-model cleanup · Go 1.18–1.28

Generic methods (type parameters on methods) · Go 1.18–1.28

Compile-time performance, concurrency and the self-PGO'd compiler · Go 1.18–1.28

Package paths, -p, and build-system contract · Go 1.18–1.28

Middle end and SSA optimizer

SSA backend arrival (dev.ssa): bring-up, coverage, default-on · Go 1.0–1.9

Prove pass and bounds-check elimination · Go 1.0–1.9

Escape analysis (esc.c → esc.go) · Go 1.0–1.9

Write-barrier insertion: from gc to the SSA writebarrier pass · Go 1.0–1.9

Interface conversions, type assertions and devirtualization · Go 1.0–1.9

Preparing the backend for concurrent compilation (Go 1.9) · Go 1.0–1.9

Lowering of copies, strings and slices; intrinsics · Go 1.0–1.9

Prove pass: unsatisfiability, partial-order facts, loop bounds-check elimination · Go 1.10–1.17

Escape analysis: the esc.go fixes, the escape.go rewrite, and the move to package escape · Go 1.10–1.17

Inlining: budget, mid-stack inlining, closures, and what became inlinable · Go 1.10–1.17

Open-coded defers and defer lowering · Go 1.10–1.17

Late call expansion and the SSA side of the register ABI · Go 1.10–1.17

Rewrite-rule generator, typed Aux/AuxInt, and rule syntax · Go 1.10–1.17

Profile-guided optimization (PGO): hot-call inlining, devirtualization, profile preprocessing · Go 1.18–1.28

Inliner: budget, closures, and the interleaved inline/devirtualize driver · Go 1.18–1.28

Allocation avoidance: stack-allocated slice backing stores and allocation-free literals · Go 1.18–1.28

New inliner heuristics (GOEXPERIMENT=newinliner, inline/inlheur) · Go 1.18–1.28

Prove pass and bounds-check elimination: from poset relations to a dense limit table, topo-sorted walk, and division-aware proofs · Go 1.18–1.28

Known-bits pass (bitwise constant folding) · Go 1.18–1.28

Stack-slot merging (mergelocals) · Go 1.18–1.28

Switch lowering: jump tables, type-switch caches, and switch lookup tables · Go 1.18–1.28

Loop variable per-iteration semantics (loopvar) · Go 1.18–1.28

testing.B.Loop support in the compiler (bloop) · Go 1.18–1.28

Range-loop and range-over-func lowering in walk · Go 1.18–1.28

Branch-free lowering: CondSelect-into-math and ARM64 CCMP · Go 1.18–1.28

Constant-folding loads from type metadata and dictionaries · Go 1.18–1.28

SSA package decomposition and compiler-infrastructure refactor · Go 1.18–1.28

Backends and assemblers

Stack frame layout, prologues, stack split and frame pointers · Go 1.0–1.6

liblink: a shared assembler/linker library · Go 1.0–1.6

The Plan 9 C compilers (cc, 5c/6c/8c) in the Go toolchain · Go 1.0–1.6

Assemblers: 5a/6a/8a/9a and the Go cmd/asm · Go 1.0–1.6

C→Go translation of the toolchain (liblink, assemblers, compilers; dev.cc) · Go 1.0–1.6

Native Client (nacl/386, nacl/amd64p32, nacl/arm) and amd64p32 in the toolchain · Go 1.0–1.6

SSA backend bring-up on amd64 (dev.ssa merge) · Go 1.7–1.11

Multi-architecture SSA ports: ARM, 386, ARM64 (dev.ssa) · Go 1.7–1.11

Multi-architecture SSA ports: PPC64, MIPS64, MIPS32, s390x · Go 1.7–1.11

WebAssembly backend · Go 1.7–1.11

Removal of the legacy backend and decoupling gc from the code generators · Go 1.7–1.11

Liveness, stack maps, safepoints and write barriers · Go 1.7–1.11

DWARF variable locations, statement positions and inline info from the backend · Go 1.7–1.11

Intrinsics for atomics, math/bits, math and runtime helpers · Go 1.7–1.11

cmd/internal/obj: Prog/LSym refactoring, concurrent backend and object-writing · Go 1.7–1.11

ARM64 assembler · Go 1.7–1.11

Register-based ABI (ABIInternal) and ABI wrappers · Go 1.12–1.17

Late call expansion, AuxCall and the expand_calls pass · Go 1.12–1.17

riscv64 port: assembler and compiler · Go 1.12–1.17

WebAssembly backend · Go 1.12–1.17

math/bits, atomic and runtime intrinsics (cross-architecture) · Go 1.12–1.17

Safepoints, unsafe points and stack maps for asynchronous preemption · Go 1.12–1.17

New object file format and content-addressable symbols (dev.link, assembler side) · Go 1.12–1.17

Register-based calling convention (ABIInternal) ports beyond amd64 · Go 1.18–1.28

amd64 code generation and GOAMD64 microarchitecture levels · Go 1.18–1.28

arm64 code generation and assembler · Go 1.18–1.28

riscv64 compiler and assembler (RVA profiles, vector, compressed) · Go 1.18–1.28

loong64 backend and assembler · Go 1.18–1.28

PPC64 / Power10 backend (GOPPC64, prefixed instructions, PC-relative code) · Go 1.18–1.28

Stack slot merging, liveness and stack maps · Go 1.18–1.28

Atomics and memory-ordering code generation · Go 1.18–1.28

WebAssembly backend · Go 1.18–1.28

s390x, MIPS, 386 and 32-bit ARM backends · Go 1.18–1.28

Backend hooks for GOEXPERIMENT=simd (amd64 AVX-512, arm64 SVE, wasm) · Go 1.18–1.28

SSA package split into subpackages (issue #80409) · Go 1.18–1.28

Compiler SIMD type system, ABI and register-allocation support · Go 1.18–1.28

simdgen: the instruction-table-driven generator · Go 1.18–1.28

AMD64 archsimd API: AVX, AVX2 and AVX-512 operations · Go 1.18–1.28

Mask representation, masked operations and merge peepholes · Go 1.18–1.28

dev.simd branch, GOEXPERIMENT=simd lifecycle and merges to master · Go 1.18–1.28

ARM64 SVE: scalable vectors and predicate masks · Go 1.18–1.28

Spec-driven API generation (internal/spec, specgen, specfill) · Go 1.18–1.28

API shaping and renames before stabilisation · Go 1.18–1.28

Linker and object files

Go symbol table, pc/line table and function metadata (gosymtab, pclntab, findfunc) · Go 1.0–1.9

Dead code and data elimination · Go 1.0–1.9

External (host) linking and cgo · Go 1.0–1.9

Build modes: -shared, c-archive, c-shared, shared, PIE, plugin · Go 1.0–1.9

liblink, the object file format and the move into the compilers · Go 1.0–1.9

From C to Go: cmd/link · Go 1.0–1.9

Runtime type data, GC metadata and sections laid out by the linker · Go 1.0–1.9

New object file format and the loader (dev.link) · Go 1.10–1.17

Wavefront conversion of linker passes to the loader; sym.Symbol removal · Go 1.10–1.17

Linker performance and memory engineering · Go 1.10–1.17

DWARF compression and Mach-O dsymutil combining · Go 1.10–1.17

Symbol ABIs: stable ABI0 vs ABIInternal in the linker and object files · Go 1.10–1.17

Mach-O and Darwin support · Go 1.10–1.17

PE / Windows · Go 1.10–1.17

AIX / XCOFF · Go 1.10–1.17

WebAssembly · Go 1.10–1.17

Architecture ports and trampoline insertion · Go 1.10–1.17

GOEXPERIMENT plumbing and tool configuration · Go 1.10–1.17

Relocation-free pclntab and funcdata (offsets instead of relocations) · Go 1.18–1.28

Type, itab and typelink layout (.go.type section, relro rework) · Go 1.18–1.28

//go:linkname restrictions and the blocklist · Go 1.18–1.28

DWARF 5 migration · Go 1.18–1.28

Darwin split DWARF (dSYM) · Go 1.18–1.28

Reproducible build IDs, buildinfo and symbol tables · Go 1.18–1.28

FIPS 140 support in the linker · Go 1.18–1.28