diff options
author | Alon Zakai <azakai@mozilla.com> | 2010-11-14 20:41:20 -0800 |
---|---|---|
committer | Alon Zakai <azakai@mozilla.com> | 2010-11-14 20:41:20 -0800 |
commit | 1a9c1c95c6552f835f53493299e90a9f6743c6f7 (patch) | |
tree | d75ff3e44c704b1ecbf9f9dc3777e4b017b22073 /src | |
parent | 9e467f4b1d113315bd18aad25af8ccac4ace077c (diff) |
optimize Pointer_make
Diffstat (limited to 'src')
-rw-r--r-- | src/preamble.js | 58 | ||||
-rw-r--r-- | src/settings.js | 3 |
2 files changed, 51 insertions, 10 deletions
diff --git a/src/preamble.js b/src/preamble.js index 8a42243a..439e0e41 100644 --- a/src/preamble.js +++ b/src/preamble.js @@ -66,18 +66,54 @@ var ALLOC_STATIC = 2; // Cannot be freed function Pointer_make(slab, pos, allocator) { pos = pos ? pos : 0; + assert(pos === 0); // TODO: remove 'pos' if (slab === HEAP) return pos; - // Flatten out - needed for global consts/vars - function flatten(slab) { - if (!slab || slab.length === undefined || typeof slab === 'function') return [slab]; - return slab.map(flatten).reduce(function(a,b) { return a.concat(b) }, []); + var size = 0; + + // The slab may contain arrays, which we basically need to 'flatten' out + // into one long slab. We do that by traversing it, and not by creating + // a new slab, to save time and memory + var stack = [[slab, 0]], top, curr; + while(1) { + top = stack[stack.length-1]; + if (top[1] >= top[0].length) { + stack.pop(); + if (stack.length === 0) break; + top = stack[stack.length-1]; + top[1]++; + continue; + } + var curr = top[0][top[1]]; + if (curr === undefined) + throw 'Invalid element in slab'; // This can be caught, and you can try again to allocate later, see globalFuncs in run() + if (curr.length) { + stack.push([curr,0]); + continue; + } + size++; + top[1]++; } - var slab = flatten(slab); + // Finalize - var ret = [_malloc, Runtime.stackAlloc, Runtime.staticAlloc][allocator ? allocator : ALLOC_STATIC](Math.max(slab.length - pos, 1)); - for (var i = 0; i < slab.length - pos; i++) { - var curr = slab[pos + i]; - if (curr === undefined) throw 'Invalid element in slab'; // This can be caught, and you can try again to allocate later, see globalFuncs in run() + var ret = [_malloc, Runtime.stackAlloc, Runtime.staticAlloc][allocator ? allocator : ALLOC_STATIC](Math.max(size, 1)); + + stack = [[slab, 0]]; + var i = 0; + while(1) { + top = stack[stack.length-1]; + if (top[1] >= top[0].length) { + stack.pop(); + if (stack.length === 0) break; + top = stack[stack.length-1]; + top[1]++; + continue; + } + var curr = top[0][top[1]]; + if (curr.length) { + stack.push([curr,0]); + continue; + } + if (typeof curr === 'function') { curr = Runtime.getFunctionIndex(curr); } @@ -96,7 +132,11 @@ function Pointer_make(slab, pos, allocator) { HEAP[ret + i] = curr; #endif #endif + + top[1]++; + i++; } + return ret; } diff --git a/src/settings.js b/src/settings.js index aaaee344..95012abc 100644 --- a/src/settings.js +++ b/src/settings.js @@ -34,10 +34,11 @@ EXCEPTION_DEBUG = 1; // Print out exceptions in emscriptened code EXECUTION_TIMEOUT = -1; // Throw an exception after X seconds - useful to debug infinite loops // Compiler debugging options -DEBUG_TAGS_SHOWING = ['unparsedFunctions']; +DEBUG_TAGS_SHOWING = []; // Some useful items: // enzymatic // gconst // types // relooping + // unparsedFunctions |