Skip to content

build: schedule package initialization in Go order - #2254

Open
cpunion wants to merge 1 commit into
xgo-dev:mainfrom
cpunion:codex/goroot-package-init-20260801
Open

build: schedule package initialization in Go order#2254
cpunion wants to merge 1 commit into
xgo-dev:mainfrom
cpunion:codex/goroot-package-init-20260801

Conversation

@cpunion

@cpunion cpunion commented Aug 1, 2026

Copy link
Copy Markdown
Collaborator

Summary

  • schedule reachable package initializers with the same dependency-constrained lexical ordering used by the Go linker
  • expose the root ..inittask header from the synthetic entry module for compiler-internal linkname compatibility
  • centralize package-kind init filtering in cl.PkgSkipsInit
  • remove the fixed noinit.go and issue31636.go xfails, plus stale Darwin init1.go xfails

The ordering is computed globally at final link time. This avoids the tempting but incorrect fix of sorting only direct imports: the added a -> z, independent b, shared tracker regression requires b, z, a, whereas sorted DFS would produce z, a, b. Existing guarded package init functions make the pre-scheduled calls idempotent when the root init later reaches its direct imports.

Validation

  • go test ./internal/build -count=1
  • go test ./internal/build ./test/goroot -count=1 -timeout=15m
  • go test -vet=off ./test/go -run ^TestPackageInitializationUsesLexicalReadyOrder$ -count=1 -timeout=10m
  • focused coverage run: packageInitOrder and linkedPackageInitNames both 100%
  • Go 1.24.11 and 1.25.0 GOROOT init1.go + noinit.go with the normal xfail file
  • Go 1.26.5 GOROOT init1.go, noinit.go, and fixedbugs/issue31636.go with the normal xfail file

go test ./test/go without -vet=off still hits the pre-existing Go 1.26 vendored printf analyzer panic; the same command fails on unchanged main.

@github-actions

github-actions Bot commented Aug 1, 2026

Copy link
Copy Markdown

LLGo baseline benchmarks

fac2e9e6af63 | workflow run | long-term charts

Program measurements

Platform Workload File size vs main Build vs main Run vs main
Linux cprintf 18624 B new 262.471 ms new 846.639 us new
Linux fmtprintf 2233584 B new 2.589 s new 1.732 ms new
Linux println 71592 B new 261.569 ms new 1.000 ms new
macOS cprintf 84672 B new 512.563 ms new 4.805 ms new
macOS fmtprintf 2380304 B new 6.115 s new 26.556 ms new
macOS println 125712 B new 435.402 ms new 4.815 ms new
Core language and compiler benchmarks
Platform Benchmark ns/op vs main
Linux BenchmarkLookupPCRandom 8.279 ns/op new
Linux BenchmarkMergeCompilerFlags 100 ns/op new
Linux BenchmarkMergeLinkerFlags 64.580 ns/op new
Linux BenchmarkChannelBuffered 42.150 ns/op new
Linux BenchmarkChannelHandoff 19993 ns/op new
Linux BenchmarkDefer 41.210 ns/op new
Linux BenchmarkDirectCall 0.261 ns/op new
Linux BenchmarkGlobalRead 0.354 ns/op new
Linux BenchmarkGlobalWrite 7.067 ns/op new
Linux BenchmarkGoroutine 28229 ns/op new
Linux BenchmarkInterfaceCall 3.900 ns/op new
Linux BenchmarkRuntimeGetG 0.735 ns/op new
macOS BenchmarkLookupPCRandom 24.930 ns/op new
macOS BenchmarkMergeCompilerFlags 214 ns/op new
macOS BenchmarkMergeLinkerFlags 112.400 ns/op new
macOS BenchmarkChannelBuffered 36.050 ns/op new
macOS BenchmarkChannelHandoff 6265 ns/op new
macOS BenchmarkDefer 62.660 ns/op new
macOS BenchmarkDirectCall 1.265 ns/op new
macOS BenchmarkGlobalRead 1.717 ns/op new
macOS BenchmarkGlobalWrite 1.272 ns/op new
macOS BenchmarkGoroutine 57628 ns/op new
macOS BenchmarkInterfaceCall 6.467 ns/op new
macOS BenchmarkRuntimeGetG 3.886 ns/op new

No main baseline exists yet; all metrics are marked new.

Warning

  • The rendered benchmark data could not be pushed.

@fennoai fennoai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review summary

Reviewed the substantive changes (package-init ordering + unconditional main. symbol prefix); the large set of cl/_testdata, cl/_testgo, cl/_testrt, and cl/_testmeta updates are mechanical fixture regenerations from the symbol rename and were not individually reviewed.

The change is well-structured and well-tested:

  • packageInitOrder (Kahn's toposort, ready packages picked by lexicographically-smallest import path) matches Go's cross-package initialization contract, and the test/go/package_init_order_test.go integration probe (b,z,a) plus main_module_test.go assertions pin the observable ordering.
  • The RewriteMainPrefix flag removal is complete and consistent — no dangling references remain across flags.go, build.go, abi.go, and llgenf.go — and main_module.go:107 now adds a pkg.Types != nil guard that the base version lacked.
  • In ModeTest the computed packageInits are intentionally not appended; dependency inits still run transitively via the test main's guarded init, so this is not a dropped-init bug.

No bugs, regressions, security, or performance concerns found. The O(n^2) selection loop in packageInitOrder is fine at build-time scale. One minor maintainability note inline.

Comment thread internal/build/init_order.go Outdated
@codecov

codecov Bot commented Aug 1, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 97.72727% with 2 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
internal/build/build.go 50.00% 1 Missing and 1 partial ⚠️

📢 Thoughts on this report? Let us know!

@cpunion
cpunion force-pushed the codex/goroot-package-init-20260801 branch from d822bf8 to fac2e9e Compare August 1, 2026 12:44
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant