Changeset 155149 in webkit


Ignore:
Timestamp:
Sep 5, 2013 2:19:09 PM (11 years ago)
Author:
fpizlo@apple.com
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):

Location:
trunk/Source/JavaScriptCore
Files:
11 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/ChangeLog

    r155143 r155149  
     12013-09-05  Filip Pizlo  <fpizlo@apple.com>
     2
     3        REGRESSION(149636, merged in 153145): ToThis conversion doesn't work in the DFG
     4        https://bugs.webkit.org/show_bug.cgi?id=120781
     5
     6        Reviewed by Mark Hahnenberg.
     7       
     8        - Use some method table hacks to detect if the CheckStructure optimization is
     9          valid for to_this.
     10       
     11        - Introduce a FinalObjectUse and use it for ToThis->Identity conversion.
     12       
     13        This looks like it might be perf-neutral on the major benchmarks, but it
     14        introduces some horrible performance cliffs. For example if you add methods to
     15        the Array prototype, you'll get horrible performance cliffs. As in virtual calls
     16        to C++ every time you call a JS function even if it's inlined.
     17        LongSpider/3d-cube appears to hit this.
     18
     19        * dfg/DFGAbstractInterpreterInlines.h:
     20        (JSC::DFG::::executeEffects):
     21        * dfg/DFGByteCodeParser.cpp:
     22        (JSC::DFG::ByteCodeParser::parseBlock):
     23        * dfg/DFGFixupPhase.cpp:
     24        (JSC::DFG::FixupPhase::fixupNode):
     25        * dfg/DFGSafeToExecute.h:
     26        (JSC::DFG::SafeToExecuteEdge::operator()):
     27        * dfg/DFGSpeculativeJIT.cpp:
     28        (JSC::DFG::SpeculativeJIT::speculateFinalObject):
     29        (JSC::DFG::SpeculativeJIT::speculate):
     30        * dfg/DFGSpeculativeJIT.h:
     31        * dfg/DFGSpeculativeJIT32_64.cpp:
     32        (JSC::DFG::SpeculativeJIT::compile):
     33        * dfg/DFGSpeculativeJIT64.cpp:
     34        (JSC::DFG::SpeculativeJIT::compile):
     35        * dfg/DFGUseKind.cpp:
     36        (WTF::printInternal):
     37        * dfg/DFGUseKind.h:
     38        (JSC::DFG::typeFilterFor):
     39        (JSC::DFG::isCell):
     40
    1412013-09-05  Anders Carlsson  <andersca@apple.com>
    242
  • trunk/Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h

    r155023 r155149  
    10871087           
    10881088        destination = source;
    1089         destination.merge(SpecObjectOther);
     1089        destination.merge(SpecObject);
    10901090        break;
    10911091    }
  • trunk/Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp

    r155023 r155149  
    19031903                    || !profile->m_singletonValue
    19041904                    || !profile->m_singletonValue.isCell()
    1905                     || profile->m_singletonValue.asCell()->classInfo() != Structure::info())
     1905                    || profile->m_singletonValue.asCell()->classInfo() != Structure::info()
     1906                    || static_cast<Structure*>(profile->m_singletonValue.asCell())->classInfo()->methodTable.toThis != JSObject::info()->methodTable.toThis)
    19061907                    setThis(addToGraph(ToThis, op1));
    19071908                else {
  • trunk/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp

    r155023 r155149  
    707707           
    708708            if (isFinalObjectSpeculation(node->child1()->prediction())) {
    709                 setUseKindAndUnboxIfProfitable<ObjectUse>(node->child1());
     709                setUseKindAndUnboxIfProfitable<FinalObjectUse>(node->child1());
    710710                node->convertToIdentity();
    711711                break;
  • trunk/Source/JavaScriptCore/dfg/DFGSafeToExecute.h

    r155023 r155149  
    5454        case CellUse:
    5555        case ObjectUse:
     56        case FinalObjectUse:
    5657        case ObjectOrOtherUse:
    5758        case StringIdentUse:
  • trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp

    r154403 r155149  
    46134613}
    46144614
     4615void SpeculativeJIT::speculateFinalObject(Edge edge)
     4616{
     4617    if (!needsTypeCheck(edge, SpecFinalObject))
     4618        return;
     4619   
     4620    SpeculateCellOperand operand(this, edge);
     4621    GPRTemporary structure(this);
     4622    GPRReg gpr = operand.gpr();
     4623    GPRReg structureGPR = structure.gpr();
     4624    m_jit.loadPtr(MacroAssembler::Address(gpr, JSCell::structureOffset()), structureGPR);
     4625    DFG_TYPE_CHECK(
     4626        JSValueSource::unboxedCell(gpr), edge, SpecFinalObject, m_jit.branch8(
     4627            MacroAssembler::NotEqual,
     4628            MacroAssembler::Address(structureGPR, Structure::typeInfoTypeOffset()),
     4629            TrustedImm32(FinalObjectType)));
     4630}
     4631
    46154632void SpeculativeJIT::speculateObjectOrOther(Edge edge)
    46164633{
     
    48484865    case ObjectUse:
    48494866        speculateObject(edge);
     4867        break;
     4868    case FinalObjectUse:
     4869        speculateFinalObject(edge);
    48504870        break;
    48514871    case ObjectOrOtherUse:
  • trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h

    r154442 r155149  
    21192119    void speculateCell(Edge);
    21202120    void speculateObject(Edge);
     2121    void speculateFinalObject(Edge);
    21212122    void speculateObjectOrOther(Edge);
    21222123    void speculateString(Edge edge, GPRReg cell);
  • trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp

    r155023 r155149  
    36503650    case ToThis: {
    36513651        ASSERT(node->child1().useKind() == UntypedUse);
    3652 
    36533652        JSValueOperand thisValue(this, node->child1());
     3653        GPRTemporary temp(this);
     3654        GPRReg thisValuePayloadGPR = thisValue.payloadGPR();
    36543655        GPRReg thisValueTagGPR = thisValue.tagGPR();
    3655         GPRReg thisValuePayloadGPR = thisValue.payloadGPR();
    3656        
    3657         flushRegisters();
    3658        
    3659         GPRResult2 resultTag(this);
    3660         GPRResult resultPayload(this);
    3661         callOperation(operationToThis, resultTag.gpr(), resultPayload.gpr(), thisValueTagGPR, thisValuePayloadGPR);
    3662        
    3663         cellResult(resultPayload.gpr(), node);
     3656        GPRReg tempGPR = temp.gpr();
     3657       
     3658        MacroAssembler::JumpList slowCases;
     3659        slowCases.append(m_jit.branch32(
     3660            MacroAssembler::NotEqual, thisValueTagGPR, TrustedImm32(JSValue::CellTag)));
     3661        m_jit.loadPtr(
     3662            MacroAssembler::Address(thisValuePayloadGPR, JSCell::structureOffset()), tempGPR);
     3663        slowCases.append(m_jit.branch8(
     3664            MacroAssembler::NotEqual,
     3665            MacroAssembler::Address(tempGPR, Structure::typeInfoTypeOffset()),
     3666            TrustedImm32(FinalObjectType)));
     3667        m_jit.move(thisValuePayloadGPR, tempGPR);
     3668        addSlowPathGenerator(
     3669            slowPathCall(slowCases, this, operationToThis, tempGPR, thisValueTagGPR, thisValuePayloadGPR));
     3670
     3671        cellResult(tempGPR, node);
    36643672        break;
    36653673    }
  • trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp

    r155023 r155149  
    35713571        ASSERT(node->child1().useKind() == UntypedUse);
    35723572        JSValueOperand thisValue(this, node->child1());
     3573        GPRTemporary temp(this);
    35733574        GPRReg thisValueGPR = thisValue.gpr();
    3574        
    3575         flushRegisters();
    3576        
    3577         GPRResult result(this);
    3578         callOperation(operationToThis, result.gpr(), thisValueGPR);
    3579 
    3580         cellResult(result.gpr(), node);
     3575        GPRReg tempGPR = temp.gpr();
     3576       
     3577        MacroAssembler::JumpList slowCases;
     3578        slowCases.append(m_jit.branchTest64(
     3579            MacroAssembler::NonZero, thisValueGPR, GPRInfo::tagMaskRegister));
     3580        m_jit.loadPtr(
     3581            MacroAssembler::Address(thisValueGPR, JSCell::structureOffset()), tempGPR);
     3582        slowCases.append(m_jit.branch8(
     3583            MacroAssembler::NotEqual,
     3584            MacroAssembler::Address(tempGPR, Structure::typeInfoTypeOffset()),
     3585            TrustedImm32(FinalObjectType)));
     3586        m_jit.move(thisValueGPR, tempGPR);
     3587        addSlowPathGenerator(
     3588            slowPathCall(slowCases, this, operationToThis, tempGPR, thisValueGPR));
     3589
     3590        cellResult(tempGPR, node);
    35813591        break;
    35823592    }
  • trunk/Source/JavaScriptCore/dfg/DFGUseKind.cpp

    r153245 r155149  
    6666        out.print("Object");
    6767        break;
     68    case FinalObjectUse:
     69        out.print("FinalObject");
     70        break;
    6871    case ObjectOrOtherUse:
    6972        out.print("ObjectOrOther");
  • trunk/Source/JavaScriptCore/dfg/DFGUseKind.h

    r154141 r155149  
    4747    KnownCellUse,
    4848    ObjectUse,
     49    FinalObjectUse,
    4950    ObjectOrOtherUse,
    5051    StringIdentUse,
     
    7879    case ObjectUse:
    7980        return SpecObject;
     81    case FinalObjectUse:
     82        return SpecFinalObject;
    8083    case ObjectOrOtherUse:
    8184        return SpecObject | SpecOther;
     
    151154    case KnownCellUse:
    152155    case ObjectUse:
     156    case FinalObjectUse:
    153157    case StringIdentUse:
    154158    case StringUse:
Note: See TracChangeset for help on using the changeset viewer.