Commit 9a58da10 authored by oliver@apple.com's avatar oliver@apple.com

fourthTier: FTL should support CompareStrictEqConstant

https://bugs.webkit.org/show_bug.cgi?id=115941

Reviewed by Mark Hahnenberg.

Pretty simple, but factors out the craziness of comparing against null or undefined
in a way that is reusable for both == and ===.

* ftl/FTLCapabilities.cpp:
(JSC::FTL::canCompile):
* ftl/FTLLowerDFGToLLVM.cpp:
(JSC::FTL::LowerDFGToLLVM::compileNode):
(JSC::FTL::LowerDFGToLLVM::compileCompareEqConstant):
(JSC::FTL::LowerDFGToLLVM::compileCompareStrictEqConstant):
(LowerDFGToLLVM):
(JSC::FTL::LowerDFGToLLVM::equalNullOrUndefined):

git-svn-id: http://svn.webkit.org/repository/webkit/trunk@153155 268f45cc-cd09-0410-ab3c-d52691b4dbfc
parent aafa46d1
2013-05-10 Filip Pizlo <fpizlo@apple.com>
fourthTier: FTL should support CompareStrictEqConstant
https://bugs.webkit.org/show_bug.cgi?id=115941
Reviewed by Mark Hahnenberg.
Pretty simple, but factors out the craziness of comparing against null or undefined
in a way that is reusable for both == and ===.
* ftl/FTLCapabilities.cpp:
(JSC::FTL::canCompile):
* ftl/FTLLowerDFGToLLVM.cpp:
(JSC::FTL::LowerDFGToLLVM::compileNode):
(JSC::FTL::LowerDFGToLLVM::compileCompareEqConstant):
(JSC::FTL::LowerDFGToLLVM::compileCompareStrictEqConstant):
(LowerDFGToLLVM):
(JSC::FTL::LowerDFGToLLVM::equalNullOrUndefined):
2013-05-10 Filip Pizlo <fpizlo@apple.com>
fourthTier: FTL should support CompareEqConstant
......
......@@ -101,6 +101,7 @@ bool canCompile(Graph& graph)
case UInt32ToNumber:
case Int32ToDouble:
case CompareEqConstant:
case CompareStrictEqConstant:
// These are OK.
break;
case GetArrayLength:
......
......@@ -370,6 +370,9 @@ private:
case CompareStrictEq:
compileCompareStrictEq();
break;
case CompareStrictEqConstant:
compileCompareStrictEqConstant();
break;
case CompareLess:
compileCompareLess();
break;
......@@ -971,57 +974,8 @@ private:
void compileCompareEqConstant()
{
ASSERT(m_graph.valueOfJSConstant(m_node->child2().node()).isNull());
bool validWatchpoint = masqueradesAsUndefinedWatchpointIfIsStillValid();
LValue value = lowJSValue(m_node->child1());
LBasicBlock cellCase = FTL_NEW_BLOCK(m_out, ("CompareEqConstant cell case"));
LBasicBlock primitiveCase = FTL_NEW_BLOCK(m_out, ("CompareEqConstant primitive case"));
LBasicBlock continuation = FTL_NEW_BLOCK(m_out, ("CompareEqConstant continuation"));
m_out.branch(isNotCell(value), primitiveCase, cellCase);
LBasicBlock lastNext = m_out.appendTo(cellCase, primitiveCase);
Vector<ValueFromBlock, 3> results;
if (validWatchpoint) {
results.append(m_out.anchor(m_out.booleanFalse));
m_out.jump(continuation);
} else {
LBasicBlock masqueradesCase =
FTL_NEW_BLOCK(m_out, ("CompareEqConstant masquerades case"));
LValue structure = m_out.loadPtr(value, m_heaps.JSCell_structure);
results.append(m_out.anchor(m_out.booleanFalse));
m_out.branch(
m_out.testNonZero8(
m_out.load8(structure, m_heaps.Structure_typeInfoFlags),
m_out.constInt8(MasqueradesAsUndefined)),
masqueradesCase, continuation);
m_out.appendTo(masqueradesCase, primitiveCase);
results.append(m_out.anchor(
m_out.equal(
m_out.constIntPtr(m_graph.globalObjectFor(m_node->codeOrigin)),
m_out.loadPtr(structure, m_heaps.Structure_globalObject))));
m_out.jump(continuation);
}
m_out.appendTo(primitiveCase, continuation);
results.append(m_out.anchor(m_out.equal(
m_out.bitAnd(value, m_out.constInt64(~TagBitUndefined)),
m_out.constInt64(ValueNull))));
m_out.jump(continuation);
m_out.appendTo(continuation, lastNext);
m_booleanValues.add(m_node, m_out.phi(m_out.boolean, results));
masqueradesAsUndefinedWatchpointIfIsStillValid();
equalNullOrUndefined(m_node->child1(), EqualNullOrUndefined);
}
void compileCompareStrictEq()
......@@ -1052,6 +1006,29 @@ private:
RELEASE_ASSERT_NOT_REACHED();
}
void compileCompareStrictEqConstant()
{
JSValue constant = m_graph.valueOfJSConstant(m_node->child2().node());
if (constant.isUndefinedOrNull()
&& !masqueradesAsUndefinedWatchpointIfIsStillValid()) {
if (constant.isNull()) {
equalNullOrUndefined(m_node->child1(), EqualNull);
return;
}
ASSERT(constant.isUndefined());
equalNullOrUndefined(m_node->child1(), EqualUndefined);
return;
}
m_booleanValues.add(
m_node,
m_out.equal(
lowJSValue(m_node->child1()),
m_out.constInt64(JSValue::encode(constant))));
}
void compileCompareLess()
{
if (m_node->isBinaryUseKind(Int32Use)) {
......@@ -1163,6 +1140,73 @@ private:
}
}
enum EqualNullOrUndefinedMode { EqualNull, EqualUndefined, EqualNullOrUndefined };
void equalNullOrUndefined(Edge edge, EqualNullOrUndefinedMode mode)
{
bool validWatchpoint = masqueradesAsUndefinedWatchpointIsStillValid();
LValue value = lowJSValue(edge);
LBasicBlock cellCase = FTL_NEW_BLOCK(m_out, ("CompareEqConstant cell case"));
LBasicBlock primitiveCase = FTL_NEW_BLOCK(m_out, ("CompareEqConstant primitive case"));
LBasicBlock continuation = FTL_NEW_BLOCK(m_out, ("CompareEqConstant continuation"));
m_out.branch(isNotCell(value), primitiveCase, cellCase);
LBasicBlock lastNext = m_out.appendTo(cellCase, primitiveCase);
Vector<ValueFromBlock, 3> results;
if (validWatchpoint) {
results.append(m_out.anchor(m_out.booleanFalse));
m_out.jump(continuation);
} else {
LBasicBlock masqueradesCase =
FTL_NEW_BLOCK(m_out, ("CompareEqConstant masquerades case"));
LValue structure = m_out.loadPtr(value, m_heaps.JSCell_structure);
results.append(m_out.anchor(m_out.booleanFalse));
m_out.branch(
m_out.testNonZero8(
m_out.load8(structure, m_heaps.Structure_typeInfoFlags),
m_out.constInt8(MasqueradesAsUndefined)),
masqueradesCase, continuation);
m_out.appendTo(masqueradesCase, primitiveCase);
results.append(m_out.anchor(
m_out.equal(
m_out.constIntPtr(m_graph.globalObjectFor(m_node->codeOrigin)),
m_out.loadPtr(structure, m_heaps.Structure_globalObject))));
m_out.jump(continuation);
}
m_out.appendTo(primitiveCase, continuation);
LValue primitiveResult;
switch (mode) {
case EqualNull:
primitiveResult = m_out.equal(value, m_out.constInt64(ValueNull));
break;
case EqualUndefined:
primitiveResult = m_out.equal(value, m_out.constInt64(ValueUndefined));
break;
case EqualNullOrUndefined:
primitiveResult = m_out.equal(
m_out.bitAnd(value, m_out.constInt64(~TagBitUndefined)),
m_out.constInt64(ValueNull));
break;
}
results.append(m_out.anchor(primitiveResult));
m_out.jump(continuation);
m_out.appendTo(continuation, lastNext);
m_booleanValues.add(m_node, m_out.phi(m_out.boolean, results));
}
void speculateBackward(
ExitKind kind, FormattedValue lowValue, Node* highValue, LValue failCondition)
{
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment