Skip to content

Commit

Permalink
Import JIT
Browse files Browse the repository at this point in the history
  • Loading branch information
qwe661234 committed May 3, 2023
1 parent 8d21699 commit 36f304c
Show file tree
Hide file tree
Showing 11 changed files with 1,821 additions and 108 deletions.
2 changes: 2 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,8 @@ OBJS := \
elf.o \
cache.o \
mpool.o \
codegen.o \
compile.o \
$(OBJS_EXT) \
main.o

Expand Down
143 changes: 138 additions & 5 deletions src/cache.c
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
#include <stddef.h>
#include <stdlib.h>
#include <string.h>
#include <sys/mman.h>

#include "cache.h"
#include "mpool.h"
Expand All @@ -18,7 +19,11 @@
(((val) * (GOLDEN_RATIO_32)) >> (32 - (cache_size_bits))) & (cache_size - 1)
/* THRESHOLD is set to identify hot spots. Once the frequency of use for a block
* exceeds the THRESHOLD, the JIT compiler flow is triggered. */
#define THRESHOLD 1000
#define THRESHOLD 100000
#define CODE_CACHE_SIZE (64 * 1024 * 1024)
#define sys_icache_invalidate(addr, size) \
__builtin___clear_cache((char *) (addr), (char *) (addr) + (size));
#define JIT 1

static uint32_t cache_size, cache_size_bits;
static struct mpool *cache_mp;
Expand Down Expand Up @@ -64,9 +69,11 @@ struct hlist_node {
typedef struct {
void *value;
uint32_t key;
uint32_t frequency;
cache_list_t type;
struct list_head list;
struct hlist_node ht_list;
uint64_t offset;
} arc_entry_t;
#else /* !RV32_HAS(ARC) */
typedef struct {
Expand All @@ -75,6 +82,7 @@ typedef struct {
uint32_t frequency;
struct list_head list;
struct hlist_node ht_list;
uint64_t offset;
} lfu_entry_t;
#endif

Expand All @@ -93,6 +101,10 @@ typedef struct cache {
#endif
hashtable_t *map;
uint32_t capacity;
#if JIT
uint8_t *jitcode;
uint64_t offset;
#endif
} cache_t;

static inline void INIT_LIST_HEAD(struct list_head *head)
Expand Down Expand Up @@ -286,6 +298,12 @@ cache_t *cache_create(int size_bits)
mpool_create(cache_size * sizeof(lfu_entry_t), sizeof(lfu_entry_t));
#endif
cache->capacity = cache_size;
#if JIT
cache->jitcode = (uint8_t *) mmap(NULL, CODE_CACHE_SIZE,
PROT_READ | PROT_WRITE | PROT_EXEC,
MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
cache->offset = 0;
#endif
return cache;
}

Expand Down Expand Up @@ -338,7 +356,7 @@ static inline void move_to_mru(cache_t *cache,

void *cache_get(cache_t *cache, uint32_t key)
{
if (!cache->capacity || hlist_empty(&cache->map->ht_list_head[HASH(key)]))
if (hlist_empty(&cache->map->ht_list_head[HASH(key)]))
return NULL;

#if RV32_HAS(ARC)
Expand All @@ -353,8 +371,10 @@ void *cache_get(cache_t *cache, uint32_t key)
if (entry->key == key)
break;
}
if (!entry || entry->key != key)
if (!entry)
return NULL;
if (entry->frequency < THRESHOLD)
entry->frequency++;
/* cache hit in LRU_list */
if (entry->type == LRU_list && cache->lru_capacity != cache->capacity)
move_to_mru(cache, entry, LFU_list);
Expand Down Expand Up @@ -398,7 +418,7 @@ void *cache_get(cache_t *cache, uint32_t key)
if (entry->key == key)
break;
}
if (!entry || entry->key != key)
if (!entry)
return NULL;

/* Once the frequency of use for a specific block exceeds the predetermined
Expand Down Expand Up @@ -468,6 +488,7 @@ void *cache_put(cache_t *cache, uint32_t key, void *value)
arc_entry_t *new_entry = mpool_alloc(cache_mp);
new_entry->key = key;
new_entry->value = value;
new_entry->frequency = 0;
/* check if all cache become LFU */
if (cache->lru_capacity != 0) {
new_entry->type = LRU_list;
Expand Down Expand Up @@ -539,4 +560,116 @@ void cache_free(cache_t *cache, void (*callback)(void *))
free(cache->map->ht_list_head);
free(cache->map);
free(cache);
}
}

bool cache_hot(struct cache *cache, uint32_t key)
{
if (!cache->capacity || hlist_empty(&cache->map->ht_list_head[HASH(key)]))
return false;
#if RV32_HAS(ARC)
arc_entry_t *entry = NULL;
#ifdef __HAVE_TYPEOF
hlist_for_each_entry (entry, &cache->map->ht_list_head[HASH(key)], ht_list)
#else
hlist_for_each_entry (entry, &cache->map->ht_list_head[HASH(key)], ht_list,
arc_entry_t)
#endif
{
if (entry->key == key && entry->frequency == THRESHOLD)
return true;
}
#else
lfu_entry_t *entry = NULL;
#ifdef __HAVE_TYPEOF
hlist_for_each_entry (entry, &cache->map->ht_list_head[HASH(key)], ht_list)
#else
hlist_for_each_entry (entry, &cache->map->ht_list_head[HASH(key)], ht_list,
lfu_entry_t)
#endif
{
if (entry->key == key && entry->frequency == THRESHOLD)
return true;
}
#endif
return false;
}

uint8_t *code_cache_lookup(cache_t *cache, uint32_t key)
{
if (!cache->capacity || hlist_empty(&cache->map->ht_list_head[HASH(key)]))
return NULL;
#if RV32_HAS(ARC)
arc_entry_t *entry = NULL;
#ifdef __HAVE_TYPEOF
hlist_for_each_entry (entry, &cache->map->ht_list_head[HASH(key)], ht_list)
#else
hlist_for_each_entry (entry, &cache->map->ht_list_head[HASH(key)], ht_list,
arc_entry_t)
#endif
{
if (entry->key == key)
return cache->jitcode + entry->offset;
}
#else
lfu_entry_t *entry = NULL;
#ifdef __HAVE_TYPEOF
hlist_for_each_entry (entry, &cache->map->ht_list_head[HASH(key)], ht_list)
#else
hlist_for_each_entry (entry, &cache->map->ht_list_head[HASH(key)], ht_list,
lfu_entry_t)
#endif
{
if (entry->key == key)
return cache->jitcode + entry->offset;
}
#endif
return NULL;
}

static inline uint64_t align_to(uint64_t val, uint64_t align)
{
if (!align)
return val;
return (val + align - 1) & ~(align - 1);
}

uint8_t *code_cache_add(cache_t *cache,
uint64_t key,
uint8_t *code,
size_t sz,
uint64_t align)
{
cache->offset = align_to(cache->offset, align);
if (!cache->capacity || hlist_empty(&cache->map->ht_list_head[HASH(key)]))
return NULL;
#if RV32_HAS(ARC)
arc_entry_t *entry = NULL;
#ifdef __HAVE_TYPEOF
hlist_for_each_entry (entry, &cache->map->ht_list_head[HASH(key)], ht_list)
#else
hlist_for_each_entry (entry, &cache->map->ht_list_head[HASH(key)], ht_list,
arc_entry_t)
#endif
{
if (entry->key == key)
break;
}
#else
lfu_entry_t *entry = NULL;
#ifdef __HAVE_TYPEOF
hlist_for_each_entry (entry, &cache->map->ht_list_head[HASH(key)], ht_list)
#else
hlist_for_each_entry (entry, &cache->map->ht_list_head[HASH(key)], ht_list,
lfu_entry_t)
#endif
{
if (entry->key == key)
break;
}
#endif
memcpy(cache->jitcode + cache->offset, code, sz);
entry->offset = cache->offset;
cache->offset += sz;
sys_icache_invalidate(cache->jitcode + entry->offset, sz);
return cache->jitcode + entry->offset;
}
13 changes: 12 additions & 1 deletion src/cache.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

#pragma once

#include <stdbool.h>
#include <stdint.h>

struct cache;
Expand Down Expand Up @@ -37,4 +38,14 @@ void *cache_put(struct cache *cache, uint32_t key, void *value);
* @cache: a pointer points to target cache
* @callback: a function for freeing cache entry completely
*/
void cache_free(struct cache *cache, void (*callback)(void *));
void cache_free(struct cache *cache, void (*callback)(void *));

bool cache_hot(struct cache *cache, uint32_t key);

uint8_t *code_cache_lookup(struct cache *cache, uint32_t key);

uint8_t *code_cache_add(struct cache *cache,
uint64_t key,
uint8_t *code,
size_t sz,
uint64_t align);

0 comments on commit 36f304c

Please sign in to comment.