Skip to content

proposal: scope compile-level memoization to the compilation instead of package globals #2049

Description

@cpunion

Background

#2048 releases per-compile memory in in-process drivers. Part of that fix clears the runtime-caller tracking memoization when build.Do returns:

func ClearRuntimeCallerCaches() {
	runtimeCallerBaseCache.Clear()
	runtimeCallerExtendedCache.Clear()
}

runtimeCallerBaseCache / runtimeCallerExtendedCache (cl/instr.go) are package-level sync.Maps keyed by *ssa.Package. Without the clear they pin every compiled package's go/types + go/ssa graphs for the life of the process (the dominant part of the cl.test 140MB→2GB climb); with it they are released per compile.

Problem

The clear is correct today because build.Do runs one compile at a time per process. If Do is ever invoked concurrently in one process (parallel test harness, a daemonized build server, a future -p-style in-process parallelism), one compile's deferred clear would drop another in-flight compile's memoization. That is still correctness-safe (the sets are recomputed on demand) but it degenerates the memoization to per-query recomputation, and the globals would again retain whatever the concurrent compiles insert until the last one finishes.

This concurrency hazard is pre-existing: package-level caches keyed by *ssa.Package were already shared mutable state across any concurrent compiles; #2048 only adds the (equally global) clear.

Proposal

Move the memoization from package globals into a compile-scoped owner so no clear is needed and concurrent compiles are isolated:

  • attach the two maps to the cl compile context (or to llssa.Program, which is already one-per-Do and now has a Dispose lifecycle), and
  • delete ClearRuntimeCallerCaches once nothing global remains.

The memoization's access pattern is per-ssa.Package within one program, so a per-Program map preserves all current hits.

Related: #2004 (follow-ups), #2048.

🤖 Generated with Claude Code

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions