Example #1
0
CallLinkStatus::CallLinkStatus(JSValue value)
    : m_couldTakeSlowPath(false)
    , m_isProved(false)
{
    if (!value || !value.isCell()) {
        m_couldTakeSlowPath = true;
        return;
    }
    
    m_variants.append(CallVariant(value.asCell()));
}
void CallEdgeProfile::visitWeak()
{
    if (!m_primaryCallee && !m_otherCallees)
        return;
    
    ConcurrentJITLocker locker(m_lock);
    
    // See if anything is dead and if that can be rectified by despecifying.
    if (worthDespecifying()) {
        CallSpectrum newSpectrum;
        
        if (!!m_primaryCallee)
            newSpectrum.add(m_primaryCallee.despecifiedClosure(), m_numCallsToPrimary);
        
        if (m_otherCallees) {
            for (unsigned i = m_otherCallees->m_processed.size(); i--;) {
                newSpectrum.add(
                    m_otherCallees->m_processed[i].callee().despecifiedClosure(),
                    m_otherCallees->m_processed[i].count());
            }
        }
        
        Vector<CallSpectrum::KeyAndCount> list = newSpectrum.buildList();
        RELEASE_ASSERT(list.size());
        m_primaryCallee = list.last().key;
        m_numCallsToPrimary = list.last().count;
        
        if (m_otherCallees) {
            m_otherCallees->m_processed.clear();

            // We could have a situation where the GC clears the primary and then log processing
            // reinstates it without ever doing an addSlow and subsequent mergeBack. In such a case
            // the primary could duplicate an entry in otherCallees, which means that even though we
            // had an otherCallees object, the list size is just 1.
            if (list.size() >= 2) {
                for (unsigned i = list.size() - 1; i--;)
                    m_otherCallees->m_processed.append(CallEdge(list[i].key, list[i].count));
            }
        }
        
        m_closuresAreDespecified = true;
        
        return;
    }
    
    if (!!m_primaryCallee && !Heap::isMarked(m_primaryCallee.rawCalleeCell())) {
        m_numCallsToUnknownCell += m_numCallsToPrimary;
        
        m_primaryCallee = CallVariant();
        m_numCallsToPrimary = 0;
    }
    
    if (m_otherCallees) {
        for (unsigned i = 0; i < m_otherCallees->m_processed.size(); i++) {
            if (Heap::isMarked(m_otherCallees->m_processed[i].callee().rawCalleeCell()))
                continue;
            
            m_numCallsToUnknownCell += m_otherCallees->m_processed[i].count();
            m_otherCallees->m_processed[i--] = m_otherCallees->m_processed.last();
            m_otherCallees->m_processed.removeLast();
        }
        
        // Only exists while we are processing the log.
        RELEASE_ASSERT(!m_otherCallees->m_temporarySpectrum);
    }
}