diff --git a/js/src/jit-test/tests/ion/dce-with-rinstructions.js b/js/src/jit-test/tests/ion/dce-with-rinstructions.js index 17ea857b1416..e15332c1f251 100644 --- a/js/src/jit-test/tests/ion/dce-with-rinstructions.js +++ b/js/src/jit-test/tests/ion/dce-with-rinstructions.js @@ -296,6 +296,14 @@ function rconcat_number(i) { return i; } +var uceFault_string_length = eval(uneval(uceFault).replace('uceFault', 'uceFault_string_length')); +function rstring_length(i) { + var x = i.toString().length; + if (uceFault_string_length(i) || uceFault_string_length(i)) + assertEq(x, 2); + return i; +} + var uceFault_floor_number = eval(uneval(uceFault).replace('uceFault', 'uceFault_floor_number')); function rfloor_number(i) { var x = Math.floor(i + 0.1111); @@ -425,6 +433,7 @@ for (i = 0; i < 100; i++) { rmod_object(i); rconcat_string(i); rconcat_number(i); + rstring_length(i); rfloor_number(i); rfloor_object(i); rround_number(i); diff --git a/js/src/jit/MIR.h b/js/src/jit/MIR.h index 54c29c3468b8..fda3e435f272 100644 --- a/js/src/jit/MIR.h +++ b/js/src/jit/MIR.h @@ -8920,6 +8920,11 @@ class MStringLength } void computeRange(TempAllocator &alloc); + + bool writeRecoverData(CompactBufferWriter &writer) const; + bool canRecoverOnBailout() const { + return true; + } }; // Inlined version of Math.floor(). diff --git a/js/src/jit/Recover.cpp b/js/src/jit/Recover.cpp index f60f7c2a387d..b78f32c1a186 100644 --- a/js/src/jit/Recover.cpp +++ b/js/src/jit/Recover.cpp @@ -510,6 +510,31 @@ RConcat::recover(JSContext *cx, SnapshotIterator &iter) const return true; } +RStringLength::RStringLength(CompactBufferReader &reader) +{} + +bool +RStringLength::recover(JSContext *cx, SnapshotIterator &iter) const +{ + RootedValue operand(cx, iter.read()); + RootedValue result(cx); + + MOZ_ASSERT(!operand.isObject()); + if (!js::GetLengthProperty(operand, &result)) + return false; + + iter.storeInstructionResult(result); + return true; +} + +bool +MStringLength::writeRecoverData(CompactBufferWriter &writer) const +{ + MOZ_ASSERT(canRecoverOnBailout()); + writer.writeUnsigned(uint32_t(RInstruction::Recover_StringLength)); + return true; +} + bool MFloor::writeRecoverData(CompactBufferWriter &writer) const { diff --git a/js/src/jit/Recover.h b/js/src/jit/Recover.h index d1f36d244be2..ad24a6e393f2 100644 --- a/js/src/jit/Recover.h +++ b/js/src/jit/Recover.h @@ -31,6 +31,7 @@ namespace jit { _(Div) \ _(Mod) \ _(Concat) \ + _(StringLength) \ _(Floor) \ _(Round) \ _(CharCodeAt) \ @@ -274,6 +275,18 @@ class RConcat MOZ_FINAL : public RInstruction bool recover(JSContext *cx, SnapshotIterator &iter) const; }; +class RStringLength MOZ_FINAL : public RInstruction +{ +public: + RINSTRUCTION_HEADER_(StringLength) + + virtual uint32_t numOperands() const { + return 1; + } + + bool recover(JSContext *cx, SnapshotIterator &iter) const; +}; + class RFloor MOZ_FINAL : public RInstruction { public: