Diff
Modified: trunk/Source/_javascript_Core/ChangeLog (164492 => 164493)
--- trunk/Source/_javascript_Core/ChangeLog 2014-02-21 20:37:01 UTC (rev 164492)
+++ trunk/Source/_javascript_Core/ChangeLog 2014-02-21 20:37:19 UTC (rev 164493)
@@ -1,3 +1,38 @@
+2014-02-21 Filip Pizlo <[email protected]>
+
+ DFG write barriers should do more speculations
+ https://bugs.webkit.org/show_bug.cgi?id=129160
+
+ Reviewed by Mark Hahnenberg.
+
+ Replace ConditionalStoreBarrier with the cheapest speculation that you could do
+ instead.
+
+ Miniscule speed-up on some things. It's a decent difference in code size, though.
+
+ * bytecode/SpeculatedType.cpp:
+ (JSC::speculationToAbbreviatedString):
+ * bytecode/SpeculatedType.h:
+ (JSC::isNotCellSpeculation):
+ * dfg/DFGFixupPhase.cpp:
+ (JSC::DFG::FixupPhase::fixupNode):
+ (JSC::DFG::FixupPhase::insertStoreBarrier):
+ (JSC::DFG::FixupPhase::insertPhantomCheck):
+ * dfg/DFGNode.h:
+ (JSC::DFG::Node::shouldSpeculateOther):
+ (JSC::DFG::Node::shouldSpeculateNotCell):
+ * ftl/FTLCapabilities.cpp:
+ (JSC::FTL::canCompile):
+ * ftl/FTLLowerDFGToLLVM.cpp:
+ (JSC::FTL::LowerDFGToLLVM::compareEqObjectOrOtherToObject):
+ (JSC::FTL::LowerDFGToLLVM::equalNullOrUndefined):
+ (JSC::FTL::LowerDFGToLLVM::isNotOther):
+ (JSC::FTL::LowerDFGToLLVM::isOther):
+ (JSC::FTL::LowerDFGToLLVM::speculate):
+ (JSC::FTL::LowerDFGToLLVM::speculateObjectOrOther):
+ (JSC::FTL::LowerDFGToLLVM::speculateOther):
+ (JSC::FTL::LowerDFGToLLVM::speculateNotCell):
+
2014-02-21 Joseph Pecoraro <[email protected]>
Revert r164486, causing a number of test failures.
Modified: trunk/Source/_javascript_Core/bytecode/SpeculatedType.cpp (164492 => 164493)
--- trunk/Source/_javascript_Core/bytecode/SpeculatedType.cpp 2014-02-21 20:37:01 UTC (rev 164492)
+++ trunk/Source/_javascript_Core/bytecode/SpeculatedType.cpp 2014-02-21 20:37:19 UTC (rev 164493)
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2011, 2012, 2013 Apple Inc. All rights reserved.
+ * Copyright (C) 2011, 2012, 2013, 2014 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -255,6 +255,8 @@
return "<Boolean>";
if (isOtherSpeculation(prediction))
return "<Other>";
+ if (isNotCellSpeculation(prediction))
+ return "<NotCell>";
return "";
}
Modified: trunk/Source/_javascript_Core/bytecode/SpeculatedType.h (164492 => 164493)
--- trunk/Source/_javascript_Core/bytecode/SpeculatedType.h 2014-02-21 20:37:01 UTC (rev 164492)
+++ trunk/Source/_javascript_Core/bytecode/SpeculatedType.h 2014-02-21 20:37:19 UTC (rev 164493)
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2011, 2012, 2013 Apple Inc. All rights reserved.
+ * Copyright (C) 2011, 2012, 2013, 2014 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -340,6 +340,11 @@
return !value || value == SpecOther;
}
+inline bool isNotCellSpeculation(SpeculatedType value)
+{
+ return !!value && !(value & SpecCell);
+}
+
inline bool isEmptySpeculation(SpeculatedType value)
{
return value == SpecEmpty;
Modified: trunk/Source/_javascript_Core/dfg/DFGFixupPhase.cpp (164492 => 164493)
--- trunk/Source/_javascript_Core/dfg/DFGFixupPhase.cpp 2014-02-21 20:37:01 UTC (rev 164492)
+++ trunk/Source/_javascript_Core/dfg/DFGFixupPhase.cpp 2014-02-21 20:37:19 UTC (rev 164493)
@@ -1056,11 +1056,6 @@
// FIXME: Get rid of this by allowing Phantoms after terminals.
// https://bugs.webkit.org/show_bug.cgi?id=126778
m_requiredPhantoms.resize(0);
- // Since StoreBarriers are recursively fixed up so that their children look
- // identical to that of the node they're barrier-ing, we need to avoid adding
- // any Phantoms when processing them because this would invalidate the
- // InsertionSet's invariant of inserting things in a monotonically increasing
- // order. This should be okay anyways because StoreBarriers can't exit.
} else
addPhantomsIfNecessary();
}
@@ -1609,15 +1604,47 @@
void insertStoreBarrier(unsigned indexInBlock, Edge child1, Edge child2 = Edge())
{
- Node* barrierNode;
- if (!child2)
- barrierNode = m_graph.addNode(SpecNone, StoreBarrier, m_currentNode->origin, Edge(child1.node(), child1.useKind()));
- else {
- barrierNode = m_graph.addNode(SpecNone, ConditionalStoreBarrier, m_currentNode->origin,
- Edge(child1.node(), child1.useKind()), Edge(child2.node(), child2.useKind()));
+ if (!child2) {
+ m_insertionSet.insertNode(
+ indexInBlock, SpecNone, StoreBarrier, m_currentNode->origin, child1);
+ return;
}
- m_insertionSet.insert(indexInBlock, barrierNode);
+
+ // Figure out some cheap way of avoiding the barrier entirely. In addition to being
+ // cheap, we try to make these checks strong: we want to prove as much as possible for
+ // the code that follows.
+ if (child2->shouldSpeculateInt32()) {
+ insertPhantomCheck(indexInBlock, child2.node(), Int32Use);
+ return;
+ }
+ if (child2->shouldSpeculateMachineInt()) {
+ insertPhantomCheck(indexInBlock, child2.node(), MachineIntUse);
+ return;
+ }
+ if (child2->shouldSpeculateBoolean()) {
+ insertPhantomCheck(indexInBlock, child2.node(), BooleanUse);
+ return;
+ }
+ if (child2->shouldSpeculateOther()) {
+ insertPhantomCheck(indexInBlock, child2.node(), OtherUse);
+ return;
+ }
+ if (child2->shouldSpeculateNotCell()) {
+ insertPhantomCheck(indexInBlock, child2.node(), NotCellUse);
+ return;
+ }
+
+ m_insertionSet.insertNode(
+ indexInBlock, SpecNone, ConditionalStoreBarrier, m_currentNode->origin,
+ child1, Edge(child2.node(), UntypedUse));
}
+
+ void insertPhantomCheck(unsigned indexInBlock, Node* node, UseKind useKind)
+ {
+ m_insertionSet.insertNode(
+ indexInBlock, SpecNone, Phantom, m_currentNode->origin, Edge(node, useKind));
+ observeUseKindOnNode(node, useKind);
+ }
void fixIntEdge(Edge& edge)
{
Modified: trunk/Source/_javascript_Core/dfg/DFGNode.h (164492 => 164493)
--- trunk/Source/_javascript_Core/dfg/DFGNode.h 2014-02-21 20:37:01 UTC (rev 164492)
+++ trunk/Source/_javascript_Core/dfg/DFGNode.h 2014-02-21 20:37:19 UTC (rev 164493)
@@ -1481,11 +1481,21 @@
return isObjectOrOtherSpeculation(prediction());
}
+ bool shouldSpeculateOther()
+ {
+ return isOtherSpeculation(prediction());
+ }
+
bool shouldSpeculateCell()
{
return isCellSpeculation(prediction());
}
+ bool shouldSpeculateNotCell()
+ {
+ return isNotCellSpeculation(prediction());
+ }
+
static bool shouldSpeculateBoolean(Node* op1, Node* op2)
{
return op1->shouldSpeculateBoolean() && op2->shouldSpeculateBoolean();
Modified: trunk/Source/_javascript_Core/ftl/FTLCapabilities.cpp (164492 => 164493)
--- trunk/Source/_javascript_Core/ftl/FTLCapabilities.cpp 2014-02-21 20:37:01 UTC (rev 164492)
+++ trunk/Source/_javascript_Core/ftl/FTLCapabilities.cpp 2014-02-21 20:37:19 UTC (rev 164493)
@@ -330,6 +330,7 @@
case StringOrStringObjectUse:
case FinalObjectUse:
case NotCellUse:
+ case OtherUse:
// These are OK.
break;
default:
Modified: trunk/Source/_javascript_Core/ftl/FTLLowerDFGToLLVM.cpp (164492 => 164493)
--- trunk/Source/_javascript_Core/ftl/FTLLowerDFGToLLVM.cpp 2014-02-21 20:37:01 UTC (rev 164492)
+++ trunk/Source/_javascript_Core/ftl/FTLLowerDFGToLLVM.cpp 2014-02-21 20:37:19 UTC (rev 164493)
@@ -3822,7 +3822,7 @@
m_out.appendTo(leftNotCellCase, continuation);
FTL_TYPE_CHECK(
- jsValueValue(leftValue), leftChild, SpecOther | SpecCell, isNotNully(leftValue));
+ jsValueValue(leftValue), leftChild, SpecOther | SpecCell, isNotOther(leftValue));
ValueFromBlock notCellResult = m_out.anchor(m_out.booleanFalse);
m_out.jump(continuation);
@@ -4156,11 +4156,11 @@
primitiveResult = m_out.equal(value, m_out.constInt64(ValueUndefined));
break;
case EqualNullOrUndefined:
- primitiveResult = isNully(value);
+ primitiveResult = isOther(value);
break;
case SpeculateNullOrUndefined:
FTL_TYPE_CHECK(
- jsValueValue(value), edge, SpecCell | SpecOther, isNotNully(value));
+ jsValueValue(value), edge, SpecCell | SpecOther, isNotOther(value));
primitiveResult = m_out.booleanTrue;
break;
}
@@ -4809,13 +4809,13 @@
value, m_out.constInt64(ValueTrue), m_out.constInt64(ValueFalse));
}
- LValue isNotNully(LValue value)
+ LValue isNotOther(LValue value)
{
return m_out.notEqual(
m_out.bitAnd(value, m_out.constInt64(~TagBitUndefined)),
m_out.constInt64(ValueNull));
}
- LValue isNully(LValue value)
+ LValue isOther(LValue value)
{
return m_out.equal(
m_out.bitAnd(value, m_out.constInt64(~TagBitUndefined)),
@@ -4868,6 +4868,9 @@
case MachineIntUse:
speculateMachineInt(edge);
break;
+ case OtherUse:
+ speculateOther(edge);
+ break;
case BooleanUse:
speculateBoolean(edge);
break;
@@ -5015,7 +5018,7 @@
m_out.appendTo(primitiveCase, continuation);
FTL_TYPE_CHECK(
- jsValueValue(value), edge, SpecCell | SpecOther, isNotNully(value));
+ jsValueValue(value), edge, SpecCell | SpecOther, isNotOther(value));
m_out.jump(continuation);
@@ -5138,6 +5141,15 @@
lowWhicheverInt52(edge, kind);
}
+ void speculateOther(Edge edge)
+ {
+ if (!m_interpreter.needsTypeCheck(edge))
+ return;
+
+ LValue value = lowJSValue(edge, ManualOperandSpeculation);
+ typeCheck(jsValueValue(value), edge, SpecOther, isNotOther(value));
+ }
+
void speculateBoolean(Edge edge)
{
lowBoolean(edge);
@@ -5148,7 +5160,7 @@
if (!m_interpreter.needsTypeCheck(edge))
return;
- LValue value = lowJSValue(edge);
+ LValue value = lowJSValue(edge, ManualOperandSpeculation);
typeCheck(jsValueValue(value), edge, ~SpecCell, isCell(value));
}