aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlon Zakai <alonzakai@gmail.com>2012-05-15 13:37:09 -0700
committerAlon Zakai <alonzakai@gmail.com>2012-05-15 13:37:09 -0700
commit46f641bf1e97000a774a5747128c965ea9d425be (patch)
treee0593c70c0aa6ed71b4a90895ced5d9f41b5a160
parent1a55bf326caa5e2a8f3a1d3a0494f3a44a10f47d (diff)
working early gc test
-rw-r--r--src/library_gc.js9
-rw-r--r--system/include/gc.h10
-rwxr-xr-xtests/runner.py51
3 files changed, 62 insertions, 8 deletions
diff --git a/src/library_gc.js b/src/library_gc.js
index 7683eda7..d9bb895b 100644
--- a/src/library_gc.js
+++ b/src/library_gc.js
@@ -1,6 +1,7 @@
if (GC_SUPPORT) {
var LibraryGC = {
+ $GC__deps: ['sbrk'],
$GC: {
ALLOCATIONS_TO_GC: 1*1024*1024,
@@ -28,7 +29,7 @@ if (GC_SUPPORT) {
if (!bytes) return 0;
var ptr;
if (clear) {
- ptr = _calloc(bytes);
+ ptr = _calloc(1, bytes);
} else {
ptr = _malloc(bytes);
}
@@ -42,7 +43,7 @@ if (GC_SUPPORT) {
free: function(ptr) { // does not check if anything refers to it, this is a forced free
var finalizer = GC.finalizers[ptr];
if (finalizer) {
- Runtime.getFuncWrapper(finalizer)(GC.finalizerArgs[ptr]);
+ Runtime.getFuncWrapper(finalizer)(ptr, GC.finalizerArgs[ptr]);
GC.finalizers[ptr] = 0;
}
_free(ptr);
@@ -80,7 +81,7 @@ if (GC_SUPPORT) {
},
scan: function(start, end) { // scans a memory region and adds new reachable objects
- for (var i = start; i < sbrk.end; i += {{{ Runtime.getNativeTypeSize('void*') }}}) {
+ for (var i = start; i < end; i += {{{ Runtime.getNativeTypeSize('void*') }}}) {
var ptr = {{{ makeGetValue('i', '0', 'void*') }}};
if (GC.sizes[ptr] && !GC.reachable[ptr]) {
GC.reachable[ptr] = 1;
@@ -96,7 +97,7 @@ if (GC_SUPPORT) {
GC.reachableList = []; // each reachable is added once to this. XXX
// static data areas
var staticStart = STACK_MAX;
- var staticEnd = sbrk.DYNAMIC_START || STATICTOP; // after DYNAMIC_START, sbrk manages it (but it might not exist yet)
+ var staticEnd = _sbrk.DYNAMIC_START || STATICTOP; // after DYNAMIC_START, sbrk manages it (but it might not exist yet)
GC.scan(staticStart, staticEnd);
// TODO: scan stack and registers. Currently we assume we run from a timeout or such, so no stack/regs
// stack: STACK_ROOT to STACKTOP
diff --git a/system/include/gc.h b/system/include/gc.h
index 773098ff..baeaf2b5 100644
--- a/system/include/gc.h
+++ b/system/include/gc.h
@@ -2,16 +2,18 @@
* Boehm-compatible GC API
*/
+#include <stdlib.h>
+
#ifdef __cplusplus
extern "C" {
#endif
void __attribute__((used)) __GC_KEEPALIVE__() {
// Force inclusion of necessary dlmalloc functions
- static times = 1;
+ static int times = 1;
void *x = malloc(times);
free(x);
- x = calloc(times);
+ x = calloc(times, 1);
free(x);
times++;
}
@@ -29,8 +31,8 @@ void *GC_MALLOC_ATOMIC(int bytes);
void GC_FREE(void *ptr);
/* Register a finalizer. func(ptr, arg) will be called. The old values are saved in old_func, old_arg */
-void GC_REGISTER_FINALIZER_NO_ORDER((void*)ptr, void (*func)(), void *arg,
- void *(*old_func)(), void *old_arg);
+void GC_REGISTER_FINALIZER_NO_ORDER(void *ptr, void (*func)(void *, void *), void *arg,
+ void *(*old_func)(void *, void *), void *old_arg);
/* Non-Boehm additions */
diff --git a/tests/runner.py b/tests/runner.py
index 49d4159a..da04aafd 100755
--- a/tests/runner.py
+++ b/tests/runner.py
@@ -6094,6 +6094,57 @@ def process(filename):
'''
self.do_run(src, 'hello, world!\ncleanup\nExit Status: 118')
+ def test_gc(self):
+ Settings.GC_SUPPORT = 1
+
+ src = r'''
+ #include <stdio.h>
+ #include <gc.h>
+ #include <assert.h>
+
+ void *global;
+
+ void finalizer(void *ptr, void *arg) {
+ printf("finalizing (global == %d)\n", ptr == global);
+ }
+
+ void finalizer2(void *ptr, void *arg) {
+ printf("finalizing2 (global == %d)\n", ptr == global);
+ }
+
+ int main() {
+ GC_INIT();
+
+ global = GC_MALLOC(1024); // rooted since in a static allocation
+ GC_REGISTER_FINALIZER_NO_ORDER(global, finalizer, 0, 0, 0);
+ printf("alloc %p\n", global);
+
+ void *local = GC_MALLOC(1024); // not rooted since stack is not scanned
+ GC_REGISTER_FINALIZER_NO_ORDER(local, finalizer, 0, 0, 0);
+ printf("alloc %p\n", local);
+
+ assert((char*)local - (char*)global >= 1024 || (char*)global - (char*)local >= 1024);
+
+ void *local2 = GC_MALLOC(1024); // no finalizer
+ printf("alloc %p\n", local2);
+
+ void *local3 = GC_MALLOC(1024); // with finalizable2
+ GC_REGISTER_FINALIZER_NO_ORDER(local3, finalizer2, 0, 0, 0);
+ printf("alloc %p\n", local);
+
+ void *local4 = GC_MALLOC(1024); // yet another
+ GC_REGISTER_FINALIZER_NO_ORDER(local4, finalizer2, 0, 0, 0);
+ printf("alloc %p\n", local);
+
+ printf("*\n");
+ GC_FORCE_COLLECT();
+ printf("*\n");
+
+ GC_FREE(global);
+ global = 0;
+ }
+ '''
+ self.do_run(src, '*\nfinalizing (global == 0)\nfinalizing2 (global == 0)\nfinalizing2 (global == 0)\n*\nfinalizing (global == 1)\n')
# Generate tests for everything
def make_run(fullname, name=-1, compiler=-1, llvm_opts=0, embetter=0, quantum_size=0, typed_arrays=0, emcc_args=None):