Diff
Modified: trunk/Source/_javascript_Core/ChangeLog (155148 => 155149)
--- trunk/Source/_javascript_Core/ChangeLog 2013-09-05 21:17:35 UTC (rev 155148)
+++ trunk/Source/_javascript_Core/ChangeLog 2013-09-05 21:19:09 UTC (rev 155149)
@@ -1,3 +1,43 @@
+2013-09-05 Filip Pizlo <[email protected]>
+
+ REGRESSION(149636, merged in 153145): ToThis conversion doesn't work in the DFG
+ https://bugs.webkit.org/show_bug.cgi?id=120781
+
+ Reviewed by Mark Hahnenberg.
+
+ - Use some method table hacks to detect if the CheckStructure optimization is
+ valid for to_this.
+
+ - Introduce a FinalObjectUse and use it for ToThis->Identity conversion.
+
+ This looks like it might be perf-neutral on the major benchmarks, but it
+ introduces some horrible performance cliffs. For example if you add methods to
+ the Array prototype, you'll get horrible performance cliffs. As in virtual calls
+ to C++ every time you call a JS function even if it's inlined.
+ LongSpider/3d-cube appears to hit this.
+
+ * dfg/DFGAbstractInterpreterInlines.h:
+ (JSC::DFG::::executeEffects):
+ * dfg/DFGByteCodeParser.cpp:
+ (JSC::DFG::ByteCodeParser::parseBlock):
+ * dfg/DFGFixupPhase.cpp:
+ (JSC::DFG::FixupPhase::fixupNode):
+ * dfg/DFGSafeToExecute.h:
+ (JSC::DFG::SafeToExecuteEdge::operator()):
+ * dfg/DFGSpeculativeJIT.cpp:
+ (JSC::DFG::SpeculativeJIT::speculateFinalObject):
+ (JSC::DFG::SpeculativeJIT::speculate):
+ * dfg/DFGSpeculativeJIT.h:
+ * dfg/DFGSpeculativeJIT32_64.cpp:
+ (JSC::DFG::SpeculativeJIT::compile):
+ * dfg/DFGSpeculativeJIT64.cpp:
+ (JSC::DFG::SpeculativeJIT::compile):
+ * dfg/DFGUseKind.cpp:
+ (WTF::printInternal):
+ * dfg/DFGUseKind.h:
+ (JSC::DFG::typeFilterFor):
+ (JSC::DFG::isCell):
+
2013-09-05 Anders Carlsson <[email protected]>
GCAssertions.h should use STL type traits and static_assert
Modified: trunk/Source/_javascript_Core/dfg/DFGAbstractInterpreterInlines.h (155148 => 155149)
--- trunk/Source/_javascript_Core/dfg/DFGAbstractInterpreterInlines.h 2013-09-05 21:17:35 UTC (rev 155148)
+++ trunk/Source/_javascript_Core/dfg/DFGAbstractInterpreterInlines.h 2013-09-05 21:19:09 UTC (rev 155149)
@@ -1086,7 +1086,7 @@
AbstractValue& destination = forNode(node);
destination = source;
- destination.merge(SpecObjectOther);
+ destination.merge(SpecObject);
break;
}
Modified: trunk/Source/_javascript_Core/dfg/DFGByteCodeParser.cpp (155148 => 155149)
--- trunk/Source/_javascript_Core/dfg/DFGByteCodeParser.cpp 2013-09-05 21:17:35 UTC (rev 155148)
+++ trunk/Source/_javascript_Core/dfg/DFGByteCodeParser.cpp 2013-09-05 21:19:09 UTC (rev 155149)
@@ -1902,7 +1902,8 @@
if (profile->m_singletonValueIsTop
|| !profile->m_singletonValue
|| !profile->m_singletonValue.isCell()
- || profile->m_singletonValue.asCell()->classInfo() != Structure::info())
+ || profile->m_singletonValue.asCell()->classInfo() != Structure::info()
+ || static_cast<Structure*>(profile->m_singletonValue.asCell())->classInfo()->methodTable.toThis != JSObject::info()->methodTable.toThis)
setThis(addToGraph(ToThis, op1));
else {
addToGraph(
Modified: trunk/Source/_javascript_Core/dfg/DFGFixupPhase.cpp (155148 => 155149)
--- trunk/Source/_javascript_Core/dfg/DFGFixupPhase.cpp 2013-09-05 21:17:35 UTC (rev 155148)
+++ trunk/Source/_javascript_Core/dfg/DFGFixupPhase.cpp 2013-09-05 21:19:09 UTC (rev 155149)
@@ -706,7 +706,7 @@
}
if (isFinalObjectSpeculation(node->child1()->prediction())) {
- setUseKindAndUnboxIfProfitable<ObjectUse>(node->child1());
+ setUseKindAndUnboxIfProfitable<FinalObjectUse>(node->child1());
node->convertToIdentity();
break;
}
Modified: trunk/Source/_javascript_Core/dfg/DFGSafeToExecute.h (155148 => 155149)
--- trunk/Source/_javascript_Core/dfg/DFGSafeToExecute.h 2013-09-05 21:17:35 UTC (rev 155148)
+++ trunk/Source/_javascript_Core/dfg/DFGSafeToExecute.h 2013-09-05 21:19:09 UTC (rev 155149)
@@ -53,6 +53,7 @@
case BooleanUse:
case CellUse:
case ObjectUse:
+ case FinalObjectUse:
case ObjectOrOtherUse:
case StringIdentUse:
case StringUse:
Modified: trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.cpp (155148 => 155149)
--- trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.cpp 2013-09-05 21:17:35 UTC (rev 155148)
+++ trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.cpp 2013-09-05 21:19:09 UTC (rev 155149)
@@ -4612,6 +4612,23 @@
MacroAssembler::TrustedImmPtr(m_jit.vm()->stringStructure.get())));
}
+void SpeculativeJIT::speculateFinalObject(Edge edge)
+{
+ if (!needsTypeCheck(edge, SpecFinalObject))
+ return;
+
+ SpeculateCellOperand operand(this, edge);
+ GPRTemporary structure(this);
+ GPRReg gpr = operand.gpr();
+ GPRReg structureGPR = structure.gpr();
+ m_jit.loadPtr(MacroAssembler::Address(gpr, JSCell::structureOffset()), structureGPR);
+ DFG_TYPE_CHECK(
+ JSValueSource::unboxedCell(gpr), edge, SpecFinalObject, m_jit.branch8(
+ MacroAssembler::NotEqual,
+ MacroAssembler::Address(structureGPR, Structure::typeInfoTypeOffset()),
+ TrustedImm32(FinalObjectType)));
+}
+
void SpeculativeJIT::speculateObjectOrOther(Edge edge)
{
if (!needsTypeCheck(edge, SpecObject | SpecOther))
@@ -4848,6 +4865,9 @@
case ObjectUse:
speculateObject(edge);
break;
+ case FinalObjectUse:
+ speculateFinalObject(edge);
+ break;
case ObjectOrOtherUse:
speculateObjectOrOther(edge);
break;
Modified: trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.h (155148 => 155149)
--- trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.h 2013-09-05 21:17:35 UTC (rev 155148)
+++ trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.h 2013-09-05 21:19:09 UTC (rev 155149)
@@ -2118,6 +2118,7 @@
void speculateBoolean(Edge);
void speculateCell(Edge);
void speculateObject(Edge);
+ void speculateFinalObject(Edge);
void speculateObjectOrOther(Edge);
void speculateString(Edge edge, GPRReg cell);
void speculateStringIdentAndLoadStorage(Edge edge, GPRReg string, GPRReg storage);
Modified: trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT32_64.cpp (155148 => 155149)
--- trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT32_64.cpp 2013-09-05 21:17:35 UTC (rev 155148)
+++ trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT32_64.cpp 2013-09-05 21:19:09 UTC (rev 155149)
@@ -3649,18 +3649,26 @@
case ToThis: {
ASSERT(node->child1().useKind() == UntypedUse);
-
JSValueOperand thisValue(this, node->child1());
+ GPRTemporary temp(this);
+ GPRReg thisValuePayloadGPR = thisValue.payloadGPR();
GPRReg thisValueTagGPR = thisValue.tagGPR();
- GPRReg thisValuePayloadGPR = thisValue.payloadGPR();
+ GPRReg tempGPR = temp.gpr();
- flushRegisters();
-
- GPRResult2 resultTag(this);
- GPRResult resultPayload(this);
- callOperation(operationToThis, resultTag.gpr(), resultPayload.gpr(), thisValueTagGPR, thisValuePayloadGPR);
-
- cellResult(resultPayload.gpr(), node);
+ MacroAssembler::JumpList slowCases;
+ slowCases.append(m_jit.branch32(
+ MacroAssembler::NotEqual, thisValueTagGPR, TrustedImm32(JSValue::CellTag)));
+ m_jit.loadPtr(
+ MacroAssembler::Address(thisValuePayloadGPR, JSCell::structureOffset()), tempGPR);
+ slowCases.append(m_jit.branch8(
+ MacroAssembler::NotEqual,
+ MacroAssembler::Address(tempGPR, Structure::typeInfoTypeOffset()),
+ TrustedImm32(FinalObjectType)));
+ m_jit.move(thisValuePayloadGPR, tempGPR);
+ addSlowPathGenerator(
+ slowPathCall(slowCases, this, operationToThis, tempGPR, thisValueTagGPR, thisValuePayloadGPR));
+
+ cellResult(tempGPR, node);
break;
}
Modified: trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT64.cpp (155148 => 155149)
--- trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT64.cpp 2013-09-05 21:17:35 UTC (rev 155148)
+++ trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT64.cpp 2013-09-05 21:19:09 UTC (rev 155149)
@@ -3570,14 +3570,24 @@
case ToThis: {
ASSERT(node->child1().useKind() == UntypedUse);
JSValueOperand thisValue(this, node->child1());
+ GPRTemporary temp(this);
GPRReg thisValueGPR = thisValue.gpr();
+ GPRReg tempGPR = temp.gpr();
- flushRegisters();
-
- GPRResult result(this);
- callOperation(operationToThis, result.gpr(), thisValueGPR);
+ MacroAssembler::JumpList slowCases;
+ slowCases.append(m_jit.branchTest64(
+ MacroAssembler::NonZero, thisValueGPR, GPRInfo::tagMaskRegister));
+ m_jit.loadPtr(
+ MacroAssembler::Address(thisValueGPR, JSCell::structureOffset()), tempGPR);
+ slowCases.append(m_jit.branch8(
+ MacroAssembler::NotEqual,
+ MacroAssembler::Address(tempGPR, Structure::typeInfoTypeOffset()),
+ TrustedImm32(FinalObjectType)));
+ m_jit.move(thisValueGPR, tempGPR);
+ addSlowPathGenerator(
+ slowPathCall(slowCases, this, operationToThis, tempGPR, thisValueGPR));
- cellResult(result.gpr(), node);
+ cellResult(tempGPR, node);
break;
}
Modified: trunk/Source/_javascript_Core/dfg/DFGUseKind.cpp (155148 => 155149)
--- trunk/Source/_javascript_Core/dfg/DFGUseKind.cpp 2013-09-05 21:17:35 UTC (rev 155148)
+++ trunk/Source/_javascript_Core/dfg/DFGUseKind.cpp 2013-09-05 21:19:09 UTC (rev 155149)
@@ -65,6 +65,9 @@
case ObjectUse:
out.print("Object");
break;
+ case FinalObjectUse:
+ out.print("FinalObject");
+ break;
case ObjectOrOtherUse:
out.print("ObjectOrOther");
break;
Modified: trunk/Source/_javascript_Core/dfg/DFGUseKind.h (155148 => 155149)
--- trunk/Source/_javascript_Core/dfg/DFGUseKind.h 2013-09-05 21:17:35 UTC (rev 155148)
+++ trunk/Source/_javascript_Core/dfg/DFGUseKind.h 2013-09-05 21:19:09 UTC (rev 155149)
@@ -46,6 +46,7 @@
CellUse,
KnownCellUse,
ObjectUse,
+ FinalObjectUse,
ObjectOrOtherUse,
StringIdentUse,
StringUse,
@@ -77,6 +78,8 @@
return SpecCell;
case ObjectUse:
return SpecObject;
+ case FinalObjectUse:
+ return SpecFinalObject;
case ObjectOrOtherUse:
return SpecObject | SpecOther;
case StringIdentUse:
@@ -150,6 +153,7 @@
case CellUse:
case KnownCellUse:
case ObjectUse:
+ case FinalObjectUse:
case StringIdentUse:
case StringUse:
case KnownStringUse: