Modified: trunk/Source/_javascript_Core/ChangeLog (158411 => 158412)
--- trunk/Source/_javascript_Core/ChangeLog 2013-11-01 00:35:53 UTC (rev 158411)
+++ trunk/Source/_javascript_Core/ChangeLog 2013-11-01 00:45:47 UTC (rev 158412)
@@ -1,5 +1,21 @@
2013-10-31 Filip Pizlo <[email protected]>
+ 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 <[email protected]>
+
FTL should implement InvalidationPoint in terms of llvm.stackmap
https://bugs.webkit.org/show_bug.cgi?id=113647
Modified: trunk/Source/_javascript_Core/ftl/FTLLowerDFGToLLVM.cpp (158411 => 158412)
--- trunk/Source/_javascript_Core/ftl/FTLLowerDFGToLLVM.cpp 2013-11-01 00:35:53 UTC (rev 158411)
+++ trunk/Source/_javascript_Core/ftl/FTLLowerDFGToLLVM.cpp 2013-11-01 00:45:47 UTC (rev 158412)
@@ -1091,14 +1091,40 @@
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;
+ }
- setDouble(lowDouble(m_node->child1()));
+ 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);
+
+ 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 @@
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(