summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCrazycolorz5 <Crazycolorz5@gmail.com>2019-01-20 19:26:58 -0500
committerMarge Bot <ben+marge-bot@smart-cactus.org>2019-12-11 14:12:17 -0500
commitf80c4a66ae219afa7bd4172441f4e94ba649c9d9 (patch)
tree34c3aa2cc484ade9b2460ca18941763fcb101fcc
parent6e47a76a3d0a7b3d424442914478de579a49363c (diff)
downloadhaskell-f80c4a66ae219afa7bd4172441f4e94ba649c9d9.tar.gz
rts: Specialize hashing at call site rather than in struct.
Separate word and string hash tables on the type level, and do not store the hashing function. Thus when a different hash function is desire it is provided upon accessing the table. This is worst case the same as before the change, and in the majority of cases is better. Also mark the functions for aggressive inlining to improve performance. {F1686506} Reviewers: bgamari, erikd, simonmar Subscribers: rwbarton, thomie, carter GHC Trac Issues: #13165 Differential Revision: https://phabricator.haskell.org/D4889
-rw-r--r--includes/HsFFI.h2
-rw-r--r--libraries/base/GHC/StaticPtr.hs6
-rw-r--r--rts/FileLock.c12
-rw-r--r--rts/Hash.c124
-rw-r--r--rts/Hash.h46
-rw-r--r--rts/Hpc.c12
-rw-r--r--rts/Linker.c12
-rw-r--r--rts/LinkerInternals.h8
-rw-r--r--rts/RtsSymbolInfo.c6
-rw-r--r--rts/StaticPtrTable.c17
10 files changed, 157 insertions, 88 deletions
diff --git a/includes/HsFFI.h b/includes/HsFFI.h
index 32523b2c83..d021e6fb42 100644
--- a/includes/HsFFI.h
+++ b/includes/HsFFI.h
@@ -126,7 +126,7 @@ extern void hs_free_stable_ptr_unsafe (HsStablePtr sp);
extern void hs_free_stable_ptr (HsStablePtr sp);
extern void hs_free_fun_ptr (HsFunPtr fp);
-extern StgPtr hs_spt_lookup(StgWord64 key1, StgWord64 key2);
+extern StgPtr hs_spt_lookup(StgWord64 key[2]);
extern int hs_spt_keys(StgPtr keys[], int szKeys);
extern int hs_spt_key_count (void);
diff --git a/libraries/base/GHC/StaticPtr.hs b/libraries/base/GHC/StaticPtr.hs
index ee5ba786f6..b8d5c116d1 100644
--- a/libraries/base/GHC/StaticPtr.hs
+++ b/libraries/base/GHC/StaticPtr.hs
@@ -48,7 +48,7 @@ module GHC.StaticPtr
) where
import Foreign.C.Types (CInt(..))
-import Foreign.Marshal (allocaArray, peekArray)
+import Foreign.Marshal (allocaArray, peekArray, withArray)
import GHC.Ptr (Ptr(..), nullPtr)
import GHC.Fingerprint (Fingerprint(..))
import GHC.Prim
@@ -87,13 +87,13 @@ staticKey (StaticPtr w0 w1 _ _) = Fingerprint (W64# w0) (W64# w1)
--
unsafeLookupStaticPtr :: StaticKey -> IO (Maybe (StaticPtr a))
unsafeLookupStaticPtr (Fingerprint w1 w2) = do
- ptr@(Ptr addr) <- hs_spt_lookup w1 w2
+ ptr@(Ptr addr) <- withArray [w1, w2] hs_spt_lookup
if (ptr == nullPtr)
then return Nothing
else case addrToAny# addr of
(# spe #) -> return (Just spe)
-foreign import ccall unsafe hs_spt_lookup :: Word64 -> Word64 -> IO (Ptr a)
+foreign import ccall unsafe hs_spt_lookup :: Ptr Word64 -> IO (Ptr a)
-- | A class for things buildable from static pointers.
class IsStatic p where
diff --git a/rts/FileLock.c b/rts/FileLock.c
index ac21bea206..351d2a58f7 100644
--- a/rts/FileLock.c
+++ b/rts/FileLock.c
@@ -34,14 +34,14 @@ static HashTable *fd_hash;
static Mutex file_lock_mutex;
#endif
-static int cmpLocks(StgWord w1, StgWord w2)
+STATIC_INLINE int cmpLocks(StgWord w1, StgWord w2)
{
Lock *l1 = (Lock *)w1;
Lock *l2 = (Lock *)w2;
return (l1->device == l2->device && l1->inode == l2->inode);
}
-static int hashLock(const HashTable *table, StgWord w)
+STATIC_INLINE int hashLock(const HashTable *table, StgWord w)
{
Lock *l = (Lock *)w;
StgWord key = l->inode ^ (l->inode >> 32) ^ l->device ^ (l->device >> 32);
@@ -52,7 +52,7 @@ static int hashLock(const HashTable *table, StgWord w)
void
initFileLocking(void)
{
- obj_hash = allocHashTable_(hashLock, cmpLocks);
+ obj_hash = allocHashTable();
fd_hash = allocHashTable(); /* ordinary word-based table */
#if defined(THREADED_RTS)
initMutex(&file_lock_mutex);
@@ -85,7 +85,7 @@ lockFile(int fd, StgWord64 dev, StgWord64 ino, int for_writing)
key.device = dev;
key.inode = ino;
- lock = lookupHashTable(obj_hash, (StgWord)&key);
+ lock = lookupHashTable_(obj_hash, (StgWord)&key, hashLock, cmpLocks);
if (lock == NULL)
{
@@ -93,7 +93,7 @@ lockFile(int fd, StgWord64 dev, StgWord64 ino, int for_writing)
lock->device = dev;
lock->inode = ino;
lock->readers = for_writing ? -1 : 1;
- insertHashTable(obj_hash, (StgWord)lock, (void *)lock);
+ insertHashTable_(obj_hash, (StgWord)lock, (void *)lock, hashLock);
insertHashTable(fd_hash, fd, lock);
RELEASE_LOCK(&file_lock_mutex);
return 0;
@@ -135,7 +135,7 @@ unlockFile(int fd)
}
if (lock->readers == 0) {
- removeHashTable(obj_hash, (StgWord)lock, NULL);
+ removeHashTable_(obj_hash, (StgWord)lock, NULL, hashLock, cmpLocks);
stgFree(lock);
}
removeHashTable(fd_hash, fd, NULL);
diff --git a/rts/Hash.c b/rts/Hash.c
index 2f611c9079..4e11228961 100644
--- a/rts/Hash.c
+++ b/rts/Hash.c
@@ -49,22 +49,25 @@ struct hashtable {
HashList **dir[HDIRSIZE]; /* Directory of segments */
HashList *freeList; /* free list of HashLists */
HashListChunk *chunks;
- HashFunction *hash; /* hash function */
- CompareFunction *compare; /* key comparison function */
};
+/* Create an identical structure, but is distinct on a type level,
+ * for string hash table. Since it's a direct embedding of
+ * a hashtable and not a reference, there shouldn't be
+ * any overhead post-compilation. */
+struct strhashtable { struct hashtable table; };
+
/* -----------------------------------------------------------------------------
* Hash first using the smaller table. If the bucket is less than the
* next bucket to be split, re-hash using the larger table.
* -------------------------------------------------------------------------- */
-
int
hashWord(const HashTable *table, StgWord key)
{
int bucket;
/* Strip the boring zero bits */
- key /= sizeof(StgWord);
+ key >>= sizeof(StgWord);
/* Mod the size of the hash table (a power of 2) */
bucket = key & table->mask1;
@@ -97,13 +100,13 @@ hashStr(const HashTable *table, StgWord w)
return bucket;
}
-static int
+STATIC_INLINE int
compareWord(StgWord key1, StgWord key2)
{
return (key1 == key2);
}
-static int
+STATIC_INLINE int
compareStr(StgWord key1, StgWord key2)
{
return (strcmp((char *)key1, (char *)key2) == 0);
@@ -114,7 +117,7 @@ compareStr(StgWord key1, StgWord key2)
* Allocate a new segment of the dynamically growing hash table.
* -------------------------------------------------------------------------- */
-static void
+STATIC_INLINE void
allocSegment(HashTable *table, int segment)
{
table->dir[segment] = stgMallocBytes(HSEGSIZE * sizeof(HashList *),
@@ -128,8 +131,8 @@ allocSegment(HashTable *table, int segment)
* by @table->split@ is affected by the expansion.
* -------------------------------------------------------------------------- */
-static void
-expand(HashTable *table)
+STATIC_INLINE void
+expand(HashTable *table, HashFunction f)
{
int oldsegment;
int oldindex;
@@ -170,7 +173,7 @@ expand(HashTable *table)
old = new = NULL;
for (hl = table->dir[oldsegment][oldindex]; hl != NULL; hl = next) {
next = hl->next;
- if (table->hash(table, hl->key) == newbucket) {
+ if (f(table, hl->key) == newbucket) {
hl->next = new;
new = hl;
} else {
@@ -184,19 +187,20 @@ expand(HashTable *table)
return;
}
-void *
-lookupHashTable(const HashTable *table, StgWord key)
+STATIC_INLINE void*
+lookupHashTable_inlined(const HashTable *table, StgWord key,
+ HashFunction f, CompareFunction cmp)
{
int bucket;
int segment;
int index;
+
HashList *hl;
- bucket = table->hash(table, key);
+ bucket = f(table, key);
segment = bucket / HSEGSIZE;
index = bucket % HSEGSIZE;
- CompareFunction *cmp = table->compare;
for (hl = table->dir[segment][index]; hl != NULL; hl = hl->next) {
if (cmp(hl->key, key))
return (void *) hl->data;
@@ -206,6 +210,26 @@ lookupHashTable(const HashTable *table, StgWord key)
return NULL;
}
+void *
+lookupHashTable_(const HashTable *table, StgWord key,
+ HashFunction f, CompareFunction cmp)
+{
+ return lookupHashTable_inlined(table, key, f, cmp);
+}
+
+void *
+lookupHashTable(const HashTable *table, StgWord key)
+{
+ return lookupHashTable_inlined(table, key, hashWord, compareWord);
+}
+
+void *
+lookupStrHashTable(const StrHashTable* table, const char* key)
+{
+ return lookupHashTable_inlined(&table->table, (StgWord) key,
+ hashStr, compareStr);
+}
+
// Puts up to szKeys keys of the hash table into the given array. Returns the
// actual amount of keys that have been retrieved.
//
@@ -273,8 +297,9 @@ freeHashList (HashTable *table, HashList *hl)
table->freeList = hl;
}
-void
-insertHashTable(HashTable *table, StgWord key, const void *data)
+STATIC_INLINE void
+insertHashTable_inlined(HashTable *table, StgWord key,
+ const void *data, HashFunction f)
{
int bucket;
int segment;
@@ -287,9 +312,9 @@ insertHashTable(HashTable *table, StgWord key, const void *data)
/* When the average load gets too high, we expand the table */
if (++table->kcount >= HLOAD * table->bcount)
- expand(table);
+ expand(table, f);
- bucket = table->hash(table, key);
+ bucket = f(table, key);
segment = bucket / HSEGSIZE;
index = bucket % HSEGSIZE;
@@ -299,11 +324,30 @@ insertHashTable(HashTable *table, StgWord key, const void *data)
hl->data = data;
hl->next = table->dir[segment][index];
table->dir[segment][index] = hl;
+}
+void
+insertHashTable_(HashTable *table, StgWord key,
+ const void *data, HashFunction f)
+{
+ return insertHashTable_inlined(table, key, data, f);
}
-void *
-removeHashTable(HashTable *table, StgWord key, const void *data)
+void
+insertHashTable(HashTable *table, StgWord key, const void *data)
+{
+ insertHashTable_inlined(table, key, data, hashWord);
+}
+
+void
+insertStrHashTable(StrHashTable *table, const char * key, const void *data)
+{
+ insertHashTable_inlined(&table->table, (StgWord) key, data, hashStr);
+}
+
+STATIC_INLINE void*
+removeHashTable_inlined(HashTable *table, StgWord key, const void *data,
+ HashFunction f, CompareFunction cmp)
{
int bucket;
int segment;
@@ -311,12 +355,12 @@ removeHashTable(HashTable *table, StgWord key, const void *data)
HashList *hl;
HashList *prev = NULL;
- bucket = table->hash(table, key);
+ bucket = f(table, key);
segment = bucket / HSEGSIZE;
index = bucket % HSEGSIZE;
for (hl = table->dir[segment][index]; hl != NULL; hl = hl->next) {
- if (table->compare(hl->key,key) && (data == NULL || hl->data == data)) {
+ if (cmp(hl->key, key) && (data == NULL || hl->data == data)) {
if (prev == NULL)
table->dir[segment][index] = hl->next;
else
@@ -333,6 +377,26 @@ removeHashTable(HashTable *table, StgWord key, const void *data)
return NULL;
}
+void*
+removeHashTable_(HashTable *table, StgWord key, const void *data,
+ HashFunction f, CompareFunction cmp)
+{
+ return removeHashTable_inlined(table, key, data, f, cmp);
+}
+
+void *
+removeHashTable(HashTable *table, StgWord key, const void *data)
+{
+ return removeHashTable_inlined(table, key, data, hashWord, compareWord);
+}
+
+void *
+removeStrHashTable(StrHashTable *table, const char * key, const void *data)
+{
+ return removeHashTable_inlined(&table->table, (StgWord) key,
+ data, hashStr, compareStr);
+}
+
/* -----------------------------------------------------------------------------
* When we free a hash table, we are also good enough to free the
* data part of each (key, data) pair, as long as our caller can tell
@@ -406,7 +470,7 @@ mapHashTable(HashTable *table, void *data, MapHashFn fn)
* -------------------------------------------------------------------------- */
HashTable *
-allocHashTable_(HashFunction *hash, CompareFunction *compare)
+allocHashTable(void)
{
HashTable *table;
HashList **hb;
@@ -426,24 +490,10 @@ allocHashTable_(HashFunction *hash, CompareFunction *compare)
table->bcount = HSEGSIZE;
table->freeList = NULL;
table->chunks = NULL;
- table->hash = hash;
- table->compare = compare;
return table;
}
-HashTable *
-allocHashTable(void)
-{
- return allocHashTable_(hashWord, compareWord);
-}
-
-HashTable *
-allocStrHashTable(void)
-{
- return allocHashTable_(hashStr, compareStr);
-}
-
void
exitHashTable(void)
{
diff --git a/rts/Hash.h b/rts/Hash.h
index be388fb62f..59e2e22a09 100644
--- a/rts/Hash.h
+++ b/rts/Hash.h
@@ -11,6 +11,7 @@
#include "BeginPrivate.h"
typedef struct hashtable HashTable; /* abstract */
+typedef struct strhashtable StrHashTable;
/* Hash table access where the keys are StgWords.
* Values are passed into the hash table and stored as `const void *` values,
@@ -40,27 +41,44 @@ void mapHashTable(HashTable *table, void *data, MapHashFn fn);
* assumed to be allocated by the caller, and mustn't be deallocated
* until the corresponding hash table entry has been removed).
*/
-HashTable * allocStrHashTable ( void );
-
-#define lookupStrHashTable(table, key) \
- (lookupHashTable(table, (StgWord)key))
-
-#define insertStrHashTable(table, key, data) \
- (insertHashTable(table, (StgWord)key, data))
-
-#define removeStrHashTable(table, key, data) \
- (removeHashTable(table, (StgWord)key, data))
-
-/* Hash tables for arbitrary keys */
+INLINE_HEADER StrHashTable * allocStrHashTable ( void )
+{
+ return (StrHashTable*) allocHashTable();
+}
+
+void insertStrHashTable ( StrHashTable *table, const char * key,
+ const void *data );
+void * lookupStrHashTable ( const StrHashTable *table, const char * key);
+void * removeStrHashTable ( StrHashTable *table, const char * key,
+ const void *data );
+
+/*
+ * Hash tables for arbitrary key types.
+ * Generally, these functions allow for the specification of the
+ * HashFunction and CompareFunction. It's recommended that those
+ * are inlinable so there's a chance the compiler can discard
+ * some parameter-passing, as well as function calls, though note
+ * it's not guaranteed. Either way, the functions are parameters
+ * as the types should be statically known and thus
+ * storing them is unnecessary.
+ */
typedef int HashFunction(const HashTable *table, StgWord key);
typedef int CompareFunction(StgWord key1, StgWord key2);
-HashTable * allocHashTable_(HashFunction *hash, CompareFunction *compare);
int hashWord(const HashTable *table, StgWord key);
-int hashStr(const HashTable *table, StgWord key);
+int hashStr(const HashTable *table, StgWord w);
+void insertHashTable_ ( HashTable *table, StgWord key,
+ const void *data, HashFunction f );
+void * lookupHashTable_ ( const HashTable *table, StgWord key,
+ HashFunction f, CompareFunction cmp );
+void * removeHashTable_ ( HashTable *table, StgWord key,
+ const void *data, HashFunction f,
+ CompareFunction cmp );
/* Freeing hash tables
*/
void freeHashTable ( HashTable *table, void (*freeDataFun)(void *) );
+#define freeStrHashTable(table, f) \
+ (freeHashTable((HashTable*) table, f))
void exitHashTable ( void );
diff --git a/rts/Hpc.c b/rts/Hpc.c
index 52a833307f..37df56b6af 100644
--- a/rts/Hpc.c
+++ b/rts/Hpc.c
@@ -39,7 +39,7 @@ static pid_t hpc_pid = 0; // pid of this process at hpc-boot time.
static FILE *tixFile; // file being read/written
static int tix_ch; // current char
-static HashTable * moduleHash = NULL; // module name -> HpcModuleInfo
+static StrHashTable * moduleHash = NULL; // module name -> HpcModuleInfo
HpcModuleInfo *modules = 0;
@@ -152,11 +152,11 @@ readTix(void) {
expect(']');
ws();
- lookup = lookupHashTable(moduleHash, (StgWord)tmpModule->modName);
+ lookup = lookupStrHashTable(moduleHash, tmpModule->modName);
if (lookup == NULL) {
debugTrace(DEBUG_hpc,"readTix: new HpcModuleInfo for %s",
tmpModule->modName);
- insertHashTable(moduleHash, (StgWord)tmpModule->modName, tmpModule);
+ insertStrHashTable(moduleHash, tmpModule->modName, tmpModule);
} else {
ASSERT(lookup->tixArr != 0);
ASSERT(!strcmp(tmpModule->modName, lookup->modName));
@@ -265,7 +265,7 @@ hs_hpc_module(char *modName,
moduleHash = allocStrHashTable();
}
- tmpModule = lookupHashTable(moduleHash, (StgWord)modName);
+ tmpModule = lookupStrHashTable(moduleHash, modName);
if (tmpModule == NULL)
{
// Did not find entry so add one on.
@@ -282,7 +282,7 @@ hs_hpc_module(char *modName,
tmpModule->next = modules;
tmpModule->from_file = false;
modules = tmpModule;
- insertHashTable(moduleHash, (StgWord)modName, tmpModule);
+ insertStrHashTable(moduleHash, modName, tmpModule);
}
else
{
@@ -392,7 +392,7 @@ exitHpc(void) {
writeTix(f);
}
- freeHashTable(moduleHash, (void (*)(void *))freeHpcModuleInfo);
+ freeStrHashTable(moduleHash, (void (*)(void *))freeHpcModuleInfo);
moduleHash = NULL;
stgFree(tixFilename);
diff --git a/rts/Linker.c b/rts/Linker.c
index 7bd2e67278..3539f90584 100644
--- a/rts/Linker.c
+++ b/rts/Linker.c
@@ -158,7 +158,7 @@
2) The number of duplicate symbols, since now only symbols that are
true duplicates will display the error.
*/
-/*Str*/HashTable *symhash;
+StrHashTable *symhash;
/* List of currently loaded objects */
ObjectCode *objects = NULL; /* initially empty */
@@ -227,7 +227,7 @@ int ocTryLoad( ObjectCode* oc );
static void *mmap_32bit_base = (void *)MMAP_32BIT_BASE_DEFAULT;
-static void ghciRemoveSymbolTable(HashTable *table, const SymbolName* key,
+static void ghciRemoveSymbolTable(StrHashTable *table, const SymbolName* key,
ObjectCode *owner)
{
RtsSymbolInfo *pinfo = lookupStrHashTable(table, key);
@@ -262,7 +262,7 @@ static void ghciRemoveSymbolTable(HashTable *table, const SymbolName* key,
*/
int ghciInsertSymbolTable(
pathchar* obj_name,
- HashTable *table,
+ StrHashTable *table,
const SymbolName* key,
SymbolAddr* data,
HsBool weak,
@@ -373,7 +373,7 @@ int ghciInsertSymbolTable(
* Returns: 0 on failure and result is not set,
* nonzero on success and result set to nonzero pointer
*/
-HsBool ghciLookupSymbolInfo(HashTable *table,
+HsBool ghciLookupSymbolInfo(StrHashTable *table,
const SymbolName* key, RtsSymbolInfo **result)
{
RtsSymbolInfo *pinfo = lookupStrHashTable(table, key);
@@ -524,7 +524,7 @@ exitLinker( void ) {
}
#endif
if (linker_init_done == 1) {
- freeHashTable(symhash, free);
+ freeStrHashTable(symhash, free);
}
#if defined(THREADED_RTS)
closeMutex(&linker_mutex);
@@ -1200,7 +1200,7 @@ void freeObjectCode (ObjectCode *oc)
}
if (oc->extraInfos != NULL) {
- freeHashTable(oc->extraInfos, NULL);
+ freeStrHashTable(oc->extraInfos, NULL);
oc->extraInfos = NULL;
}
diff --git a/rts/LinkerInternals.h b/rts/LinkerInternals.h
index 0f47b82761..8a8df50098 100644
--- a/rts/LinkerInternals.h
+++ b/rts/LinkerInternals.h
@@ -243,7 +243,7 @@ typedef struct _ObjectCode {
/* Holds the list of symbols in the .o file which
require extra information.*/
- HashTable *extraInfos;
+ StrHashTable *extraInfos;
#if RTS_LINKER_USE_MMAP == 1
/* The m32 allocators used for allocating small sections and symbol extras
@@ -304,12 +304,12 @@ void addSection (Section *s, SectionKind kind, SectionAlloc alloc,
void* start, StgWord size, StgWord mapped_offset,
void* mapped_start, StgWord mapped_size);
-HsBool ghciLookupSymbolInfo(HashTable *table,
+HsBool ghciLookupSymbolInfo(StrHashTable *table,
const SymbolName* key, RtsSymbolInfo **result);
int ghciInsertSymbolTable(
pathchar* obj_name,
- HashTable *table,
+ StrHashTable *table,
const SymbolName* key,
SymbolAddr* data,
HsBool weak,
@@ -318,7 +318,7 @@ int ghciInsertSymbolTable(
/* lock-free version of lookupSymbol */
SymbolAddr* lookupSymbol_ (SymbolName* lbl);
-extern /*Str*/HashTable *symhash;
+extern StrHashTable *symhash;
pathchar*
resolveSymbolAddr (pathchar* buffer, int size,
diff --git a/rts/RtsSymbolInfo.c b/rts/RtsSymbolInfo.c
index 0553308f36..1110d582d6 100644
--- a/rts/RtsSymbolInfo.c
+++ b/rts/RtsSymbolInfo.c
@@ -93,7 +93,7 @@ static void unmarkImport(SymbolInfo* info)
/* -----------------------------------------------------------------------------
* Marks the symbol at the given address as weak or not.
* If the extra symbol infos table has not been initialized
-* yet this will create and allocate a new Hashtable
+* yet this will create and allocate a new StrHashtable
*/
void setWeakSymbol(ObjectCode *owner, const void *label)
{
@@ -103,7 +103,7 @@ void setWeakSymbol(ObjectCode *owner, const void *label)
/* -----------------------------------------------------------------------------
* Marks the symbol at the given address as import or not.
* If the extra symbol infos table has not been initialized
-* yet this will create and allocate a new Hashtable
+* yet this will create and allocate a new StrHashtable
*/
void setImportSymbol(ObjectCode *owner, const void *label)
{
@@ -113,7 +113,7 @@ void setImportSymbol(ObjectCode *owner, const void *label)
/* -----------------------------------------------------------------------------
* Clear the import symbol flag.
* If the extra symbol infos table has not been initialized
-* yet this will create and allocate a new Hashtable
+* yet this will create and allocate a new StrHashtable
*/
void clearImportSymbol(ObjectCode *owner, const void *label)
{
diff --git a/rts/StaticPtrTable.c b/rts/StaticPtrTable.c
index f5e6239ad0..9754cfad41 100644
--- a/rts/StaticPtrTable.c
+++ b/rts/StaticPtrTable.c
@@ -21,14 +21,14 @@ static Mutex spt_lock;
#endif
/// Hash function for the SPT.
-static int hashFingerprint(const HashTable *table, StgWord key) {
+STATIC_INLINE int hashFingerprint(const HashTable *table, StgWord key) {
const StgWord64* ptr = (StgWord64*) key;
// Take half of the key to compute the hash.
return hashWord(table, *(ptr + 1));
}
/// Comparison function for the SPT.
-static int compareFingerprint(StgWord a, StgWord b) {
+STATIC_INLINE int compareFingerprint(StgWord a, StgWord b) {
const StgWord64* ptra = (StgWord64*) a;
const StgWord64* ptrb = (StgWord64*) b;
return *ptra == *ptrb && *(ptra + 1) == *(ptrb + 1);
@@ -38,14 +38,14 @@ void hs_spt_insert_stableptr(StgWord64 key[2], StgStablePtr *entry) {
// hs_spt_insert is called from constructor functions, so
// the SPT needs to be initialized here.
if (spt == NULL) {
- spt = allocHashTable_(hashFingerprint, compareFingerprint);
+ spt = allocHashTable();
#if defined(THREADED_RTS)
initMutex(&spt_lock);
#endif
}
ACQUIRE_LOCK(&spt_lock);
- insertHashTable(spt, (StgWord)key, entry);
+ insertHashTable_(spt, (StgWord)key, entry, hashFingerprint);
RELEASE_LOCK(&spt_lock);
}
@@ -68,7 +68,8 @@ static void freeSptEntry(void* entry) {
void hs_spt_remove(StgWord64 key[2]) {
if (spt) {
ACQUIRE_LOCK(&spt_lock);
- StgStablePtr* entry = removeHashTable(spt, (StgWord)key, NULL);
+ StgStablePtr* entry = removeHashTable_(spt, (StgWord)key, NULL,
+ hashFingerprint, compareFingerprint);
RELEASE_LOCK(&spt_lock);
if (entry)
@@ -76,11 +77,11 @@ void hs_spt_remove(StgWord64 key[2]) {
}
}
-StgPtr hs_spt_lookup(StgWord64 key1, StgWord64 key2) {
+StgPtr hs_spt_lookup(StgWord64 key[2]) {
if (spt) {
ACQUIRE_LOCK(&spt_lock);
- StgWord64 key[2] = { key1, key2 };
- const StgStablePtr * entry = lookupHashTable(spt, (StgWord)key);
+ const StgStablePtr * entry = lookupHashTable_(spt, (StgWord)key,
+ hashFingerprint, compareFingerprint);
const StgPtr ret = entry ? deRefStablePtr(*entry) : NULL;
RELEASE_LOCK(&spt_lock);
return ret;