diff options
author | Alon Zakai <alonzakai@gmail.com> | 2011-08-26 14:29:52 -0700 |
---|---|---|
committer | Alon Zakai <alonzakai@gmail.com> | 2011-08-26 14:29:52 -0700 |
commit | 67e4662ac91d5b514a96957d00b0a8db69bfcf65 (patch) | |
tree | 4231a8f7a2faa07c0ef627a7e88e71b9e9335cca | |
parent | 5b3b4c5ca4e10ce6ea22fb24ea429cb2c7dc213d (diff) |
optimize generateStructTypes and flatten
-rw-r--r-- | src/parseTools.js | 33 | ||||
-rw-r--r-- | src/utility.js | 28 |
2 files changed, 44 insertions, 17 deletions
diff --git a/src/parseTools.js b/src/parseTools.js index 4b3e63e1..edf8384d 100644 --- a/src/parseTools.js +++ b/src/parseTools.js @@ -597,19 +597,32 @@ function calcAllocatedSize(type) { function generateStructTypes(type) { if (isArray(type)) return type; // already in the form of [type, type,...] if (Runtime.isNumberType(type) || isPointerType(type)) { - return [type];//.concat(zeros(getNativeFieldSize(type))); + return [type].concat(zeros(getNativeFieldSize(type))); } + + // Avoid multiple concats by finding the size first. This is much faster var typeData = Types.types[type]; - assert(typeData, 'invalid type in generateStructTypes: ' + type); - var fields = typeData.fields; - var ret = []; - for (var i = 0; i < fields.length; i++) { - ret = ret.concat(generateStructTypes(fields[i])); - if (i < fields.length-1) { - ret = ret.concat(zeros(typeData.flatIndexes[i+1] - ret.length)); + var size = typeData.flatSize; + var ret = new Array(size); + var index = 0; + function add(typeData) { + var start = index; + for (var i = 0; i < typeData.fields.length; i++) { + var type = typeData.fields[i]; + if (Runtime.isNumberType(type) || isPointerType(type)) { + ret[index++] = type; + } else { + add(Types.types[type]); + } + var more = (i+1 < typeData.fields.length ? typeData.flatIndexes[i+1] : typeData.flatSize) - (index - start); + for (var j = 0; j < more; j++) { + ret[index++] = 0; + } } } - return ret.concat(zeros(typeData.flatSize - ret.length)); + add(typeData); + assert(index == size); + return ret; } // Flow blocks @@ -891,7 +904,6 @@ function makePointer(slab, pos, allocator, type) { assert(type, 'makePointer requires type info'); if (slab.substr(0, 4) === 'HEAP' || (USE_TYPED_ARRAYS == 1 && slab in set('IHEAP', 'FHEAP'))) return pos; var types = generateStructTypes(type); - // compress type info and data if possible var de; try { @@ -915,7 +927,6 @@ function makePointer(slab, pos, allocator, type) { types = de[0]; } } - return 'allocate(' + slab + ', ' + JSON.stringify(types) + (allocator ? ', ' + allocator : '') + ')'; } diff --git a/src/utility.js b/src/utility.js index 7ab9e1ed..1b0a14f3 100644 --- a/src/utility.js +++ b/src/utility.js @@ -196,16 +196,32 @@ function isArray(x) { } } +// Flattens something like [5, 6, 'hi', [1, 'bye'], 44] into +// [5, 6, 'hi', 1, bye, 44]. function flatten(x) { - if (typeof x !== 'object') return x; - var ret = []; - for (var i = 0; i < x.length; i++) { - if (typeof x[i] === 'number') { - ret.push(x[i]); + if (typeof x !== 'object') return [x]; + // Avoid multiple concats by finding the size first. This is much faster + function getSize(y) { + if (typeof y !== 'object') { + return 1; } else { - ret = ret.concat(flatten(x[i])); + return sum(y.map(getSize)); + } + } + var size = getSize(x); + var ret = new Array(size); + var index = 0; + function add(y) { + for (var i = 0; i < y.length; i++) { + if (typeof y[i] !== 'object') { + ret[index++] = y[i]; + } else { + add(y[i]); + } } } + add(x); + assert(index == size); return ret; } |