summaryrefslogtreecommitdiff
path: root/rts/Hash.c
diff options
context:
space:
mode:
authorAlexander Vershilov <alexander.vershilov@tweag.io>2015-01-14 17:58:30 -0600
committerAustin Seipp <austin@well-typed.com>2015-01-16 10:15:45 -0600
commitfffbf0627c2c2ee4bc49f9d26a226b39a066945e (patch)
treea3f74945126cef5faa1c28f524097a20ac5d4cd5 /rts/Hash.c
parent6392df07e89304a4daeb1af379c051b03a39cda7 (diff)
downloadhaskell-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.c24
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;
}