Change information
Commit message:
go/ssa: avoid allocations on the MethodValue hit path
MethodValue is called once per (call site, concrete type) pair by RTA
and VTA, and nearly every call finds a Function it already created.
Three things still allocated on that path.
A builder was declared before the critical section and captured by
the closure, so it escaped to the heap on every call. The closure now
returns a builder only when it created a Function; a hit returns nil
and allocates nothing.
waitForSharedFunction allocated a task and a channel before checking
whether the function was already built, and iterate then closed and
waited on them. It now checks first.
The method table was keyed by Id(), which builds a new string for
every unexported method. Key it by (package path, name) instead,
which is the same equivalence without the concatenation. LookupMethod
uses the same key, so its fast path stops allocating too.
TestMethodValueNoAlloc checks with testing.AllocsPerRun that neither
MethodValue nor LookupMethod allocates once the method exists, for an
exported method, an unexported one, and a wrapper.
Updates golang/go#81308
Change-Id: Ib2dbbec10561672166436a882d555ba9a078fe6a
GitHub-Last-Rev: e40b3b08dd2140f864fe105f72b808a0aedc078e
GitHub-Pull-Request: golang/tools#687
Files:
- M go/ssa/builder.go
- M go/ssa/methods.go
- M go/ssa/methods_test.go
Change size: M
Delta: 3 files changed, 132 insertions(+), 37 deletions(-)
Branch: refs/heads/master