Ignore:
Timestamp:
Jul 29, 2011, 3:40:02 PM (14 years ago)
Author:
[email protected]
Message:

DFG JIT does not have any way of undoing double speculation.
https://bugs.webkit.org/show_bug.cgi?id=65334

Reviewed by Gavin Barraclough.

This adds code to do a branchConvertDoubleToInt on specualtion failure.
This is performance-neutral on most benchmarks but does result in
a slight improvement in Kraken.

  • dfg/DFGJITCompiler.cpp:

(JSC::DFG::GeneralizedRegister::moveTo):
(JSC::DFG::GeneralizedRegister::swapWith):
(JSC::DFG::ShuffledRegister::handleNonCyclingPermutation):
(JSC::DFG::ShuffledRegister::handleCyclingPermutation):
(JSC::DFG::JITCompiler::jumpFromSpeculativeToNonSpeculative):

File:
1 edited

Legend:

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

    r91825 r92024  
    179179    }
    180180   
    181     void moveTo(GeneralizedRegister& other, DataFormat myDataFormat, DataFormat otherDataFormat, JITCompiler& jit)
     181    void moveTo(GeneralizedRegister& other, DataFormat myDataFormat, DataFormat otherDataFormat, JITCompiler& jit, FPRReg scratchFPR)
    182182    {
    183183        if (UNLIKELY(isFPR())) {
     
    187187            }
    188188           
     189            JITCompiler::Jump done;
     190           
     191            if (scratchFPR != InvalidFPRReg) {
     192                // we have a scratch FPR, so attempt a conversion to int
     193                JITCompiler::JumpList notInt;
     194                jit.branchConvertDoubleToInt32(fpr(), other.gpr(), notInt, scratchFPR);
     195                jit.orPtr(GPRInfo::tagTypeNumberRegister, other.gpr());
     196                done = jit.jump();
     197                notInt.link(&jit);
     198            }
     199           
    189200            jit.moveDoubleToPtr(fpr(), other.gpr());
    190201            jit.subPtr(GPRInfo::tagTypeNumberRegister, other.gpr());
     202           
     203            if (done.isSet())
     204                done.link(&jit);
    191205            return;
    192206        }
     
    230244            jit.move(other.gpr(), scratchGPR);
    231245           
     246            JITCompiler::Jump done;
     247           
     248            if (scratchFPR != InvalidFPRReg) {
     249                JITCompiler::JumpList notInt;
     250                jit.branchConvertDoubleToInt32(fpr(), other.gpr(), notInt, scratchFPR);
     251                jit.orPtr(GPRInfo::tagTypeNumberRegister, other.gpr());
     252                done = jit.jump();
     253                notInt.link(&jit);
     254            }
     255           
    232256            jit.moveDoubleToPtr(fpr(), other.gpr());
    233257            jit.subPtr(GPRInfo::tagTypeNumberRegister, other.gpr());
     258           
     259            if (done.isSet())
     260                done.link(&jit);
    234261           
    235262            jit.addPtr(GPRInfo::tagTypeNumberRegister, scratchGPR);
     
    291318    }
    292319   
    293     void handleNonCyclingPermutation(const SpeculationCheck& check, const EntryLocation& entry, JITCompiler& jit, FPRReg& scratchFPR)
     320    void handleNonCyclingPermutation(const SpeculationCheck& check, const EntryLocation& entry, JITCompiler& jit, FPRReg& scratchFPR1, FPRReg& scratchFPR2)
    294321    {
    295322        ShuffledRegister* cur = this;
    296323        while (cur->previous) {
    297             cur->previous->reg.moveTo(cur->reg, cur->previous->reg.previousDataFormat(check), cur->reg.nextDataFormat(entry), jit);
     324            cur->previous->reg.moveTo(cur->reg, cur->previous->reg.previousDataFormat(check), cur->reg.nextDataFormat(entry), jit, scratchFPR1);
    298325            cur->handled = true;
    299             if (cur->reg.isFPR())
    300                 scratchFPR = cur->reg.fpr();
     326            if (cur->reg.isFPR()) {
     327                if (scratchFPR1 == InvalidFPRReg)
     328                    scratchFPR1 = cur->reg.fpr();
     329                else
     330                    scratchFPR2 = cur->reg.fpr();
     331            }
    301332            cur = cur->previous;
    302333        }
    303334        cur->handled = true;
    304         if (cur->reg.isFPR())
    305             scratchFPR = cur->reg.fpr();
    306     }
    307    
    308     void handleCyclingPermutation(const SpeculationCheck& check, const EntryLocation& entry, JITCompiler& jit, GPRReg scratchGPR, FPRReg scratchFPR)
     335        if (cur->reg.isFPR()) {
     336            if (scratchFPR1 == InvalidFPRReg)
     337                scratchFPR1 = cur->reg.fpr();
     338            else
     339                scratchFPR2 = cur->reg.fpr();
     340        }
     341    }
     342   
     343    void handleCyclingPermutation(const SpeculationCheck& check, const EntryLocation& entry, JITCompiler& jit, GPRReg scratchGPR, FPRReg scratchFPR1, FPRReg scratchFPR2)
    309344    {
    310345        // first determine the cycle length
     
    334369           
    335370        case 2:
    336             reg.swapWith(previous->reg, reg.previousDataFormat(check), reg.nextDataFormat(entry), previous->reg.previousDataFormat(check), previous->reg.nextDataFormat(entry), jit, scratchGPR, scratchFPR);
     371            reg.swapWith(previous->reg, reg.previousDataFormat(check), reg.nextDataFormat(entry), previous->reg.previousDataFormat(check), previous->reg.nextDataFormat(entry), jit, scratchGPR, scratchFPR1);
    337372            break;
    338373           
     
    340375            GeneralizedRegister scratch;
    341376            if (UNLIKELY(reg.isFPR() && next->reg.isFPR())) {
    342                 if (scratchFPR == InvalidFPRReg) {
     377                if (scratchFPR2 == InvalidFPRReg) {
    343378                    scratch = GeneralizedRegister::createGPR(scratchGPR);
    344                     reg.moveTo(scratch, DataFormatDouble, DataFormatJSDouble, jit);
     379                    reg.moveTo(scratch, DataFormatDouble, DataFormatJSDouble, jit, scratchFPR1);
    345380                } else {
    346                     scratch = GeneralizedRegister::createFPR(scratchFPR);
    347                     reg.moveTo(scratch, DataFormatDouble, DataFormatDouble, jit);
     381                    scratch = GeneralizedRegister::createFPR(scratchFPR2);
     382                    reg.moveTo(scratch, DataFormatDouble, DataFormatDouble, jit, scratchFPR1);
    348383                }
    349384            } else {
    350385                scratch = GeneralizedRegister::createGPR(scratchGPR);
    351                 reg.moveTo(scratch, reg.previousDataFormat(check), next->reg.nextDataFormat(entry), jit);
     386                reg.moveTo(scratch, reg.previousDataFormat(check), next->reg.nextDataFormat(entry), jit, scratchFPR1);
    352387            }
    353388           
     
    355390            while (cur->previous != this) {
    356391                ASSERT(cur);
    357                 cur->previous->reg.moveTo(cur->reg, cur->previous->reg.previousDataFormat(check), cur->reg.nextDataFormat(entry), jit);
     392                cur->previous->reg.moveTo(cur->reg, cur->previous->reg.previousDataFormat(check), cur->reg.nextDataFormat(entry), jit, scratchFPR1);
    358393                cur = cur->previous;
    359394            }
    360395           
    361396            if (UNLIKELY(reg.isFPR() && next->reg.isFPR())) {
    362                 if (scratchFPR == InvalidFPRReg)
    363                     scratch.moveTo(next->reg, DataFormatJSDouble, DataFormatDouble, jit);
     397                if (scratchFPR2 == InvalidFPRReg)
     398                    scratch.moveTo(next->reg, DataFormatJSDouble, DataFormatDouble, jit, scratchFPR1);
    364399                else
    365                     scratch.moveTo(next->reg, DataFormatDouble, DataFormatDouble, jit);
     400                    scratch.moveTo(next->reg, DataFormatDouble, DataFormatDouble, jit, scratchFPR1);
    366401            } else
    367                 scratch.moveTo(next->reg, next->reg.nextDataFormat(entry), next->reg.nextDataFormat(entry), jit);
     402                scratch.moveTo(next->reg, next->reg.nextDataFormat(entry), next->reg.nextDataFormat(entry), jit, scratchFPR1);
    368403            break;
    369404        }
     
    471506   
    472507    checkNodeToRegisterMap.clear();
     508    entryNodeToRegisterMap.clear();
     509   
     510    GPRReg scratchGPR = InvalidGPRReg;
     511    FPRReg scratchFPR1 = InvalidFPRReg;
     512    FPRReg scratchFPR2 = InvalidFPRReg;
     513    bool needToRestoreTagMaskRegister = false;
    473514   
    474515    for (unsigned index = 0; index < GPRInfo::numberOfRegisters; ++index) {
    475         NodeIndex nodeIndex = check.m_gprInfo[index].nodeIndex;
    476         if (nodeIndex != NoNode)
    477             checkNodeToRegisterMap.set(nodeIndex, GeneralizedRegister::createGPR(GPRInfo::toRegister(index)));
     516        NodeIndex nodeIndexInCheck = check.m_gprInfo[index].nodeIndex;
     517        if (nodeIndexInCheck != NoNode)
     518            checkNodeToRegisterMap.set(nodeIndexInCheck, GeneralizedRegister::createGPR(GPRInfo::toRegister(index)));
     519        NodeIndex nodeIndexInEntry = entry.m_gprInfo[index].nodeIndex;
     520        if (nodeIndexInEntry != NoNode)
     521            entryNodeToRegisterMap.set(nodeIndexInEntry, GeneralizedRegister::createGPR(GPRInfo::toRegister(index)));
     522        else if (nodeIndexInCheck == NoNode)
     523            scratchGPR = GPRInfo::toRegister(index);
    478524    }
    479525   
    480526    for (unsigned index = 0; index < FPRInfo::numberOfRegisters; ++index) {
    481         NodeIndex nodeIndex = check.m_fprInfo[index].nodeIndex;
    482         if (nodeIndex != NoNode)
    483             checkNodeToRegisterMap.set(nodeIndex, GeneralizedRegister::createFPR(FPRInfo::toRegister(index)));
    484     }
    485    
    486     entryNodeToRegisterMap.clear();
    487    
    488     for (unsigned index = 0; index < GPRInfo::numberOfRegisters; ++index) {
    489         NodeIndex nodeIndex = entry.m_gprInfo[index].nodeIndex;
    490         if (nodeIndex != NoNode)
    491             entryNodeToRegisterMap.set(nodeIndex, GeneralizedRegister::createGPR(GPRInfo::toRegister(index)));
    492     }
    493    
    494     for (unsigned index = 0; index < FPRInfo::numberOfRegisters; ++index) {
    495         NodeIndex nodeIndex = entry.m_fprInfo[index].nodeIndex;
    496         if (nodeIndex != NoNode)
    497             entryNodeToRegisterMap.set(nodeIndex, GeneralizedRegister::createFPR(FPRInfo::toRegister(index)));
    498     }
     527        NodeIndex nodeIndexInCheck = check.m_fprInfo[index].nodeIndex;
     528        if (nodeIndexInCheck != NoNode)
     529            checkNodeToRegisterMap.set(nodeIndexInCheck, GeneralizedRegister::createFPR(FPRInfo::toRegister(index)));
     530        NodeIndex nodeIndexInEntry = entry.m_fprInfo[index].nodeIndex;
     531        if (nodeIndexInEntry != NoNode)
     532            entryNodeToRegisterMap.set(nodeIndexInEntry, GeneralizedRegister::createFPR(FPRInfo::toRegister(index)));
     533        else if (nodeIndexInCheck == NoNode) {
     534            if (scratchFPR1 == InvalidFPRReg)
     535                scratchFPR1 = FPRInfo::toRegister(index);
     536            else
     537                scratchFPR2 = FPRInfo::toRegister(index);
     538        }
     539    }
     540   
     541    ASSERT((scratchFPR1 == InvalidFPRReg && scratchFPR2 == InvalidFPRReg) || (scratchFPR1 != scratchFPR2));
    499542   
    500543    // How this works:
     
    509552    // save them.
    510553   
    511     GPRReg scratchGPR = InvalidGPRReg;
    512     FPRReg scratchFPR = InvalidFPRReg;
    513     bool needToRestoreTagMaskRegister = false;
    514    
    515554    // Part 1: spill any values that are not spilled on speculative, but are
    516555    //         spilled on non-speculative.
     
    583622        subPtr(GPRInfo::tagTypeNumberRegister, scratchGPR);
    584623        storePtr(scratchGPR, addressFor(virtualRegister));
    585        
    586         scratchFPR = FPRInfo::toRegister(index);
     624
     625        if (scratchFPR1 == InvalidFPRReg)
     626            scratchFPR1 = FPRInfo::toRegister(index);
     627        else if (scratchFPR2)
     628            scratchFPR2 = FPRInfo::toRegister(index);
     629        ASSERT((scratchFPR1 == InvalidFPRReg && scratchFPR2 == InvalidFPRReg) || (scratchFPR1 != scratchFPR2));
    587630    }
    588631   
     
    595638            continue;
    596639       
    597         reg.handleNonCyclingPermutation(check, entry, *this, scratchFPR);
     640        reg.handleNonCyclingPermutation(check, entry, *this, scratchFPR1, scratchFPR2);
     641        ASSERT((scratchFPR1 == InvalidFPRReg && scratchFPR2 == InvalidFPRReg) || (scratchFPR1 != scratchFPR2));
    598642    }
    599643   
     
    603647            continue;
    604648       
    605         reg.handleCyclingPermutation(check, entry, *this, scratchGPR, scratchFPR);
     649        reg.handleCyclingPermutation(check, entry, *this, scratchGPR, scratchFPR1, scratchFPR2);
     650        ASSERT((scratchFPR1 == InvalidFPRReg && scratchFPR2 == InvalidFPRReg) || (scratchFPR1 != scratchFPR2));
    606651    }
    607652
Note: See TracChangeset for help on using the changeset viewer.