diff options
author | Matt Valentine-House <[email protected]> | 2024-04-02 13:52:50 +0100 |
---|---|---|
committer | Matt Valentine-House <[email protected]> | 2024-04-15 19:50:47 +0100 |
commit | 065710c0f5c1e81f0fa7ab6ddd3ccbc41e9cc2cc (patch) | |
tree | b3cf24415dad95defcb3dcaa9088b36946dfd3c4 | |
parent | a2ea4ec30c409ebe8ae7952f092e0bd8c1912a17 (diff) |
Initialize external GC Library
Co-Authored-By: Peter Zhu <[email protected]>
-rw-r--r-- | dln.c | 4 | ||||
-rw-r--r-- | dln.h | 1 | ||||
-rw-r--r-- | dmydln.c | 10 | ||||
-rw-r--r-- | gc.c | 53 | ||||
-rw-r--r-- | internal/gc.h | 4 | ||||
-rw-r--r-- | vm_core.h | 11 |
6 files changed, 79 insertions, 4 deletions
@@ -339,7 +339,7 @@ dln_disable_dlclose(void) #endif #if defined(_WIN32) || defined(USE_DLN_DLOPEN) -static void * +void * dln_open(const char *file) { static const char incompatible[] = "incompatible library version"; @@ -427,7 +427,7 @@ dln_open(const char *file) dln_loaderror("%s - %s", error, file); } -static void * +void * dln_sym(void *handle, const char *symbol) { #if defined(_WIN32) @@ -25,6 +25,7 @@ RUBY_SYMBOL_EXPORT_BEGIN char *dln_find_exe_r(const char*,const char*,char*,size_t DLN_FIND_EXTRA_ARG_DECL); char *dln_find_file_r(const char*,const char*,char*,size_t DLN_FIND_EXTRA_ARG_DECL); void *dln_load(const char*); +void *dln_open(const char *file); void *dln_symbol(void*,const char*); RUBY_SYMBOL_EXPORT_END @@ -20,3 +20,13 @@ dln_symbol(void *handle, const char *symbol) UNREACHABLE_RETURN(NULL); } + +NORETURN(void *dln_open(const char*)); +void* +dln_open(const char *library) +{ + rb_loaderror("this executable file can't load extension libraries"); + + UNREACHABLE_RETURN(NULL); +} + @@ -1884,6 +1884,55 @@ rb_gc_initial_stress_set(VALUE flag) initial_stress = flag; } +static void * Alloc_GC_impl(void); + +#if USE_SHARED_GC +# include "dln.h" +# define Alloc_GC rb_gc_functions->init + +void +ruby_external_gc_init() +{ + rb_gc_function_map_t *map = malloc(sizeof(rb_gc_function_map_t)); + rb_gc_functions = map; + + char *gc_so_path = getenv("RUBY_GC_LIBRARY_PATH"); + if (!gc_so_path) { + map->init = Alloc_GC_impl; + return; + } + + void *h = dln_open(gc_so_path); + if (!h) { + rb_bug( + "ruby_external_gc_init: Shared library %s cannot be opened.", + gc_so_path + ); + } + + void *gc_init_func = dln_symbol(h, "Init_GC"); + if (!gc_init_func) { + rb_bug( + "ruby_external_gc_init: Init_GC func not exported by library %s", + gc_so_path + ); + } + + map->init = gc_init_func; +} +#else +# define Alloc_GC Alloc_GC_impl +#endif + +rb_objspace_t * +rb_objspace_alloc(void) +{ +#if USE_SHARED_GC + ruby_external_gc_init(); +#endif + return (rb_objspace_t *)Alloc_GC(); +} + static void free_stack_chunks(mark_stack_t *); static void mark_stack_free_cache(mark_stack_t *); static void heap_page_free(rb_objspace_t *objspace, struct heap_page *page); @@ -3489,8 +3538,8 @@ static const struct st_hash_type object_id_hash_type = { object_id_hash, }; -rb_objspace_t * -rb_objspace_alloc(void) +static void * +Alloc_GC_impl(void) { rb_objspace_t *objspace = calloc1(sizeof(rb_objspace_t)); ruby_current_vm_ptr->objspace = objspace; diff --git a/internal/gc.h b/internal/gc.h index 5b1180fd91..91dbc0ccf3 100644 --- a/internal/gc.h +++ b/internal/gc.h @@ -16,6 +16,10 @@ #include "ruby/ruby.h" /* for rb_event_flag_t */ #include "vm_core.h" /* for GET_EC() */ +#ifndef USE_SHARED_GC +# define USE_SHARED_GC 0 +#endif + #if defined(__x86_64__) && !defined(_ILP32) && defined(__GNUC__) #define SET_MACHINE_STACK_END(p) __asm__ __volatile__ ("movq\t%%rsp, %0" : "=r" (*(p))) #elif defined(__i386) && defined(__GNUC__) @@ -106,6 +106,14 @@ extern int ruby_assert_critical_section_entered; #include "ruby/thread_native.h" +#if USE_SHARED_GC +typedef struct gc_function_map { + void *(*init)(void); +} rb_gc_function_map_t; + +#define rb_gc_functions (GET_VM()->gc_functions_map) +#endif + /* * implementation selector of get_insn_info algorithm * 0: linear search @@ -752,6 +760,9 @@ typedef struct rb_vm_struct { int coverage_mode; struct rb_objspace *objspace; +#if USE_SHARED_GC + rb_gc_function_map_t *gc_functions_map; +#endif rb_at_exit_list *at_exit; |