Skip to content

Commit

Permalink
optimize Pointer_make (both input size and processing time)
Browse files Browse the repository at this point in the history
  • Loading branch information
kripken committed Jun 5, 2011
1 parent 304221e commit c5d4ba7
Show file tree
Hide file tree
Showing 3 changed files with 67 additions and 19 deletions.
2 changes: 1 addition & 1 deletion src/library.js
Original file line number Diff line number Diff line change
Expand Up @@ -900,7 +900,7 @@ var Library = {
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0
];
me.ret = Pointer_make([Pointer_make(values, 0, ALLOC_STATIC, 'void*')+256], 0, ALLOC_STATIC, 'i16');
me.ret = Pointer_make([Pointer_make(values, 0, ALLOC_STATIC, 'i16')+256], 0, ALLOC_STATIC, 'void*');
#if USE_TYPED_ARRAYS == 0
assert(HEAP[HEAP[me.ret]] == 2);
assert(HEAP[HEAP[me.ret]-2] == 0);
Expand Down
28 changes: 26 additions & 2 deletions src/parseTools.js
Original file line number Diff line number Diff line change
Expand Up @@ -585,7 +585,7 @@ function generateStructTypes(type) {
ret = ret.concat(zeros(typeData.flatIndexes[i+1] - ret.length));
}
}
return ret;
return ret.concat(zeros(typeData.flatSize - ret.length));
}

// Flow blocks
Expand Down Expand Up @@ -819,7 +819,31 @@ 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);
if (dedup(types).length === 1) types = types[0];

// compress type info and data if possible
var de;
try {
// compress all-zeros into a number (which will become zeros(..)).
// note that we cannot always eval the slab, e.g., if it contains ident,0,0 etc. In that case, no compression TODO: ensure we get arrays here, not str
var evaled = typeof slab === 'string' ? eval(slab) : slab;
de = dedup(evaled);
if (de.length === 1 && de[0] === 0) {
slab = evaled.length;
}
// TODO: if not all zeros, at least filter out items with type === 0. requires cleverness to know how to skip at runtime though. also
// be careful of structure padding
} catch(e){}
de = dedup(types);
if (de.length === 1) {
types = de[0];
} else if (de.length === 2 && typeof slab === 'number') {
// If slab is all zeros, we can compress types even if we have i32,0,0,0,i32,0,0,0 etc. - we do not need the zeros
de = de.filter(function(x) { return x !== 0 });
if (de.length === 1) {
types = de[0];
}
}

return 'Pointer_make(' + slab + ', ' + (pos ? pos : 0) + (allocator ? ', ' + allocator : '') + ', ' +
JSON.stringify(types) +
')';
Expand Down
56 changes: 40 additions & 16 deletions src/preamble.js
Original file line number Diff line number Diff line change
Expand Up @@ -262,32 +262,56 @@ function Pointer_make(slab, pos, allocator, types) {
pos = pos ? pos : 0;
assert(pos === 0); // TODO: remove 'pos'
if (slab === HEAP) return pos;
var size = slab.length;

var i;
#if ASSERTIONS
for (i = 0; i < size; i++) {
if (slab[i] === undefined) {
throw 'Invalid element in slab at ' + new Error().stack; // This can be caught, and you can try again to allocate later, see globalFuncs in run()
}
var zeroinit, size;
if (typeof slab === 'number') {
zeroinit = true;
size = slab;
} else {
zeroinit = false;
size = slab.length;
}
#endif

// Finalize
var ret = [_malloc, Runtime.stackAlloc, Runtime.staticAlloc][allocator ? allocator : ALLOC_STATIC](Math.max(size, 1));

var type = typeof types === 'string' ? types : null;
var singleType = typeof types === 'string' ? types : null;

for (i = 0; i < size; i++) {
var curr = slab[i];
var i = 0, type;
while (i < size) {
var curr = zeroinit ? 0 : slab[i];

if (typeof curr === 'function') {
curr = Runtime.getFunctionIndex(curr);
}

if (type || types[i]) {
{{{ makeSetValue(0, 'ret+i', 'curr', '#type || types[i]') }}}
type = singleType || types[i];
if (type === 0) {
i++;
continue;
}
#if ASSERTIONS
assert(type, 'Must know what type to store in Pointer_make!');
#endif

if (type === 'i8') {
{{{ makeSetValue(0, 'ret+i', 'curr', 'i8') }}}
i += {{{ getNativeFieldSize('i8', true) }}};
} else if (type === 'i16') {
{{{ makeSetValue(0, 'ret+i', 'curr', 'i16') }}}
i += {{{ getNativeFieldSize('i16', true) }}};
} else if (type === 'i32' || type[type.length-1] === '*') { // hardcoded pointers as 32-bit
{{{ makeSetValue(0, 'ret+i', 'curr', 'i32') }}}
i += {{{ getNativeFieldSize('i32', true) }}};
} else if (type === 'i64') {
{{{ makeSetValue(0, 'ret+i', 'curr', 'i64') }}}
i += {{{ getNativeFieldSize('i64', true) }}};
} else if (type === 'float') {
{{{ makeSetValue(0, 'ret+i', 'curr', 'float') }}}
i += {{{ getNativeFieldSize('float', true) }}};
} else if (type === 'double') {
{{{ makeSetValue(0, 'ret+i', 'curr', 'double') }}}
i += {{{ getNativeFieldSize('double', true) }}};
} else throw 'invalid type for Pointer_make: ' + type;
}

return ret;
Expand Down Expand Up @@ -488,8 +512,8 @@ function intArrayToString(array) {
return ret;
}

var unSign = {{{ unSign.toString() }}}
var reSign = {{{ reSign.toString() }}}
{{{ unSign }}}
{{{ reSign }}}

// Use console read if available, otherwise we are in a browser, use an XHR
if (!this['read']) {
Expand Down

0 comments on commit c5d4ba7

Please sign in to comment.