diff options
author | Alon Zakai <alonzakai@gmail.com> | 2011-06-05 11:49:17 -0700 |
---|---|---|
committer | Alon Zakai <alonzakai@gmail.com> | 2011-06-05 11:49:17 -0700 |
commit | 5b2f181ab4662dca21f3605aeca8c2e0cd212b20 (patch) | |
tree | a29f4d3ec44c0ed99d8858e530b6eb6ba67f6429 | |
parent | c5d4ba79fab0ad46dec71eaa8c4c1d47cca169ee (diff) |
generalize heap access generation with getHeapOffset
-rw-r--r-- | src/compiler.js | 5 | ||||
-rw-r--r-- | src/parseTools.js | 20 | ||||
-rw-r--r-- | src/preamble.js | 41 |
3 files changed, 45 insertions, 21 deletions
diff --git a/src/compiler.js b/src/compiler.js index bdfdbba8..e5e8a755 100644 --- a/src/compiler.js +++ b/src/compiler.js @@ -25,6 +25,7 @@ var settings = JSON.parse(readline()); for (setting in settings) { this[setting] = settings[setting]; } + var CONSTANTS = { 'QUANTUM_SIZE': QUANTUM_SIZE }; if (CORRECT_SIGNS >= 2) { @@ -42,6 +43,10 @@ if (SAFE_HEAP >= 2) { EXPORTED_FUNCTIONS = set(EXPORTED_FUNCTIONS); +// Settings sanity checks + +assert(!(USE_TYPED_ARRAYS === 2 && QUANTUM_SIZE !== 4), 'For USE_TYPED_ARRAYS == 2, must have normal QUANTUM_SIZE of 4'); + // Load compiler code load('framework.js'); diff --git a/src/parseTools.js b/src/parseTools.js index 6ae0e5d3..5813c908 100644 --- a/src/parseTools.js +++ b/src/parseTools.js @@ -660,6 +660,18 @@ function checkSafeHeap() { } +function getHeapOffset(offset, type) { + if (USE_TYPED_ARRAYS !== 2) { + return offset; + } else { + if (getNativeFieldSize(type) > 4) { + dprint(type + ' has size > 4, which means we cannot be guaranteed to load it aligned! For now, USE_TYPED_ARRAYS==2 cannot handle that.'); + return 'abort("size > 4, alignment issues with USE_TYPED_ARRAYS==2")'; + } + return '((' + offset + ')>>' + (Math.log(getNativeFieldSize(type, true))/Math.LN2) + ')'; + } +} + // See makeSetValue function makeGetValue(ptr, pos, type, noNeedFirst) { if (isStructType(type)) { @@ -677,7 +689,7 @@ function makeGetValue(ptr, pos, type, noNeedFirst) { if (type[0] === '#') type = type.substr(1); return 'SAFE_HEAP_LOAD(' + offset + ', ' + type + ', ' + !checkSafeHeap() + ')'; } else { - return makeGetSlabs(ptr, type)[0] + '[' + offset + ']'; + return makeGetSlabs(ptr, type)[0] + '[' + getHeapOffset(offset, type) + ']'; } } @@ -721,13 +733,13 @@ function makeSetValue(ptr, pos, value, type, noNeedFirst, ignore) { if (type[0] === '#') type = type.substr(1); return 'SAFE_HEAP_STORE(' + offset + ', ' + value + ', ' + type + ', ' + ((!checkSafeHeap() || ignore)|0) + ');'; } else { - return makeGetSlabs(ptr, type, true).map(function(slab) { return slab + '[' + offset + ']=' + value }).join('; ') + ';'; + return makeGetSlabs(ptr, type, true).map(function(slab) { return slab + '[' + getHeapOffset(offset, type) + ']=' + value }).join('; ') + ';'; } } function makeSetValues(ptr, pos, value, type, num) { function safety() { - return ';' + (SAFE_HEAP ? 'SAFE_HEAP_ACCESS(' + dest + '+$mcpi$, ' + type + ', 1)' : ''); + return ';' + (SAFE_HEAP ? 'SAFE_HEAP_ACCESS(' + getFastValue(ptr, '+', pos) + '+$mspi$, ' + type + ', 1)' : ''); } if (USE_TYPED_ARRAYS in set(0, 1)) { return 'for (var $mspi$ = 0; $mspi$ < ' + num + '; $mspi$++) {\n' + @@ -868,7 +880,7 @@ function makeGetSlabs(ptr, type, allowMultiple) { case 'i8': return ['HEAP8']; break; case 'i16': return ['HEAP16']; break; case 'i32': return ['HEAP32']; break; - case 'i64': return ['HEAP64']; break; + case 'i64': return ['abort("No HEAP64")']; break; case 'float': return ['HEAPF32']; break; case 'double': return ['HEAPF64']; break; default: { diff --git a/src/preamble.js b/src/preamble.js index 9314f192..dd7f9f3e 100644 --- a/src/preamble.js +++ b/src/preamble.js @@ -72,13 +72,14 @@ function SAFE_HEAP_STORE(dest, value, type, ignore) { #else #if USE_TYPED_ARRAYS == 2 assert(type != 'null', 'typed arrays 2 with null type!'); + if (type[type.length-1] === '*') type = 'i32'; // hardcoded pointers as 32-bit switch(type) { case 'i8': HEAP8[dest] = value; break; - case 'i16': HEAP16[dest] = value; break; - case 'i32': HEAP32[dest] = value; break; - case 'i64': HEAP64[dest] = value; break; - case 'float': HEAPF32[dest] = value; break; - case 'double': HEAPF64[dest] = value; break; + case 'i16': HEAP16[dest>>1] = value; break; + case 'i32': HEAP32[dest>>2] = value; break; + case 'i64': abort('no HEAP64'); break; + case 'float': HEAPF32[dest>>2] = value; break; + case 'double': HEAPF64[dest>>3] = value; break; default: throw 'weird type for typed array II: ' + type + new Error().stack; } #else @@ -97,13 +98,14 @@ function SAFE_HEAP_LOAD(dest, type, ignore) { } #else #if USE_TYPED_ARRAYS == 2 + if (type[type.length-1] === '*') type = 'i32'; // hardcoded pointers as 32-bit switch(type) { case 'i8': return HEAP8[dest]; break; - case 'i16': return HEAP16[dest]; break; - case 'i32': return HEAP32[dest]; break; - case 'i64': return HEAP64[dest]; break; - case 'float': return HEAPF32[dest]; break; - case 'double': return HEAPF64[dest]; break; + case 'i16': return HEAP16[dest>>1]; break; + case 'i32': return HEAP32[dest>>2]; break; + case 'i64': abort('no HEAP64'); break; + case 'float': return HEAPF32[dest>>2]; break; + case 'double': return HEAPF64[dest>>3]; break; default: throw 'weird type for typed array II: ' + type; } return null; @@ -293,7 +295,10 @@ function Pointer_make(slab, pos, allocator, types) { assert(type, 'Must know what type to store in Pointer_make!'); #endif - if (type === 'i8') { + if (type === 'i1') { + {{{ makeSetValue(0, 'ret+i', 'curr', 'i1') }}} + i += {{{ getNativeFieldSize('i1', true) }}}; + } else if (type === 'i8') { {{{ makeSetValue(0, 'ret+i', 'curr', 'i8') }}} i += {{{ getNativeFieldSize('i8', true) }}}; } else if (type === 'i16') { @@ -302,16 +307,18 @@ function Pointer_make(slab, pos, allocator, types) { } 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 === 'i64') { + {{{ makeSetValue(0, 'ret+i', 'curr', 'i64') }}} + i += {{{ getNativeFieldSize('i64', true) }}}; } else if (type === 'double') { {{{ makeSetValue(0, 'ret+i', 'curr', 'double') }}} i += {{{ getNativeFieldSize('double', true) }}}; - } else throw 'invalid type for Pointer_make: ' + type; + } else { + abort('invalid type for Pointer_make: ' + type); + } } return ret; @@ -379,13 +386,13 @@ function __initializeRuntime__() { var FAST_MEMORY = TOTAL_MEMORY/32; HEAP = new Array(FAST_MEMORY); for (var i = 0; i < FAST_MEMORY; i++) { - HEAP[i] = 0; // XXX We do *not* use {{{ makeSetValue(0, 'i', 0, 'null') }}} here, since this is done just to optimize runtime speed + HEAP[i] = 0; // XXX We do *not* use {{| makeSetValue(0, 'i', 0, 'null') |}} here, since this is done just to optimize runtime speed } #if USE_TYPED_ARRAYS == 1 IHEAP = FHEAP = HEAP; #endif #if USE_TYPED_ARRAYS == 2 - HEAP8 = HEAP16 = HEAP32 = HEAPF32 = HEAPF64 = HEAP; + abort('Cannot fallback to non-typed array case in USE_TYPED_ARRAYS == 2: Code is too specialized'); #endif } |