Avoid calling Named.resolveUnderlying in the first place (there
is only one caller) if Named.underlying exists already.
In Named.resolveUnderlying remove initial atomic check because
of the check in Named.Underlying. Also, remove a 2nd atomic
check after acquiring the lock as it likely won't help much.
Change-Id: Ife87218fa2549d0903a10218f4dd7a70f85d6c7c
Reviewed-on: https://go-review.googlesource.com/c/go/+/713521
Auto-Submit: Robert Griesemer <gri@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Robert Griesemer <gri@google.com>
Reviewed-by: Mark Freeman <markfreeman@google.com>
}
}
- n.resolveUnderlying()
+ if !n.stateHas(underlying) {
+ n.resolveUnderlying()
+ }
+
return n.underlying
}
func (n *Named) resolveUnderlying() {
assert(n.stateHas(resolved))
- // optimization for likely case
- if n.stateHas(underlying) {
- return
- }
-
var seen map[*Named]int // allocated lazily
var u Type
for rhs := Type(n); u == nil; {
break
}
- // acquire the lock without checking; performance is probably fine
- t.resolve()
- t.mu.Lock()
- defer t.mu.Unlock()
-
- // t.underlying might have been set while we were locking
+ // avoid acquiring the lock if we can
if t.stateHas(underlying) {
u = t.underlying
break
}
seen[t] = len(seen)
+ t.resolve()
+ t.mu.Lock()
+ defer t.mu.Unlock()
assert(t.fromRHS != nil || t.allowNilRHS)
rhs = t.fromRHS
}
}
- n.resolveUnderlying()
+ if !n.stateHas(underlying) {
+ n.resolveUnderlying()
+ }
+
return n.underlying
}
func (n *Named) resolveUnderlying() {
assert(n.stateHas(resolved))
- // optimization for likely case
- if n.stateHas(underlying) {
- return
- }
-
var seen map[*Named]int // allocated lazily
var u Type
for rhs := Type(n); u == nil; {
break
}
- // acquire the lock without checking; performance is probably fine
- t.resolve()
- t.mu.Lock()
- defer t.mu.Unlock()
-
- // t.underlying might have been set while we were locking
+ // avoid acquiring the lock if we can
if t.stateHas(underlying) {
u = t.underlying
break
}
seen[t] = len(seen)
+ t.resolve()
+ t.mu.Lock()
+ defer t.mu.Unlock()
assert(t.fromRHS != nil || t.allowNilRHS)
rhs = t.fromRHS