Diff
Modified: trunk/Source/_javascript_Core/ChangeLog (195487 => 195488)
--- trunk/Source/_javascript_Core/ChangeLog 2016-01-22 23:26:42 UTC (rev 195487)
+++ trunk/Source/_javascript_Core/ChangeLog 2016-01-22 23:30:07 UTC (rev 195488)
@@ -1,3 +1,32 @@
+2016-01-22 Mark Lam <[email protected]>
+
+ We should OSR exit with Int52Overflow when we fail to make an Int52 where we expect one.
+ https://bugs.webkit.org/show_bug.cgi?id=153379
+
+ Reviewed by Filip Pizlo.
+
+ In DFG::Graph::addShouldSpeculateMachineInt(), we check
+ !hasExitSite(add, Int52Overflow) when determining whether it's ok to speculate
+ that an operand is of type Int52 or not. However, the Int52Rep code that
+ converts a double to Int52 will OSR exit with exit kind BadType instead.
+ This renders the hasExitSite() check in addShouldSpeculateMachineInt() useless.
+ This patch fixes this by changing Int52Rep to OSR exit with exit kind
+ Int52Overflow instead when it fails to convert a double to an Int52.
+
+ * dfg/DFGSpeculativeJIT.cpp:
+ (JSC::DFG::SpeculativeJIT::terminateSpeculativeExecution):
+ (JSC::DFG::SpeculativeJIT::typeCheck):
+ (JSC::DFG::SpeculativeJIT::usedRegisters):
+ * dfg/DFGSpeculativeJIT.h:
+ (JSC::DFG::SpeculativeJIT::needsTypeCheck):
+ (JSC::DFG::SpeculativeJIT::speculateStringObjectForStructure):
+ * dfg/DFGSpeculativeJIT64.cpp:
+ (JSC::DFG::SpeculativeJIT::compile):
+ * ftl/FTLLowerDFGToLLVM.cpp:
+ (JSC::FTL::DFG::LowerDFGToLLVM::typeCheck):
+ (JSC::FTL::DFG::LowerDFGToLLVM::appendTypeCheck):
+ (JSC::FTL::DFG::LowerDFGToLLVM::doubleToStrictInt52):
+
2016-01-22 Saam barati <[email protected]>
Current implementation of Parser::createSavePoint is a foot gun
Modified: trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.cpp (195487 => 195488)
--- trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.cpp 2016-01-22 23:26:42 UTC (rev 195487)
+++ trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.cpp 2016-01-22 23:30:07 UTC (rev 195488)
@@ -298,11 +298,11 @@
terminateSpeculativeExecution(kind, jsValueRegs, nodeUse.node());
}
-void SpeculativeJIT::typeCheck(JSValueSource source, Edge edge, SpeculatedType typesPassedThrough, MacroAssembler::Jump jumpToFail)
+void SpeculativeJIT::typeCheck(JSValueSource source, Edge edge, SpeculatedType typesPassedThrough, MacroAssembler::Jump jumpToFail, ExitKind exitKind)
{
ASSERT(needsTypeCheck(edge, typesPassedThrough));
m_interpreter.filter(edge, typesPassedThrough);
- speculationCheck(BadType, source, edge.node(), jumpToFail);
+ speculationCheck(exitKind, source, edge.node(), jumpToFail);
}
RegisterSet SpeculativeJIT::usedRegisters()
Modified: trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.h (195487 => 195488)
--- trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.h 2016-01-22 23:26:42 UTC (rev 195487)
+++ trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.h 2016-01-22 23:30:07 UTC (rev 195488)
@@ -2447,7 +2447,7 @@
// Helpers for performing type checks on an edge stored in the given registers.
bool needsTypeCheck(Edge edge, SpeculatedType typesPassedThrough) { return m_interpreter.needsTypeCheck(edge, typesPassedThrough); }
- void typeCheck(JSValueSource, Edge, SpeculatedType typesPassedThrough, MacroAssembler::Jump jumpToFail);
+ void typeCheck(JSValueSource, Edge, SpeculatedType typesPassedThrough, MacroAssembler::Jump jumpToFail, ExitKind = BadType);
void speculateCellTypeWithoutTypeFiltering(Edge, GPRReg cellGPR, JSType);
void speculateCellType(Edge, GPRReg cellGPR, SpeculatedType, JSType);
@@ -3379,15 +3379,18 @@
}
}
-#define DFG_TYPE_CHECK(source, edge, typesPassedThrough, jumpToFail) do { \
+#define DFG_TYPE_CHECK_WITH_EXIT_KIND(exitKind, source, edge, typesPassedThrough, jumpToFail) do { \
JSValueSource _dtc_source = (source); \
Edge _dtc_edge = (edge); \
SpeculatedType _dtc_typesPassedThrough = typesPassedThrough; \
if (!needsTypeCheck(_dtc_edge, _dtc_typesPassedThrough)) \
break; \
- typeCheck(_dtc_source, _dtc_edge, _dtc_typesPassedThrough, (jumpToFail)); \
+ typeCheck(_dtc_source, _dtc_edge, _dtc_typesPassedThrough, (jumpToFail), exitKind); \
} while (0)
+#define DFG_TYPE_CHECK(source, edge, typesPassedThrough, jumpToFail) \
+ DFG_TYPE_CHECK_WITH_EXIT_KIND(BadType, source, edge, typesPassedThrough, jumpToFail)
+
} } // namespace JSC::DFG
#endif
Modified: trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT64.cpp (195487 => 195488)
--- trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT64.cpp 2016-01-22 23:26:42 UTC (rev 195487)
+++ trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT64.cpp 2016-01-22 23:30:07 UTC (rev 195488)
@@ -2211,7 +2211,7 @@
callOperation(operationConvertDoubleToInt52, resultGPR, valueFPR);
- DFG_TYPE_CHECK(
+ DFG_TYPE_CHECK_WITH_EXIT_KIND(Int52Overflow,
JSValueRegs(), node->child1(), SpecInt52AsDouble,
m_jit.branch64(
JITCompiler::Equal, resultGPR,
Modified: trunk/Source/_javascript_Core/ftl/FTLLowerDFGToLLVM.cpp (195487 => 195488)
--- trunk/Source/_javascript_Core/ftl/FTLLowerDFGToLLVM.cpp 2016-01-22 23:26:42 UTC (rev 195487)
+++ trunk/Source/_javascript_Core/ftl/FTLLowerDFGToLLVM.cpp 2016-01-22 23:30:07 UTC (rev 195488)
@@ -109,15 +109,18 @@
// Using this instead of typeCheck() helps to reduce the load on LLVM, by creating
// significantly less dead code.
-#define FTL_TYPE_CHECK(lowValue, highValue, typesPassedThrough, failCondition) do { \
+#define FTL_TYPE_CHECK_WITH_EXIT_KIND(exitKind, lowValue, highValue, typesPassedThrough, failCondition) do { \
FormattedValue _ftc_lowValue = (lowValue); \
Edge _ftc_highValue = (highValue); \
SpeculatedType _ftc_typesPassedThrough = (typesPassedThrough); \
if (!m_interpreter.needsTypeCheck(_ftc_highValue, _ftc_typesPassedThrough)) \
break; \
- typeCheck(_ftc_lowValue, _ftc_highValue, _ftc_typesPassedThrough, (failCondition)); \
+ typeCheck(_ftc_lowValue, _ftc_highValue, _ftc_typesPassedThrough, (failCondition), exitKind); \
} while (false)
+#define FTL_TYPE_CHECK(lowValue, highValue, typesPassedThrough, failCondition) \
+ FTL_TYPE_CHECK_WITH_EXIT_KIND(BadType, lowValue, highValue, typesPassedThrough, failCondition)
+
class LowerDFGToLLVM {
WTF_MAKE_NONCOPYABLE(LowerDFGToLLVM);
public:
@@ -8974,19 +8977,19 @@
void typeCheck(
FormattedValue lowValue, Edge highValue, SpeculatedType typesPassedThrough,
- LValue failCondition)
+ LValue failCondition, ExitKind exitKind = BadType)
{
- appendTypeCheck(lowValue, highValue, typesPassedThrough, failCondition);
+ appendTypeCheck(lowValue, highValue, typesPassedThrough, failCondition, exitKind);
}
void appendTypeCheck(
FormattedValue lowValue, Edge highValue, SpeculatedType typesPassedThrough,
- LValue failCondition)
+ LValue failCondition, ExitKind exitKind)
{
if (!m_interpreter.needsTypeCheck(highValue, typesPassedThrough))
return;
ASSERT(mayHaveTypeCheck(highValue.useKind()));
- appendOSRExit(BadType, lowValue, highValue.node(), failCondition, m_origin);
+ appendOSRExit(exitKind, lowValue, highValue.node(), failCondition, m_origin);
m_interpreter.filter(highValue, typesPassedThrough);
}
@@ -9399,7 +9402,7 @@
{
LValue possibleResult = m_out.call(
m_out.int64, m_out.operation(operationConvertDoubleToInt52), value);
- FTL_TYPE_CHECK(
+ FTL_TYPE_CHECK_WITH_EXIT_KIND(Int52Overflow,
doubleValue(value), edge, SpecInt52AsDouble,
m_out.equal(possibleResult, m_out.constInt64(JSValue::notInt52)));