Unreviewed, rolling out r226434.
authorcommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 5 Jan 2018 08:26:02 +0000 (08:26 +0000)
committercommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 5 Jan 2018 08:26:02 +0000 (08:26 +0000)
https://bugs.webkit.org/show_bug.cgi?id=181322

32bit JSC failure in x86 (Requested by yusukesuzuki on
#webkit).

Reverted changeset:

"[DFG] Unify ToNumber implementation in 32bit and 64bit by
changing 32bit Int32Tag and LowestTag"
https://bugs.webkit.org/show_bug.cgi?id=181134
https://trac.webkit.org/changeset/226434

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@226440 268f45cc-cd09-0410-ab3c-d52691b4dbfc

19 files changed:
Source/JavaScriptCore/ChangeLog
Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp
Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h
Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp
Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp
Source/JavaScriptCore/jit/AssemblyHelpers.cpp
Source/JavaScriptCore/jit/AssemblyHelpers.h
Source/JavaScriptCore/jit/JITAddGenerator.cpp
Source/JavaScriptCore/jit/JITArithmetic32_64.cpp
Source/JavaScriptCore/jit/JITDivGenerator.cpp
Source/JavaScriptCore/jit/JITMulGenerator.cpp
Source/JavaScriptCore/jit/JITNegGenerator.cpp
Source/JavaScriptCore/jit/JITOpcodes32_64.cpp
Source/JavaScriptCore/jit/JITRightShiftGenerator.cpp
Source/JavaScriptCore/jit/JITSubGenerator.cpp
Source/JavaScriptCore/llint/LLIntData.cpp
Source/JavaScriptCore/llint/LowLevelInterpreter.asm
Source/JavaScriptCore/llint/LowLevelInterpreter32_64.asm
Source/JavaScriptCore/runtime/JSCJSValue.h

index 6366755..1d62708 100644 (file)
@@ -1,3 +1,18 @@
+2018-01-05  Commit Queue  <commit-queue@webkit.org>
+
+        Unreviewed, rolling out r226434.
+        https://bugs.webkit.org/show_bug.cgi?id=181322
+
+        32bit JSC failure in x86 (Requested by yusukesuzuki on
+        #webkit).
+
+        Reverted changeset:
+
+        "[DFG] Unify ToNumber implementation in 32bit and 64bit by
+        changing 32bit Int32Tag and LowestTag"
+        https://bugs.webkit.org/show_bug.cgi?id=181134
+        https://trac.webkit.org/changeset/226434
+
 2018-01-04  Devin Rousso  <webkit@devinrousso.com>
 
         Web Inspector: replace HTMLCanvasElement with CanvasRenderingContext for instrumentation logic
index cd4cb38..92a5e74 100644 (file)
@@ -2427,7 +2427,7 @@ void SpeculativeJIT::compileValueToInt32(Node* node)
                             MacroAssembler::AboveOrEqual, tagGPR,
                             TrustedImm32(JSValue::LowestTag)));
                 } else {
-                    JITCompiler::Jump isDouble = m_jit.branch32(MacroAssembler::Below, tagGPR, TrustedImm32(JSValue::LowestTag));
+                    JITCompiler::Jump isNumber = m_jit.branch32(MacroAssembler::Below, tagGPR, TrustedImm32(JSValue::LowestTag));
                     
                     DFG_TYPE_CHECK(
                         op1.jsValueRegs(), node->child1(), ~SpecCell,
@@ -2442,7 +2442,7 @@ void SpeculativeJIT::compileValueToInt32(Node* node)
                     m_jit.move(payloadGPR, resultGpr);
                     converted.append(m_jit.jump());
                     
-                    isDouble.link(&m_jit);
+                    isNumber.link(&m_jit);
                 }
 
                 unboxDouble(tagGPR, payloadGPR, fpr, scratch.fpr());
@@ -2644,7 +2644,7 @@ void SpeculativeJIT::compileDoubleRep(Node* node)
             MacroAssembler::Equal, op1TagGPR, TrustedImm32(JSValue::Int32Tag));
 
         if (node->child1().useKind() == NotCellUse) {
-            JITCompiler::Jump isDouble = m_jit.branch32(JITCompiler::Below, op1TagGPR, JITCompiler::TrustedImm32(JSValue::LowestTag));
+            JITCompiler::Jump isNumber = m_jit.branch32(JITCompiler::Below, op1TagGPR, JITCompiler::TrustedImm32(JSValue::LowestTag + 1));
             JITCompiler::Jump isUndefined = m_jit.branch32(JITCompiler::Equal, op1TagGPR, TrustedImm32(JSValue::UndefinedTag));
 
             static const double zero = 0;
@@ -2666,7 +2666,7 @@ void SpeculativeJIT::compileDoubleRep(Node* node)
             m_jit.loadDouble(TrustedImmPtr(&NaN), resultFPR);
             done.append(m_jit.jump());
 
-            isDouble.link(&m_jit);
+            isNumber.link(&m_jit);
         } else if (needsTypeCheck(node->child1(), SpecBytecodeNumber)) {
             typeCheck(
                 JSValueRegs(op1TagGPR, op1PayloadGPR), node->child1(), SpecBytecodeNumber,
@@ -9127,8 +9127,20 @@ void SpeculativeJIT::speculateNumber(Edge edge)
         return;
     
     JSValueOperand value(this, edge, ManualOperandSpeculation);
-    JSValueRegs valueRegs = value.jsValueRegs();
-    DFG_TYPE_CHECK(valueRegs, edge, SpecBytecodeNumber, m_jit.branchIfNotNumber(valueRegs));
+#if USE(JSVALUE64)
+    GPRReg gpr = value.gpr();
+    typeCheck(
+        JSValueRegs(gpr), edge, SpecBytecodeNumber,
+        m_jit.branchTest64(MacroAssembler::Zero, gpr, GPRInfo::tagTypeNumberRegister));
+#else
+    GPRReg tagGPR = value.tagGPR();
+    DFG_TYPE_CHECK(
+        value.jsValueRegs(), edge, ~SpecInt32Only,
+        m_jit.branch32(MacroAssembler::Equal, tagGPR, TrustedImm32(JSValue::Int32Tag)));
+    DFG_TYPE_CHECK(
+        value.jsValueRegs(), edge, SpecBytecodeNumber,
+        m_jit.branch32(MacroAssembler::AboveOrEqual, tagGPR, TrustedImm32(JSValue::LowestTag)));
+#endif
 }
 
 void SpeculativeJIT::speculateRealNumber(Edge edge)
@@ -9594,7 +9606,18 @@ void SpeculativeJIT::speculateOther(Edge edge)
 
 void SpeculativeJIT::speculateMisc(Edge edge, JSValueRegs regs)
 {
-    DFG_TYPE_CHECK(regs, edge, SpecMisc, m_jit.branchIfNotMisc(regs));
+#if USE(JSVALUE64)
+    DFG_TYPE_CHECK(
+        regs, edge, SpecMisc,
+        m_jit.branch64(MacroAssembler::Above, regs.gpr(), MacroAssembler::TrustedImm64(TagBitTypeOther | TagBitBool | TagBitUndefined)));
+#else
+    DFG_TYPE_CHECK(
+        regs, edge, ~SpecInt32Only,
+        m_jit.branch32(MacroAssembler::Equal, regs.tagGPR(), MacroAssembler::TrustedImm32(JSValue::Int32Tag)));
+    DFG_TYPE_CHECK(
+        regs, edge, SpecMisc,
+        m_jit.branch32(MacroAssembler::Below, regs.tagGPR(), MacroAssembler::TrustedImm32(JSValue::UndefinedTag)));
+#endif
 }
 
 void SpeculativeJIT::speculateMisc(Edge edge)
@@ -10907,7 +10930,7 @@ void SpeculativeJIT::compileNormalizeMapKey(Node* node)
 
     CCallHelpers::JumpList passThroughCases;
 
-    passThroughCases.append(m_jit.branchIfNotNumber(keyRegs));
+    passThroughCases.append(m_jit.branchIfNotNumber(keyRegs, scratchGPR));
     passThroughCases.append(m_jit.branchIfInt32(keyRegs));
 
 #if USE(JSVALUE64)
@@ -11431,42 +11454,6 @@ void SpeculativeJIT::compileToPrimitive(Node* node)
     jsValueResult(resultRegs, node, DataFormatJS, UseChildrenCalledExplicitly);
 }
 
-void SpeculativeJIT::compileToNumber(Node* node)
-{
-    JSValueOperand argument(this, node->child1());
-    JSValueRegs argumentRegs = argument.jsValueRegs();
-
-    // We have several attempts to remove ToNumber. But ToNumber still exists.
-    // It means that converting non-numbers to numbers by this ToNumber is not rare.
-    // Instead of the slow path generator, we emit callOperation here.
-    if (!(m_state.forNode(node->child1()).m_type & SpecBytecodeNumber)) {
-        flushRegisters();
-        JSValueRegsFlushedCallResult result(this);
-        JSValueRegs resultRegs = result.regs();
-        callOperation(operationToNumber, resultRegs, argumentRegs);
-        m_jit.exceptionCheck();
-        jsValueResult(resultRegs, node);
-        return;
-    }
-
-    JSValueRegsTemporary result(this, Reuse, argument);
-    JSValueRegs resultRegs = result.regs();
-
-    auto notNumber = m_jit.branchIfNotNumber(argumentRegs);
-    m_jit.moveValueRegs(argumentRegs, resultRegs);
-    auto done = m_jit.jump();
-
-    notNumber.link(&m_jit);
-    silentSpillAllRegisters(resultRegs);
-    callOperation(operationToNumber, resultRegs, argumentRegs);
-    silentFillAllRegisters();
-    m_jit.exceptionCheck();
-
-    done.link(&m_jit);
-
-    jsValueResult(resultRegs, node);
-}
-
 void SpeculativeJIT::compileLogShadowChickenPrologue(Node* node)
 {
     flushRegisters();
index e69ef7e..94f66c9 100644 (file)
@@ -3109,7 +3109,6 @@ public:
     void compileCreateThis(Node*);
     void compileNewObject(Node*);
     void compileToPrimitive(Node*);
-    void compileToNumber(Node*);
     void compileLogShadowChickenPrologue(Node*);
     void compileLogShadowChickenTail(Node*);
 
index b86f466..4f3ed05 100644 (file)
@@ -346,7 +346,7 @@ void SpeculativeJIT::nonSpeculativeNonPeepholeCompareNullOrUndefined(Edge operan
         
         notCell.link(&m_jit);
         // null or undefined?
-        static_assert((JSValue::UndefinedTag | 1) == JSValue::NullTag, "");
+        COMPILE_ASSERT((JSValue::UndefinedTag | 1) == JSValue::NullTag, UndefinedTag_OR_1_EQUALS_NullTag);
         m_jit.or32(TrustedImm32(1), argTagGPR, resultPayloadGPR);
         m_jit.compare32(JITCompiler::Equal, resultPayloadGPR, TrustedImm32(JSValue::NullTag), resultPayloadGPR);
 
@@ -410,7 +410,7 @@ void SpeculativeJIT::nonSpeculativePeepholeBranchNullOrUndefined(Edge operand, N
         
         notCell.link(&m_jit);
         // null or undefined?
-        static_assert((JSValue::UndefinedTag | 1) == JSValue::NullTag, "");
+        COMPILE_ASSERT((JSValue::UndefinedTag | 1) == JSValue::NullTag, UndefinedTag_OR_1_EQUALS_NullTag);
         m_jit.or32(TrustedImm32(1), argTagGPR, resultGPR);
         branch32(invert ? JITCompiler::NotEqual : JITCompiler::Equal, resultGPR, JITCompiler::TrustedImm32(JSValue::NullTag), taken);
     }
@@ -1781,7 +1781,7 @@ void SpeculativeJIT::compileObjectOrOtherLogicalNot(Edge nodeUse)
     
     notCell.link(&m_jit);
  
-    static_assert((JSValue::UndefinedTag | 1) == JSValue::NullTag, "");
+    COMPILE_ASSERT((JSValue::UndefinedTag | 1) == JSValue::NullTag, UndefinedTag_OR_1_EQUALS_NullTag);
     if (needsTypeCheck(nodeUse, SpecCell | SpecOther)) {
         m_jit.or32(TrustedImm32(1), valueTagGPR, resultPayloadGPR);
         typeCheck(
@@ -1899,7 +1899,7 @@ void SpeculativeJIT::emitObjectOrOtherBranch(Edge nodeUse, BasicBlock* taken, Ba
     
     notCell.link(&m_jit);
     
-    static_assert((JSValue::UndefinedTag | 1) == JSValue::NullTag, "");
+    COMPILE_ASSERT((JSValue::UndefinedTag | 1) == JSValue::NullTag, UndefinedTag_OR_1_EQUALS_NullTag);
     if (needsTypeCheck(nodeUse, SpecCell | SpecOther)) {
         m_jit.or32(TrustedImm32(1), valueTagGPR, scratchGPR);
         typeCheck(
@@ -3450,7 +3450,44 @@ void SpeculativeJIT::compile(Node* node)
     }
 
     case ToNumber: {
-        compileToNumber(node);
+        JSValueOperand argument(this, node->child1());
+        GPRTemporary resultTag(this, Reuse, argument, TagWord);
+        GPRTemporary resultPayload(this, Reuse, argument, PayloadWord);
+
+        GPRReg argumentPayloadGPR = argument.payloadGPR();
+        GPRReg argumentTagGPR = argument.tagGPR();
+        JSValueRegs argumentRegs = argument.jsValueRegs();
+        JSValueRegs resultRegs(resultTag.gpr(), resultPayload.gpr());
+
+        argument.use();
+
+        // We have several attempts to remove ToNumber. But ToNumber still exists.
+        // It means that converting non-numbers to numbers by this ToNumber is not rare.
+        // Instead of the slow path generator, we emit callOperation here.
+        if (!(m_state.forNode(node->child1()).m_type & SpecBytecodeNumber)) {
+            flushRegisters();
+            callOperation(operationToNumber, resultRegs, argumentRegs);
+            m_jit.exceptionCheck();
+        } else {
+            MacroAssembler::Jump notNumber;
+            {
+                GPRTemporary scratch(this);
+                notNumber = m_jit.branchIfNotNumber(argument.jsValueRegs(), scratch.gpr());
+            }
+            m_jit.move(argumentTagGPR, resultRegs.tagGPR());
+            m_jit.move(argumentPayloadGPR, resultRegs.payloadGPR());
+            MacroAssembler::Jump done = m_jit.jump();
+
+            notNumber.link(&m_jit);
+            silentSpillAllRegisters(resultRegs);
+            callOperation(operationToNumber, resultRegs, argumentRegs);
+            silentFillAllRegisters();
+            m_jit.exceptionCheck();
+
+            done.link(&m_jit);
+        }
+
+        jsValueResult(resultRegs.tagGPR(), resultRegs.payloadGPR(), node, UseChildrenCalledExplicitly);
         break;
     }
         
@@ -4348,7 +4385,8 @@ void SpeculativeJIT::compile(Node* node)
         JSValueOperand value(this, node->child1());
         GPRTemporary result(this, Reuse, value, TagWord);
         
-        m_jit.compare32(JITCompiler::BelowOrEqual, result.gpr(), JITCompiler::TrustedImm32(JSValue::LowestTag), result.gpr());
+        m_jit.add32(TrustedImm32(1), value.tagGPR(), result.gpr());
+        m_jit.compare32(JITCompiler::Below, result.gpr(), JITCompiler::TrustedImm32(JSValue::LowestTag + 1), result.gpr());
         booleanResult(result.gpr(), node);
         break;
     }
index 196ea53..04e16e4 100644 (file)
@@ -3665,7 +3665,36 @@ void SpeculativeJIT::compile(Node* node)
     }
 
     case ToNumber: {
-        compileToNumber(node);
+        JSValueOperand argument(this, node->child1());
+        GPRTemporary result(this, Reuse, argument);
+
+        GPRReg argumentGPR = argument.gpr();
+        GPRReg resultGPR = result.gpr();
+
+        argument.use();
+
+        // We have several attempts to remove ToNumber. But ToNumber still exists.
+        // It means that converting non-numbers to numbers by this ToNumber is not rare.
+        // Instead of the slow path generator, we emit callOperation here.
+        if (!(m_state.forNode(node->child1()).m_type & SpecBytecodeNumber)) {
+            flushRegisters();
+            callOperation(operationToNumber, resultGPR, argumentGPR);
+            m_jit.exceptionCheck();
+        } else {
+            MacroAssembler::Jump notNumber = m_jit.branchIfNotNumber(argumentGPR);
+            m_jit.move(argumentGPR, resultGPR);
+            MacroAssembler::Jump done = m_jit.jump();
+
+            notNumber.link(&m_jit);
+            silentSpillAllRegisters(resultGPR);
+            callOperation(operationToNumber, resultGPR, argumentGPR);
+            silentFillAllRegisters();
+            m_jit.exceptionCheck();
+
+            done.link(&m_jit);
+        }
+
+        jsValueResult(resultGPR, node, UseChildrenCalledExplicitly);
         break;
     }
         
index 71766a7..b7715df 100644 (file)
@@ -87,7 +87,7 @@ AssemblyHelpers::JumpList AssemblyHelpers::branchIfNotType(
         break;
 
     case InferredType::Number:
-        result.append(branchIfNotNumber(regs, mode));
+        result.append(branchIfNotNumber(regs, tempGPR, mode));
         break;
 
     case InferredType::String:
@@ -260,9 +260,11 @@ void AssemblyHelpers::jitAssertIsJSInt32(GPRReg gpr)
 
 void AssemblyHelpers::jitAssertIsJSNumber(GPRReg gpr)
 {
-    Jump checkJSNumber = branch32(BelowOrEqual, gpr, TrustedImm32(JSValue::LowestTag));
+    Jump checkJSInt32 = branch32(Equal, gpr, TrustedImm32(JSValue::Int32Tag));
+    Jump checkJSDouble = branch32(Below, gpr, TrustedImm32(JSValue::LowestTag));
     abortWithReason(AHIsNotJSNumber);
-    checkJSNumber.link(this);
+    checkJSInt32.link(this);
+    checkJSDouble.link(this);
 }
 
 void AssemblyHelpers::jitAssertIsJSDouble(GPRReg gpr)
@@ -719,7 +721,12 @@ void AssemblyHelpers::emitConvertValueToBoolean(VM& vm, JSValueRegs value, GPRRe
     done.append(jump());
 
     notBoolean.link(this);
-    auto isNotNumber = branchIfNotNumber(value);
+#if USE(JSVALUE64)
+    auto isNotNumber = branchIfNotNumber(value.gpr());
+#else
+    ASSERT(scratch != InvalidGPRReg);
+    auto isNotNumber = branchIfNotNumber(value, scratch);
+#endif
     auto isDouble = branchIfNotInt32(value);
 
     // It's an int32.
index 9f2741d..7308d9e 100644 (file)
@@ -731,29 +731,7 @@ public:
         return branch32(NotEqual, tempGPR, TrustedImm32(JSValue::NullTag));
 #endif
     }
-
-    Jump branchIfMisc(JSValueRegs regs)
-    {
-#if USE(JSVALUE64)
-        return branch64(BelowOrEqual, regs.gpr(), TrustedImm64(TagBitTypeOther | TagBitBool | TagBitUndefined));
-#else
-        static_assert(static_cast<unsigned>(JSValue::NullTag) >= static_cast<unsigned>(JSValue::BooleanTag), "");
-        static_assert(static_cast<unsigned>(JSValue::UndefinedTag) >= static_cast<unsigned>(JSValue::BooleanTag), "");
-        return branch32(AboveOrEqual, regs.tagGPR(), TrustedImm32(JSValue::BooleanTag));
-#endif
-    }
     
-    Jump branchIfNotMisc(JSValueRegs regs)
-    {
-#if USE(JSVALUE64)
-        return branch64(Above, regs.gpr(), TrustedImm64(TagBitTypeOther | TagBitBool | TagBitUndefined));
-#else
-        static_assert(static_cast<unsigned>(JSValue::NullTag) >= static_cast<unsigned>(JSValue::BooleanTag), "");
-        static_assert(static_cast<unsigned>(JSValue::UndefinedTag) >= static_cast<unsigned>(JSValue::BooleanTag), "");
-        return branch32(Below, regs.tagGPR(), TrustedImm32(JSValue::BooleanTag));
-#endif
-    }
-
     Jump branchIfInt32(JSValueRegs regs, TagRegistersMode mode = HaveTagRegisters)
     {
 #if USE(JSVALUE64)
@@ -785,13 +763,16 @@ public:
 #endif
     }
 
-    Jump branchIfNumber(JSValueRegs regs, TagRegistersMode mode = HaveTagRegisters)
+    // Note that the tempGPR is not used in 64-bit mode.
+    Jump branchIfNumber(JSValueRegs regs, GPRReg tempGPR, TagRegistersMode mode = HaveTagRegisters)
     {
 #if USE(JSVALUE64)
+        UNUSED_PARAM(tempGPR);
         return branchIfNumber(regs.gpr(), mode);
 #else
         UNUSED_PARAM(mode);
-        return branch32(BelowOrEqual, regs.tagGPR(), TrustedImm32(JSValue::LowestTag));
+        add32(TrustedImm32(1), regs.tagGPR(), tempGPR);
+        return branch32(Below, tempGPR, TrustedImm32(JSValue::LowestTag + 1));
 #endif
     }
 
@@ -804,13 +785,16 @@ public:
     }
 #endif
     
-    Jump branchIfNotNumber(JSValueRegs regs, TagRegistersMode mode = HaveTagRegisters)
+    // Note that the tempGPR is not used in 64-bit mode.
+    Jump branchIfNotNumber(JSValueRegs regs, GPRReg tempGPR, TagRegistersMode mode = HaveTagRegisters)
     {
 #if USE(JSVALUE64)
+        UNUSED_PARAM(tempGPR);
         return branchIfNotNumber(regs.gpr(), mode);
 #else
         UNUSED_PARAM(mode);
-        return branch32(Above, regs.tagGPR(), TrustedImm32(JSValue::LowestTag));
+        add32(TrustedImm32(1), regs.tagGPR(), tempGPR);
+        return branch32(AboveOrEqual, tempGPR, TrustedImm32(JSValue::LowestTag + 1));
 #endif
     }
 
@@ -831,7 +815,7 @@ public:
         return branchTest64(Zero, regs.gpr(), TrustedImm64(TagTypeNumber));
 #else
         UNUSED_PARAM(mode);
-        return branch32(Above, regs.tagGPR(), TrustedImm32(JSValue::LowestTag));
+        return branch32(AboveOrEqual, regs.tagGPR(), TrustedImm32(JSValue::LowestTag));
 #endif
     }
 
@@ -1478,7 +1462,7 @@ public:
         
         notCell.link(this);
 
-        Jump notNumber = branchIfNotNumber(regs);
+        Jump notNumber = branchIfNotNumber(regs, tempGPR);
         functor(TypeofType::Number, false);
         notNumber.link(this);
         
index 1019a5a..627af27 100644 (file)
@@ -113,7 +113,7 @@ bool JITAddGenerator::generateFastPath(CCallHelpers& jit, CCallHelpers::JumpList
         // Try to do doubleVar + double(intConstant).
         notInt32.link(&jit);
         if (!varOpr.definitelyIsNumber())
-            slowPathJumpList.append(jit.branchIfNotNumber(var));
+            slowPathJumpList.append(jit.branchIfNotNumber(var, m_scratchGPR));
 
         jit.unboxDoubleNonDestructive(var, m_leftFPR, m_scratchGPR, m_scratchFPR);
 
@@ -148,9 +148,9 @@ bool JITAddGenerator::generateFastPath(CCallHelpers& jit, CCallHelpers::JumpList
 
         leftNotInt.link(&jit);
         if (!m_leftOperand.definitelyIsNumber())
-            slowPathJumpList.append(jit.branchIfNotNumber(m_left));
+            slowPathJumpList.append(jit.branchIfNotNumber(m_left, m_scratchGPR));
         if (!m_rightOperand.definitelyIsNumber())
-            slowPathJumpList.append(jit.branchIfNotNumber(m_right));
+            slowPathJumpList.append(jit.branchIfNotNumber(m_right, m_scratchGPR));
 
         jit.unboxDoubleNonDestructive(m_left, m_leftFPR, m_scratchGPR, m_scratchFPR);
         CCallHelpers::Jump rightIsDouble = jit.branchIfNotInt32(m_right);
@@ -160,7 +160,7 @@ bool JITAddGenerator::generateFastPath(CCallHelpers& jit, CCallHelpers::JumpList
 
         rightNotInt.link(&jit);
         if (!m_rightOperand.definitelyIsNumber())
-            slowPathJumpList.append(jit.branchIfNotNumber(m_right));
+            slowPathJumpList.append(jit.branchIfNotNumber(m_right, m_scratchGPR));
 
         jit.convertInt32ToDouble(m_left.payloadGPR(), m_leftFPR);
 
index 62a8147..83a26b9 100644 (file)
@@ -178,7 +178,7 @@ void JIT::emitBinaryDoubleOp(OpcodeID opcodeID, int dst, int op1, int op2, Opera
 
         // Verify Op1 is double.
         if (!types.first().definitelyIsNumber())
-            addSlowCase(branch32(AboveOrEqual, regT1, TrustedImm32(JSValue::LowestTag)));
+            addSlowCase(branch32(Above, regT1, TrustedImm32(JSValue::LowestTag)));
 
         if (!op2IsInRegisters)
             emitLoad(op2, regT3, regT2);
@@ -251,7 +251,7 @@ void JIT::emitBinaryDoubleOp(OpcodeID opcodeID, int dst, int op1, int op2, Opera
 
         // Verify op2 is double.
         if (!types.second().definitelyIsNumber())
-            addSlowCase(branch32(AboveOrEqual, regT3, TrustedImm32(JSValue::LowestTag)));
+            addSlowCase(branch32(Above, regT3, TrustedImm32(JSValue::LowestTag)));
 
         // Do the math.
         switch (opcodeID) {
index fdab3c9..a5db7e1 100644 (file)
@@ -50,7 +50,7 @@ void JITDivGenerator::loadOperand(CCallHelpers& jit, SnippetOperand& opr, JSValu
 #endif
     } else {
         if (!opr.definitelyIsNumber())
-            m_slowPathJumpList.append(jit.branchIfNotNumber(oprRegs));
+            m_slowPathJumpList.append(jit.branchIfNotNumber(oprRegs, m_scratchGPR));
         CCallHelpers::Jump notInt32 = jit.branchIfNotInt32(oprRegs);
         jit.convertInt32ToDouble(oprRegs.payloadGPR(), destFPR);
         CCallHelpers::Jump oprIsLoaded = jit.jump();
index a4966af..93c69e2 100644 (file)
@@ -51,9 +51,9 @@ JITMathICInlineResult JITMulGenerator::generateInline(CCallHelpers& jit, MathICG
             return JITMathICInlineResult::DontGenerate;
 
         if (!m_leftOperand.definitelyIsNumber())
-            state.slowPathJumps.append(jit.branchIfNotNumber(m_left));
+            state.slowPathJumps.append(jit.branchIfNotNumber(m_left, m_scratchGPR));
         if (!m_rightOperand.definitelyIsNumber())
-            state.slowPathJumps.append(jit.branchIfNotNumber(m_right));
+            state.slowPathJumps.append(jit.branchIfNotNumber(m_right, m_scratchGPR));
         state.slowPathJumps.append(jit.branchIfInt32(m_left));
         state.slowPathJumps.append(jit.branchIfInt32(m_right));
         jit.unboxDoubleNonDestructive(m_left, m_leftFPR, m_scratchGPR, m_scratchFPR);
@@ -130,7 +130,7 @@ bool JITMulGenerator::generateFastPath(CCallHelpers& jit, CCallHelpers::JumpList
         // Try to do doubleVar * double(intConstant).
         notInt32.link(&jit);
         if (!varOpr.definitelyIsNumber())
-            slowPathJumpList.append(jit.branchIfNotNumber(var));
+            slowPathJumpList.append(jit.branchIfNotNumber(var, m_scratchGPR));
 
         jit.unboxDoubleNonDestructive(var, m_leftFPR, m_scratchGPR, m_scratchFPR);
 
@@ -163,9 +163,9 @@ bool JITMulGenerator::generateFastPath(CCallHelpers& jit, CCallHelpers::JumpList
 
         leftNotInt.link(&jit);
         if (!m_leftOperand.definitelyIsNumber())
-            slowPathJumpList.append(jit.branchIfNotNumber(m_left));
+            slowPathJumpList.append(jit.branchIfNotNumber(m_left, m_scratchGPR));
         if (!m_rightOperand.definitelyIsNumber())
-            slowPathJumpList.append(jit.branchIfNotNumber(m_right));
+            slowPathJumpList.append(jit.branchIfNotNumber(m_right, m_scratchGPR));
 
         jit.unboxDoubleNonDestructive(m_left, m_leftFPR, m_scratchGPR, m_scratchFPR);
         CCallHelpers::Jump rightIsDouble = jit.branchIfNotInt32(m_right);
@@ -175,7 +175,7 @@ bool JITMulGenerator::generateFastPath(CCallHelpers& jit, CCallHelpers::JumpList
 
         rightNotInt.link(&jit);
         if (!m_rightOperand.definitelyIsNumber())
-            slowPathJumpList.append(jit.branchIfNotNumber(m_right));
+            slowPathJumpList.append(jit.branchIfNotNumber(m_right, m_scratchGPR));
 
         jit.convertInt32ToDouble(m_left.payloadGPR(), m_leftFPR);
 
index 2479800..92c29dd 100644 (file)
@@ -64,7 +64,7 @@ JITMathICInlineResult JITNegGenerator::generateInline(CCallHelpers& jit, MathICG
     }
     if (observedTypes.isOnlyNumber()) {
         state.slowPathJumps.append(jit.branchIfInt32(m_src));
-        state.slowPathJumps.append(jit.branchIfNotNumber(m_src));
+        state.slowPathJumps.append(jit.branchIfNotNumber(m_src, m_scratchGPR));
 #if USE(JSVALUE64)
         if (m_src.payloadGPR() != m_result.payloadGPR()) {
             jit.move(CCallHelpers::TrustedImm64(static_cast<int64_t>(1ull << 63)), m_result.payloadGPR());
@@ -74,7 +74,6 @@ JITMathICInlineResult JITNegGenerator::generateInline(CCallHelpers& jit, MathICG
             jit.xor64(m_scratchGPR, m_result.payloadGPR());
         }
 #else
-        UNUSED_PARAM(m_scratchGPR);
         jit.moveValueRegs(m_src, m_result);
         jit.xor32(CCallHelpers::TrustedImm32(1 << 31), m_result.tagGPR());
 #endif
@@ -107,7 +106,7 @@ bool JITNegGenerator::generateFastPath(CCallHelpers& jit, CCallHelpers::JumpList
     endJumpList.append(jit.jump());
 
     srcNotInt.link(&jit);
-    slowPathJumpList.append(jit.branchIfNotNumber(m_src));
+    slowPathJumpList.append(jit.branchIfNotNumber(m_src, m_scratchGPR));
 
     // For a double, all we need to do is to invert the sign bit.
 #if USE(JSVALUE64)
index 8a8bdc3..c90b5fa 100644 (file)
@@ -273,7 +273,8 @@ void JIT::emit_op_is_number(Instruction* currentInstruction)
     int value = currentInstruction[2].u.operand;
     
     emitLoadTag(value, regT0);
-    compare32(BelowOrEqual, regT0, TrustedImm32(JSValue::LowestTag), regT0);
+    add32(TrustedImm32(1), regT0);
+    compare32(Below, regT0, TrustedImm32(JSValue::LowestTag + 1), regT0);
     emitStoreBool(dst, regT0);
 }
 
@@ -400,7 +401,7 @@ void JIT::emit_op_jeq_null(Instruction* currentInstruction)
 
     // Now handle the immediate cases - undefined & null
     isImmediate.link(this);
-    static_assert((JSValue::UndefinedTag + 1 == JSValue::NullTag) && (JSValue::NullTag & 0x1), "");
+    ASSERT((JSValue::UndefinedTag + 1 == JSValue::NullTag) && (JSValue::NullTag & 0x1));
     or32(TrustedImm32(1), regT1);
     addJump(branch32(Equal, regT1, TrustedImm32(JSValue::NullTag)), target);
 
@@ -426,7 +427,7 @@ void JIT::emit_op_jneq_null(Instruction* currentInstruction)
     // Now handle the immediate cases - undefined & null
     isImmediate.link(this);
 
-    static_assert((JSValue::UndefinedTag + 1 == JSValue::NullTag) && (JSValue::NullTag & 0x1), "");
+    ASSERT((JSValue::UndefinedTag + 1 == JSValue::NullTag) && (JSValue::NullTag & 0x1));
     or32(TrustedImm32(1), regT1);
     addJump(branch32(NotEqual, regT1, TrustedImm32(JSValue::NullTag)), target);
 
@@ -653,7 +654,9 @@ void JIT::emit_op_to_number(Instruction* currentInstruction)
 
     emitLoad(src, regT1, regT0);
 
-    addSlowCase(branch32(Above, regT1, TrustedImm32(JSValue::LowestTag)));
+    Jump isInt32 = branch32(Equal, regT1, TrustedImm32(JSValue::Int32Tag));
+    addSlowCase(branch32(AboveOrEqual, regT1, TrustedImm32(JSValue::LowestTag)));
+    isInt32.link(this);
 
     emitValueProfilingSite();
     if (src != dst)
@@ -1110,9 +1113,10 @@ void JIT::emit_op_profile_type(Instruction* currentInstruction)
         jumpToEnd.append(branch32(Equal, regT3, TrustedImm32(JSValue::BooleanTag)));
     else if (cachedTypeLocation->m_lastSeenType == TypeAnyInt)
         jumpToEnd.append(branch32(Equal, regT3, TrustedImm32(JSValue::Int32Tag)));
-    else if (cachedTypeLocation->m_lastSeenType == TypeNumber)
-        jumpToEnd.append(branch32(BelowOrEqual, regT3, TrustedImm32(JSValue::LowestTag)));
-    else if (cachedTypeLocation->m_lastSeenType == TypeString) {
+    else if (cachedTypeLocation->m_lastSeenType == TypeNumber) {
+        jumpToEnd.append(branch32(Below, regT3, TrustedImm32(JSValue::LowestTag)));
+        jumpToEnd.append(branch32(Equal, regT3, TrustedImm32(JSValue::Int32Tag)));
+    } else if (cachedTypeLocation->m_lastSeenType == TypeString) {
         Jump isNotCell = branch32(NotEqual, regT3, TrustedImm32(JSValue::CellTag));
         jumpToEnd.append(branch8(Equal, Address(regT0, JSCell::typeInfoTypeOffset()), TrustedImm32(StringType)));
         isNotCell.link(this);
index 52aecf7..4e75faf 100644 (file)
@@ -67,7 +67,7 @@ void JITRightShiftGenerator::generateFastPath(CCallHelpers& jit)
             // Try to do (doubleVar >> intConstant).
             notInt.link(&jit);
 
-            m_slowPathJumpList.append(jit.branchIfNotNumber(m_left));
+            m_slowPathJumpList.append(jit.branchIfNotNumber(m_left, m_scratchGPR));
 
             jit.unboxDoubleNonDestructive(m_left, m_leftFPR, m_scratchGPR, m_scratchFPR);
             m_slowPathJumpList.append(jit.branchTruncateDoubleToInt32(m_leftFPR, m_scratchGPR));
@@ -120,7 +120,7 @@ void JITRightShiftGenerator::generateFastPath(CCallHelpers& jit)
             // Try to do (doubleVar >> intVar).
             leftNotInt.link(&jit);
 
-            m_slowPathJumpList.append(jit.branchIfNotNumber(m_left));
+            m_slowPathJumpList.append(jit.branchIfNotNumber(m_left, m_scratchGPR));
             jit.unboxDoubleNonDestructive(m_left, m_leftFPR, m_scratchGPR, m_scratchFPR);
             m_slowPathJumpList.append(jit.branchTruncateDoubleToInt32(m_leftFPR, m_scratchGPR));
 
index ffc5e74..795c275 100644 (file)
@@ -51,9 +51,9 @@ JITMathICInlineResult JITSubGenerator::generateInline(CCallHelpers& jit, MathICG
             return JITMathICInlineResult::DontGenerate;
 
         if (!m_leftOperand.definitelyIsNumber())
-            state.slowPathJumps.append(jit.branchIfNotNumber(m_left));
+            state.slowPathJumps.append(jit.branchIfNotNumber(m_left, m_scratchGPR));
         if (!m_rightOperand.definitelyIsNumber())
-            state.slowPathJumps.append(jit.branchIfNotNumber(m_right));
+            state.slowPathJumps.append(jit.branchIfNotNumber(m_right, m_scratchGPR));
         state.slowPathJumps.append(jit.branchIfInt32(m_left));
         state.slowPathJumps.append(jit.branchIfInt32(m_right));
         jit.unboxDoubleNonDestructive(m_left, m_leftFPR, m_scratchGPR, m_scratchFPR);
@@ -107,9 +107,9 @@ bool JITSubGenerator::generateFastPath(CCallHelpers& jit, CCallHelpers::JumpList
 
     leftNotInt.link(&jit);
     if (!m_leftOperand.definitelyIsNumber())
-        slowPathJumpList.append(jit.branchIfNotNumber(m_left));
+        slowPathJumpList.append(jit.branchIfNotNumber(m_left, m_scratchGPR));
     if (!m_rightOperand.definitelyIsNumber())
-        slowPathJumpList.append(jit.branchIfNotNumber(m_right));
+        slowPathJumpList.append(jit.branchIfNotNumber(m_right, m_scratchGPR));
 
     jit.unboxDoubleNonDestructive(m_left, m_leftFPR, m_scratchGPR, m_scratchFPR);
     CCallHelpers::Jump rightIsDouble = jit.branchIfNotInt32(m_right);
@@ -119,7 +119,7 @@ bool JITSubGenerator::generateFastPath(CCallHelpers& jit, CCallHelpers::JumpList
 
     rightNotInt.link(&jit);
     if (!m_rightOperand.definitelyIsNumber())
-        slowPathJumpList.append(jit.branchIfNotNumber(m_right));
+        slowPathJumpList.append(jit.branchIfNotNumber(m_right, m_scratchGPR));
 
     jit.convertInt32ToDouble(m_left.payloadGPR(), m_leftFPR);
 
index 4511c2f..4cf8c6d 100644 (file)
@@ -117,7 +117,16 @@ void Data::performAssertions(VM& vm)
     ASSERT(OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.tag) == 4);
     ASSERT(OBJECT_OFFSETOF(EncodedValueDescriptor, asBits.payload) == 0);
 #endif
-#if USE(JSVALUE64)
+#if USE(JSVALUE32_64)
+    STATIC_ASSERT(JSValue::Int32Tag == static_cast<unsigned>(-1));
+    STATIC_ASSERT(JSValue::BooleanTag == static_cast<unsigned>(-2));
+    STATIC_ASSERT(JSValue::NullTag == static_cast<unsigned>(-3));
+    STATIC_ASSERT(JSValue::UndefinedTag == static_cast<unsigned>(-4));
+    STATIC_ASSERT(JSValue::CellTag == static_cast<unsigned>(-5));
+    STATIC_ASSERT(JSValue::EmptyValueTag == static_cast<unsigned>(-6));
+    STATIC_ASSERT(JSValue::DeletedValueTag == static_cast<unsigned>(-7));
+    STATIC_ASSERT(JSValue::LowestTag == static_cast<unsigned>(-7));
+#else
     STATIC_ASSERT(TagBitTypeOther == 0x2);
     STATIC_ASSERT(TagBitBool == 0x4);
     STATIC_ASSERT(TagBitUndefined == 0x8);
index 448d770..9f9d2f7 100644 (file)
@@ -194,14 +194,14 @@ if JSVALUE64
     const TagTypeNumber   = 0xffff000000000000
     const TagMask         = TagTypeNumber | TagBitTypeOther
 else
-    const NullTag = constexpr JSValue::NullTag
-    const UndefinedTag = constexpr JSValue::UndefinedTag
-    const BooleanTag = constexpr JSValue::BooleanTag
-    const CellTag = constexpr JSValue::CellTag
-    const EmptyValueTag = constexpr JSValue::EmptyValueTag
-    const DeletedValueTag = constexpr JSValue::DeletedValueTag
-    const Int32Tag = constexpr JSValue::Int32Tag
-    const LowestTag = constexpr JSValue::LowestTag
+    const Int32Tag = -1
+    const BooleanTag = -2
+    const NullTag = -3
+    const UndefinedTag = -4
+    const CellTag = -5
+    const EmptyValueTag = -6
+    const DeletedValueTag = -7
+    const LowestTag = DeletedValueTag
 end
 
 # PutByIdFlags data
index 0cb02c0..d70b665 100644 (file)
@@ -914,8 +914,9 @@ _llint_op_to_number:
     loadi 8[PC], t0
     loadi 4[PC], t1
     loadConstantOrVariable(t0, t2, t3)
-    bia t2, Int32Tag, .opToNumberSlow
-.opToNumberIsNumber:
+    bieq t2, Int32Tag, .opToNumberIsInt
+    biaeq t2, LowestTag, .opToNumberSlow
+.opToNumberIsInt:
     storei t2, TagOffset[cfr, t1, 8]
     storei t3, PayloadOffset[cfr, t1, 8]
     valueProfile(t2, t3, 12, t1)
@@ -1273,7 +1274,8 @@ _llint_op_is_number:
     loadi 4[PC], t2
     loadConstantOrVariableTag(t1, t0)
     storei BooleanTag, TagOffset[cfr, t2, 8]
-    cibeq t0, LowestTag, t1
+    addi 1, t0
+    cib t0, LowestTag + 1, t1
     storei t1, PayloadOffset[cfr, t2, 8]
     dispatch(constexpr op_is_number_length)
 
@@ -1490,7 +1492,13 @@ _llint_op_put_by_id:
     bilt t1, PutByIdSecondaryTypeInt32, .opPutByIdTypeCheckLessThanInt32
 
     # We are either Int32 or Number.
-    bibeq t2, LowestTag, .opPutByIdDoneCheckingTypes
+    bieq t1, PutByIdSecondaryTypeNumber, .opPutByIdTypeCheckNumber
+
+    bieq t2, Int32Tag, .opPutByIdDoneCheckingTypes
+    jmp .opPutByIdSlow
+
+.opPutByIdTypeCheckNumber:
+    bib t2, LowestTag + 1, .opPutByIdDoneCheckingTypes
     jmp .opPutByIdSlow
 
 .opPutByIdTypeCheckLessThanInt32:
index 38920ab..9f39a3c 100644 (file)
@@ -147,15 +147,15 @@ class JSValue {
 
 public:
 #if USE(JSVALUE32_64)
-    enum { NullTag =         0xffffffff };
-    enum { UndefinedTag =    0xfffffffe }; // ^ Other
-    enum { BooleanTag =      0xfffffffd }; // ^ Misc
-    enum { CellTag =         0xfffffffc };
-    enum { EmptyValueTag =   0xfffffffb };
-    enum { DeletedValueTag = 0xfffffffa };
-    enum { Int32Tag =        0xfffffff9 }; // v Number
-
-    enum { LowestTag =  Int32Tag };
+    enum { Int32Tag =        0xffffffff };
+    enum { BooleanTag =      0xfffffffe };
+    enum { NullTag =         0xfffffffd };
+    enum { UndefinedTag =    0xfffffffc };
+    enum { CellTag =         0xfffffffb };
+    enum { EmptyValueTag =   0xfffffffa };
+    enum { DeletedValueTag = 0xfffffff9 };
+
+    enum { LowestTag =  DeletedValueTag };
 #endif
 
     static EncodedJSValue encode(JSValue);