summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatt Valentine-House <[email protected]>2024-04-02 13:52:50 +0100
committerMatt Valentine-House <[email protected]>2024-04-15 19:50:47 +0100
commit065710c0f5c1e81f0fa7ab6ddd3ccbc41e9cc2cc (patch)
treeb3cf24415dad95defcb3dcaa9088b36946dfd3c4
parenta2ea4ec30c409ebe8ae7952f092e0bd8c1912a17 (diff)
Initialize external GC Library
Co-Authored-By: Peter Zhu <[email protected]>
-rw-r--r--dln.c4
-rw-r--r--dln.h1
-rw-r--r--dmydln.c10
-rw-r--r--gc.c53
-rw-r--r--internal/gc.h4
-rw-r--r--vm_core.h11
6 files changed, 79 insertions, 4 deletions
diff --git a/dln.c b/dln.c
index db6ea5aa0f..3e08728a6b 100644
--- a/dln.c
+++ b/dln.c
@@ -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)
diff --git a/dln.h b/dln.h
index d624bb6611..13eef58d9f 100644
--- a/dln.h
+++ b/dln.h
@@ -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
diff --git a/dmydln.c b/dmydln.c
index 35824ebec8..22f40e82eb 100644
--- a/dmydln.c
+++ b/dmydln.c
@@ -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);
+}
+
diff --git a/gc.c b/gc.c
index 9be07febc8..a08a151efa 100644
--- a/gc.c
+++ b/gc.c
@@ -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__)
diff --git a/vm_core.h b/vm_core.h
index 9873ada2d5..9d6f8d87d0 100644
--- a/vm_core.h
+++ b/vm_core.h
@@ -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;