Changeset 171662 in webkit for trunk/Source/JavaScriptCore/dfg


Ignore:
Timestamp:
Jul 27, 2014, 4:35:32 PM (11 years ago)
Author:
[email protected]
Message:

[REGRESSION][ftlopt merge][32-bit] stress/prune-multi-put-by-offset-replace-or-transition-variant.js.dfg-eager hits an assertion in SpeculativeJIT::silentSavePlanForGPR
https://bugs.webkit.org/show_bug.cgi?id=135323

Reviewed by Oliver Hunt.

SpeculativeJIT::silentSavePlanForGPR likes to believe that if a node is a constant,
then it's a constant that can be represented using that node's current DataFormat.
This doesn't work if the constant had been filled as a JSValue, and then one of the
fillSpeculateBlah() methods had speculated that it's of some type that the constant
isn't. Unless fillSpeculateBlah() specifically defends against this case, we'll have
a constant that claims to have a contradictory data format.

This patch fixes such a bug in the 32-bit fillSpeculateCell(). The 64-bit
fillSpeculateCell() appears to not have this bug, but I added a similar defense
mechanism anyway just in case, since this is one of those mistakes that keeps
reappearing.

  • dfg/DFGSpeculativeJIT.cpp:

(JSC::DFG::SpeculativeJIT::silentSavePlanForGPR):

  • dfg/DFGSpeculativeJIT32_64.cpp:

(JSC::DFG::SpeculativeJIT::fillSpeculateCell):

  • dfg/DFGSpeculativeJIT64.cpp:

(JSC::DFG::SpeculativeJIT::fillSpeculateCell):

Location:
trunk/Source/JavaScriptCore/dfg
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp

    r171660 r171662  
    344344        ASSERT(info.gpr() == source);
    345345        if (node->hasConstant()) {
     346            DFG_ASSERT(m_jit.graph(), m_currentNode, node->isCellConstant());
    346347            node->asCell(); // To get the assertion.
    347348            fillAction = SetCellConstant;
  • trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp

    r171660 r171662  
    868868    VirtualRegister virtualRegister = edge->virtualRegister();
    869869    GenerationInfo& info = generationInfoFromVirtualRegister(virtualRegister);
     870   
     871    if (edge->hasConstant() && !edge->isCellConstant()) {
     872        // Protect the silent spill/fill logic by failing early. If we "speculate" on
     873        // the constant then the silent filler may think that we have a cell and a
     874        // constant, so it will try to fill this as an cell constant. Bad things will
     875        // happen.
     876        terminateSpeculativeExecution(Uncountable, JSValueRegs(), 0);
     877        return allocate();
     878    }
    870879
    871880    switch (info.registerFormat()) {
     
    879888            JSValue jsValue = edge->asJSValue();
    880889            GPRReg gpr = allocate();
    881             if (jsValue.isCell()) {
    882                 m_gprs.retain(gpr, virtualRegister, SpillOrderConstant);
    883                 m_jit.move(MacroAssembler::TrustedImmPtr(jsValue.asCell()), gpr);
    884                 info.fillCell(*m_stream, gpr);
    885                 return gpr;
    886             }
    887             terminateSpeculativeExecution(Uncountable, JSValueRegs(), 0);
     890            m_gprs.retain(gpr, virtualRegister, SpillOrderConstant);
     891            m_jit.move(MacroAssembler::TrustedImmPtr(jsValue.asCell()), gpr);
     892            info.fillCell(*m_stream, gpr);
    888893            return gpr;
    889894        }
  • trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp

    r171660 r171662  
    996996    GenerationInfo& info = generationInfoFromVirtualRegister(virtualRegister);
    997997
     998    if (edge->hasConstant() && !edge->isCellConstant()) {
     999        // Better to fail early on constants.
     1000        terminateSpeculativeExecution(Uncountable, JSValueRegs(), 0);
     1001        return allocate();
     1002    }
     1003
    9981004    switch (info.registerFormat()) {
    9991005    case DataFormatNone: {
     
    10021008        if (edge->hasConstant()) {
    10031009            JSValue jsValue = edge->asJSValue();
    1004             if (jsValue.isCell()) {
    1005                 m_gprs.retain(gpr, virtualRegister, SpillOrderConstant);
    1006                 m_jit.move(MacroAssembler::TrustedImm64(JSValue::encode(jsValue)), gpr);
    1007                 info.fillJSValue(*m_stream, gpr, DataFormatJSCell);
    1008                 return gpr;
    1009             }
    1010             terminateSpeculativeExecution(Uncountable, JSValueRegs(), 0);
     1010            m_gprs.retain(gpr, virtualRegister, SpillOrderConstant);
     1011            m_jit.move(MacroAssembler::TrustedImm64(JSValue::encode(jsValue)), gpr);
     1012            info.fillJSValue(*m_stream, gpr, DataFormatJSCell);
    10111013            return gpr;
    10121014        }
Note: See TracChangeset for help on using the changeset viewer.