aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authoralon@honor <none@none>2010-09-29 20:26:56 -0700
committeralon@honor <none@none>2010-09-29 20:26:56 -0700
commit335bd8e73d093b10c38036072186254531e8c099 (patch)
tree3615986bd0fe5aa3552fc8f8368c0b017bc05d1e /src
parent6cd9fc881bce4f51f5c548f12d6ec8f5b235aedf (diff)
clean up memory allocation
Diffstat (limited to 'src')
-rw-r--r--src/jsifier.js20
-rw-r--r--src/postamble.js8
-rw-r--r--src/preamble.js85
3 files changed, 60 insertions, 53 deletions
diff --git a/src/jsifier.js b/src/jsifier.js
index b84b2cf9..3fd6506a 100644
--- a/src/jsifier.js
+++ b/src/jsifier.js
@@ -19,13 +19,13 @@ function JSify(data) {
},
});
- function makePointer(slab, pos, stacked) {
+ function makePointer(slab, pos, allocator) {
// XXX hardcoded ptr impl
if (slab == 'HEAP') return pos;
if (slab[0] != '[') {
slab = '[' + slab + ']';
}
- return 'Pointer_make(' + slab + ', ' + (pos ? pos : 0) + (stacked ? ', true' : '') + ')';
+ return 'Pointer_make(' + slab + ', ' + (pos ? pos : 0) + (allocator ? ', ' + allocator : '') + ')';
}
function makeGetSlab(ptr) {
@@ -95,12 +95,12 @@ function JSify(data) {
function parseConst(value, type) {
dprint('gconst', '//yyyyy ' + JSON.stringify(value) + ',' + type + '\n');
if (isNumberType(type) || pointingLevels(type) == 1) {
- return makePointer(parseNumerical(value.text));
+ return makePointer(parseNumerical(value.text), null, 'ALLOC_UNFREEABLE');
} else if (value.text == 'zeroinitializer') {
- return makePointer(JSON.stringify(makeEmptyStruct(type)));
+ return makePointer(JSON.stringify(makeEmptyStruct(type)), null, 'ALLOC_UNFREEABLE');
} else if (value.text && value.text[0] == '"') {
value.text = value.text.substr(1, value.text.length-2);
- return makePointer(JSON.stringify(parseLLVMString(value.text)) + ' /* ' + value.text + '*/');
+ return makePointer(JSON.stringify(parseLLVMString(value.text)) + ' /* ' + value.text + '*/', null, 'ALLOC_UNFREEABLE');
} else {
// Gets an array of constant items, separated by ',' tokens
function handleSegments(tokens) {
@@ -136,12 +136,12 @@ function JSify(data) {
}
if (value.item) {
// list of items
- return makePointer('[ ' + alignStruct(handleSegments(value.item[0].tokens), type).join(', ') + ' ]');
+ return makePointer('[ ' + alignStruct(handleSegments(value.item[0].tokens), type).join(', ') + ' ]', null, 'ALLOC_UNFREEABLE');
} else if (value.type == '{') {
// struct
- return makePointer('[ ' + alignStruct(handleSegments(value.tokens), type).join(', ') + ' ]');
+ return makePointer('[ ' + alignStruct(handleSegments(value.tokens), type).join(', ') + ' ]', null, 'ALLOC_UNFREEABLE');
} else if (value[0]) {
- return makePointer('[ ' + alignStruct(handleSegments(value[0].tokens), type).join(', ') + ' ]');
+ return makePointer('[ ' + alignStruct(handleSegments(value[0].tokens), type).join(', ') + ' ]', null, 'ALLOC_UNFREEABLE');
} else {
throw '// failzzzzzzzzzzzzzz ' + dump(value.item) + ' ::: ' + dump(value);
}
@@ -512,9 +512,9 @@ function JSify(data) {
dprint('alloca', dump(item));
if (pointingLevels(item.allocatedType.text) == 0 && isStructType(item.allocatedType.text)) {
// TODO: allocate on a stack, not on the heap (we currently leak all this)
- return makePointer(JSON.stringify(makeEmptyStruct(item.allocatedType.text)), null, true);
+ return makePointer(JSON.stringify(makeEmptyStruct(item.allocatedType.text)), null, 'ALLOC_STACK');
} else {
- return makePointer('[0]', null, true);
+ return makePointer('[0]', null, 'ALLOC_STACK');
}
});
makeFuncLineZyme('phi', function(item) {
diff --git a/src/postamble.js b/src/postamble.js
index a34370b2..f47f3d42 100644
--- a/src/postamble.js
+++ b/src/postamble.js
@@ -2,19 +2,21 @@
// === Auto-generated postamble setup entry stuff ===
function run(args) {
+ __initializeRuntime__();
+
var argc = args.length+1;
function pad() {
for (var i = 0; i < QUANTUM_SIZE-1; i++) {
argv.push(0);
}
}
- var argv = [Pointer_make(intArrayFromString("/bin/this.program")) ];
+ var argv = [Pointer_make(intArrayFromString("/bin/this.program"), null, ALLOC_UNFREEABLE) ];
pad();
for (var i = 0; i < argc-1; i = i + 1) {
- argv.push(Pointer_make(intArrayFromString(args[i])));
+ argv.push(Pointer_make(intArrayFromString(args[i]), null, ALLOC_UNFREEABLE));
pad();
}
- argv = Pointer_make(argv);
+ argv = Pointer_make(argv, null, ALLOC_UNFREEABLE);
__globalConstructor__();
diff --git a/src/preamble.js b/src/preamble.js
index 467ac8e5..d61a8ce5 100644
--- a/src/preamble.js
+++ b/src/preamble.js
@@ -35,26 +35,22 @@ INDENT = '';
START_TIME = Date.now();
#endif
-function abort(text) {
- text = "ABORT: " + text;
- print(text + "\n");
-// print((new Error).stack); // for stack traces
- print("\n");
- throw text;
+function assert(condition, text) {
+ if (!condition) {
+ throw 'Assertion failed: ' + text + ':\n' + (new Error).stack;
+ }
}
function Pointer_niceify(ptr) {
-// XXX hardcoded ptr impl
return { slab: HEAP, pos: ptr };
-// if (!ptr.slab)
-// return { slab: ptr[0], pos: ptr[1] };
-// else
-// return ptr;
}
-function Pointer_make(slab, pos, stacked) {
+// Creates a pointer for a certain slab and a certain address in that slab.
+// If just a slab is given, will allocate room for it and copy it there. In
+// other words, do whatever is necessary in order to return a pointer, that
+// points to the slab (and possibly position) we are given.
+function Pointer_make(slab, pos, allocator) {
pos = pos ? pos : 0;
-// XXX hardcoded ptr impl
if (slab === HEAP) return pos;
// Flatten out - needed for global consts/vars
function flatten(slab) {
@@ -63,7 +59,7 @@ function Pointer_make(slab, pos, stacked) {
}
var slab = flatten(slab);
// Finalize
- var ret = (stacked ? stackAlloc : _malloc)(Math.max(slab.length - pos, 1));
+ var ret = [_malloc, stackAlloc, unfreeableMalloc][allocator ? allocator : ALLOC_UNFREEABLE](Math.max(slab.length - pos, 1));
for (var i = 0; i < slab.length - pos; i++) {
#if SAFE_HEAP
SAFE_HEAP_STORE(ret + i, slab[pos + i]);
@@ -72,7 +68,6 @@ function Pointer_make(slab, pos, stacked) {
#endif
}
return ret;
-// return { slab: slab, pos: pos ? pos : 0 };
}
function Pointer_stringify(ptr) {
@@ -92,6 +87,12 @@ function Pointer_stringify(ptr) {
return ret;
}
+// Memory management
+
+ALLOC_NORMAL = 0;
+ALLOC_STACK = 1;
+ALLOC_UNFREEABLE = 2;
+
// Stack allocation
function stackEnter() {
STACK_STACK.push(STACKTOP);
@@ -102,43 +103,47 @@ function stackExit() {
function stackAlloc(size) {
size = Math.ceil(size/QUANTUM_SIZE)*QUANTUM_SIZE; // Allocate blocks of proper minimum size
// Also keeps STACKTOP aligned
+ assert(STACKTOP + size < TOTAL_STACK);
var ret = STACKTOP;
STACKTOP += size;
return ret;
}
+function unfreeableMalloc(size) {
+ size = Math.ceil(size/1)*1; // Allocate blocks of proper minimum size
+ // Also keeps HEAPTOP aligned
+ var ret = HEAPTOP;
+ HEAPTOP += size;
+ return ret;
+}
+
+function unfreeableFree(ptr) {
+}
+
// If we don't have malloc/free implemented, use a simple implementation. This
// allows compiled C/C++ to implement its own malloc/free
if (!this._malloc) {
- _malloc = function(size) {
- size = Math.ceil(size/QUANTUM_SIZE)*QUANTUM_SIZE; // Allocate blocks of proper minimum size
- // Also keeps HEAPTOP aligned
- var ret = HEAPTOP;
- HEAPTOP += size;
- return ret;
- }
-
- _free = function(ptr) {
- // XXX TODO - actual implementation! Currently we leak it all
- }
+ _malloc = unfreeableMalloc;
+ _free = unfreeableFree;
}
+
// Mangled "new"s... need a heuristic for autogeneration...
-__Znwj = _malloc; // gcc
-__Znaj = _malloc; // gcc
+__Znwj = _malloc; // llvm-gcc
+__Znaj = _malloc; // llvm-gcc
__Znam = _malloc; // clang
__Znwm = _malloc; // clang
// Mangled "delete"s... need a heuristic for autogeneration...
-__ZdlPv = _free; // gcc
-__ZdaPv = _free; // gcc
-
-var HEAP = [];
-var HEAPTOP = 0;
-Pointer_make(intArrayFromString('(null)')); // So printing %s of NULL gives '(null)'
- // Also this ensures we leave 0 as an invalid address, 'NULL'
-STACK_STACK = [];
-STACKTOP = HEAPTOP;
-TOTAL_STACK = 64*1024; // Reserved room for stack
-HEAPTOP += TOTAL_STACK;
+__ZdlPv = _free; // llvm-gcc
+__ZdaPv = _free; // llvm-gcc
+
+function __initializeRuntime__() {
+ HEAP = intArrayFromString('(null)'); // So printing %s of NULL gives '(null)'
+ // Also this ensures we leave 0 as an invalid address, 'NULL'
+ TOTAL_STACK = 64*1024; // Reserved room for stack
+ STACK_STACK = [];
+ STACKTOP = HEAP.length;
+ HEAPTOP = STACKTOP + TOTAL_STACK;
+}
// stdio.h
@@ -179,7 +184,7 @@ function __formatString() {
textIndex += 1;
}
}
- return Pointer_make(ret);
+ return Pointer_make(ret); // Leak!
}
// Copies a list of num items on the HEAP into a