Beispiel #1
0
bool GetByIdStatus::appendVariant(const GetByIdVariant& variant)
{
    for (unsigned i = 0; i < m_variants.size(); ++i) {
        if (m_variants[i].structureSet().overlaps(variant.structureSet()))
            return false;
    }
    m_variants.append(variant);
    return true;
}
Beispiel #2
0
bool GetByIdStatus::appendVariant(const GetByIdVariant& variant)
{
    // Attempt to merge this variant with an already existing variant.
    for (unsigned i = 0; i < m_variants.size(); ++i) {
        if (m_variants[i].attemptToMerge(variant))
            return true;
    }
    
    // Make sure there is no overlap. We should have pruned out opportunities for
    // overlap but it's possible that an inline cache got into a weird state. We are
    // defensive and bail if we detect crazy.
    for (unsigned i = 0; i < m_variants.size(); ++i) {
        if (m_variants[i].structureSet().overlaps(variant.structureSet()))
            return false;
    }
    
    m_variants.append(variant);
    return true;
}
Beispiel #3
0
    void emitGetByOffset(unsigned indexInBlock, Node* node, const AbstractValue& baseValue, const GetByIdVariant& variant, unsigned identifierNumber)
    {
        NodeOrigin origin = node->origin;
        Edge childEdge = node->child1();
        Node* child = childEdge.node();

        addBaseCheck(indexInBlock, node, baseValue, variant.structureSet());
        
        JSValue baseForLoad;
        if (variant.alternateBase())
            baseForLoad = variant.alternateBase();
        else
            baseForLoad = baseValue.m_value;
        if (JSValue value = m_graph.tryGetConstantProperty(baseForLoad, variant.baseStructure(), variant.offset())) {
            m_graph.convertToConstant(node, m_graph.freeze(value));
            return;
        }
        
        if (variant.alternateBase()) {
            child = m_insertionSet.insertConstant(indexInBlock, origin, variant.alternateBase());
            childEdge = Edge(child, KnownCellUse);
        } else
            childEdge.setUseKind(KnownCellUse);
        
        Edge propertyStorage;
        
        if (isInlineOffset(variant.offset()))
            propertyStorage = childEdge;
        else {
            propertyStorage = Edge(m_insertionSet.insertNode(
                indexInBlock, SpecNone, GetButterfly, origin, childEdge));
        }
        
        node->convertToGetByOffset(m_graph.m_storageAccessData.size(), propertyStorage);
        
        StorageAccessData storageAccessData;
        storageAccessData.offset = variant.offset();
        storageAccessData.identifierNumber = identifierNumber;
        m_graph.m_storageAccessData.append(storageAccessData);
    }
    void emitGetByOffset(unsigned indexInBlock, Node* node, Structure* structure, const GetByIdVariant& variant, unsigned identifierNumber)
    {
        NodeOrigin origin = node->origin;
        Edge childEdge = node->child1();
        Node* child = childEdge.node();

        bool needsWatchpoint = !m_state.forNode(child).m_currentKnownStructure.hasSingleton();
        bool needsCellCheck = m_state.forNode(child).m_type & ~SpecCell;
        
        ASSERT(!variant.chain());
        ASSERT(variant.structureSet().contains(structure));
        
        // Now before we do anything else, push the CFA forward over the GetById
        // and make sure we signal to the loop that it should continue and not
        // do any eliminations.
        m_interpreter.execute(indexInBlock);
        
        if (needsWatchpoint) {
            m_insertionSet.insertNode(
                indexInBlock, SpecNone, StructureTransitionWatchpoint, origin,
                OpInfo(structure), childEdge);
        } else if (needsCellCheck) {
            m_insertionSet.insertNode(
                indexInBlock, SpecNone, Phantom, origin, childEdge);
        }
        
        if (variant.specificValue()) {
            m_graph.convertToConstant(node, variant.specificValue());
            return;
        }
        
        childEdge.setUseKind(KnownCellUse);
        
        Edge propertyStorage;
        
        if (isInlineOffset(variant.offset()))
            propertyStorage = childEdge;
        else {
            propertyStorage = Edge(m_insertionSet.insertNode(
                indexInBlock, SpecNone, GetButterfly, origin, childEdge));
        }
        
        node->convertToGetByOffset(m_graph.m_storageAccessData.size(), propertyStorage);
        
        StorageAccessData storageAccessData;
        storageAccessData.offset = variant.offset();
        storageAccessData.identifierNumber = identifierNumber;
        m_graph.m_storageAccessData.append(storageAccessData);
    }