Initialize external GC Library

Co-Authored-By: Peter Zhu <peter@peterzhu.ca>
This commit is contained in:
Matt Valentine-House 2024-04-02 13:52:50 +01:00
parent a2ea4ec30c
commit 065710c0f5
6 changed files with 79 additions and 4 deletions

4
dln.c
View File

@ -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)

1
dln.h
View File

@ -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

View File

@ -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);
}

53
gc.c
View File

@ -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;

View File

@ -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__)

View File

@ -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;