typed arrays support; function __index__ing ; 36% speedup

This commit is contained in:
alon@honor 2010-10-10 22:52:54 -07:00
Родитель 5a4c4614b7
Коммит 425295d786
9 изменённых файлов: 227 добавлений и 95 удалений

Просмотреть файл

@ -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;

Просмотреть файл

@ -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

Просмотреть файл

@ -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;
},

Просмотреть файл

@ -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;

Просмотреть файл

@ -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();
}
}

Просмотреть файл

@ -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.
@ -69,8 +73,19 @@ function Pointer_make(slab, pos, allocator) {
for (var i = 0; i < slab.length - pos; i++) {
#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 = '';

Просмотреть файл

@ -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

Просмотреть файл

@ -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..."

Просмотреть файл

@ -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