Skip to content

Commit afcde95

Browse files
authored
Merge pull request #249 from qwe661234/unify_hash
Unify the hash function of cache and map
2 parents f3c7b89 + c6e7e66 commit afcde95

File tree

5 files changed

+35
-27
lines changed

5 files changed

+35
-27
lines changed

src/cache.c

Lines changed: 18 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,7 @@
1111

1212
#include "cache.h"
1313
#include "mpool.h"
14-
15-
#define GOLDEN_RATIO_32 0x61C88647
16-
#define HASH(val) \
17-
(((val) * (GOLDEN_RATIO_32)) >> (32 - (cache_size_bits))) & (cache_size - 1)
14+
#include "utils.h"
1815

1916
/* THRESHOLD is set to identify hot spots. Once the frequency of use for a block
2017
* exceeds the THRESHOLD, the JIT compiler flow is triggered.
@@ -24,6 +21,9 @@
2421
static uint32_t cache_size, cache_size_bits;
2522
static struct mpool *cache_mp;
2623

24+
/* hash function for the cache */
25+
HASH_FUNC_IMPL(cache_hash, cache_size_bits, cache_size);
26+
2727
#if RV32_HAS(ARC)
2828
/* The Adaptive Replacement Cache (ARC) improves the traditional LRU strategy
2929
* by dividing the cache into two lists: T1 and T2. T1 follows the LRU
@@ -337,16 +337,18 @@ static inline void move_to_mru(cache_t *cache,
337337

338338
void *cache_get(cache_t *cache, uint32_t key)
339339
{
340-
if (!cache->capacity || hlist_empty(&cache->map->ht_list_head[HASH(key)]))
340+
if (!cache->capacity ||
341+
hlist_empty(&cache->map->ht_list_head[cache_hash(key)]))
341342
return NULL;
342343

343344
#if RV32_HAS(ARC)
344345
arc_entry_t *entry = NULL;
345346
#ifdef __HAVE_TYPEOF
346-
hlist_for_each_entry (entry, &cache->map->ht_list_head[HASH(key)], ht_list)
347+
hlist_for_each_entry (entry, &cache->map->ht_list_head[cache_hash(key)],
348+
ht_list)
347349
#else
348-
hlist_for_each_entry (entry, &cache->map->ht_list_head[HASH(key)], ht_list,
349-
arc_entry_t)
350+
hlist_for_each_entry (entry, &cache->map->ht_list_head[cache_hash(key)],
351+
ht_list, arc_entry_t)
350352
#endif
351353
{
352354
if (entry->key == key)
@@ -388,10 +390,11 @@ void *cache_get(cache_t *cache, uint32_t key)
388390
#else /* !RV32_HAS(ARC) */
389391
lfu_entry_t *entry = NULL;
390392
#ifdef __HAVE_TYPEOF
391-
hlist_for_each_entry (entry, &cache->map->ht_list_head[HASH(key)], ht_list)
393+
hlist_for_each_entry (entry, &cache->map->ht_list_head[cache_hash(key)],
394+
ht_list)
392395
#else
393-
hlist_for_each_entry (entry, &cache->map->ht_list_head[HASH(key)], ht_list,
394-
lfu_entry_t)
396+
hlist_for_each_entry (entry, &cache->map->ht_list_head[cache_hash(key)],
397+
ht_list, lfu_entry_t)
395398
#endif
396399
{
397400
if (entry->key == key)
@@ -478,7 +481,8 @@ void *cache_put(cache_t *cache, uint32_t key, void *value)
478481
list_add(&new_entry->list, cache->lists[LRU_ghost_list]);
479482
cache->list_size[LRU_ghost_list]++;
480483
}
481-
hlist_add_head(&new_entry->ht_list, &cache->map->ht_list_head[HASH(key)]);
484+
hlist_add_head(&new_entry->ht_list,
485+
&cache->map->ht_list_head[cache_hash(key)]);
482486

483487
CACHE_ASSERT(cache);
484488
#else /* !RV32_HAS(ARC) */
@@ -504,7 +508,8 @@ void *cache_put(cache_t *cache, uint32_t key, void *value)
504508
new_entry->frequency = 0;
505509
list_add(&new_entry->list, cache->lists[new_entry->frequency++]);
506510
cache->list_size++;
507-
hlist_add_head(&new_entry->ht_list, &cache->map->ht_list_head[HASH(key)]);
511+
hlist_add_head(&new_entry->ht_list,
512+
&cache->map->ht_list_head[cache_hash(key)]);
508513
assert(cache->list_size <= cache->capacity);
509514
#endif
510515
return delete_value;

src/emulate.c

Lines changed: 4 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -277,17 +277,8 @@ void rv_debug(riscv_t *rv)
277277
}
278278
#endif /* RV32_HAS(GDBSTUB) */
279279

280-
/* hash function is used when mapping address into the block map */
281-
static inline uint32_t hash(size_t k)
282-
{
283-
k ^= k << 21;
284-
k ^= k >> 17;
285-
#if (SIZE_MAX > 0xFFFFFFFF)
286-
k ^= k >> 35;
287-
k ^= k >> 51;
288-
#endif
289-
return k;
290-
}
280+
/* hash function for the block map */
281+
HASH_FUNC_IMPL(map_hash, BLOCK_MAP_CAPACITY_BITS, 1 << BLOCK_MAP_CAPACITY_BITS);
291282

292283
/* allocate a basic block */
293284
static block_t *block_alloc(riscv_t *rv)
@@ -304,7 +295,7 @@ static void block_insert(block_map_t *map, const block_t *block)
304295
{
305296
assert(map && block);
306297
const uint32_t mask = map->block_capacity - 1;
307-
uint32_t index = hash(block->pc_start);
298+
uint32_t index = map_hash(block->pc_start);
308299

309300
/* insert into the block map */
310301
for (;; index++) {
@@ -320,7 +311,7 @@ static void block_insert(block_map_t *map, const block_t *block)
320311
static block_t *block_find(const block_map_t *map, const uint32_t addr)
321312
{
322313
assert(map);
323-
uint32_t index = hash(addr);
314+
uint32_t index = map_hash(addr);
324315
const uint32_t mask = map->block_capacity - 1;
325316

326317
/* find block in block map */

src/riscv.c

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@
1111
#include "riscv_private.h"
1212
#include "state.h"
1313

14-
#define BLOCK_MAP_CAPACITY_BITS 10
1514
#define BLOCK_IR_MAP_CAPACITY_BITS 10
1615

1716
/* initialize the block map */

src/riscv.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,8 @@ enum {
7979
#define MSTATUS_MPIE (1 << MSTATUS_MPIE_SHIFT)
8080
#define MSTATUS_MPP (3 << MSTATUS_MPP_SHIFT)
8181

82+
#define BLOCK_MAP_CAPACITY_BITS 10
83+
8284
/* forward declaration for internal structure */
8385
typedef struct riscv_internal riscv_t;
8486
typedef void *riscv_user_t;

src/utils.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,3 +10,14 @@ void rv_gettimeofday(struct timeval *tv);
1010

1111
/* Retrieve the value used by a clock which is specified by clock_id. */
1212
void rv_clock_gettime(struct timespec *tp);
13+
14+
/* This hashing routine is adapted from Linux kernel.
15+
* See
16+
* https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/tree/include/linux/hash.h
17+
*/
18+
#define HASH_FUNC_IMPL(name, size_bits, size) \
19+
FORCE_INLINE uint32_t name(uint32_t val) \
20+
{ \
21+
/* 0x61C88647 is 32-bit golden ratio */ \
22+
return (val * 0x61C88647 >> (32 - size_bits)) & ((size) -1); \
23+
}

0 commit comments

Comments
 (0)