diff --git a/src/rt/rust_abi.h b/src/rt/rust_abi.h new file mode 100644 index 00000000000..1894a56f6a4 --- /dev/null +++ b/src/rt/rust_abi.h @@ -0,0 +1,38 @@ +#ifndef RUST_ABI_H +#define RUST_ABI_H + +#ifdef __WIN32__ +#include +#else +#include +#endif + +template +class weak_symbol { +private: + bool init; + T *data; + const char *name; + + void fill() { + if (init) + return; + +#ifdef __WIN32__ + data = (T *)GetProcAddress(GetModuleHandle(NULL), name); +#else + data = (T *)dlsym(RTLD_DEFAULT, name); +#endif + + init = true; + } + +public: + weak_symbol(const char *in_name) + : init(false), data(NULL), name(in_name) {} + + T *&operator*() { fill(); return data; } +}; + +#endif + diff --git a/src/rt/rust_gc.cpp b/src/rt/rust_gc.cpp index b83c54ed73c..cb9d7e949ad 100644 --- a/src/rt/rust_gc.cpp +++ b/src/rt/rust_gc.cpp @@ -6,6 +6,7 @@ #include #include +#include "rust_abi.h" #include "rust_gc.h" #include "rust_internal.h" #include "rust_shape.h" @@ -22,6 +23,8 @@ namespace gc { +weak_symbol safe_point_data("rust_gc_safe_points"); + struct frame { uint8_t *bp; // The frame pointer. void (*ra)(); // The return address. @@ -77,7 +80,7 @@ class safe_point_map { public: safe_point_map() { - const uintptr_t *data = get_safe_point_data(); + const uintptr_t *data = *safe_point_data; n_safe_points = *data++; index = (const safe_point_index_entry *)data; data += n_safe_points * 2; @@ -85,22 +88,6 @@ public: } const safe_point *get_safe_point(void (*addr)()); - - static const uintptr_t *get_safe_point_data() { - static bool init = false; - static const uintptr_t *data; - if (!init) { -#ifdef __WIN32__ - data = (const uintptr_t *)GetProcAddress(GetModuleHandle(NULL), - "rust_gc_safe_points"); -#else - data = (const uintptr_t *)dlsym(RTLD_DEFAULT, - "rust_gc_safe_points"); -#endif - init = true; - } - return data; - } }; class gc { @@ -192,7 +179,7 @@ gc::run() { void maybe_gc(rust_task *task) { - if (safe_point_map::get_safe_point_data() == NULL) + if (*safe_point_data == NULL) return; // FIXME: We ought to lock this.