From a3f842a4c1aea97a79f751887555fd8497d0fed0 Mon Sep 17 00:00:00 2001 From: Russ Cox Date: Fri, 28 Jun 2013 13:37:07 -0700 Subject: [PATCH] runtime: shorten hash lookup stack frames On amd64 the frames are very close to the limit for a nosplit (textflag 7) function, in part because the C compiler does not make any attempt to reclaim space allocated for completely registerized variables. Avoid a few short-lived variables to reclaim two words. R=golang-dev, r CC=golang-dev https://golang.org/cl/10758043 --- src/pkg/runtime/hashmap_fast.c | 40 +++++++++++++++------------------- 1 file changed, 18 insertions(+), 22 deletions(-) diff --git a/src/pkg/runtime/hashmap_fast.c b/src/pkg/runtime/hashmap_fast.c index afff7b1aad0..fccd49ccb5d 100644 --- a/src/pkg/runtime/hashmap_fast.c +++ b/src/pkg/runtime/hashmap_fast.c @@ -16,10 +16,8 @@ void HASH_LOOKUP1(MapType *t, Hmap *h, KEYTYPE key, byte *value) { - uintptr hash; - uintptr bucket, oldbucket; + uintptr bucket, i; Bucket *b; - uintptr i; KEYTYPE *k; byte *v; uint8 top; @@ -80,21 +78,21 @@ HASH_LOOKUP1(MapType *t, Hmap *h, KEYTYPE key, byte *value) } } else { dohash: - hash = h->hash0; - HASHFUNC(&hash, sizeof(KEYTYPE), &key); - bucket = hash & (((uintptr)1 << h->B) - 1); + bucket = h->hash0; + HASHFUNC(&bucket, sizeof(KEYTYPE), &key); + top = bucket >> (sizeof(uintptr)*8 - 8); + if(top == 0) + top = 1; + bucket &= (((uintptr)1 << h->B) - 1); if(h->oldbuckets != nil) { - oldbucket = bucket & (((uintptr)1 << (h->B - 1)) - 1); - b = (Bucket*)(h->oldbuckets + oldbucket * h->bucketsize); + i = bucket & (((uintptr)1 << (h->B - 1)) - 1); + b = (Bucket*)(h->oldbuckets + i * h->bucketsize); if(evacuated(b)) { b = (Bucket*)(h->buckets + bucket * h->bucketsize); } } else { b = (Bucket*)(h->buckets + bucket * h->bucketsize); } - top = hash >> (sizeof(uintptr)*8 - 8); - if(top == 0) - top = 1; do { for(i = 0, k = (KEYTYPE*)b->data, v = (byte*)(k + BUCKETSIZE); i < BUCKETSIZE; i++, k++, v += h->valuesize) { if(b->tophash[i] == top && EQFUNC(key, *k)) { @@ -114,10 +112,8 @@ dohash: void HASH_LOOKUP2(MapType *t, Hmap *h, KEYTYPE key, byte *value, bool res) { - uintptr hash; - uintptr bucket, oldbucket; + uintptr bucket, i; Bucket *b; - uintptr i; KEYTYPE *k; byte *v; uint8 top; @@ -184,21 +180,21 @@ HASH_LOOKUP2(MapType *t, Hmap *h, KEYTYPE key, byte *value, bool res) } } else { dohash: - hash = h->hash0; - HASHFUNC(&hash, sizeof(KEYTYPE), &key); - bucket = hash & (((uintptr)1 << h->B) - 1); + bucket = h->hash0; + HASHFUNC(&bucket, sizeof(KEYTYPE), &key); + top = bucket >> (sizeof(uintptr)*8 - 8); + if(top == 0) + top = 1; + bucket &= (((uintptr)1 << h->B) - 1); if(h->oldbuckets != nil) { - oldbucket = bucket & (((uintptr)1 << (h->B - 1)) - 1); - b = (Bucket*)(h->oldbuckets + oldbucket * h->bucketsize); + i = bucket & (((uintptr)1 << (h->B - 1)) - 1); + b = (Bucket*)(h->oldbuckets + i * h->bucketsize); if(evacuated(b)) { b = (Bucket*)(h->buckets + bucket * h->bucketsize); } } else { b = (Bucket*)(h->buckets + bucket * h->bucketsize); } - top = hash >> (sizeof(uintptr)*8 - 8); - if(top == 0) - top = 1; do { for(i = 0, k = (KEYTYPE*)b->data, v = (byte*)(k + BUCKETSIZE); i < BUCKETSIZE; i++, k++, v += h->valuesize) { if(b->tophash[i] == top && EQFUNC(key, *k)) {