generalize heap access generation with getHeapOffset
This commit is contained in:
Родитель
c5d4ba79fa
Коммит
5b2f181ab4
|
@ -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');
|
||||
|
|
|
@ -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: {
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче