mirror of
https://github.com/golang/go.git
synced 2026-02-04 18:05:03 +03:00
go/types, types2: simplify locking in Named.resolveUnderlying
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>
This commit is contained in:
committed by
Gopher Robot
parent
5a42af7f6c
commit
d09a8c8ef4
@@ -562,7 +562,10 @@ func (n *Named) Underlying() Type {
|
||||
}
|
||||
}
|
||||
|
||||
n.resolveUnderlying()
|
||||
if !n.stateHas(underlying) {
|
||||
n.resolveUnderlying()
|
||||
}
|
||||
|
||||
return n.underlying
|
||||
}
|
||||
|
||||
@@ -588,11 +591,6 @@ func (t *Named) String() string { return TypeString(t, nil) }
|
||||
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; {
|
||||
@@ -618,12 +616,7 @@ func (n *Named) resolveUnderlying() {
|
||||
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
|
||||
@@ -634,6 +627,9 @@ func (n *Named) resolveUnderlying() {
|
||||
}
|
||||
seen[t] = len(seen)
|
||||
|
||||
t.resolve()
|
||||
t.mu.Lock()
|
||||
defer t.mu.Unlock()
|
||||
assert(t.fromRHS != nil || t.allowNilRHS)
|
||||
rhs = t.fromRHS
|
||||
|
||||
|
||||
@@ -565,7 +565,10 @@ func (n *Named) Underlying() Type {
|
||||
}
|
||||
}
|
||||
|
||||
n.resolveUnderlying()
|
||||
if !n.stateHas(underlying) {
|
||||
n.resolveUnderlying()
|
||||
}
|
||||
|
||||
return n.underlying
|
||||
}
|
||||
|
||||
@@ -591,11 +594,6 @@ func (t *Named) String() string { return TypeString(t, nil) }
|
||||
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; {
|
||||
@@ -621,12 +619,7 @@ func (n *Named) resolveUnderlying() {
|
||||
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
|
||||
@@ -637,6 +630,9 @@ func (n *Named) resolveUnderlying() {
|
||||
}
|
||||
seen[t] = len(seen)
|
||||
|
||||
t.resolve()
|
||||
t.mu.Lock()
|
||||
defer t.mu.Unlock()
|
||||
assert(t.fromRHS != nil || t.allowNilRHS)
|
||||
rhs = t.fromRHS
|
||||
|
||||
|
||||
Reference in New Issue
Block a user