aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/parseTools.js47
-rw-r--r--src/preamble.js40
-rw-r--r--tests/runner.py4
3 files changed, 41 insertions, 50 deletions
diff --git a/src/parseTools.js b/src/parseTools.js
index 6c9494a6..6f71e75d 100644
--- a/src/parseTools.js
+++ b/src/parseTools.js
@@ -934,7 +934,7 @@ function makeSetValue(ptr, pos, value, type, noNeedFirst, ignore) {
}
}
-var UNROLL_LOOP_LIMIT = 8;
+var UNROLL_LOOP_MAX = 5;
function makeSetValues(ptr, pos, value, type, num) {
function safety(where) {
@@ -943,7 +943,7 @@ function makeSetValues(ptr, pos, value, type, num) {
}
if (USE_TYPED_ARRAYS in set(0, 1)) {
if (isNumber(num)) {
- if (num < UNROLL_LOOP_LIMIT) {
+ if (parseInt(num) <= UNROLL_LOOP_MAX) {
return range(num).map(function(i) {
return makeSetValue(ptr, getFastValue(pos, '+', i), value, type);
}).join('; ');
@@ -980,6 +980,8 @@ function makeSetValues(ptr, pos, value, type, num) {
}
}
+var TYPED_ARRAY_SET_MIN = Infinity; // .set() as memcpy seems to just slow us down
+
function makeCopyValues(dest, src, num, type, modifier) {
function safety(to, from) {
to = to || (dest + '+' + 'mcpi');
@@ -988,7 +990,7 @@ function makeCopyValues(dest, src, num, type, modifier) {
}
if (USE_TYPED_ARRAYS <= 1) {
if (isNumber(num)) {
- if (num < UNROLL_LOOP_LIMIT) {
+ if (parseInt(num) <= UNROLL_LOOP_MAX) {
return range(num).map(function(i) {
return type !== 'null' ? makeSetValue(dest, i, makeGetValue(src, i, type) + (modifier || ''), type)
: // Null is special-cased: We copy over all heaps
@@ -1012,34 +1014,45 @@ function makeCopyValues(dest, src, num, type, modifier) {
' HEAP[mcpi_d] = HEAP[mcpi_s];\n' +
'}';
} else { // USE_TYPED_ARRAYS == 1
+ if (isNumber(num) && parseInt(num) >= TYPED_ARRAY_SET_MIN) {
+ return 'IHEAP.set(IHEAP.subarray(' + src + ',' + src + '+' + num + '), ' + dest + '); ' +
+ 'FHEAP.set(FHEAP.subarray(' + src + ',' + src + '+' + num + '), ' + dest + ')';
+ }
return 'for (var mcpi_s=' + src + ',mcpi_e=' + src + '+' + num + ',mcpi_d=' + dest + '; mcpi_s<mcpi_e; mcpi_s++, mcpi_d++) {\n' +
' IHEAP[mcpi_d] = IHEAP[mcpi_s];' + (USE_FHEAP ? ' FHEAP[mcpi_d] = FHEAP[mcpi_s];' : '') + '\n' +
'}';
}
} else { // USE_TYPED_ARRAYS == 2
- return '' +
- 'var src, dest, stop, stop4, fast;\n' +
+ var ret = '' +
+ 'var src, dest, stop, stop4;\n' +
'src = ' + src + ';\n' +
'dest = ' + dest + ';\n' +
'stop = src + ' + num + ';\n' +
'if ((dest%4) == (src%4) && ' + num + ' > 8) {\n' +
' while (src%4 !== 0 && src < stop) {\n' +
' ' + safety('dest', 'src') + '; HEAP8[dest++] = HEAP8[src++];\n' +
- ' }\n' +
- ' src >>= 2;\n' +
- ' dest >>= 2;\n' +
- ' stop4 = stop >> 2;\n' +
- ' while (src < stop4) {\n' +
- safety('(dest<<2)+0', '(src<<2)+0') + ';' + safety('(dest<<2)+1', '(src<<2)+1') + ';' +
- safety('(dest<<2)+2', '(src<<2)+2') + ';' + safety('(dest<<2)+3', '(src<<2)+3') + (SAFE_HEAP ? ';\n' : '') +
- ' HEAP32[dest++] = HEAP32[src++];\n' + // this is the fast inner loop we try hard to stay in
- ' }\n' +
- ' src <<= 2;\n' +
- ' dest <<= 2;\n' +
- '}' +
+ ' }\n';
+ if (SAFE_HEAP || !(isNumber(num) && parseInt(num) >= TYPED_ARRAY_SET_MIN)) {
+ ret += ' src >>= 2;\n' +
+ ' dest >>= 2;\n' +
+ ' stop4 = stop >> 2;\n' +
+ ' while (src < stop4) {\n' +
+ safety('(dest<<2)+0', '(src<<2)+0') + ';' + safety('(dest<<2)+1', '(src<<2)+1') + ';' +
+ safety('(dest<<2)+2', '(src<<2)+2') + ';' + safety('(dest<<2)+3', '(src<<2)+3') + (SAFE_HEAP ? ';\n' : '') +
+ ' HEAP32[dest++] = HEAP32[src++];\n' +
+ ' }\n' +
+ ' src <<= 2;\n' +
+ ' dest <<= 2;\n';
+ } else {
+ ret += ' var src4 = src >> 2, stop4 = stop >> 2, num4 = (stop4 - src4) << 2;\n' +
+ ' HEAP32.set(HEAP32.subarray(src4, stop4), dest >> 2);\n' +
+ ' src += num4; dest += num4;\n';
+ }
+ ret += '}' +
'while (src < stop) {\n' +
' ' + safety('dest', 'src') + '; HEAP8[dest++] = HEAP8[src++];\n' +
'}';
+ return ret;
}
return null;
}
diff --git a/src/preamble.js b/src/preamble.js
index 45513942..7aa07cc1 100644
--- a/src/preamble.js
+++ b/src/preamble.js
@@ -537,18 +537,15 @@ var HEAP8, HEAPU8, HEAP16, HEAPU16, HEAP32, HEAPU32, HEAPF32;
var STACK_ROOT, STACKTOP, STACK_MAX;
var STATICTOP;
-var HAS_TYPED_ARRAYS = false;
var TOTAL_MEMORY = Module['TOTAL_MEMORY'] || {{{ TOTAL_MEMORY }}};
var FAST_MEMORY = Module['FAST_MEMORY'] || {{{ FAST_MEMORY }}};
// Initialize the runtime's memory
#if USE_TYPED_ARRAYS
-HAS_TYPED_ARRAYS = false;
-try {
- HAS_TYPED_ARRAYS = !!Int32Array && !!Float64Array && !!(new Int32Array(1)['subarray']); // check for full engine support (use string 'subarray' to avoid closure compiler confusion)
-} catch(e) {}
+// check for full engine support (use string 'subarray' to avoid closure compiler confusion)
+ assert(!!Int32Array && !!Float64Array && !!(new Int32Array(1)['subarray']) && !!(new Int32Array(1)['set']),
+ 'Cannot fallback to non-typed array case: Code is too specialized');
-if (HAS_TYPED_ARRAYS) {
#if USE_TYPED_ARRAYS == 1
HEAP = IHEAP = new Int32Array(TOTAL_MEMORY);
#if USE_FHEAP
@@ -569,24 +566,13 @@ if (HAS_TYPED_ARRAYS) {
HEAP32[0] = 255;
assert(HEAPU8[0] === 255 && HEAPU8[3] === 0, 'Typed arrays 2 must be run on a little-endian system');
#endif
-} else
-#endif
-{
+#else
// Make sure that our HEAP is implemented as a flat array.
HEAP = new Array(TOTAL_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
}
-#if USE_TYPED_ARRAYS == 1
- IHEAP = HEAP;
-#if USE_FHEAP
- FHEAP = HEAP;
-#endif
-#endif
-#if USE_TYPED_ARRAYS == 2
- abort('Cannot fallback to non-typed array case in USE_TYPED_ARRAYS == 2: Code is too specialized');
#endif
-}
var base = intArrayFromString('(null)'); // So printing %s of NULL gives '(null)'
// Also this ensures we leave 0 as an invalid address, 'NULL'
@@ -637,22 +623,14 @@ function __shutdownRuntime__() {
// Copies a list of num items on the HEAP into a
// a normal JavaScript array of numbers
function Array_copy(ptr, num) {
- // TODO: In the SAFE_HEAP case, do some reading here, for debugging purposes - currently this is an 'unnoticed read'.
#if USE_TYPED_ARRAYS == 1
- if (HAS_TYPED_ARRAYS) {
- return Array.prototype.slice.call(IHEAP.subarray(ptr, ptr+num)); // Make a normal array out of the typed 'view'
- // Consider making a typed array here, for speed?
- } else {
- return IHEAP.slice(ptr, ptr+num);
- }
+ // TODO: In the SAFE_HEAP case, do some reading here, for debugging purposes - currently this is an 'unnoticed read'.
+ return Array.prototype.slice.call(IHEAP.subarray(ptr, ptr+num)); // Make a normal array out of the typed 'view'
+ // Consider making a typed array here, for speed?
#endif
#if USE_TYPED_ARRAYS == 2
- if (HAS_TYPED_ARRAYS) {
- return Array.prototype.slice.call(HEAP8.subarray(ptr, ptr+num)); // Make a normal array out of the typed 'view'
- // Consider making a typed array here, for speed?
- } else {
- return HEAP8.slice(ptr, ptr+num);
- }
+ return Array.prototype.slice.call(HEAP8.subarray(ptr, ptr+num)); // Make a normal array out of the typed 'view'
+ // Consider making a typed array here, for speed?
#endif
return HEAP.slice(ptr, ptr+num);
}
diff --git a/tests/runner.py b/tests/runner.py
index 36226769..6ab84708 100644
--- a/tests/runner.py
+++ b/tests/runner.py
@@ -243,8 +243,8 @@ if 'benchmark' not in str(sys.argv):
# Run in both JavaScript engines, if optimizing - significant differences there (typed arrays)
if js_engines is None:
js_engines = [SPIDERMONKEY_ENGINE, V8_ENGINE]
- if Settings.USE_TYPED_ARRAYS == 2:
- js_engines = [SPIDERMONKEY_ENGINE] # when oh when will v8 support typed arrays in the console
+ if Settings.USE_TYPED_ARRAYS:
+ js_engines = [SPIDERMONKEY_ENGINE] # V8 issue 1822
js_engines = filter(lambda engine: os.path.exists(engine[0]), js_engines)
assert len(js_engines) > 0, 'No JS engine present to run this test with. Check ~/.emscripten and the paths therein.'
for engine in js_engines: