diff options
author | Bruce Mitchener <bruce.mitchener@gmail.com> | 2013-02-01 01:24:59 +0700 |
---|---|---|
committer | Bruce Mitchener <bruce.mitchener@gmail.com> | 2013-02-01 01:24:59 +0700 |
commit | 5105bc966c9ac893a86901658debc7b2572b82d5 (patch) | |
tree | 07baa0d1b6d1c5e2b23bbb8f2cecfbb950e510f7 | |
parent | 7b129450d48a3552dc8189d96ef695db8cc9c15b (diff) |
Add GC support for GC_MALLOC_UNCOLLECTABLE.
-rw-r--r-- | src/library_gc.js | 17 | ||||
-rw-r--r-- | system/include/gc.h | 3 | ||||
-rwxr-xr-x | tests/runner.py | 5 |
3 files changed, 20 insertions, 5 deletions
diff --git a/src/library_gc.js b/src/library_gc.js index fe4cbf63..ed40fa6c 100644 --- a/src/library_gc.js +++ b/src/library_gc.js @@ -9,6 +9,7 @@ if (GC_SUPPORT) { sizes: {}, // if in this map, then a live allocated object. this is iterable scannables: {}, + uncollectables: {}, finalizers: {}, finalizerArgs: {}, @@ -34,7 +35,7 @@ if (GC_SUPPORT) { } }, - malloc: function(bytes, clear, scannable) { + malloc: function(bytes, clear, scannable, collectable) { if (!bytes) return 0; var ptr; if (clear) { @@ -42,6 +43,9 @@ if (GC_SUPPORT) { } else { ptr = _malloc(bytes); } + if (!collectable) { + GC.uncollectables[ptr] = true; + } GC.scannables[ptr] = scannable; GC.sizes[ptr] = bytes; GC.totalAllocations += bytes; @@ -123,7 +127,7 @@ if (GC_SUPPORT) { sweep: function() { // traverse all objects and free all unreachable var freeList = []; for (var ptr in GC.sizes) { - if (!GC.reachable[ptr]) { + if (!GC.reachable[ptr] && !GC.uncollectables[ptr]) { freeList.push(parseInt(ptr)); } } @@ -140,12 +144,17 @@ if (GC_SUPPORT) { GC_MALLOC__deps: ['$GC'], GC_MALLOC: function(bytes) { - return GC.malloc(bytes, true, true); + return GC.malloc(bytes, true, true, true); }, GC_MALLOC_ATOMIC__deps: ['$GC'], GC_MALLOC_ATOMIC: function(bytes) { - return GC.malloc(bytes, false, false); + return GC.malloc(bytes, false, false, true); + }, + + GC_MALLOC_UNCOLLECTABLE__deps: ['$GC'], + GC_MALLOC_UNCOLLECTABLE: function(bytes) { + return GC.malloc(bytes, true, true, false); }, GC_FREE__deps: ['$GC'], diff --git a/system/include/gc.h b/system/include/gc.h index e0419dcb..e4593c51 100644 --- a/system/include/gc.h +++ b/system/include/gc.h @@ -29,6 +29,9 @@ void *GC_MALLOC(int bytes); /* Allocate memory for an object that the user promises will not contain pointers. */ void *GC_MALLOC_ATOMIC(int bytes); +/* Allocate memory that might container pointers but that can't be collected. */ +void *GC_MALLOC_UNCOLLECTABLE(int bytes); + /* Explicitly deallocate an object. Dangerous as it forces a free and does not check if the object is reffed. */ void GC_FREE(void *ptr); diff --git a/tests/runner.py b/tests/runner.py index 06b74caa..6d1a3cba 100755 --- a/tests/runner.py +++ b/tests/runner.py @@ -7893,7 +7893,7 @@ def process(filename): int main() { GC_INIT(); - void *local, *local2, *local3, *local4; + void *local, *local2, *local3, *local4, *local5; // Hold on to global, drop locals @@ -7938,6 +7938,9 @@ def process(filename): GC_REGISTER_FINALIZER_NO_ORDER(local3, finalizer, (void*)3, 0, 0); local4 = GC_MALLOC(12); GC_REGISTER_FINALIZER_NO_ORDER(local4, finalizer, (void*)4, 0, 0); + local5 = GC_MALLOC_UNCOLLECTABLE(12); + // This should never trigger since local5 is uncollectable + GC_REGISTER_FINALIZER_NO_ORDER(local5, finalizer, (void*)5, 0, 0); void **globalData = (void**)global; globalData[0] = local; |