author | Bill McCloskey <wmccloskey@mozilla.com> |
Tue, 21 Dec 2010 16:47:13 -0800 | |
changeset 59913 | a4f9580c9b72328c944220e08a3bb4e0232c6e98 |
parent 59912 | e852f9426d25059502162ac18d445f229ac23636 |
child 59914 | 89ec0c0b48e2b24e1822ee16261c8d2c80114f1e |
push id | 17820 |
push user | cleary@mozilla.com |
push date | Tue, 04 Jan 2011 21:40:57 +0000 |
treeherder | mozilla-central@969691cfe40e [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | njn |
bugs | 620029 |
milestone | 2.0b8pre |
first release with | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
--- a/js/src/jit-test/tests/basic/testNegativeArrayLength.js +++ b/js/src/jit-test/tests/basic/testNegativeArrayLength.js @@ -1,10 +1,10 @@ function f() { try { - for ( var i = 1; i > -2; i-- ) + for ( var i = HOTLOOP-1; i > -2; i-- ) new Array(i).join('*'); } catch (e) { return e instanceof RangeError; } return false; } assertEq(f(), true);
--- a/js/src/jstracer.cpp +++ b/js/src/jstracer.cpp @@ -8469,16 +8469,33 @@ TraceRecorder::makeNumberInt32(LIns* d, // This means "convert double to int if it's integral, otherwise // exit". We first convert the double to an int, then convert it back // and exit if the two doubles don't match. If 'f' is a non-integral // immediate we'll end up aborting. *out = d2i(d, /* resultCanBeImpreciseIfFractional = */true); return guard(true, w.eqd(d, w.i2d(*out)), MISMATCH_EXIT, /* abortIfAlwaysExits = */true); } +JS_REQUIRES_STACK RecordingStatus +TraceRecorder::makeNumberUint32(LIns* d, LIns** out) +{ + JS_ASSERT(d->isD()); + if (IsPromoteUint(d)) { + *out = w.demote(d); + return RECORD_CONTINUE; + } + + // This means "convert double to uint if it's integral, otherwise + // exit". We first convert the double to an unsigned int, then + // convert it back and exit if the two doubles don't match. If + // 'f' is a non-integral immediate we'll end up aborting. + *out = d2u(d); + return guard(true, w.eqd(d, w.ui2d(*out)), MISMATCH_EXIT, /* abortIfAlwaysExits = */true); +} + JS_REQUIRES_STACK LIns* TraceRecorder::stringify(const Value& v) { LIns* v_ins = get(&v); if (v.isString()) return v_ins; LIns* args[] = { v_ins, cx_ins }; @@ -10960,17 +10977,19 @@ TraceRecorder::newArray(JSObject* ctor, LIns *arr_ins; if (argc == 0) { LIns *args[] = { proto_ins, cx_ins }; arr_ins = w.call(&js::NewDenseEmptyArray_ci, args); guard(false, w.eqp0(arr_ins), OOM_EXIT); } else if (argc == 1 && argv[0].isNumber()) { /* Abort on RangeError if the double doesn't fit in a uint. */ - LIns *args[] = { proto_ins, d2i(get(argv)), cx_ins }; + LIns *len_ins; + CHECK_STATUS(makeNumberUint32(get(argv), &len_ins)); + LIns *args[] = { proto_ins, len_ins, cx_ins }; arr_ins = w.call(&js::NewDenseUnallocatedArray_ci, args); guard(false, w.eqp0(arr_ins), OOM_EXIT); } else { LIns *args[] = { proto_ins, w.nameImmi(argc), cx_ins }; arr_ins = w.call(&js::NewDenseAllocatedArray_ci, args); guard(false, w.eqp0(arr_ins), OOM_EXIT);
--- a/js/src/jstracer.h +++ b/js/src/jstracer.h @@ -1273,16 +1273,17 @@ class TraceRecorder JS_REQUIRES_STACK void guardNonNeg(nanojit::LIns* d0, nanojit::LIns* d1, VMSideExit* exit); JS_REQUIRES_STACK nanojit::LIns* alu(nanojit::LOpcode op, jsdouble v0, jsdouble v1, nanojit::LIns* s0, nanojit::LIns* s1); nanojit::LIns* d2i(nanojit::LIns* f, bool resultCanBeImpreciseIfFractional = false); nanojit::LIns* d2u(nanojit::LIns* d); JS_REQUIRES_STACK RecordingStatus makeNumberInt32(nanojit::LIns* d, nanojit::LIns** num_ins); + JS_REQUIRES_STACK RecordingStatus makeNumberUint32(nanojit::LIns* d, nanojit::LIns** num_ins); JS_REQUIRES_STACK nanojit::LIns* stringify(const Value& v); JS_REQUIRES_STACK nanojit::LIns* newArguments(nanojit::LIns* callee_ins, bool strict); JS_REQUIRES_STACK bool canCallImacro() const; JS_REQUIRES_STACK RecordingStatus callImacro(jsbytecode* imacro); JS_REQUIRES_STACK RecordingStatus callImacroInfallibly(jsbytecode* imacro);