aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlon Zakai <alonzakai@gmail.com>2011-08-26 14:29:52 -0700
committerAlon Zakai <alonzakai@gmail.com>2011-08-26 14:29:52 -0700
commit67e4662ac91d5b514a96957d00b0a8db69bfcf65 (patch)
tree4231a8f7a2faa07c0ef627a7e88e71b9e9335cca
parent5b3b4c5ca4e10ce6ea22fb24ea429cb2c7dc213d (diff)
optimize generateStructTypes and flatten
-rw-r--r--src/parseTools.js33
-rw-r--r--src/utility.js28
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;
}