Ignore:
Timestamp:
Aug 11, 2011, 8:41:48 PM (14 years ago)
Author:
[email protected]
Message:

DFG JIT speculation failure code sometimes picks the wrong register
as a scratch register.
https://bugs.webkit.org/show_bug.cgi?id=66104

Reviewed by Gavin Barraclough.

Hardened the code with more assertions and fixed the bug. Now a
spilled register is only used for scratch if it also isn't being
used for shuffling.

  • dfg/DFGJITCompiler.cpp:

(JSC::DFG::ShuffledRegister::handleNonCyclingPermutation):
(JSC::DFG::JITCompiler::jumpFromSpeculativeToNonSpeculative):

File:
1 edited

Legend:

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

    r92071 r92909  
    327327                if (scratchFPR1 == InvalidFPRReg)
    328328                    scratchFPR1 = cur->reg.fpr();
    329                 else
     329                else {
     330                    ASSERT(scratchFPR1 != cur->reg.fpr());
    330331                    scratchFPR2 = cur->reg.fpr();
     332                }
    331333            }
    332334            cur = cur->previous;
     
    336338            if (scratchFPR1 == InvalidFPRReg)
    337339                scratchFPR1 = cur->reg.fpr();
    338             else
     340            else {
     341                ASSERT(scratchFPR1 != cur->reg.fpr());
    339342                scratchFPR2 = cur->reg.fpr();
     343            }
    340344        }
    341345    }
     
    569573       
    570574        // Bail out if this register isn't assigned to anything.
    571         if (nodeIndex == NoNode) {
    572             scratchGPR = GPRInfo::toRegister(index);
     575        if (nodeIndex == NoNode)
    573576            continue;
    574         }
    575577       
    576578        // If the non-speculative path also has a register for the nodeIndex that this
     
    588590            if (!mapIterator->second.findInEntryLocation(entry).isSpilled)
    589591                continue;
     592        } else {
     593            // If the non-speculative entry isn't using this register and it does not need
     594            // the value in this register to be placed into any other register, then this
     595            // register can be used for scratch.
     596            if (entry.m_gprInfo[index].nodeIndex == NoNode)
     597                scratchGPR = GPRInfo::toRegister(index);
    590598        }
    591599       
     
    602610            orPtr(GPRInfo::tagTypeNumberRegister, GPRInfo::toRegister(index));
    603611        storePtr(GPRInfo::toRegister(index), addressFor(virtualRegister));
    604        
    605         scratchGPR = GPRInfo::toRegister(index);
    606612    }
    607613   
     
    626632            if (!mapIterator->second.findInEntryLocation(entry).isSpilled)
    627633                continue;
     634        } else {
     635            // If the non-speculative entry isn't using this register and it does not need
     636            // the value in this register to be placed into any other register, then this
     637            // register can be used for scratch.
     638            if (entry.m_fprInfo[index].nodeIndex == NoNode) {
     639                if (scratchFPR1 == InvalidFPRReg)
     640                    scratchFPR1 = FPRInfo::toRegister(index);
     641                else if (scratchFPR2)
     642                    scratchFPR2 = FPRInfo::toRegister(index);
     643                ASSERT((scratchFPR1 == InvalidFPRReg && scratchFPR2 == InvalidFPRReg) || (scratchFPR1 != scratchFPR2));
     644            }
    628645        }
    629646       
     
    636653        subPtr(GPRInfo::tagTypeNumberRegister, scratchGPR);
    637654        storePtr(scratchGPR, addressFor(virtualRegister));
    638 
    639         if (scratchFPR1 == InvalidFPRReg)
    640             scratchFPR1 = FPRInfo::toRegister(index);
    641         else if (scratchFPR2)
    642             scratchFPR2 = FPRInfo::toRegister(index);
    643         ASSERT((scratchFPR1 == InvalidFPRReg && scratchFPR2 == InvalidFPRReg) || (scratchFPR1 != scratchFPR2));
    644     }
     655    }
     656   
     657#if !ASSERT_DISABLED
     658    // Assert that we've not assigned a scratch register to something that we're going to shuffle.
     659    ASSERT(scratchGPR != InvalidGPRReg);
     660    if (scratchGPR != GPRInfo::tagMaskRegister) {
     661        ASSERT(!gprs[GPRInfo::toIndex(scratchGPR)].hasTo);
     662        ASSERT(!gprs[GPRInfo::toIndex(scratchGPR)].hasFrom);
     663    }
     664    if (scratchFPR1 != InvalidFPRReg) {
     665        ASSERT(scratchFPR1 != scratchFPR2);
     666        ASSERT(!fprs[FPRInfo::toIndex(scratchFPR1)].hasTo);
     667        ASSERT(!fprs[FPRInfo::toIndex(scratchFPR1)].hasFrom);
     668        if (scratchFPR2 != InvalidFPRReg) {
     669            ASSERT(!fprs[FPRInfo::toIndex(scratchFPR2)].hasTo);
     670            ASSERT(!fprs[FPRInfo::toIndex(scratchFPR2)].hasFrom);
     671        }
     672    } else
     673        ASSERT(scratchFPR2 == InvalidFPRReg);
     674#endif
    645675   
    646676    // Part 2: For the set of nodes that are in registers on both paths,
Note: See TracChangeset for help on using the changeset viewer.