Skip to content

Commit

Permalink
dynamic library cache
Browse files Browse the repository at this point in the history
  • Loading branch information
smaludzi committed Oct 9, 2019
1 parent 9555537 commit d6c82c1
Show file tree
Hide file tree
Showing 13 changed files with 203 additions and 32 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
*~
*.o
*.so

# generated
nev
Expand All @@ -12,6 +13,7 @@ test_object
test_scanner
test_symtab
test_vm
test_dlcache

# build
build/
Expand Down
45 changes: 41 additions & 4 deletions back/dlcache.c
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
#include "dlcache.h"
#include "fficall.h"
#include "hash.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include <dlfcn.h>

dlcache_entry * dlcache_entry_new(unsigned int size)
{
Expand Down Expand Up @@ -94,10 +96,14 @@ dlcache * dlcache_new(unsigned int size)
{
dlcache * cache = (dlcache *)malloc(sizeof(dlcache));
dlcache_entry * entries = dlcache_entry_new(size);
void * host_handle = NULL;

cache->size = 0;
cache->size = size;
cache->count = 0;
cache->entries = entries;

host_handle = ffi_decl_get_handle("host");
dlcache_add_dl(cache, "host", host_handle);

return cache;
}
Expand All @@ -106,15 +112,23 @@ void dlcache_delete(dlcache * cache)
{
if (cache->entries != NULL)
{
unsigned int i = 0;

for (i = 0; i < cache->size; i++)
{
if (cache->entries[i].handle != NULL)
{
dlclose(cache->entries[i].handle);
}
}

dlcache_entry_delete(cache->entries);
}
free(cache);
}

void dlcache_open_dl(dlcache * cache, const char * dl_name)
void dlcache_add_dl(dlcache * cache, const char * dl_name, void * handle)
{
void * handle = NULL;

if (dl_name == NULL)
{
return;
Expand All @@ -135,6 +149,29 @@ dlcache_entry * dlcache_lookup(dlcache * cache, const char * dl_name)
return entry;
}

void * dlcache_get_handle(dlcache * cache, const char * dl_name)
{
void * handle = NULL;

dlcache_entry * entry = dlcache_lookup(cache, dl_name);
if (entry != NULL)
{
handle = entry->handle;
}
else
{
handle = ffi_decl_get_handle(dl_name);
if (handle == NULL)
{
fprintf(stderr, "cannot open library %s\n", dl_name);
return NULL;
}
dlcache_add_dl(cache, dl_name, handle);
}

return handle;
}

void dlcache_resize(dlcache * cache)
{
if (cache->count > cache->size * 3 / 4)
Expand Down
6 changes: 5 additions & 1 deletion back/dlcache.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
#ifndef __DLCACHE_H__
#define __DLCACHE_H__

#define DEFAULT_DLCACHE_SIZE 16

typedef struct dlcache_entry
{
const char * dl_name;
Expand Down Expand Up @@ -29,9 +31,11 @@ void dlcache_entry_print(dlcache_entry * entry);
dlcache * dlcache_new(unsigned int size);
void dlcache_delete(dlcache * cache);

void dlcache_open_dl(dlcache * cache, const char * dl_name);
void dlcache_add_dl(dlcache * cache, const char * dl_name, void * handle);
dlcache_entry * dlcache_lookup(dlcache * cache, const char * dl_name);

void * dlcache_get_handle(dlcache * cache, const char * dl_name);

void dlcache_resize(dlcache * cache);

void dlcache_print(dlcache * cache);
Expand Down
41 changes: 22 additions & 19 deletions back/fficall.c
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,6 @@ ffi_decl * ffi_decl_new(unsigned int count)
value->count = count;
value->param_types = (ffi_type **)malloc(count * sizeof(ffi_type *));
value->param_values = (void **)malloc(count * sizeof(void *));
value->handle = NULL;

return value;
}
Expand Down Expand Up @@ -91,28 +90,41 @@ int ffi_decl_prepare(ffi_decl * decl)
return FFI_SUCC;
}

int ffi_decl_call(ffi_decl * decl, char * fname, char * libname)
void * ffi_decl_get_handle(const char * libname)
{
void (* func)(void) = NULL;
void * handle = NULL;

/* open for main program */
if (strcmp(libname, "host") == 0)
{
libname = NULL;
}
decl->handle = dlopen(libname, RTLD_LAZY);
if (decl->handle == NULL)

handle = dlopen(libname, RTLD_LAZY);
if (handle == NULL)
{
fprintf(stderr, "cannot open library %s\n", libname);
return FFI_FAIL;
return NULL;
}

return handle;
}

func = dlsym(decl->handle, fname);
void ffi_decl_close_handle(void * handle)
{
if (handle != NULL)
{
dlclose(handle);
}
}

int ffi_decl_call(ffi_decl * decl, char * fname, void * handle)
{
void (* func)(void) = NULL;

func = dlsym(handle, fname);
if (func == NULL)
{
dlclose(decl->handle);
decl->handle = NULL;
fprintf(stderr, "cannot obtain address of a symbol %s\n", fname);
return FFI_FAIL;
}
Expand All @@ -122,15 +134,6 @@ int ffi_decl_call(ffi_decl * decl, char * fname, char * libname)
return FFI_SUCC;
}

void ffi_decl_close(ffi_decl * value)
{
if (value->handle != NULL)
{
dlclose(value->handle);
value->handle = NULL;
}
}

int test_print_str(const char * str)
{
printf("test print str %s", str);
Expand Down
7 changes: 4 additions & 3 deletions back/fficall.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,19 +40,20 @@ typedef struct ffi_decl {
char * ret_string_value;
};
ffi_cif cif;
void * handle;
} ffi_decl;

ffi_decl * ffi_decl_new(unsigned int count);
void ffi_decl_delete(ffi_decl * value);
void ffi_decl_close(ffi_decl * value);

int ffi_decl_set_param_type(ffi_decl * decl, unsigned int index, ffi_type * param_type);
int ffi_decl_set_param_value(ffi_decl * decl, unsigned int index, void * param_value);
int ffi_decl_set_ret_type(ffi_decl * decl , ffi_type * ret_type);

void * ffi_decl_get_handle(const char * libname);
void ffi_decl_close_handle(void * handle);

int ffi_decl_prepare(ffi_decl * decl);
int ffi_decl_call(ffi_decl * decl, char * fname, char * libname);
int ffi_decl_call(ffi_decl * decl, char * fname, void * handle);

int test_print_str(const char * str);

Expand Down
21 changes: 18 additions & 3 deletions back/vm.c
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
#include "module.h"
#include "strutil.h"
#include "fficall.h"
#include "dlcache.h"
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
Expand Down Expand Up @@ -2087,12 +2088,22 @@ void vm_execute_func_ffi(vm * machine, bytecode * code)
gc_stack entry = { 0 };
mem_ptr addr = { 0 };
char ** strtab_array = NULL;
void * handle = NULL;

assert(machine->prog->module_value != NULL);
strtab_array = machine->prog->module_value->strtab_array;

ret = ffi_decl_call(fd, strtab_array[code->ffi.fname_index],
strtab_array[code->ffi.libname_index]);
handle = dlcache_get_handle(machine->dlib_cache, strtab_array[code->ffi.libname_index]);
if (handle == NULL)
{
ffi_decl_delete(fd);

machine->running = VM_EXCEPTION;
machine->exception = EXCEPT_FFI_FAIL;
return;
}

ret = ffi_decl_call(fd, strtab_array[code->ffi.fname_index], handle);
if (ret != FFI_SUCC)
{
ffi_decl_delete(fd);
Expand Down Expand Up @@ -2121,7 +2132,6 @@ void vm_execute_func_ffi(vm * machine, bytecode * code)
assert(0);
}

ffi_decl_close(fd);
ffi_decl_delete(fd);

machine->sp++;
Expand Down Expand Up @@ -2445,6 +2455,7 @@ vm * vm_new(unsigned int mem_size, unsigned int stack_size)
machine->stack_size = stack_size;
machine->stack = gc_stack_new(stack_size);
machine->collector = gc_new(mem_size);
machine->dlib_cache = dlcache_new(DEFAULT_DLCACHE_SIZE);
machine->exception = EXCEPT_NO_UNKNOWN;
machine->line_no = 0;

Expand All @@ -2463,6 +2474,10 @@ void vm_delete(vm * machine)
{
gc_delete(machine->collector);
}
if (machine->dlib_cache != NULL)
{
dlcache_delete(machine->dlib_cache);
}
free(machine);
}

Expand Down
1 change: 1 addition & 0 deletions back/vm.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ typedef struct vm
int stack_size;
struct gc_stack * stack;
struct gc * collector;
struct dlcache * dlib_cache;

except_no exception;
unsigned int line_no;
Expand Down
7 changes: 7 additions & 0 deletions dyntest/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@

CC = gcc -g
CFLAGS = -Wall

dyntest.o: dyntest.c dyntest.h
$(CC) $(CFLAGS) -fPIC -c dyntest.c -o dyntest.o
$(CC) -shared dyntest.o -o dyntest.so
31 changes: 31 additions & 0 deletions dyntest/dyntest.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
#include <stdio.h>

void __attribute__ ((constructor)) init_dyntest(void)
{
printf("dyntest initalized\n");
}

void __attribute__ ((destructor)) destroy_dyntest(void)
{
printf("dyntest destructed\n");
}

char * test_conc_str(const char * a, const char * b)
{
static char c[20];

sprintf(c, "dt%s%s", a, b);

return c;
}

char * test_conc_int_str(int d, const char * s)
{
static char c[20];

sprintf(c, "dt%d:%s", d, s);

return c;
}


6 changes: 6 additions & 0 deletions dyntest/dyntest.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@

char * test_conc_str(const char * a, const char * b);

char * test_conc_int_str(int d, const char * s);


4 changes: 2 additions & 2 deletions sample/sample_fficonc.nev
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@

#extern "../../dyntest/dyntest.so" func test_conc_str(a : string, b : string) -> string
#extern "../../dyntest/dyntest.so" func test_conc_int_str(d : int, str : string) -> string
#extern "../dyntest/dyntest.so" func test_conc_str(a : string, b : string) -> string
#extern "../dyntest/dyntest.so" func test_conc_int_str(d : int, str : string) -> string

extern "host" func test_conc_str(a : string, b : string) -> string
extern "host" func test_conc_int_str(d : int, str : string) -> string
Expand Down
3 changes: 3 additions & 0 deletions test/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ add_executable(test_exctab test_exctab.c)
add_executable(test_strtab test_strtab.c)
add_executable(test_strutil test_strutil.c)
add_executable(test_ffi test_ffi.c)
add_executable(test_dlcache test_dlcache.c)

add_test(NAME test_vm COMMAND test_vm)
add_test(NAME test_symtab COMMAND test_symtab)
Expand All @@ -34,6 +35,7 @@ add_test(NAME test_exctab COMMAND test_exctab)
add_test(NAME test_strtab COMMAND test_strtab)
add_test(NAME test_strutil COMMAND test_strutil)
add_test(NAME test_ffi COMMAND test_ffi)
add_test(NAME test_dlcache COMMAND test_dlcache)

target_link_libraries(test_vm nev)
# target_link_libraries(test_scanner nev)
Expand All @@ -47,4 +49,5 @@ target_link_libraries(test_exctab nev)
target_link_libraries(test_strtab nev)
target_link_libraries(test_strutil nev)
target_link_libraries(test_ffi nev)
target_link_libraries(test_dlcache nev)

Loading

0 comments on commit d6c82c1

Please sign in to comment.