diff options
-rw-r--r-- | src/compiler.js | 4 | ||||
-rw-r--r-- | src/jsifier.js | 82 | ||||
-rw-r--r-- | src/library.js | 35 | ||||
-rw-r--r-- | src/parseTools.js | 39 | ||||
-rw-r--r-- | src/postamble.js | 6 | ||||
-rw-r--r-- | src/preamble.js | 70 | ||||
-rw-r--r-- | src/settings.js | 1 | ||||
-rw-r--r-- | tests/runner.py | 72 | ||||
-rw-r--r-- | tests/settings.py | 13 |
9 files changed, 227 insertions, 95 deletions
diff --git a/src/compiler.js b/src/compiler.js index ba36f215..13b2d3cc 100644 --- a/src/compiler.js +++ b/src/compiler.js @@ -29,6 +29,10 @@ for (setting in settings) { this[setting] = settings[setting]; } +// Sanity of settings + +assert(!(USE_TYPED_ARRAYS && SAFE_HEAP)); + // Read llvm var lines = []; var line; diff --git a/src/jsifier.js b/src/jsifier.js index bcc436a4..547bde72 100644 --- a/src/jsifier.js +++ b/src/jsifier.js @@ -4,6 +4,10 @@ function JSify(data) { substrate = new Substrate('JSifyer'); var TYPES = data.types; + var FUNCTIONS = {}; + data.functions.forEach(function(func) { + FUNCTIONS[func.ident] = func; + }); // type substrate.addZyme('Type', { @@ -20,20 +24,29 @@ function JSify(data) { }); function makePointer(slab, pos, allocator, type) { // type is FFU - if (slab == 'HEAP') return pos; + if (slab in set('HEAP', 'IHEAP', 'FHEAP')) return pos; if (slab[0] != '[') { slab = '[' + slab + ']'; } return 'Pointer_make(' + slab + ', ' + (pos ? pos : 0) + (allocator ? ', ' + allocator : '') + ')'; } - function makeGetSlab(ptr) { - // return ptr + '.slab'; - return 'HEAP'; + function makeGetSlab(ptr, type) { + assert(type); + if (!USE_TYPED_ARRAYS) { + return 'HEAP'; + } else { + if (type in FLOAT_TYPES || type === 'int64') { + return 'FHEAP'; + } else if (type in INT_TYPES || isPointerType(type)) { + return 'IHEAP'; + } else { + return 'HEAP'; + } + } } function makeGetPos(ptr) { - // return ptr + '.pos'; return ptr; } @@ -43,15 +56,23 @@ function JSify(data) { } function makeGetValue(ptr, pos, noNeedFirst, type) { - return makeGetSlab(ptr) + '[' + calcFastOffset(ptr, pos, noNeedFirst) + ']'; + return makeGetSlab(ptr, type) + '[' + calcFastOffset(ptr, pos, noNeedFirst) + ']'; + } + + function indexizeFunctions(value) { // TODO: Also check for other functions (externals, library, etc.) + if (value in FUNCTIONS) { + value = value + '.__index__'; // Store integer value + } + return value; } function makeSetValue(ptr, pos, value, noNeedFirst, type) { + value = indexizeFunctions(value); var offset = calcFastOffset(ptr, pos, noNeedFirst); if (SAFE_HEAP) { return 'SAFE_HEAP_STORE(' + offset + ', ' + value + ')'; } else { - return makeGetSlab(ptr) + '[' + offset + '] = ' + value; + return makeGetSlab(ptr, type) + '[' + offset + '] = ' + value; } } @@ -135,7 +156,7 @@ function JSify(data) { throw 'Invalid segment: ' + dump(segment); } }; - return splitTokenList(tokens).map(handleSegment).map(parseNumerical); + return splitTokenList(tokens).map(handleSegment).map(parseNumerical).map(indexizeFunctions); } if (value.item) { // list of items @@ -206,6 +227,17 @@ function JSify(data) { this.forwardItems(ret, 'FuncLineTriager'); }, }); + + var FUNCTION_INDEX = 0; + var FUNCTION_HASH = {}; + function getFunctionIndex(name_) { + if (!(name_ in FUNCTION_HASH)) { + FUNCTION_HASH[name_] = FUNCTION_INDEX; + FUNCTION_INDEX++; + } + return FUNCTION_HASH[name_]; + } + // function reconstructor & post-JS optimizer substrate.addZyme('FunctionReconstructor', { funcs: {}, @@ -339,14 +371,21 @@ function JSify(data) { // Finalize function if (LABEL_DEBUG) func.JS += " INDENT = INDENT.substr(0, INDENT.length-2);\n"; func.JS += '}\n'; + func.JS += func.ident + '.__index__ = ' + getFunctionIndex(func.ident) + ';\n'; + func.JS += 'FUNCTION_TABLE[' + getFunctionIndex(func.ident) + '] = ' + func.ident + ';\n'; func.__result__ = true; return func; }, }); - function getVarData(funcData, ident) { - if (funcData.variables[ident]) { - return funcData.variables[ident].impl; + function getVarData(funcData, ident) { // XXX - need to check globals as well! + return funcData.variables[ident]; + } + + function getVarImpl(funcData, ident) { + var data = getVarData(funcData, ident); + if (data) { + return data.impl; } else { return 'emulated'; // All global are emulated } @@ -383,7 +422,7 @@ function JSify(data) { var type = item.value.type; var value = parseNumerical(item.value.JS); //print("zz var: " + item.JS); - var impl = getVarData(item.funcData, item.ident); + var impl = getVarImpl(item.funcData, item.ident); switch (impl) { case VAR_NATIVE: { break; @@ -422,7 +461,7 @@ function JSify(data) { } var impl = VAR_EMULATED; if (item.pointer.intertype == 'value') { - impl = getVarData(item.funcData, item.ident); + impl = getVarImpl(item.funcData, item.ident); } switch (impl) { case VAR_NATIVIZED: @@ -537,7 +576,7 @@ function JSify(data) { }); makeFuncLineZyme('load', function(item) { var ident = toNiceIdent(item.ident); - var impl = getVarData(item.funcData, item.ident); + var impl = getVarImpl(item.funcData, item.ident); switch (impl) { case VAR_NATIVIZED: { return ident; // We have the actual value here @@ -721,7 +760,7 @@ function JSify(data) { function finalizeLLVMFunctionCall(item) { switch(item.intertype) { case 'getelementptr': - return makePointer(makeGetSlab(item.ident), getGetElementPtrIndexes(item), null, item.type); + return makePointer(makeGetSlab(item.ident, item.type), getGetElementPtrIndexes(item), null, item.type); case 'bitcast': case 'inttoptr': case 'ptrtoint': @@ -747,7 +786,7 @@ function JSify(data) { return ident; }); - function makeFunctionCall(ident, params) { + function makeFunctionCall(ident, params, funcData) { // Special cases if (ident == '_llvm_va_start') { var args = 'Array.prototype.slice.call(arguments, __numArgs__)'; @@ -755,7 +794,7 @@ function JSify(data) { if (SAFE_HEAP) { return 'SAFE_HEAP_STORE(' + params[0].ident + ', ' + data + ', 0)'; } else { - return 'HEAP[' + params[0].ident + '] = ' + data; + return 'IHEAP[' + params[0].ident + '] = ' + data; } } else if (ident == '_llvm_va_end') { return ';' @@ -767,12 +806,17 @@ function JSify(data) { } else { return toNiceIdent(param.ident); } - }); + }).map(indexizeFunctions); + + if (funcData && getVarData(funcData, ident)) { + ident = 'FUNCTION_TABLE[' + ident + ']'; + } + return ident + '(' + params.join(', ') + ')'; } makeFuncLineZyme('getelementptr', function(item) { return finalizeLLVMFunctionCall(item) }); makeFuncLineZyme('call', function(item) { - return makeFunctionCall(item.ident, item.params) + (item.standalone ? ';' : ''); + return makeFunctionCall(item.ident, item.params, item.funcData) + (item.standalone ? ';' : ''); }); // Optimzed intertypes diff --git a/src/library.js b/src/library.js index 09c4d8f1..0663d6c1 100644 --- a/src/library.js +++ b/src/library.js @@ -19,11 +19,11 @@ var Library = { }, vsnprintf: function(dst, num, src, ptr) { - var args = Array_copy(ptr+1, HEAP[ptr]); // # of args in in first place + var args = Array_copy(ptr+1, IHEAP[ptr]); // # of args in in first place var text = __formatString.apply(null, [src].concat(args)); for (var i = 0; i < num; i++) { - HEAP[dst+i] = HEAP[text+i]; - if (HEAP[dst+i] == 0) break; + IHEAP[dst+i] = IHEAP[text+i]; + if (IHEAP[dst+i] == 0) break; } }, @@ -42,7 +42,7 @@ var Library = { strlen: function(p) { var q = p; - while (HEAP[q] != 0) q++; + while (IHEAP[q] != 0) q++; return q - p; }, @@ -65,22 +65,22 @@ var Library = { strcpy: function(pdest, psrc) { var i = 0; do { - HEAP[pdest+i] = HEAP[psrc+i]; + IHEAP[pdest+i] = IHEAP[psrc+i]; i ++; - } while (HEAP[psrc+i-1] != 0); + } while (IHEAP[psrc+i-1] != 0); }, strncpy: function(pdest, psrc, num) { var padding = false; for (var i = 0; i < num; i++) { - HEAP[pdest+i] = padding ? 0 : HEAP[psrc+i]; - padding = padding || HEAP[psrc+i] == 0; + IHEAP[pdest+i] = padding ? 0 : IHEAP[psrc+i]; + padding = padding || IHEAP[psrc+i] == 0; } }, strlen: function(ptr) { var i = 0; - while (HEAP[ptr+i] != 0) i++; + while (IHEAP[ptr+i] != 0) i++; return i; }, @@ -88,9 +88,9 @@ var Library = { var len = Pointer_stringify(pdest).length; // TODO: use strlen, but need dependencies system var i = 0; do { - HEAP[pdest+len+i] = HEAP[psrc+i]; + IHEAP[pdest+len+i] = IHEAP[psrc+i]; i ++; - } while (HEAP[psrc+i-1] != 0); + } while (IHEAP[psrc+i-1] != 0); }, strtol: function(ptr) { @@ -101,8 +101,8 @@ var Library = { strcmp: function(px, py) { var i = 0; while (true) { - var x = HEAP[px+i]; - var y = HEAP[py+i]; + var x = IHEAP[px+i]; + var y = IHEAP[py+i]; if (x == y && x == 0) return 0; if (x == 0) return -1; if (y == 0) return 1; @@ -132,13 +132,6 @@ var Library = { return 0; }, - llvm_memset_i32: function(ptr, value, num) { - for (var i = 0; i < num; i++) { - HEAP[ptr+i] = value; - } - }, - llvm_memset_p0i8_i32: 'llvm_memset_i32', - llvm_eh_exception: function() { return 'code-generated exception: ' + (new Error().stack); }, @@ -229,7 +222,7 @@ var Library = { time: function(ptr) { var ret = Math.floor(Date.now()/1000); if (ptr) { - HEAP[ptr] = ret; + IHEAP[ptr] = ret; } return ret; }, diff --git a/src/parseTools.js b/src/parseTools.js index c4dae65e..4d1ed438 100644 --- a/src/parseTools.js +++ b/src/parseTools.js @@ -8,26 +8,27 @@ function preprocess(text, constants) { } var lines = text.split('\n'); var ret = ''; - var show = true; + var showStack = []; for (var i = 0; i < lines.length; i++) { var line = lines[i]; if (line[0] != '#') { - if (show) { + if (showStack.indexOf(false) == -1) { ret += line + '\n'; } } else { if (line[1] == 'i') { // if var ident = line.substr(4); - show = !!this[ident] && this[ident] > 0; + showStack.push(!!this[ident] && this[ident] > 0); } else if (line[2] == 'l') { // else - show = !show; + showStack.push(!showStack.pop()); } else if (line[2] == 'n') { // endif - show = true; + showStack.pop(); } else { throw "Unclear preprocessor command: " + line; } } } + assert(showStack.length == 0); return ret; } @@ -47,6 +48,10 @@ function pointingLevels(type) { return ret; } +function removeAllPointing(type) { + return removePointing(type, pointingLevels(type)); +} + function toNiceIdent(ident) { assert(ident); if (parseFloat(ident) == ident) return ident; @@ -80,7 +85,7 @@ function isStructType(type) { return !isNumberType(type) && type[0] == '%'; } -function isPointerType(type) { // TODO! +function isPointerType(type) { return pointingLevels(type) > 0; } @@ -88,18 +93,13 @@ function isVoidType(type) { return type == 'void'; } -function isType(type) { // TODO! - return isVoidType(type) || isNumberType(type) || isStructType(type) || isPointerType(type); -} - // Detects a function definition, ([...|type,[type,...]]) function isFunctionDef(token) { var text = token.text; - var pointing = pointingLevels(text); - var nonPointing = removePointing(text, pointing); + var nonPointing = removeAllPointing(text); if (nonPointing[0] != '(' || nonPointing.substr(-1) != ')') return false; - if (nonPointing == '(...)') return true; + if (nonPointing in set('()', '(...)')) return true; if (!token.item) return false; var fail = false; splitTokenList(token.item[0].tokens).forEach(function(segment) { @@ -109,6 +109,19 @@ function isFunctionDef(token) { return !fail; } +function isFunctionType(type) { + var parts = type.split(' '); + if (parts.length != 2) return false; + if (pointingLevels(type) !== 1) return false; + var text = removeAllPointing(parts[1]); + var ret = isType(parts[0]) && isFunctionDef({ text: text, item: [{tokens: [{text: text.substr(1, text.length-2)}]}] }); + return ret; +} + +function isType(type) { // TODO! + return isVoidType(type) || isNumberType(type) || isStructType(type) || isPointerType(type) || isFunctionType(type); +} + function addIdent(token) { token.ident = token.text; return token; diff --git a/src/postamble.js b/src/postamble.js index 1329a1a4..07fe1d2e 100644 --- a/src/postamble.js +++ b/src/postamble.js @@ -23,7 +23,11 @@ function run(args) { _main(argc, argv); while( __ATEXIT__.length > 0) { - __ATEXIT__.pop()(); + var func = __ATEXIT__.pop(); + if (typeof func === 'number') { + func = FUNCTION_TABLE[func]; + } + func(); } } diff --git a/src/preamble.js b/src/preamble.js index 5496170d..1af1a6e9 100644 --- a/src/preamble.js +++ b/src/preamble.js @@ -3,6 +3,10 @@ function __globalConstructor__() { } +// Maps ints ==> functions. This lets us pass around ints, which are +// actually pointers to functions, and we convert at call()time +FUNCTION_TABLE = []; + var __THREW__ = false; // Used in checking for thrown exceptions. var __ATEXIT__ = []; @@ -43,7 +47,7 @@ function assert(condition, text) { } function Pointer_niceify(ptr) { - return { slab: HEAP, pos: ptr }; + return { slab: IHEAP, pos: ptr }; } // Creates a pointer for a certain slab and a certain address in that slab. @@ -70,8 +74,19 @@ function Pointer_make(slab, pos, allocator) { #if SAFE_HEAP SAFE_HEAP_STORE(ret + i, slab[pos + i]); #else +#if USE_TYPED_ARRAYS + // TODO: Check - also in non-typedarray case - for functions, and if so add |.__index__| + var curr = slab[pos + i]; + if (typeof curr === 'number') { + IHEAP[ret + i] = curr; // TODO: optimize. Can easily detect floats, but 1.0 might look like an int... + FHEAP[ret + i] = curr; + } else { + HEAP[ret + i] = curr; + } +#else HEAP[ret + i] = slab[pos + i]; #endif +#endif } return ret; } @@ -118,10 +133,28 @@ __ZdaPv = _free; // llvm-gcc function __initializeRuntime__() { HEAP = intArrayFromString('(null)'); // So printing %s of NULL gives '(null)' // Also this ensures we leave 0 as an invalid address, 'NULL' +#if USE_TYPED_ARRAYS + if (!this['TOTAL_MEMORY']) TOTAL_MEMORY = 50*1024*1024; + if (this['Int32Array']) { // check for engine support + IHEAP = new Int32Array(TOTAL_MEMORY); + for (var i = 0; i < HEAP.length; i++) { + IHEAP[i] = HEAP[i]; + } + } else { + IHEAP = HEAP; // fallback + } + if (this['Float64Array']) { // check for engine support + FHEAP = new Float64Array(TOTAL_MEMORY); + } else { + FHEAP = HEAP; // fallback + } +#else + IHEAP = HEAP; // We use that name in our runtime code that processes strings etc., see library.js +#endif STACK_STACK = []; STACK_ROOT = STACKTOP = alignMemoryPage(10); - if (!this['TOTAL_STACK']) TOTAL_STACK = 64*1024*100; // Reserved room for stack + if (!this['TOTAL_STACK']) TOTAL_STACK = 1024*1024; // Reserved room for stack STACK_MAX = STACK_ROOT + TOTAL_STACK; STATICTOP = alignMemoryPage(STACK_MAX); @@ -136,13 +169,22 @@ function __formatString() { var ret = []; var curr = -1; while (curr != 0) { +#if USE_TYPED_ARRAYS + curr = IHEAP[textIndex]; + next = IHEAP[textIndex+1]; +#else curr = HEAP[textIndex]; next = HEAP[textIndex+1]; +#endif if (curr == '%'.charCodeAt(0) && ['d', 'u', 'f', '.'].indexOf(String.fromCharCode(next)) != -1) { var argText = String(arguments[argIndex]); // Handle very very simply formatting, namely only %.Xf if (next == '.'.charCodeAt(0)) { +#if USE_TYPED_ARRAYS + var limit = parseInt(String.fromCharCode(IHEAP[textIndex+2])); +#else var limit = parseInt(String.fromCharCode(HEAP[textIndex+2])); +#endif var dotIndex = argText.indexOf('.'); if (dotIndex == -1) { dotIndex = argText.length; @@ -174,14 +216,16 @@ function __formatString() { // Copies a list of num items on the HEAP into a // a normal JavaScript array of numbers function Array_copy(ptr, num) { - // XXX hardcoded ptr impl - return HEAP.slice(ptr, ptr+num); +#if USE_TYPED_ARRAYS + return Array.prototype.slice.call(IHEAP.slice(ptr, ptr+num)); // Make a normal array out of the typed one +#else + return IHEAP.slice(ptr, ptr+num); +#endif } // Copies a C-style string, terminated by a zero, from the HEAP into // a normal JavaScript array of numbers function String_copy(ptr, addZero) { - // XXX hardcoded ptr impl return Array_copy(ptr, _strlen(ptr)).concat(addZero ? [0] : []); } @@ -199,6 +243,11 @@ function _llvm_memcpy_i32(dest, src, num, idunno) { SAFE_HEAP_STORE(dest + i, HEAP[src + i]); #else HEAP[dest + i] = HEAP[src + i]; +#if USE_TYPED_ARRAYS + // TODO: optimize somehow - this is slower than without typed arrays + IHEAP[dest + i] = IHEAP[src + i]; + FHEAP[dest + i] = FHEAP[src + i]; +#endif #endif } // dest = Pointer_niceify(dest); @@ -208,6 +257,17 @@ function _llvm_memcpy_i32(dest, src, num, idunno) { _llvm_memcpy_i64 = _llvm_memcpy_i32; _llvm_memcpy_p0i8_p0i8_i32 = _llvm_memcpy_i32; +function llvm_memset_i32(ptr, value, num) { + for (var i = 0; i < num; i++) { +#if USE_TYPED_ARRAYS + HEAP[ptr+i] = IHEAP[ptr+i] = FHEAP[ptr+i] = value; +#else + HEAP[ptr+i] = value; +#endif + } +} +_llvm_memset_p0i8_i32 = llvm_memset_i32; + // Tools PRINTBUFFER = ''; diff --git a/src/settings.js b/src/settings.js index d79869f1..6b621770 100644 --- a/src/settings.js +++ b/src/settings.js @@ -25,6 +25,7 @@ GUARD_MEMORY = 1; // Whether we should check that each allocation to the stack d // Code embetterments OPTIMIZE = 0; // Optimize llvm operations into js commands RELOOP = 0; // Recreate js native loops from llvm data +USE_TYPED_ARRAYS = 0; // Try to use typed arrays for the heap // Generated code debugging options SAFE_HEAP = 0; // Check each write to the heap against a list of blocked addresses diff --git a/tests/runner.py b/tests/runner.py index 3cd99993..44b5f272 100644 --- a/tests/runner.py +++ b/tests/runner.py @@ -69,17 +69,19 @@ class RunnerCore(unittest.TestCase): output = Popen([LLVM_DIS, filename + '.o'] + LLVM_DIS_OPTS + ['-o=' + filename + '.o.ll'], stdout=PIPE, stderr=STDOUT).communicate()[0] # Run Emscripten - emscripten_settings = ['{ "QUANTUM_SIZE": %d, "RELOOP": %d, "OPTIMIZE": %d, "GUARD_MEMORY": %d }' % (QUANTUM_SIZE, RELOOP, OPTIMIZE, GUARD_MEMORY)] + exported_settings = {} + for setting in ['QUANTUM_SIZE', 'RELOOP', 'OPTIMIZE', 'GUARD_MEMORY', 'USE_TYPED_ARRAYS']: + exported_settings[setting] = eval(setting) out = open(filename + '.o.js', 'w') if not OUTPUT_TO_SCREEN else None - timeout_run(Popen([EMSCRIPTEN, filename + '.o.ll', PARSER_ENGINE] + emscripten_settings, stdout=out, stderr=STDOUT), 240, 'Compiling') + timeout_run(Popen([EMSCRIPTEN, filename + '.o.ll', COMPILER_ENGINE[0], str(exported_settings).replace("'", '"')], stdout=out, stderr=STDOUT), 240, 'Compiling') output = open(filename + '.o.js').read() if output_processor is not None: output_processor(output) if output is not None and 'Traceback' in output: print output; assert 0 - def run_generated_code(self, filename, args=[], check_timeout=True): - return timeout_run(Popen([JS_ENGINE] + JS_ENGINE_OPTS + [filename] + ([] if JS_ENGINE == SPIDERMONKEY_ENGINE else ['--']) + args, - stdout=PIPE, stderr=STDOUT), 120 if check_timeout else None, 'Execution') + def run_generated_code(self, engine, filename, args=[], check_timeout=True): + return timeout_run(Popen(engine + [filename] + ([] if engine == SPIDERMONKEY_ENGINE else ['--']) + args, + stdout=PIPE, stderr=STDOUT), 30 if check_timeout else None, 'Execution') if 'benchmark' not in sys.argv: class T(RunnerCore): # Short name, to make it more fun to use manually on the commandline @@ -92,12 +94,14 @@ if 'benchmark' not in sys.argv: if not no_build: self.build(src, dirname, filename, output_processor, main_file) - # Run - js_output = self.run_generated_code(filename + '.o.js', args) - if output_nicerizer is not None: - js_output = output_nicerizer(js_output) - self.assertContained(expected_output, js_output) - self.assertNotContained('ERROR', js_output) + # Run in both JavaScript engines, if optimizing - significant differences there (typed arrays) + engines = [V8_ENGINE] if not OPTIMIZE else [V8_ENGINE, SPIDERMONKEY_ENGINE] + for engine in engines: + js_output = self.run_generated_code(engine, filename + '.o.js', args) + if output_nicerizer is not None: + js_output = output_nicerizer(js_output) + self.assertContained(expected_output, js_output) + self.assertNotContained('ERROR', js_output) #shutil.rmtree(dirname) # TODO: leave no trace in memory. But for now nice for debugging @@ -475,6 +479,26 @@ if 'benchmark' not in sys.argv: ''' self.do_test(src, '*11,74*') + def test_funcptr(self): + src = ''' + #include <stdio.h> + int calc1() { return 26; } + int calc2() { return 90; } + typedef int (*fp_t)(); + int main() + { + fp_t fp = calc1; + void *vp = (void*)fp; + fp_t fpb = (fp_t)vp; + fp_t fp2 = calc2; + void *vp2 = (void*)fp2; + fp_t fpb2 = (fp_t)vp2; + printf("*%d,%d,%d,%d*\\n", fp(), fpb(), fp2(), fpb2()); + return 0; + } + ''' + self.do_test(src, '*26,26,90,90*') + def test_emptyclass(self): src = ''' #include <stdio.h> @@ -849,7 +873,7 @@ if 'benchmark' not in sys.argv: def test_sauer(self): # XXX Warning: Running this in SpiderMonkey can lead to an extreme amount of memory being # used, see Mozilla bug 593659. - assert PARSER_ENGINE != SPIDERMONKEY_ENGINE + assert COMPILER_ENGINE != SPIDERMONKEY_ENGINE self.do_test(path_from_root(['tests', 'sauer']), '*\nTemp is 33\n9\n5\nhello, everyone\n*', main_file='command.cpp') @@ -857,15 +881,10 @@ if 'benchmark' not in sys.argv: def make_test(compiler, embetter): class TT(T): def setUp(self): - global COMPILER + global COMPILER, QUANTUM_SIZE, RELOOP, OPTIMIZE, GUARD_MEMORY, USE_TYPED_ARRAYS COMPILER = compiler['path'] - global QUANTUM_SIZE QUANTUM_SIZE = compiler['quantum_size'] - global RELOOP - RELOOP = embetter - global OPTIMIZE - OPTIMIZE = embetter - global GUARD_MEMORY + RELOOP = OPTIMIZE = USE_TYPED_ARRAYS = embetter GUARD_MEMORY = 1-embetter return TT for embetter in [0,1]: @@ -879,15 +898,14 @@ else: sys.argv = filter(lambda x: x != 'benchmark', sys.argv) COMPILER = LLVM_GCC - PARSER_ENGINE = V8_ENGINE JS_ENGINE = SPIDERMONKEY_ENGINE - if JS_ENGINE == SPIDERMONKEY_ENGINE: - JS_ENGINE_OPTS += ['-j', '-m'] # TODO: use this everywhere else + #JS_ENGINE = V8_ENGINE - RELOOP = OPTIMIZE = 1 - GUARD_MEMORY = 0 QUANTUM_SIZE = 1 - TEST_REPS = 20 + RELOOP = OPTIMIZE = USE_TYPED_ARRAYS = 1 + GUARD_MEMORY = 0 + + TEST_REPS = 10 TOTAL_TESTS = 2 tests_done = 0 @@ -913,7 +931,7 @@ else: times = [] for i in range(TEST_REPS): start = time.time() - self.run_generated_code(filename + '.o.js', args, check_timeout=False) + self.run_generated_code(JS_ENGINE, filename + '.o.js', args, check_timeout=False) curr = time.time()-start times.append(curr) total_times[i] += curr @@ -936,7 +954,7 @@ else: self.do_benchmark(src, ['5', '64']) if __name__ == '__main__': - for cmd in map(lambda compiler: compiler['path'], COMPILERS.values()) + [LLVM_DIS, PARSER_ENGINE, JS_ENGINE]: + for cmd in map(lambda compiler: compiler['path'], COMPILERS.values()) + [LLVM_DIS, SPIDERMONKEY_ENGINE[0], V8_ENGINE[0]]: print "Checking for existence of", cmd assert(os.path.exists(cmd)) print "Running Emscripten tests..." diff --git a/tests/settings.py b/tests/settings.py index 4702dc09..9452fa81 100644 --- a/tests/settings.py +++ b/tests/settings.py @@ -25,18 +25,13 @@ LLVM_DIS_OPTS = [] if '2.8' in LLVM_ROOT: LLVM_DIS_OPTS += ['-show-annotations'] -SPIDERMONKEY_ENGINE=os.path.expanduser('~/Dev/mozilla-central/js/src/js') -V8_ENGINE=os.path.expanduser('~/Dev/v8/d8') +SPIDERMONKEY_ENGINE = [os.path.expanduser('~/Dev/mozilla-central/js/src/js'), '-m'] # No |-j| due to Mozilla bug XXX +V8_ENGINE = [os.path.expanduser('~/Dev/v8/d8')] # XXX Warning: Compiling the 'sauer' test in SpiderMonkey can lead to an extreme amount of memory being # used, see Mozilla bug 593659. Possibly also some other tests as well. -#PARSER_ENGINE=SPIDERMONKEY_ENGINE -PARSER_ENGINE=V8_ENGINE - -#JS_ENGINE=SPIDERMONKEY_ENGINE -JS_ENGINE=V8_ENGINE - -JS_ENGINE_OPTS=[] +#COMPILER_ENGINE=SPIDERMONKEY_ENGINE +COMPILER_ENGINE=V8_ENGINE OUTPUT_TO_SCREEN = 0 # useful for debugging specific tests, or for subjectively seeing what parts are slow |