diff options
author | alon@honor <none@none> | 2010-09-29 20:26:56 -0700 |
---|---|---|
committer | alon@honor <none@none> | 2010-09-29 20:26:56 -0700 |
commit | 335bd8e73d093b10c38036072186254531e8c099 (patch) | |
tree | 3615986bd0fe5aa3552fc8f8368c0b017bc05d1e | |
parent | 6cd9fc881bce4f51f5c548f12d6ec8f5b235aedf (diff) |
clean up memory allocation
-rw-r--r-- | src/jsifier.js | 20 | ||||
-rw-r--r-- | src/postamble.js | 8 | ||||
-rw-r--r-- | src/preamble.js | 85 |
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 |