diff options
| author | Josh Bleecher Snyder <josharian@gmail.com> | 2017-08-11 08:43:30 -0700 |
|---|---|---|
| committer | Josh Bleecher Snyder <josharian@gmail.com> | 2017-08-14 23:32:56 +0000 |
| commit | 589fc314af46e0d65a91fa1048ba319f1bf390a6 (patch) | |
| tree | 4f3b843898a930cd623034e1b72ce74d2d9e5912 /src/runtime/hashmap.go | |
| parent | 29e9b89b9ada73fa7775b351c100709c330c0a46 (diff) | |
| download | go-589fc314af46e0d65a91fa1048ba319f1bf390a6.tar.xz | |
runtime: calculate k only once in mapiternext
Make the calculation of k and v a bit lazier.
None of the following code cares about indirect-vs-direct k,
and it happens on all code paths, so check t.indirectkey earlier.
Simplifies the code and reduces both machine code and stack size.
Change-Id: I5ea4c0772848d7a4b15383baedb9a1f7feb47201
Reviewed-on: https://go-review.googlesource.com/55092
Run-TryBot: Josh Bleecher Snyder <josharian@gmail.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Keith Randall <khr@golang.org>
Diffstat (limited to 'src/runtime/hashmap.go')
| -rw-r--r-- | src/runtime/hashmap.go | 28 |
1 files changed, 10 insertions, 18 deletions
diff --git a/src/runtime/hashmap.go b/src/runtime/hashmap.go index 64ec84474e..f384964522 100644 --- a/src/runtime/hashmap.go +++ b/src/runtime/hashmap.go @@ -820,11 +820,14 @@ next: } for ; i < bucketCnt; i++ { offi := (i + it.offset) & (bucketCnt - 1) - k := add(unsafe.Pointer(b), dataOffset+uintptr(offi)*uintptr(t.keysize)) - v := add(unsafe.Pointer(b), dataOffset+bucketCnt*uintptr(t.keysize)+uintptr(offi)*uintptr(t.valuesize)) if b.tophash[offi] == empty || b.tophash[offi] == evacuatedEmpty { continue } + k := add(unsafe.Pointer(b), dataOffset+uintptr(offi)*uintptr(t.keysize)) + if t.indirectkey { + k = *((*unsafe.Pointer)(k)) + } + v := add(unsafe.Pointer(b), dataOffset+bucketCnt*uintptr(t.keysize)+uintptr(offi)*uintptr(t.valuesize)) if checkBucket != noCheck && !h.sameSizeGrow() { // Special case: iterator was started during a grow to a larger size // and the grow is not done yet. We're working on a bucket whose @@ -833,14 +836,10 @@ next: // through the oldbucket, skipping any keys that will go // to the other new bucket (each oldbucket expands to two // buckets during a grow). - k2 := k - if t.indirectkey { - k2 = *((*unsafe.Pointer)(k2)) - } - if t.reflexivekey || alg.equal(k2, k2) { + if t.reflexivekey || alg.equal(k, k) { // If the item in the oldbucket is not destined for // the current new bucket in the iteration, skip it. - hash := alg.hash(k2, uintptr(h.hash0)) + hash := alg.hash(k, uintptr(h.hash0)) if hash&(uintptr(1)<<it.B-1) != checkBucket { continue } @@ -859,9 +858,6 @@ next: } if b.tophash[offi] != evacuatedX && b.tophash[offi] != evacuatedY { // this is the golden data, we can return it. - if t.indirectkey { - k = *((*unsafe.Pointer)(k)) - } it.key = k if t.indirectvalue { v = *((*unsafe.Pointer)(v)) @@ -870,17 +866,13 @@ next: } else { // The hash table has grown since the iterator was started. // The golden data for this key is now somewhere else. - k2 := k - if t.indirectkey { - k2 = *((*unsafe.Pointer)(k2)) - } - if t.reflexivekey || alg.equal(k2, k2) { + if t.reflexivekey || alg.equal(k, k) { // Check the current hash table for the data. // This code handles the case where the key // has been deleted, updated, or deleted and reinserted. // NOTE: we need to regrab the key as it has potentially been // updated to an equal() but not identical key (e.g. +0.0 vs -0.0). - rk, rv := mapaccessK(t, h, k2) + rk, rv := mapaccessK(t, h, k) if rk == nil { continue // key has been deleted } @@ -891,7 +883,7 @@ next: // updated, so we can just return it. That's lucky for // us because when key!=key we can't look it up // successfully in the current table. - it.key = k2 + it.key = k if t.indirectvalue { v = *((*unsafe.Pointer)(v)) } |
