Title: [155149] trunk/Source/_javascript_Core
Revision
155149
Author
[email protected]
Date
2013-09-05 14:19:09 -0700 (Thu, 05 Sep 2013)

Log Message

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):

Modified Paths

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:
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to