Commit a3f842a4 authored by Russ Cox's avatar Russ Cox

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
parent 46161cd0
...@@ -16,10 +16,8 @@ ...@@ -16,10 +16,8 @@
void void
HASH_LOOKUP1(MapType *t, Hmap *h, KEYTYPE key, byte *value) HASH_LOOKUP1(MapType *t, Hmap *h, KEYTYPE key, byte *value)
{ {
uintptr hash; uintptr bucket, i;
uintptr bucket, oldbucket;
Bucket *b; Bucket *b;
uintptr i;
KEYTYPE *k; KEYTYPE *k;
byte *v; byte *v;
uint8 top; uint8 top;
...@@ -80,21 +78,21 @@ HASH_LOOKUP1(MapType *t, Hmap *h, KEYTYPE key, byte *value) ...@@ -80,21 +78,21 @@ HASH_LOOKUP1(MapType *t, Hmap *h, KEYTYPE key, byte *value)
} }
} else { } else {
dohash: dohash:
hash = h->hash0; bucket = h->hash0;
HASHFUNC(&hash, sizeof(KEYTYPE), &key); HASHFUNC(&bucket, sizeof(KEYTYPE), &key);
bucket = hash & (((uintptr)1 << h->B) - 1); top = bucket >> (sizeof(uintptr)*8 - 8);
if(top == 0)
top = 1;
bucket &= (((uintptr)1 << h->B) - 1);
if(h->oldbuckets != nil) { if(h->oldbuckets != nil) {
oldbucket = bucket & (((uintptr)1 << (h->B - 1)) - 1); i = bucket & (((uintptr)1 << (h->B - 1)) - 1);
b = (Bucket*)(h->oldbuckets + oldbucket * h->bucketsize); b = (Bucket*)(h->oldbuckets + i * h->bucketsize);
if(evacuated(b)) { if(evacuated(b)) {
b = (Bucket*)(h->buckets + bucket * h->bucketsize); b = (Bucket*)(h->buckets + bucket * h->bucketsize);
} }
} else { } else {
b = (Bucket*)(h->buckets + bucket * h->bucketsize); b = (Bucket*)(h->buckets + bucket * h->bucketsize);
} }
top = hash >> (sizeof(uintptr)*8 - 8);
if(top == 0)
top = 1;
do { do {
for(i = 0, k = (KEYTYPE*)b->data, v = (byte*)(k + BUCKETSIZE); i < BUCKETSIZE; i++, k++, v += h->valuesize) { 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)) { if(b->tophash[i] == top && EQFUNC(key, *k)) {
...@@ -114,10 +112,8 @@ dohash: ...@@ -114,10 +112,8 @@ dohash:
void void
HASH_LOOKUP2(MapType *t, Hmap *h, KEYTYPE key, byte *value, bool res) HASH_LOOKUP2(MapType *t, Hmap *h, KEYTYPE key, byte *value, bool res)
{ {
uintptr hash; uintptr bucket, i;
uintptr bucket, oldbucket;
Bucket *b; Bucket *b;
uintptr i;
KEYTYPE *k; KEYTYPE *k;
byte *v; byte *v;
uint8 top; uint8 top;
...@@ -184,21 +180,21 @@ HASH_LOOKUP2(MapType *t, Hmap *h, KEYTYPE key, byte *value, bool res) ...@@ -184,21 +180,21 @@ HASH_LOOKUP2(MapType *t, Hmap *h, KEYTYPE key, byte *value, bool res)
} }
} else { } else {
dohash: dohash:
hash = h->hash0; bucket = h->hash0;
HASHFUNC(&hash, sizeof(KEYTYPE), &key); HASHFUNC(&bucket, sizeof(KEYTYPE), &key);
bucket = hash & (((uintptr)1 << h->B) - 1); top = bucket >> (sizeof(uintptr)*8 - 8);
if(top == 0)
top = 1;
bucket &= (((uintptr)1 << h->B) - 1);
if(h->oldbuckets != nil) { if(h->oldbuckets != nil) {
oldbucket = bucket & (((uintptr)1 << (h->B - 1)) - 1); i = bucket & (((uintptr)1 << (h->B - 1)) - 1);
b = (Bucket*)(h->oldbuckets + oldbucket * h->bucketsize); b = (Bucket*)(h->oldbuckets + i * h->bucketsize);
if(evacuated(b)) { if(evacuated(b)) {
b = (Bucket*)(h->buckets + bucket * h->bucketsize); b = (Bucket*)(h->buckets + bucket * h->bucketsize);
} }
} else { } else {
b = (Bucket*)(h->buckets + bucket * h->bucketsize); b = (Bucket*)(h->buckets + bucket * h->bucketsize);
} }
top = hash >> (sizeof(uintptr)*8 - 8);
if(top == 0)
top = 1;
do { do {
for(i = 0, k = (KEYTYPE*)b->data, v = (byte*)(k + BUCKETSIZE); i < BUCKETSIZE; i++, k++, v += h->valuesize) { 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)) { if(b->tophash[i] == top && EQFUNC(key, *k)) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment