diff --git a/src/rt/rust_gc.cpp b/src/rt/rust_gc.cpp index 257df4c8134..9b8743dd03e 100644 --- a/src/rt/rust_gc.cpp +++ b/src/rt/rust_gc.cpp @@ -3,6 +3,7 @@ #include #include +#include "rust_gc.h" #include "rust_internal.h" #ifdef __WIN32__ @@ -31,38 +32,51 @@ class safe_point_map { public: safe_point_map() { - const uintptr_t *data; -#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 + const uintptr_t *data = get_safe_point_data(); n_safe_points = *data++; index = (const std::pair *)data; data += n_safe_points * 2; safe_points = (const safe_point *)data; } + + 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; + } }; void -gc() { +gc(rust_task *task) { safe_point_map map; // TODO } void -maybe_gc() { +maybe_gc(rust_task *task) { + if (safe_point_map::get_safe_point_data() == NULL) + return; + // FIXME: We ought to lock this. static int zeal = -1; if (zeal == -1) { char *ev = getenv("RUST_GC_ZEAL"); - zeal = ev[0] != '\0' && ev[0] != '0'; + zeal = ev && ev[0] != '\0' && ev[0] != '0'; } if (zeal) - gc(); + gc(task); } } diff --git a/src/rt/rust_gc.h b/src/rt/rust_gc.h new file mode 100644 index 00000000000..45349dc0f91 --- /dev/null +++ b/src/rt/rust_gc.h @@ -0,0 +1,10 @@ +// Rust garbage collection. + +struct rust_task; + +namespace gc { + +void maybe_gc(rust_task *task); + +} + diff --git a/src/rt/rust_upcall.cpp b/src/rt/rust_upcall.cpp index c13ba4def87..9462db80af1 100644 --- a/src/rt/rust_upcall.cpp +++ b/src/rt/rust_upcall.cpp @@ -1,3 +1,4 @@ +#include "rust_gc.h" #include "rust_internal.h" #include "rust_upcall.h" @@ -130,6 +131,8 @@ upcall_malloc(rust_task *task, size_t nbytes, type_desc *td) { " with gc-chain head = 0x%" PRIxPTR, nbytes, td, task->gc_alloc_chain); + gc::maybe_gc(task); + // TODO: Maybe use dladdr here to find a more useful name for the // type_desc.