FTL Int32ToDouble should handle the forward type check case where you need a recovery
authorfpizlo@apple.com <fpizlo@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 1 Nov 2013 00:45:47 +0000 (00:45 +0000)
committerfpizlo@apple.com <fpizlo@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 1 Nov 2013 00:45:47 +0000 (00:45 +0000)
https://bugs.webkit.org/show_bug.cgi?id=123605

Reviewed by Mark Hahnenberg.

If you have a Int32ToDouble that needs to do a type check and it's required to do a
forward exit, then it needs to manually pass in a value recovery for itself in the
OSR exit - since this is one of those forward-exiting nodes that doesn't have a
preceding MovHint.

* ftl/FTLLowerDFGToLLVM.cpp:
(JSC::FTL::LowerDFGToLLVM::compileInt32ToDouble):
(JSC::FTL::LowerDFGToLLVM::forwardTypeCheck):

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

Source/JavaScriptCore/ChangeLog
Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp

index 897d289..ff01783 100644 (file)
@@ -1,5 +1,21 @@
 2013-10-31  Filip Pizlo  <fpizlo@apple.com>
 
+        FTL Int32ToDouble should handle the forward type check case where you need a recovery
+        https://bugs.webkit.org/show_bug.cgi?id=123605
+
+        Reviewed by Mark Hahnenberg.
+        
+        If you have a Int32ToDouble that needs to do a type check and it's required to do a
+        forward exit, then it needs to manually pass in a value recovery for itself in the
+        OSR exit - since this is one of those forward-exiting nodes that doesn't have a
+        preceding MovHint.
+
+        * ftl/FTLLowerDFGToLLVM.cpp:
+        (JSC::FTL::LowerDFGToLLVM::compileInt32ToDouble):
+        (JSC::FTL::LowerDFGToLLVM::forwardTypeCheck):
+
+2013-10-31  Filip Pizlo  <fpizlo@apple.com>
+
         FTL should implement InvalidationPoint in terms of llvm.stackmap
         https://bugs.webkit.org/show_bug.cgi?id=113647
 
index 89e0c8a..d2654f2 100644 (file)
@@ -1091,14 +1091,40 @@ private:
     
     void compileInt32ToDouble()
     {
-        // This node is tricky to compile in the DFG backend because it tries to
-        // avoid converting child1 to a double in-place, as that would make subsequent
-        // int uses of of child1 fail. But the FTL needs no such special magic, since
-        // unlike the DFG backend, the FTL allows each node to have multiple
-        // contemporaneous low-level representations. So, this gives child1 a double
-        // representation and then forwards that representation to m_node.
+        if (!m_interpreter.needsTypeCheck(m_node->child1(), SpecFullNumber)
+            || m_node->speculationDirection() == BackwardSpeculation) {
+            setDouble(lowDouble(m_node->child1()));
+            return;
+        }
+        
+        LValue boxedValue = lowJSValue(m_node->child1(), ManualOperandSpeculation);
+        
+        LBasicBlock intCase = FTL_NEW_BLOCK(m_out, ("Double unboxing int case"));
+        LBasicBlock doubleCase = FTL_NEW_BLOCK(m_out, ("Double unboxing double case"));
+        LBasicBlock continuation = FTL_NEW_BLOCK(m_out, ("Double unboxing continuation"));
+        
+        m_out.branch(isNotInt32(boxedValue), doubleCase, intCase);
         
-        setDouble(lowDouble(m_node->child1()));
+        LBasicBlock lastNext = m_out.appendTo(intCase, doubleCase);
+        
+        ValueFromBlock intToDouble = m_out.anchor(
+            m_out.intToDouble(unboxInt32(boxedValue)));
+        m_out.jump(continuation);
+        
+        m_out.appendTo(doubleCase, continuation);
+
+        forwardTypeCheck(
+            jsValueValue(boxedValue), m_node->child1(), SpecFullNumber,
+            isCellOrMisc(boxedValue), jsValueValue(boxedValue));
+        
+        ValueFromBlock unboxedDouble = m_out.anchor(unboxDouble(boxedValue));
+        m_out.jump(continuation);
+        
+        m_out.appendTo(continuation, lastNext);
+        
+        LValue result = m_out.phi(m_out.doubleType, intToDouble, unboxedDouble);
+        
+        setDouble(result);
     }
     
     void compileCheckStructure()
@@ -2411,11 +2437,11 @@ private:
     
     void forwardTypeCheck(
         FormattedValue lowValue, Edge highValue, SpeculatedType typesPassedThrough,
-        LValue failCondition)
+        LValue failCondition, const FormattedValue& recovery)
     {
         appendTypeCheck(
             lowValue, highValue, typesPassedThrough, failCondition, ForwardSpeculation,
-            FormattedValue());
+            recovery);
     }
     
     void typeCheck(