diff options
author | Alexander Vershilov <alexander.vershilov@tweag.io> | 2015-01-14 17:58:30 -0600 |
---|---|---|
committer | Austin Seipp <austin@well-typed.com> | 2015-01-16 10:15:45 -0600 |
commit | fffbf0627c2c2ee4bc49f9d26a226b39a066945e (patch) | |
tree | a3f74945126cef5faa1c28f524097a20ac5d4cd5 /rts/Hash.c | |
parent | 6392df07e89304a4daeb1af379c051b03a39cda7 (diff) | |
download | haskell-fffbf0627c2c2ee4bc49f9d26a226b39a066945e.tar.gz |
Trac #9878: Make the static form illegal in interpreted mode.
Summary:
The entries of the static pointers table are expected to exist as
object code. Thus we have ghci complain with an intelligible error
message if the static form is used in interpreted mode.
It also includes a fix to keysHashTable in Hash.c which could cause a
crash. The iteration of the hashtable internals was incorrect. This
patch has the function keysHashTable imitate the iteration in
freeHashTable.
Finally, we submit here some minor edits to comments and
GHC.StaticPtr.StaticPtrInfo field names.
Authored-by: Alexander Vershilov <alexander.vershilov@tweag.
Authored-by: Facundo DomÃnguez <facundo.dominguez@tweag.io>
Test Plan: ./validate
Reviewers: simonpj, hvr, austin
Reviewed By: austin
Subscribers: carter, thomie, qnikst, mboes
Differential Revision: https://phabricator.haskell.org/D586
GHC Trac Issues: #9878
Diffstat (limited to 'rts/Hash.c')
-rw-r--r-- | rts/Hash.c | 24 |
1 files changed, 16 insertions, 8 deletions
diff --git a/rts/Hash.c b/rts/Hash.c index 422c3d9182..aab3b2361b 100644 --- a/rts/Hash.c +++ b/rts/Hash.c @@ -212,19 +212,27 @@ lookupHashTable(HashTable *table, StgWord key) // If the table is modified concurrently, the function behavior is undefined. // int keysHashTable(HashTable *table, StgWord keys[], int szKeys) { - int segment; + int segment, index; int k = 0; - for(segment=0;segment<HDIRSIZE && table->dir[segment];segment+=1) { - int index; - for(index=0;index<HSEGSIZE;index+=1) { - HashList *hl; - for(hl=table->dir[segment][index];hl;hl=hl->next) { - if (k == szKeys) - return k; + HashList *hl; + + + /* The last bucket with something in it is table->max + table->split - 1 */ + segment = (table->max + table->split - 1) / HSEGSIZE; + index = (table->max + table->split - 1) % HSEGSIZE; + + while (segment >= 0 && k < szKeys) { + while (index >= 0 && k < szKeys) { + hl = table->dir[segment][index]; + while (hl && k < szKeys) { keys[k] = hl->key; k += 1; + hl = hl->next; } + index--; } + segment--; + index = HSEGSIZE - 1; } return k; } |