Diff
Modified: trunk/Source/_javascript_Core/ChangeLog (153155 => 153156)
--- trunk/Source/_javascript_Core/ChangeLog 2013-07-25 04:00:00 UTC (rev 153155)
+++ trunk/Source/_javascript_Core/ChangeLog 2013-07-25 04:00:02 UTC (rev 153156)
@@ -1,3 +1,36 @@
+2013-05-11 Filip Pizlo <[email protected]>
+
+ fourthTier: FTL should support Jump and ForceOSRExit
+ https://bugs.webkit.org/show_bug.cgi?id=115942
+
+ Reviewed by Oliver Hunt.
+
+ Added two obvious nodes: Jump and ForceOSRExit. We already had everything we needed
+ to support them.
+
+ Adding these increases our coverage a fair bit, and revealed a bug: LLVM's full
+ instruction selector currently appears to mishandle doubles in constant pools (or
+ just constant pools in general) with the small code model in the MCJIT. But switching
+ to FastISel "fixes" it. That's what this patch does, for now. This will probably
+ actually be permanent; the FastISel does pretty much everything we would ever want,
+ at least in the foreseeable future.
+
+ * ftl/FTLCapabilities.cpp:
+ (JSC::FTL::canCompile):
+ (FTL):
+ * ftl/FTLCompile.cpp:
+ (JSC::FTL::compile):
+ * ftl/FTLLowerDFGToLLVM.cpp:
+ (JSC::FTL::LowerDFGToLLVM::compileBlock):
+ (JSC::FTL::LowerDFGToLLVM::compileNode):
+ (JSC::FTL::LowerDFGToLLVM::compileJSConstant):
+ (LowerDFGToLLVM):
+ (JSC::FTL::LowerDFGToLLVM::compileJump):
+ (JSC::FTL::LowerDFGToLLVM::compileReturn):
+ (JSC::FTL::LowerDFGToLLVM::compileForceOSRExit):
+ * runtime/Options.h:
+ (JSC):
+
2013-05-10 Filip Pizlo <[email protected]>
fourthTier: FTL should support CompareStrictEqConstant
Modified: trunk/Source/_javascript_Core/_javascript_Core.xcodeproj/project.pbxproj (153155 => 153156)
--- trunk/Source/_javascript_Core/_javascript_Core.xcodeproj/project.pbxproj 2013-07-25 04:00:00 UTC (rev 153155)
+++ trunk/Source/_javascript_Core/_javascript_Core.xcodeproj/project.pbxproj 2013-07-25 04:00:02 UTC (rev 153156)
@@ -2033,9 +2033,9 @@
034768DFFF38A50411DB9C8B /* Products */ = {
isa = PBXGroup;
children = (
+ 0FF922CF14F46B130041A24E /* JSCLLIntOffsetsExtractor */,
932F5BD90822A1C700736975 /* _javascript_Core.framework */,
932F5BE10822A1C700736975 /* jsc */,
- 0FF922CF14F46B130041A24E /* JSCLLIntOffsetsExtractor */,
141211200A48793C00480255 /* minidom */,
14BD59BF0A3E8F9000BAF59C /* testapi */,
6511230514046A4C002B101D /* testRegExp */,
@@ -3379,6 +3379,7 @@
0F21C27C14BE727600ADC64B /* ExecutionHarness.h in Headers */,
0FB105861675481200F8AB6E /* ExitKind.h in Headers */,
0F0B83AB14BCF5BB00885B4F /* ExpressionRangeInfo.h in Headers */,
+ 0FDB2CC9173DA520007B3C1B /* FTLAbbreviatedTypes.h in Headers */,
0FEA0A08170513DB00BB722C /* FTLAbbreviations.h in Headers */,
0FEA0A1D1708B00700BB722C /* FTLAbstractHeap.h in Headers */,
0FEA0A1F1708B00700BB722C /* FTLAbstractHeapRepository.h in Headers */,
@@ -3405,6 +3406,7 @@
0F235BE217178E1C00690C7F /* FTLThunks.h in Headers */,
0FEA0A201708B00700BB722C /* FTLTypedPointer.h in Headers */,
0F235BE417178E1C00690C7F /* FTLValueFormat.h in Headers */,
+ 0FDB2CCA173DA523007B3C1B /* FTLValueFromBlock.h in Headers */,
0F235BE617178E1C00690C7F /* FTLValueSource.h in Headers */,
BC18C4040E16F5CD00B34460 /* FunctionConstructor.h in Headers */,
0FF0F1A016B72A1A005DF95B /* FunctionExecutableDump.h in Headers */,
@@ -3507,7 +3509,6 @@
0F919D0D157EE0A2004A4E7D /* JSSymbolTableObject.h in Headers */,
BC18C42A0E16F5CD00B34460 /* JSType.h in Headers */,
6507D29E0E871E5E00D7D896 /* JSTypeInfo.h in Headers */,
- 0FDB2CCA173DA523007B3C1B /* FTLValueFromBlock.h in Headers */,
86E3C612167BABD7006D760A /* JSValue.h in Headers */,
86E3C61B167BABEE006D760A /* JSValueInternal.h in Headers */,
BC18C42C0E16F5CD00B34460 /* JSValueRef.h in Headers */,
@@ -3614,7 +3615,6 @@
0FF729BE166AD360000F5BA3 /* ProfilerExecutionCounter.h in Headers */,
0FF729BF166AD360000F5BA3 /* ProfilerOrigin.h in Headers */,
0FF729C0166AD360000F5BA3 /* ProfilerOriginStack.h in Headers */,
- 0FDB2CC9173DA520007B3C1B /* FTLAbbreviatedTypes.h in Headers */,
0FB1058C1675483300F8AB6E /* ProfilerOSRExit.h in Headers */,
0FB1058E1675483A00F8AB6E /* ProfilerOSRExitSite.h in Headers */,
0F13912C16771C3D009CCB07 /* ProfilerProfiledBytecodes.h in Headers */,
Modified: trunk/Source/_javascript_Core/ftl/FTLCapabilities.cpp (153155 => 153156)
--- trunk/Source/_javascript_Core/ftl/FTLCapabilities.cpp 2013-07-25 04:00:00 UTC (rev 153155)
+++ trunk/Source/_javascript_Core/ftl/FTLCapabilities.cpp 2013-07-25 04:00:02 UTC (rev 153156)
@@ -32,6 +32,108 @@
using namespace DFG;
+inline bool canCompile(Node* node)
+{
+ switch (node->op()) {
+ case JSConstant:
+ case WeakJSConstant:
+ case GetLocal:
+ case SetLocal:
+ case MovHintAndCheck:
+ case MovHint:
+ case ZombieHint:
+ case Phantom:
+ case Flush:
+ case PhantomLocal:
+ case SetArgument:
+ case Return:
+ case BitAnd:
+ case BitOr:
+ case BitXor:
+ case BitRShift:
+ case BitLShift:
+ case BitURShift:
+ case CheckStructure:
+ case StructureTransitionWatchpoint:
+ case PutStructure:
+ case PhantomPutStructure:
+ case GetButterfly:
+ case GetByOffset:
+ case PutByOffset:
+ case GetGlobalVar:
+ case PutGlobalVar:
+ case ValueAdd:
+ case ArithAdd:
+ case ArithSub:
+ case ArithMul:
+ case ArithNegate:
+ case UInt32ToNumber:
+ case Int32ToDouble:
+ case CompareEqConstant:
+ case CompareStrictEqConstant:
+ case Jump:
+ case ForceOSRExit:
+ // These are OK.
+ break;
+ case GetArrayLength:
+ switch (node->arrayMode().type()) {
+ case Array::Int32:
+ case Array::Double:
+ case Array::Contiguous:
+ break;
+ default:
+ return false;
+ }
+ break;
+ case GetByVal:
+ switch (node->arrayMode().type()) {
+ case Array::ForceExit:
+ return true;
+ case Array::Int32:
+ case Array::Double:
+ case Array::Contiguous:
+ break;
+ default:
+ return false;
+ }
+ switch (node->arrayMode().speculation()) {
+ case Array::SaneChain:
+ case Array::InBounds:
+ break;
+ default:
+ return false;
+ }
+ break;
+ case CompareEq:
+ case CompareStrictEq:
+ if (node->isBinaryUseKind(Int32Use))
+ break;
+ if (node->isBinaryUseKind(NumberUse))
+ break;
+ if (node->isBinaryUseKind(ObjectUse))
+ break;
+ return false;
+ case CompareLess:
+ case CompareLessEq:
+ case CompareGreater:
+ case CompareGreaterEq:
+ if (node->isBinaryUseKind(Int32Use))
+ break;
+ if (node->isBinaryUseKind(NumberUse))
+ break;
+ return false;
+ case Branch:
+ case LogicalNot:
+ if (node->child1().useKind() == BooleanUse)
+ break;
+ return false;
+ default:
+ // Don't know how to handle anything else.
+ return false;
+ }
+ return true;
+}
+
bool canCompile(Graph& graph)
{
for (BlockIndex blockIndex = graph.m_blocks.size(); blockIndex--;) {
@@ -65,99 +167,8 @@
}
}
- switch (node->op()) {
- case JSConstant:
- case WeakJSConstant:
- case GetLocal:
- case SetLocal:
- case MovHintAndCheck:
- case MovHint:
- case ZombieHint:
- case Phantom:
- case Flush:
- case PhantomLocal:
- case SetArgument:
- case Return:
- case BitAnd:
- case BitOr:
- case BitXor:
- case BitRShift:
- case BitLShift:
- case BitURShift:
- case CheckStructure:
- case StructureTransitionWatchpoint:
- case PutStructure:
- case PhantomPutStructure:
- case GetButterfly:
- case GetByOffset:
- case PutByOffset:
- case GetGlobalVar:
- case PutGlobalVar:
- case ValueAdd:
- case ArithAdd:
- case ArithSub:
- case ArithMul:
- case ArithNegate:
- case UInt32ToNumber:
- case Int32ToDouble:
- case CompareEqConstant:
- case CompareStrictEqConstant:
- // These are OK.
- break;
- case GetArrayLength:
- switch (node->arrayMode().type()) {
- case Array::Int32:
- case Array::Double:
- case Array::Contiguous:
- break;
- default:
- return false;
- }
- break;
- case GetByVal:
- switch (node->arrayMode().type()) {
- case Array::Int32:
- case Array::Double:
- case Array::Contiguous:
- break;
- default:
- return false;
- }
- switch (node->arrayMode().speculation()) {
- case Array::SaneChain:
- case Array::InBounds:
- break;
- default:
- return false;
- }
- break;
- case CompareEq:
- case CompareStrictEq:
- if (node->isBinaryUseKind(Int32Use))
- break;
- if (node->isBinaryUseKind(NumberUse))
- break;
- if (node->isBinaryUseKind(ObjectUse))
- break;
+ if (!canCompile(node))
return false;
- case CompareLess:
- case CompareLessEq:
- case CompareGreater:
- case CompareGreaterEq:
- if (node->isBinaryUseKind(Int32Use))
- break;
- if (node->isBinaryUseKind(NumberUse))
- break;
- return false;
- case Branch:
- case LogicalNot:
- if (node->child1().useKind() == BooleanUse)
- break;
- return false;
- default:
- // Don't know how to handle anything else.
- return false;
- }
}
}
Modified: trunk/Source/_javascript_Core/ftl/FTLCompile.cpp (153155 => 153156)
--- trunk/Source/_javascript_Core/ftl/FTLCompile.cpp 2013-07-25 04:00:00 UTC (rev 153155)
+++ trunk/Source/_javascript_Core/ftl/FTLCompile.cpp 2013-07-25 04:00:02 UTC (rev 153156)
@@ -48,6 +48,7 @@
options.OptLevel = Options::llvmOptimizationLevel();
options.NoFramePointerElim = true;
options.CodeModel = LLVMCodeModelSmall;
+ options.EnableFastISel = Options::enableLLVMFastISel();
if (LLVMCreateMCJITCompilerForModule(&state.engine, state.module, &options, sizeof(options), &error)) {
dataLog("FATAL: Could not create LLVM execution engine: ", error, "\n");
Modified: trunk/Source/_javascript_Core/ftl/FTLLowerDFGToLLVM.cpp (153155 => 153156)
--- trunk/Source/_javascript_Core/ftl/FTLLowerDFGToLLVM.cpp 2013-07-25 04:00:00 UTC (rev 153155)
+++ trunk/Source/_javascript_Core/ftl/FTLLowerDFGToLLVM.cpp 2013-07-25 04:00:02 UTC (rev 153156)
@@ -243,12 +243,19 @@
m_state.reset();
m_state.beginBasicBlock(m_highBlock);
- for (m_nodeIndex = 0; m_nodeIndex < m_highBlock->size(); ++m_nodeIndex)
- compileNode(m_nodeIndex);
+ for (m_nodeIndex = 0; m_nodeIndex < m_highBlock->size(); ++m_nodeIndex) {
+ if (!compileNode(m_nodeIndex))
+ break;
+ }
}
- void compileNode(unsigned nodeIndex)
+ bool compileNode(unsigned nodeIndex)
{
+ if (!m_state.isValid()) {
+ m_out.unreachable();
+ return false;
+ }
+
m_node = m_highBlock->at(nodeIndex);
m_codeOrigin = m_node->codeOrigin;
@@ -288,9 +295,6 @@
case PhantomLocal:
case SetArgument:
break;
- case Return:
- compileReturn();
- break;
case ArithAdd:
case ValueAdd:
compileAdd();
@@ -388,9 +392,18 @@
case LogicalNot:
compileLogicalNot();
break;
+ case Jump:
+ compileJump();
+ break;
case Branch:
compileBranch();
break;
+ case Return:
+ compileReturn();
+ break;
+ case ForceOSRExit:
+ compileForceOSRExit();
+ break;
default:
RELEASE_ASSERT_NOT_REACHED();
break;
@@ -404,11 +417,17 @@
if (shouldExecuteEffects)
m_state.executeEffects(nodeIndex);
+
+ return true;
}
void compileJSConstant()
{
- m_jsValueValues.add(m_node, m_out.constInt64(JSValue::encode(m_graph.valueOfJSConstant(m_node))));
+ JSValue value = m_graph.valueOfJSConstant(m_node);
+ if (value.isDouble())
+ m_doubleValues.add(m_node, m_out.constDouble(value.asDouble()));
+ else
+ m_jsValueValues.add(m_node, m_out.constInt64(JSValue::encode(value)));
}
void compileWeakJSConstant()
@@ -555,13 +574,6 @@
DFG_NODE_DO_TO_CHILDREN(m_graph, m_node, speculate);
}
- void compileReturn()
- {
- // FIXME: have a real epilogue when we switch to using our calling convention.
- // https://bugs.webkit.org/show_bug.cgi?id=113621
- m_out.ret(lowJSValue(m_node->child1()));
- }
-
void compileAdd()
{
switch (m_node->binaryUseKind()) {
@@ -1123,6 +1135,11 @@
}
}
+ void compileJump()
+ {
+ m_out.jump(m_blocks.get(m_graph.m_blocks[m_node->takenBlockIndex()].get()));
+ }
+
void compileBranch()
{
switch (m_node->child1().useKind()) {
@@ -1140,6 +1157,18 @@
}
}
+ void compileReturn()
+ {
+ // FIXME: have a real epilogue when we switch to using our calling convention.
+ // https://bugs.webkit.org/show_bug.cgi?id=113621
+ m_out.ret(lowJSValue(m_node->child1()));
+ }
+
+ void compileForceOSRExit()
+ {
+ terminate(InadequateCoverage);
+ }
+
enum EqualNullOrUndefinedMode { EqualNull, EqualUndefined, EqualNullOrUndefined };
void equalNullOrUndefined(Edge edge, EqualNullOrUndefinedMode mode)
{
Modified: trunk/Source/_javascript_Core/runtime/Options.h (153155 => 153156)
--- trunk/Source/_javascript_Core/runtime/Options.h 2013-07-25 04:00:00 UTC (rev 153155)
+++ trunk/Source/_javascript_Core/runtime/Options.h 2013-07-25 04:00:02 UTC (rev 153156)
@@ -113,6 +113,7 @@
v(bool, useExperimentalFTL, false) \
v(bool, useFTLTBAA, true) \
v(bool, enableLLVMLICM, true) \
+ v(bool, enableLLVMFastISel, true) \
v(unsigned, llvmOptimizationLevel, 2) \
\
v(bool, enableProfiler, false) \