From 369f4187acf4b563c04881531b96509d29a2eb8d Mon Sep 17 00:00:00 2001 From: David Anderson Date: Wed, 20 Oct 2010 19:13:42 -0700 Subject: [PATCH] Fixed register allocation bug in left-shift operations (bug 606063, r=dmandelin). --- js/src/methodjit/FastOps.cpp | 18 +++++++++++++----- .../tests/jaeger/testShiftSameBacking.js | 12 ++++++++++++ 2 files changed, 25 insertions(+), 5 deletions(-) create mode 100644 js/src/trace-test/tests/jaeger/testShiftSameBacking.js diff --git a/js/src/methodjit/FastOps.cpp b/js/src/methodjit/FastOps.cpp index b55d68561f6..292a5cee144 100644 --- a/js/src/methodjit/FastOps.cpp +++ b/js/src/methodjit/FastOps.cpp @@ -524,13 +524,21 @@ mjit::Compiler::jsop_bitop(JSOp op) RegisterID rr = frame.tempRegForData(rhs); #endif - if (lhs->isConstant()) { - frame.pinReg(rr); + if (frame.haveSameBacking(lhs, rhs)) { + // It's okay to allocReg(). If |rr| is evicted, it won't result in + // a load, and |rr == reg| is fine since this is (x << x). reg = frame.allocReg(); - masm.move(Imm32(lhs->getValue().toInt32()), reg); - frame.unpinReg(rr); + if (rr != reg) + masm.move(rr, reg); } else { - reg = frame.copyDataIntoReg(lhs); + frame.pinReg(rr); + if (lhs->isConstant()) { + reg = frame.allocReg(); + masm.move(Imm32(lhs->getValue().toInt32()), reg); + } else { + reg = frame.copyDataIntoReg(lhs); + } + frame.unpinReg(rr); } if (op == JSOP_LSH) { diff --git a/js/src/trace-test/tests/jaeger/testShiftSameBacking.js b/js/src/trace-test/tests/jaeger/testShiftSameBacking.js new file mode 100644 index 00000000000..cb2ce0059b4 --- /dev/null +++ b/js/src/trace-test/tests/jaeger/testShiftSameBacking.js @@ -0,0 +1,12 @@ +// vim: set ts=4 sw=4 tw=99 et: + +function f(a) { + var x = a; + var y = x; + + assertEq((x << y), (a << a)); + assertEq((y << x), (a << a)); +} + +f(2); +