Bug 810375 part 2 - Compile JSOP_POS. r=djvj
authorJan de Mooij <jdemooij@mozilla.com>
Mon, 12 Nov 2012 13:08:58 +0100
changeset 112739 79b5f9e429d0debf7c7aed5a30e14a0feb898936
parent 112738 6942d37090098428a02ac70f51d9b2765d8e9f3b
child 112740 281c54efd9918d37eb6121f751119141a7165cb5
push id1351
push userjandemooij@gmail.com
push dateMon, 12 Nov 2012 12:18:00 +0000
reviewersdjvj
bugs810375
milestone19.0a1
Bug 810375 part 2 - Compile JSOP_POS. r=djvj
js/src/ion/BaselineCompiler.cpp
js/src/ion/BaselineCompiler.h
js/src/ion/BaselineIC.cpp
js/src/ion/BaselineIC.h
js/src/ion/x64/MacroAssembler-x64.h
--- a/js/src/ion/BaselineCompiler.cpp
+++ b/js/src/ion/BaselineCompiler.cpp
@@ -228,16 +228,44 @@ BaselineCompiler::emit_JSOP_IFNE()
 
     // IC will leave a JSBool value (guaranteed) in R0, just need to branch on it.
     masm.branchTestBooleanTruthy(true, R0, labelOf(pc + GET_JUMP_OFFSET(pc)));
 
     return true;
 }
 
 bool
+BaselineCompiler::emit_JSOP_POS()
+{
+    // Allocate IC entry and stub.
+    ICToNumber_Fallback::Compiler stubCompiler(cx);
+    ICEntry *entry = allocateICEntry(stubCompiler.getStub());
+    if (!entry)
+        return false;
+
+    // Keep top stack value in R0.
+    frame.popRegsAndSync(1);
+
+    // Inline path for int32 and double.
+    Label done;
+    masm.branchTestNumber(Assembler::Equal, R0, &done);
+
+    // Call IC.
+    CodeOffsetLabel patchOffset;
+    EmitCallIC(&patchOffset, masm);
+    entry->setReturnOffset(masm.currentOffset());
+    if (!addICLoadLabel(patchOffset))
+        return false;
+
+    masm.bind(&done);
+    frame.push(R0);
+    return true;
+}
+
+bool
 BaselineCompiler::emit_JSOP_LOOPHEAD()
 {
     return true;
 }
 
 bool
 BaselineCompiler::emit_JSOP_LOOPENTRY()
 {
--- a/js/src/ion/BaselineCompiler.h
+++ b/js/src/ion/BaselineCompiler.h
@@ -29,16 +29,17 @@
 namespace js {
 namespace ion {
 
 #define OPCODE_LIST(_)         \
     _(JSOP_NOP)                \
     _(JSOP_POP)                \
     _(JSOP_GOTO)               \
     _(JSOP_IFNE)               \
+    _(JSOP_POS)                \
     _(JSOP_LOOPHEAD)           \
     _(JSOP_LOOPENTRY)          \
     _(JSOP_ZERO)               \
     _(JSOP_ONE)                \
     _(JSOP_INT8)               \
     _(JSOP_INT32)              \
     _(JSOP_UINT16)             \
     _(JSOP_UINT24)             \
--- a/js/src/ion/BaselineIC.cpp
+++ b/js/src/ion/BaselineIC.cpp
@@ -182,16 +182,51 @@ ICToBool_Bool::Compiler::generateStubCod
     // Failure case - jump to next stub
     masm.bind(&failure);
     EmitStubGuardFailure(masm);
 
     Linker linker(masm);
     return linker.newCode(cx);
 }
 
+static bool
+DoToNumberFallback(JSContext *cx, ICToNumber_Fallback *stub, HandleValue arg, MutableHandleValue ret)
+{
+    ret.set(arg);
+    return ToNumber(cx, ret.address());
+}
+
+IonCode *
+ICToNumber_Fallback::Compiler::generateStubCode()
+{
+    MacroAssembler masm;
+    JS_ASSERT(R0 == JSReturnOperand);
+
+    // Pop return address.
+    masm.pop(BaselineTailCallReg);
+
+    // Get VMFunction to call
+    typedef bool (*pf)(JSContext *, ICToNumber_Fallback *, HandleValue, MutableHandleValue);
+    static const VMFunction fun = FunctionInfo<pf>(DoToNumberFallback);
+
+    IonCode *wrapper = generateVMWrapper(fun);
+    if (!wrapper)
+        return NULL;
+
+    // Push arguments.
+    masm.pushValue(R0);
+    masm.push(BaselineStubReg);
+
+    // Call.
+    EmitTailCall(wrapper, masm);
+
+    Linker linker(masm);
+    return linker.newCode(cx);
+}
+
 //
 // BinaryArith_Fallback
 //
 
 static bool
 DoBinaryArithFallback(JSContext *cx, ICBinaryArith_Fallback *stub, HandleValue lhs,
                       HandleValue rhs, MutableHandleValue ret)
 {
--- a/js/src/ion/BaselineIC.h
+++ b/js/src/ion/BaselineIC.h
@@ -147,16 +147,18 @@ class ICEntry
 // List of baseline IC stub kinds.
 #define IC_STUB_KIND_LIST(_)    \
     _(Compare_Fallback)         \
     _(Compare_Int32)            \
                                 \
     _(ToBool_Fallback)          \
     _(ToBool_Bool)              \
                                 \
+    _(ToNumber_Fallback)        \
+                                \
     _(BinaryArith_Fallback)     \
     _(BinaryArith_Int32)
 
 #define FORWARD_DECLARE_STUBS(kindName) class IC##kindName;
     IC_STUB_KIND_LIST(FORWARD_DECLARE_STUBS)
 #undef FORWARD_DECLARE_STUBS
 
 class ICFallbackStub;
@@ -481,16 +483,44 @@ class ICToBool_Bool : public ICStub
           : ICStubCompiler(cx, ICStub::ToBool_Bool) {}
 
         ICStub *getStub() {
             return ICToBool_Bool::New(getStubCode());
         }
     };
 };
 
+// ToNumber_Fallback - shared fallback stub for:
+//     JSOP_POS
+
+class ICToNumber_Fallback : public ICFallbackStub
+{
+    ICToNumber_Fallback(IonCode *stubCode)
+      : ICFallbackStub(ICStub::ToNumber_Fallback, stubCode) {}
+
+  public:
+    static inline ICToNumber_Fallback *New(IonCode *code) {
+        return new ICToNumber_Fallback(code);
+    }
+
+    // Compiler for this stub kind.
+    class Compiler : public ICStubCompiler {
+      protected:
+        IonCode *generateStubCode();
+
+      public:
+        Compiler(JSContext *cx)
+          : ICStubCompiler(cx, ICStub::ToNumber_Fallback) {}
+
+        ICStub *getStub() {
+            return ICToNumber_Fallback::New(getStubCode());
+        }
+    };
+};
+
 // BinaryArith_Fallback - shared fallback stub for:
 //      JSOP_ADD
 
 class ICBinaryArith_Fallback : public ICFallbackStub
 {
     ICBinaryArith_Fallback(IonCode *stubCode)
       : ICFallbackStub(BinaryArith_Fallback, stubCode) {}
 
--- a/js/src/ion/x64/MacroAssembler-x64.h
+++ b/js/src/ion/x64/MacroAssembler-x64.h
@@ -287,16 +287,20 @@ class MacroAssemblerX64 : public MacroAs
     Condition testBoolean(Condition cond, const ValueOperand &src) {
         splitTag(src, ScratchReg);
         return testBoolean(cond, ScratchReg);
     }
     Condition testDouble(Condition cond, const ValueOperand &src) {
         splitTag(src, ScratchReg);
         return testDouble(cond, ScratchReg);
     }
+    Condition testNumber(Condition cond, const ValueOperand &src) {
+        splitTag(src, ScratchReg);
+        return testNumber(cond, ScratchReg);
+    }
     Condition testNull(Condition cond, const ValueOperand &src) {
         splitTag(src, ScratchReg);
         return testNull(cond, ScratchReg);
     }
     Condition testString(Condition cond, const ValueOperand &src) {
         splitTag(src, ScratchReg);
         return testString(cond, ScratchReg);
     }
@@ -614,16 +618,20 @@ class MacroAssemblerX64 : public MacroAs
     void branchTestString(Condition cond, const ValueOperand &src, Label *label) {
         cond = testString(cond, src);
         j(cond, label);
     }
     void branchTestObject(Condition cond, const ValueOperand &src, Label *label) {
         cond = testObject(cond, src);
         j(cond, label);
     }
+    void branchTestNumber(Condition cond, const ValueOperand &src, Label *label) {
+        cond = testNumber(cond, src);
+        j(cond, label);
+    }
     template <typename T>
     void branchTestGCThing(Condition cond, const T &src, Label *label) {
         cond = testGCThing(cond, src);
         j(cond, label);
     }
     template <typename T>
     void branchTestPrimitive(Condition cond, const T &t, Label *label) {
         cond = testPrimitive(cond, t);