Bug 1020638 - IonMonkey: Implement StringLength Recover Instruction. r=nbp
authorSebastian Holzapfel <schnommus@gmail.com>
Mon, 30 Jun 2014 12:43:16 -0700
changeset 191490 933a9116ef3d0f762137bba705b5b7c9deb5bda8
parent 191489 96b9c782d66a4e099291548608ba239f5c4f18c8
child 191491 78adf063a6bea5f7d6f3b740857cc80716e35fb8
push id27051
push userkwierso@gmail.com
push dateTue, 01 Jul 2014 01:00:57 +0000
treeherdermozilla-central@5f998c527a67 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersnbp
bugs1020638
milestone33.0a1
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
Bug 1020638 - IonMonkey: Implement StringLength Recover Instruction. r=nbp
js/src/jit-test/tests/ion/dce-with-rinstructions.js
js/src/jit/MIR.h
js/src/jit/Recover.cpp
js/src/jit/Recover.h
--- a/js/src/jit-test/tests/ion/dce-with-rinstructions.js
+++ b/js/src/jit-test/tests/ion/dce-with-rinstructions.js
@@ -291,16 +291,24 @@ function rconcat_string(i) {
 var uceFault_concat_number = eval(uneval(uceFault).replace('uceFault', 'uceFault_concat_number'));
 function rconcat_number(i) {
     var x = "s" + i;
     if (uceFault_concat_number(i) || uceFault_concat_number(i))
         assertEq(x, "s99");
     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);
     if (uceFault_floor_number(i) || uceFault_floor_number(i))
         assertEq(x, i);
     return i;
 }
 
@@ -420,16 +428,17 @@ for (i = 0; i < 100; i++) {
     rmul_object(i);
     rdiv_number(i);
     rdiv_float(i);
     rdiv_object(i);
     rmod_number(i);
     rmod_object(i);
     rconcat_string(i);
     rconcat_number(i);
+    rstring_length(i);
     rfloor_number(i);
     rfloor_object(i);
     rround_number(i);
     rround_double(i);
     rcharCodeAt(i);
     rfrom_char_code(i);
     rfrom_char_code_non_ascii(i);
     rpow_number(i);
--- a/js/src/jit/MIR.h
+++ b/js/src/jit/MIR.h
@@ -8915,16 +8915,21 @@ class MStringLength
     }
     AliasSet getAliasSet() const {
         // The string |length| property is immutable, so there is no
         // implicit dependency.
         return AliasSet::None();
     }
 
     void computeRange(TempAllocator &alloc);
+
+    bool writeRecoverData(CompactBufferWriter &writer) const;
+    bool canRecoverOnBailout() const {
+        return true;
+    }
 };
 
 // Inlined version of Math.floor().
 class MFloor
   : public MUnaryInstruction,
     public FloatingPointPolicy<0>
 {
     explicit MFloor(MDefinition *num)
--- a/js/src/jit/Recover.cpp
+++ b/js/src/jit/Recover.cpp
@@ -505,16 +505,41 @@ RConcat::recover(JSContext *cx, Snapshot
     MOZ_ASSERT(!lhs.isObject() && !rhs.isObject());
     if (!js::AddValues(cx, &lhs, &rhs, &result))
         return false;
 
     iter.storeInstructionResult(result);
     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
 {
     MOZ_ASSERT(canRecoverOnBailout());
     writer.writeUnsigned(uint32_t(RInstruction::Recover_Floor));
     return true;
 }
 
--- a/js/src/jit/Recover.h
+++ b/js/src/jit/Recover.h
@@ -26,16 +26,17 @@ namespace jit {
     _(Rsh)                                      \
     _(Ursh)                                     \
     _(Add)                                      \
     _(Sub)                                      \
     _(Mul)                                      \
     _(Div)                                      \
     _(Mod)                                      \
     _(Concat)                                   \
+    _(StringLength)                             \
     _(Floor)                                    \
     _(Round)                                    \
     _(CharCodeAt)                               \
     _(FromCharCode)                             \
     _(Pow)                                      \
     _(PowHalf)                                  \
     _(NewObject)                                \
     _(NewDerivedTypedObject)
@@ -269,16 +270,28 @@ class RConcat MOZ_FINAL : public RInstru
 
     virtual uint32_t numOperands() const {
         return 2;
     }
 
     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:
     RINSTRUCTION_HEADER_(Floor)
 
     virtual uint32_t numOperands() const {
         return 1;
     }