Constants folded by DFG::ByteCodeParser should not be dead.
authorfpizlo@apple.com <fpizlo@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 21 Mar 2014 20:23:55 +0000 (20:23 +0000)
committerfpizlo@apple.com <fpizlo@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 21 Mar 2014 20:23:55 +0000 (20:23 +0000)
https://bugs.webkit.org/show_bug.cgi?id=130576

Reviewed by Mark Hahnenberg.

This fixes bugs in the ByteCodeParser's constant folder by removing that constant folder. This
reduces the number of folders in JSC from fourish to just threeish (parser, DFG AI, and one
or more folders in LLVM). Doing so has no performance impact since the other constant folders
already subsume this one.

Also added a test case for the specific bug that instigated this.

* dfg/DFGByteCodeParser.cpp:
(JSC::DFG::ByteCodeParser::getJSConstantForValue):
(JSC::DFG::ByteCodeParser::getJSConstant):
(JSC::DFG::ByteCodeParser::inferredConstant):
(JSC::DFG::ByteCodeParser::handleIntrinsic):
(JSC::DFG::ByteCodeParser::parseBlock):
* dfg/DFGNode.h:
* dfg/DFGNodeFlags.h:
* tests/stress/constand-folding-osr-exit.js: Added.
(foo):
(test):
(.var):

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

Source/JavaScriptCore/ChangeLog
Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp
Source/JavaScriptCore/dfg/DFGNode.h
Source/JavaScriptCore/dfg/DFGNodeFlags.h
Source/JavaScriptCore/tests/stress/constand-folding-osr-exit.js [new file with mode: 0644]

index 92e225f..0fa360c 100644 (file)
@@ -1,3 +1,30 @@
+2014-03-21  Filip Pizlo  <fpizlo@apple.com>
+
+        Constants folded by DFG::ByteCodeParser should not be dead.
+        https://bugs.webkit.org/show_bug.cgi?id=130576
+
+        Reviewed by Mark Hahnenberg.
+        
+        This fixes bugs in the ByteCodeParser's constant folder by removing that constant folder. This
+        reduces the number of folders in JSC from fourish to just threeish (parser, DFG AI, and one
+        or more folders in LLVM). Doing so has no performance impact since the other constant folders
+        already subsume this one.
+        
+        Also added a test case for the specific bug that instigated this.
+
+        * dfg/DFGByteCodeParser.cpp:
+        (JSC::DFG::ByteCodeParser::getJSConstantForValue):
+        (JSC::DFG::ByteCodeParser::getJSConstant):
+        (JSC::DFG::ByteCodeParser::inferredConstant):
+        (JSC::DFG::ByteCodeParser::handleIntrinsic):
+        (JSC::DFG::ByteCodeParser::parseBlock):
+        * dfg/DFGNode.h:
+        * dfg/DFGNodeFlags.h:
+        * tests/stress/constand-folding-osr-exit.js: Added.
+        (foo):
+        (test):
+        (.var):
+
 2014-03-21  Mark Lam  <mark.lam@apple.com>
 
         StackLayoutPhase should find the union'ed calleeVariable before accessing its machineLocal.
index 7d723e8..1d67993 100644 (file)
@@ -530,7 +530,7 @@ private:
     // constant folding. I.e. creating constants using this if we had constant
     // field inference would be a bad idea, since the bytecode parser's folding
     // doesn't handle liveness preservation.
-    Node* getJSConstantForValue(JSValue constantValue, NodeFlags flags = NodeIsStaticConstant)
+    Node* getJSConstantForValue(JSValue constantValue)
     {
         unsigned constantIndex;
         if (!m_codeBlock->findConstant(constantValue, constantIndex)) {
@@ -540,17 +540,16 @@ private:
         
         ASSERT(m_constants.size() == m_codeBlock->numberOfConstantRegisters());
         
-        return getJSConstant(constantIndex, flags);
+        return getJSConstant(constantIndex);
     }
 
-    Node* getJSConstant(unsigned constant, NodeFlags flags = NodeIsStaticConstant)
+    Node* getJSConstant(unsigned constant)
     {
         Node* node = m_constants[constant].asJSValue;
         if (node)
             return node;
 
         Node* result = addToGraph(JSConstant, OpInfo(constant));
-        result->mergeFlags(flags);
         m_constants[constant].asJSValue = result;
         return result;
     }
@@ -704,7 +703,7 @@ private:
     {
         if (value.isCell())
             return cellConstant(value.asCell());
-        return getJSConstantForValue(value, 0);
+        return getJSConstantForValue(value);
     }
     
     InlineCallFrame* inlineCallFrame()
@@ -717,20 +716,6 @@ private:
         return CodeOrigin(m_currentIndex, inlineCallFrame());
     }
     
-    bool canFold(Node* node)
-    {
-        if (Options::validateFTLOSRExitLiveness()) {
-            // The static folding that the bytecode parser does results in the DFG
-            // being able to do some DCE that the bytecode liveness analysis would
-            // miss. Hence, we disable the static folding if we're validating FTL OSR
-            // exit liveness. This may be brutish, but this validator is powerful
-            // enough that it's worth it.
-            return false;
-        }
-        
-        return node->isStronglyProvedConstantIn(inlineCallFrame());
-    }
-
     BranchData* branchData(unsigned taken, unsigned notTaken)
     {
         // We assume that branches originating from bytecode always have a fall-through. We
@@ -1697,7 +1682,7 @@ bool ByteCodeParser::handleIntrinsic(int resultOperand, Intrinsic intrinsic, int
     }
         
     case DFGTrue: {
-        set(VirtualRegister(resultOperand), getJSConstantForValue(jsBoolean(true), 0));
+        set(VirtualRegister(resultOperand), getJSConstantForValue(jsBoolean(true)));
         return true;
     }
         
@@ -2523,15 +2508,6 @@ bool ByteCodeParser::parseBlock(unsigned limit)
         case op_less: {
             Node* op1 = get(VirtualRegister(currentInstruction[2].u.operand));
             Node* op2 = get(VirtualRegister(currentInstruction[3].u.operand));
-            if (canFold(op1) && canFold(op2)) {
-                JSValue a = valueOfJSConstant(op1);
-                JSValue b = valueOfJSConstant(op2);
-                if (a.isNumber() && b.isNumber()) {
-                    set(VirtualRegister(currentInstruction[1].u.operand),
-                        getJSConstantForValue(jsBoolean(a.asNumber() < b.asNumber())));
-                    NEXT_OPCODE(op_less);
-                }
-            }
             set(VirtualRegister(currentInstruction[1].u.operand), addToGraph(CompareLess, op1, op2));
             NEXT_OPCODE(op_less);
         }
@@ -2539,15 +2515,6 @@ bool ByteCodeParser::parseBlock(unsigned limit)
         case op_lesseq: {
             Node* op1 = get(VirtualRegister(currentInstruction[2].u.operand));
             Node* op2 = get(VirtualRegister(currentInstruction[3].u.operand));
-            if (canFold(op1) && canFold(op2)) {
-                JSValue a = valueOfJSConstant(op1);
-                JSValue b = valueOfJSConstant(op2);
-                if (a.isNumber() && b.isNumber()) {
-                    set(VirtualRegister(currentInstruction[1].u.operand),
-                        getJSConstantForValue(jsBoolean(a.asNumber() <= b.asNumber())));
-                    NEXT_OPCODE(op_lesseq);
-                }
-            }
             set(VirtualRegister(currentInstruction[1].u.operand), addToGraph(CompareLessEq, op1, op2));
             NEXT_OPCODE(op_lesseq);
         }
@@ -2555,15 +2522,6 @@ bool ByteCodeParser::parseBlock(unsigned limit)
         case op_greater: {
             Node* op1 = get(VirtualRegister(currentInstruction[2].u.operand));
             Node* op2 = get(VirtualRegister(currentInstruction[3].u.operand));
-            if (canFold(op1) && canFold(op2)) {
-                JSValue a = valueOfJSConstant(op1);
-                JSValue b = valueOfJSConstant(op2);
-                if (a.isNumber() && b.isNumber()) {
-                    set(VirtualRegister(currentInstruction[1].u.operand),
-                        getJSConstantForValue(jsBoolean(a.asNumber() > b.asNumber())));
-                    NEXT_OPCODE(op_greater);
-                }
-            }
             set(VirtualRegister(currentInstruction[1].u.operand), addToGraph(CompareGreater, op1, op2));
             NEXT_OPCODE(op_greater);
         }
@@ -2571,15 +2529,6 @@ bool ByteCodeParser::parseBlock(unsigned limit)
         case op_greatereq: {
             Node* op1 = get(VirtualRegister(currentInstruction[2].u.operand));
             Node* op2 = get(VirtualRegister(currentInstruction[3].u.operand));
-            if (canFold(op1) && canFold(op2)) {
-                JSValue a = valueOfJSConstant(op1);
-                JSValue b = valueOfJSConstant(op2);
-                if (a.isNumber() && b.isNumber()) {
-                    set(VirtualRegister(currentInstruction[1].u.operand),
-                        getJSConstantForValue(jsBoolean(a.asNumber() >= b.asNumber())));
-                    NEXT_OPCODE(op_greatereq);
-                }
-            }
             set(VirtualRegister(currentInstruction[1].u.operand), addToGraph(CompareGreaterEq, op1, op2));
             NEXT_OPCODE(op_greatereq);
         }
@@ -2587,13 +2536,6 @@ bool ByteCodeParser::parseBlock(unsigned limit)
         case op_eq: {
             Node* op1 = get(VirtualRegister(currentInstruction[2].u.operand));
             Node* op2 = get(VirtualRegister(currentInstruction[3].u.operand));
-            if (canFold(op1) && canFold(op2)) {
-                JSValue a = valueOfJSConstant(op1);
-                JSValue b = valueOfJSConstant(op2);
-                set(VirtualRegister(currentInstruction[1].u.operand),
-                    getJSConstantForValue(jsBoolean(JSValue::equal(m_codeBlock->globalObject()->globalExec(), a, b))));
-                NEXT_OPCODE(op_eq);
-            }
             set(VirtualRegister(currentInstruction[1].u.operand), addToGraph(CompareEq, op1, op2));
             NEXT_OPCODE(op_eq);
         }
@@ -2607,13 +2549,6 @@ bool ByteCodeParser::parseBlock(unsigned limit)
         case op_stricteq: {
             Node* op1 = get(VirtualRegister(currentInstruction[2].u.operand));
             Node* op2 = get(VirtualRegister(currentInstruction[3].u.operand));
-            if (canFold(op1) && canFold(op2)) {
-                JSValue a = valueOfJSConstant(op1);
-                JSValue b = valueOfJSConstant(op2);
-                set(VirtualRegister(currentInstruction[1].u.operand),
-                    getJSConstantForValue(jsBoolean(JSValue::strictEqual(m_codeBlock->globalObject()->globalExec(), a, b))));
-                NEXT_OPCODE(op_stricteq);
-            }
             set(VirtualRegister(currentInstruction[1].u.operand), addToGraph(CompareStrictEq, op1, op2));
             NEXT_OPCODE(op_stricteq);
         }
@@ -2621,13 +2556,6 @@ bool ByteCodeParser::parseBlock(unsigned limit)
         case op_neq: {
             Node* op1 = get(VirtualRegister(currentInstruction[2].u.operand));
             Node* op2 = get(VirtualRegister(currentInstruction[3].u.operand));
-            if (canFold(op1) && canFold(op2)) {
-                JSValue a = valueOfJSConstant(op1);
-                JSValue b = valueOfJSConstant(op2);
-                set(VirtualRegister(currentInstruction[1].u.operand),
-                    getJSConstantForValue(jsBoolean(!JSValue::equal(m_codeBlock->globalObject()->globalExec(), a, b))));
-                NEXT_OPCODE(op_neq);
-            }
             set(VirtualRegister(currentInstruction[1].u.operand), addToGraph(LogicalNot, addToGraph(CompareEq, op1, op2)));
             NEXT_OPCODE(op_neq);
         }
@@ -2641,13 +2569,6 @@ bool ByteCodeParser::parseBlock(unsigned limit)
         case op_nstricteq: {
             Node* op1 = get(VirtualRegister(currentInstruction[2].u.operand));
             Node* op2 = get(VirtualRegister(currentInstruction[3].u.operand));
-            if (canFold(op1) && canFold(op2)) {
-                JSValue a = valueOfJSConstant(op1);
-                JSValue b = valueOfJSConstant(op2);
-                set(VirtualRegister(currentInstruction[1].u.operand),
-                    getJSConstantForValue(jsBoolean(!JSValue::strictEqual(m_codeBlock->globalObject()->globalExec(), a, b))));
-                NEXT_OPCODE(op_nstricteq);
-            }
             Node* invertedResult;
             invertedResult = addToGraph(CompareStrictEq, op1, op2);
             set(VirtualRegister(currentInstruction[1].u.operand), addToGraph(LogicalNot, invertedResult));
@@ -2752,18 +2673,6 @@ bool ByteCodeParser::parseBlock(unsigned limit)
         case op_jtrue: {
             unsigned relativeOffset = currentInstruction[2].u.operand;
             Node* condition = get(VirtualRegister(currentInstruction[1].u.operand));
-            if (canFold(condition)) {
-                TriState state = valueOfJSConstant(condition).pureToBoolean();
-                if (state == TrueTriState) {
-                    addToGraph(Jump, OpInfo(m_currentIndex + relativeOffset));
-                    LAST_OPCODE(op_jtrue);
-                } else if (state == FalseTriState) {
-                    // Emit a placeholder for this bytecode operation but otherwise
-                    // just fall through.
-                    addToGraph(Phantom);
-                    NEXT_OPCODE(op_jtrue);
-                }
-            }
             addToGraph(Branch, OpInfo(branchData(m_currentIndex + relativeOffset, m_currentIndex + OPCODE_LENGTH(op_jtrue))), condition);
             LAST_OPCODE(op_jtrue);
         }
@@ -2771,18 +2680,6 @@ bool ByteCodeParser::parseBlock(unsigned limit)
         case op_jfalse: {
             unsigned relativeOffset = currentInstruction[2].u.operand;
             Node* condition = get(VirtualRegister(currentInstruction[1].u.operand));
-            if (canFold(condition)) {
-                TriState state = valueOfJSConstant(condition).pureToBoolean();
-                if (state == FalseTriState) {
-                    addToGraph(Jump, OpInfo(m_currentIndex + relativeOffset));
-                    LAST_OPCODE(op_jfalse);
-                } else if (state == TrueTriState) {
-                    // Emit a placeholder for this bytecode operation but otherwise
-                    // just fall through.
-                    addToGraph(Phantom);
-                    NEXT_OPCODE(op_jfalse);
-                }
-            }
             addToGraph(Branch, OpInfo(branchData(m_currentIndex + OPCODE_LENGTH(op_jfalse), m_currentIndex + relativeOffset)), condition);
             LAST_OPCODE(op_jfalse);
         }
@@ -2807,23 +2704,6 @@ bool ByteCodeParser::parseBlock(unsigned limit)
             unsigned relativeOffset = currentInstruction[3].u.operand;
             Node* op1 = get(VirtualRegister(currentInstruction[1].u.operand));
             Node* op2 = get(VirtualRegister(currentInstruction[2].u.operand));
-            if (canFold(op1) && canFold(op2)) {
-                JSValue aValue = valueOfJSConstant(op1);
-                JSValue bValue = valueOfJSConstant(op2);
-                if (aValue.isNumber() && bValue.isNumber()) {
-                    double a = aValue.asNumber();
-                    double b = bValue.asNumber();
-                    if (a < b) {
-                        addToGraph(Jump, OpInfo(m_currentIndex + relativeOffset));
-                        LAST_OPCODE(op_jless);
-                    } else {
-                        // Emit a placeholder for this bytecode operation but otherwise
-                        // just fall through.
-                        addToGraph(Phantom);
-                        NEXT_OPCODE(op_jless);
-                    }
-                }
-            }
             Node* condition = addToGraph(CompareLess, op1, op2);
             addToGraph(Branch, OpInfo(branchData(m_currentIndex + relativeOffset, m_currentIndex + OPCODE_LENGTH(op_jless))), condition);
             LAST_OPCODE(op_jless);
@@ -2833,23 +2713,6 @@ bool ByteCodeParser::parseBlock(unsigned limit)
             unsigned relativeOffset = currentInstruction[3].u.operand;
             Node* op1 = get(VirtualRegister(currentInstruction[1].u.operand));
             Node* op2 = get(VirtualRegister(currentInstruction[2].u.operand));
-            if (canFold(op1) && canFold(op2)) {
-                JSValue aValue = valueOfJSConstant(op1);
-                JSValue bValue = valueOfJSConstant(op2);
-                if (aValue.isNumber() && bValue.isNumber()) {
-                    double a = aValue.asNumber();
-                    double b = bValue.asNumber();
-                    if (a <= b) {
-                        addToGraph(Jump, OpInfo(m_currentIndex + relativeOffset));
-                        LAST_OPCODE(op_jlesseq);
-                    } else {
-                        // Emit a placeholder for this bytecode operation but otherwise
-                        // just fall through.
-                        addToGraph(Phantom);
-                        NEXT_OPCODE(op_jlesseq);
-                    }
-                }
-            }
             Node* condition = addToGraph(CompareLessEq, op1, op2);
             addToGraph(Branch, OpInfo(branchData(m_currentIndex + relativeOffset, m_currentIndex + OPCODE_LENGTH(op_jlesseq))), condition);
             LAST_OPCODE(op_jlesseq);
@@ -2859,23 +2722,6 @@ bool ByteCodeParser::parseBlock(unsigned limit)
             unsigned relativeOffset = currentInstruction[3].u.operand;
             Node* op1 = get(VirtualRegister(currentInstruction[1].u.operand));
             Node* op2 = get(VirtualRegister(currentInstruction[2].u.operand));
-            if (canFold(op1) && canFold(op2)) {
-                JSValue aValue = valueOfJSConstant(op1);
-                JSValue bValue = valueOfJSConstant(op2);
-                if (aValue.isNumber() && bValue.isNumber()) {
-                    double a = aValue.asNumber();
-                    double b = bValue.asNumber();
-                    if (a > b) {
-                        addToGraph(Jump, OpInfo(m_currentIndex + relativeOffset));
-                        LAST_OPCODE(op_jgreater);
-                    } else {
-                        // Emit a placeholder for this bytecode operation but otherwise
-                        // just fall through.
-                        addToGraph(Phantom);
-                        NEXT_OPCODE(op_jgreater);
-                    }
-                }
-            }
             Node* condition = addToGraph(CompareGreater, op1, op2);
             addToGraph(Branch, OpInfo(branchData(m_currentIndex + relativeOffset, m_currentIndex + OPCODE_LENGTH(op_jgreater))), condition);
             LAST_OPCODE(op_jgreater);
@@ -2885,23 +2731,6 @@ bool ByteCodeParser::parseBlock(unsigned limit)
             unsigned relativeOffset = currentInstruction[3].u.operand;
             Node* op1 = get(VirtualRegister(currentInstruction[1].u.operand));
             Node* op2 = get(VirtualRegister(currentInstruction[2].u.operand));
-            if (canFold(op1) && canFold(op2)) {
-                JSValue aValue = valueOfJSConstant(op1);
-                JSValue bValue = valueOfJSConstant(op2);
-                if (aValue.isNumber() && bValue.isNumber()) {
-                    double a = aValue.asNumber();
-                    double b = bValue.asNumber();
-                    if (a >= b) {
-                        addToGraph(Jump, OpInfo(m_currentIndex + relativeOffset));
-                        LAST_OPCODE(op_jgreatereq);
-                    } else {
-                        // Emit a placeholder for this bytecode operation but otherwise
-                        // just fall through.
-                        addToGraph(Phantom);
-                        NEXT_OPCODE(op_jgreatereq);
-                    }
-                }
-            }
             Node* condition = addToGraph(CompareGreaterEq, op1, op2);
             addToGraph(Branch, OpInfo(branchData(m_currentIndex + relativeOffset, m_currentIndex + OPCODE_LENGTH(op_jgreatereq))), condition);
             LAST_OPCODE(op_jgreatereq);
@@ -2911,23 +2740,6 @@ bool ByteCodeParser::parseBlock(unsigned limit)
             unsigned relativeOffset = currentInstruction[3].u.operand;
             Node* op1 = get(VirtualRegister(currentInstruction[1].u.operand));
             Node* op2 = get(VirtualRegister(currentInstruction[2].u.operand));
-            if (canFold(op1) && canFold(op2)) {
-                JSValue aValue = valueOfJSConstant(op1);
-                JSValue bValue = valueOfJSConstant(op2);
-                if (aValue.isNumber() && bValue.isNumber()) {
-                    double a = aValue.asNumber();
-                    double b = bValue.asNumber();
-                    if (a < b) {
-                        // Emit a placeholder for this bytecode operation but otherwise
-                        // just fall through.
-                        addToGraph(Phantom);
-                        NEXT_OPCODE(op_jnless);
-                    } else {
-                        addToGraph(Jump, OpInfo(m_currentIndex + relativeOffset));
-                        LAST_OPCODE(op_jnless);
-                    }
-                }
-            }
             Node* condition = addToGraph(CompareLess, op1, op2);
             addToGraph(Branch, OpInfo(branchData(m_currentIndex + OPCODE_LENGTH(op_jnless), m_currentIndex + relativeOffset)), condition);
             LAST_OPCODE(op_jnless);
@@ -2937,23 +2749,6 @@ bool ByteCodeParser::parseBlock(unsigned limit)
             unsigned relativeOffset = currentInstruction[3].u.operand;
             Node* op1 = get(VirtualRegister(currentInstruction[1].u.operand));
             Node* op2 = get(VirtualRegister(currentInstruction[2].u.operand));
-            if (canFold(op1) && canFold(op2)) {
-                JSValue aValue = valueOfJSConstant(op1);
-                JSValue bValue = valueOfJSConstant(op2);
-                if (aValue.isNumber() && bValue.isNumber()) {
-                    double a = aValue.asNumber();
-                    double b = bValue.asNumber();
-                    if (a <= b) {
-                        // Emit a placeholder for this bytecode operation but otherwise
-                        // just fall through.
-                        addToGraph(Phantom);
-                        NEXT_OPCODE(op_jnlesseq);
-                    } else {
-                        addToGraph(Jump, OpInfo(m_currentIndex + relativeOffset));
-                        LAST_OPCODE(op_jnlesseq);
-                    }
-                }
-            }
             Node* condition = addToGraph(CompareLessEq, op1, op2);
             addToGraph(Branch, OpInfo(branchData(m_currentIndex + OPCODE_LENGTH(op_jnlesseq), m_currentIndex + relativeOffset)), condition);
             LAST_OPCODE(op_jnlesseq);
@@ -2963,23 +2758,6 @@ bool ByteCodeParser::parseBlock(unsigned limit)
             unsigned relativeOffset = currentInstruction[3].u.operand;
             Node* op1 = get(VirtualRegister(currentInstruction[1].u.operand));
             Node* op2 = get(VirtualRegister(currentInstruction[2].u.operand));
-            if (canFold(op1) && canFold(op2)) {
-                JSValue aValue = valueOfJSConstant(op1);
-                JSValue bValue = valueOfJSConstant(op2);
-                if (aValue.isNumber() && bValue.isNumber()) {
-                    double a = aValue.asNumber();
-                    double b = bValue.asNumber();
-                    if (a > b) {
-                        // Emit a placeholder for this bytecode operation but otherwise
-                        // just fall through.
-                        addToGraph(Phantom);
-                        NEXT_OPCODE(op_jngreater);
-                    } else {
-                        addToGraph(Jump, OpInfo(m_currentIndex + relativeOffset));
-                        LAST_OPCODE(op_jngreater);
-                    }
-                }
-            }
             Node* condition = addToGraph(CompareGreater, op1, op2);
             addToGraph(Branch, OpInfo(branchData(m_currentIndex + OPCODE_LENGTH(op_jngreater), m_currentIndex + relativeOffset)), condition);
             LAST_OPCODE(op_jngreater);
@@ -2989,23 +2767,6 @@ bool ByteCodeParser::parseBlock(unsigned limit)
             unsigned relativeOffset = currentInstruction[3].u.operand;
             Node* op1 = get(VirtualRegister(currentInstruction[1].u.operand));
             Node* op2 = get(VirtualRegister(currentInstruction[2].u.operand));
-            if (canFold(op1) && canFold(op2)) {
-                JSValue aValue = valueOfJSConstant(op1);
-                JSValue bValue = valueOfJSConstant(op2);
-                if (aValue.isNumber() && bValue.isNumber()) {
-                    double a = aValue.asNumber();
-                    double b = bValue.asNumber();
-                    if (a >= b) {
-                        // Emit a placeholder for this bytecode operation but otherwise
-                        // just fall through.
-                        addToGraph(Phantom);
-                        NEXT_OPCODE(op_jngreatereq);
-                    } else {
-                        addToGraph(Jump, OpInfo(m_currentIndex + relativeOffset));
-                        LAST_OPCODE(op_jngreatereq);
-                    }
-                }
-            }
             Node* condition = addToGraph(CompareGreaterEq, op1, op2);
             addToGraph(Branch, OpInfo(branchData(m_currentIndex + OPCODE_LENGTH(op_jngreatereq), m_currentIndex + relativeOffset)), condition);
             LAST_OPCODE(op_jngreatereq);
index ff1f1a8..ed126b9 100644 (file)
@@ -376,17 +376,6 @@ struct Node {
         return op() == WeakJSConstant;
     }
     
-    bool isStronglyProvedConstantIn(InlineCallFrame* inlineCallFrame)
-    {
-        return !!(flags() & NodeIsStaticConstant)
-            && origin.semantic.inlineCallFrame == inlineCallFrame;
-    }
-    
-    bool isStronglyProvedConstantIn(const CodeOrigin& codeOrigin)
-    {
-        return isStronglyProvedConstantIn(codeOrigin.inlineCallFrame);
-    }
-    
     bool isPhantomArguments()
     {
         return op() == PhantomArguments;
index d02a7ce..b3cb112 100644 (file)
@@ -66,8 +66,7 @@ namespace JSC { namespace DFG {
 
 #define NodeRelevantToOSR                0x4000
 
-#define NodeIsStaticConstant             0x8000 // Used only by the parser, to determine if a constant arose statically and hence could be folded at parse-time.
-#define NodeIsFlushed                   0x10000 // Used by Graph::computeIsFlushed(), will tell you which local nodes are backwards-reachable from a Flush.
+#define NodeIsFlushed                    0x8000 // Used by Graph::computeIsFlushed(), will tell you which local nodes are backwards-reachable from a Flush.
 
 typedef uint32_t NodeFlags;
 
diff --git a/Source/JavaScriptCore/tests/stress/constand-folding-osr-exit.js b/Source/JavaScriptCore/tests/stress/constand-folding-osr-exit.js
new file mode 100644 (file)
index 0000000..12bbe18
--- /dev/null
@@ -0,0 +1,132 @@
+var foo = [
+    function(o) {
+        var x = true;
+        o.f.f;
+        if (x)
+            return;
+        throw new Error();
+    },
+    function(o) {
+        var x = true;
+        o.f.f;
+        if (!x)
+            throw new Error();
+        return;
+    },
+    function(o) {
+        var x = 0;
+        var y = 1;
+        o.f.f;
+        if (x < y)
+            return;
+        throw new Error();
+    },
+    function(o) {
+        var x = 1;
+        var y = 0;
+        o.f.f;
+        if (x > y)
+            return;
+        throw new Error();
+    },
+    function(o) {
+        var x = 0;
+        var y = 1;
+        o.f.f;
+        if (x <= y)
+            return;
+        throw new Error();
+    },
+    function(o) {
+        var x = 1;
+        var y = 0;
+        o.f.f;
+        if (x >= y)
+            return;
+        throw new Error();
+    },
+    function(o) {
+        var x = 0;
+        var y = 1;
+        o.f.f;
+        if (x >= y)
+            throw new Error();
+        return;
+    },
+    function(o) {
+        var x = 1;
+        var y = 0;
+        o.f.f;
+        if (x <= y)
+            throw new Error();
+        return;
+    },
+    function(o) {
+        var x = 0;
+        var y = 1;
+        o.f.f;
+        if (x > y)
+            throw new Error();
+        return;
+    },
+    function(o) {
+        var x = 1;
+        var y = 0;
+        o.f.f;
+        if (x < y)
+            throw new Error();
+        return;
+    },
+    function(o) {
+        var x = 42;
+        o.f.f;
+        if (x == 42)
+            return;
+        throw new Error();
+    },
+    function(o) {
+        var x = 42;
+        o.f.f;
+        if (x != 42)
+            throw new Error();
+        return;
+    },
+    function(o) {
+        var x = 42;
+        o.f.f;
+        if (x === 42)
+            return;
+        throw new Error();
+    },
+    function(o) {
+        var x = 42;
+        o.f.f;
+        if (x !== 42)
+            throw new Error();
+        return;
+    },
+];
+for (var i = 0; i < foo.length; ++i)
+    noInline(foo[i]);
+
+function test(o) {
+    var failed = [];
+    for (var i = 0; i < foo.length; ++i) {
+        try {
+            foo[i](o);
+        } catch (e) {
+            failed.push("Failed " + foo[i] + " with " + e);
+        }
+    }
+    if (failed.length)
+        throw failed;
+}
+
+var object = {f:{f:42}};
+
+for (var i = 0; i < 10000; ++i) {
+    test(object);
+}
+
+test({f:{g:43}});
+