aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBruce Mitchener <bruce.mitchener@gmail.com>2013-02-01 01:24:59 +0700
committerBruce Mitchener <bruce.mitchener@gmail.com>2013-02-01 01:24:59 +0700
commit5105bc966c9ac893a86901658debc7b2572b82d5 (patch)
tree07baa0d1b6d1c5e2b23bbb8f2cecfbb950e510f7
parent7b129450d48a3552dc8189d96ef695db8cc9c15b (diff)
Add GC support for GC_MALLOC_UNCOLLECTABLE.
-rw-r--r--src/library_gc.js17
-rw-r--r--system/include/gc.h3
-rwxr-xr-xtests/runner.py5
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;