about summary refs log tree commit diff
path: root/src/rt
diff options
context:
space:
mode:
authorPatrick Walton <pcwalton@mimiga.net>2011-08-19 13:03:46 -0700
committerPatrick Walton <pcwalton@mimiga.net>2011-08-19 14:30:01 -0700
commitcede5e53b3af92c12ae7ba6591fce7f8ca81979f (patch)
tree441629abbc494baac5e9364af96cc949009820dd /src/rt
parent390dd3861933db71339dba01f09a83594a85d3eb (diff)
downloadrust-cede5e53b3af92c12ae7ba6591fce7f8ca81979f.tar.gz
rust-cede5e53b3af92c12ae7ba6591fce7f8ca81979f.zip
rt: Call maybe_gc on mallocs
Diffstat (limited to 'src/rt')
-rw-r--r--src/rt/rust_gc.cpp36
-rw-r--r--src/rt/rust_gc.h10
-rw-r--r--src/rt/rust_upcall.cpp3
3 files changed, 38 insertions, 11 deletions
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 <utility>
 #include <stdint.h>
 
+#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<void *,const safe_point *> *)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.