bool VariableAccessData::shouldUseDoubleFormatAccordingToVote()
{
    // We don't support this facility for arguments, yet.
    // FIXME: make this work for arguments.
    if (local().isArgument())
        return false;
        
    // If the variable is not a number prediction, then this doesn't
    // make any sense.
    if (!isFullNumberSpeculation(prediction())) {
        // FIXME: we may end up forcing a local in inlined argument position to be a double even
        // if it is sometimes not even numeric, since this never signals the fact that it doesn't
        // want doubles. https://bugs.webkit.org/show_bug.cgi?id=109511
        return false;
    }
        
    // If the variable is predicted to hold only doubles, then it's a
    // no-brainer: it should be formatted as a double.
    if (isDoubleSpeculation(prediction()))
        return true;
        
    // If the variable is known to be used as an integer, then be safe -
    // don't force it to be a double.
    if (flags() & NodeBytecodeUsesAsInt)
        return false;
        
    // If the variable has been voted to become a double, then make it a
    // double.
    if (voteRatio() >= Options::doubleVoteRatioForDoubleFormat())
        return true;
        
    return false;
}
Esempio n. 2
0
// We don't expose this because we don't want anyone relying on the fact that this method currently
// just returns string constants.
static const char* speculationToAbbreviatedString(SpeculatedType prediction)
{
    if (isFinalObjectSpeculation(prediction))
        return "<Final>";
    if (isArraySpeculation(prediction))
        return "<Array>";
    if (isStringIdentSpeculation(prediction))
        return "<StringIdent>";
    if (isStringSpeculation(prediction))
        return "<String>";
    if (isFunctionSpeculation(prediction))
        return "<Function>";
    if (isInt8ArraySpeculation(prediction))
        return "<Int8array>";
    if (isInt16ArraySpeculation(prediction))
        return "<Int16array>";
    if (isInt32ArraySpeculation(prediction))
        return "<Int32array>";
    if (isUint8ArraySpeculation(prediction))
        return "<Uint8array>";
    if (isUint16ArraySpeculation(prediction))
        return "<Uint16array>";
    if (isUint32ArraySpeculation(prediction))
        return "<Uint32array>";
    if (isFloat32ArraySpeculation(prediction))
        return "<Float32array>";
    if (isFloat64ArraySpeculation(prediction))
        return "<Float64array>";
    if (isDirectArgumentsSpeculation(prediction))
        return "<DirectArguments>";
    if (isScopedArgumentsSpeculation(prediction))
        return "<ScopedArguments>";
    if (isStringObjectSpeculation(prediction))
        return "<StringObject>";
    if (isStringOrStringObjectSpeculation(prediction))
        return "<StringOrStringObject>";
    if (isObjectSpeculation(prediction))
        return "<Object>";
    if (isCellSpeculation(prediction))
        return "<Cell>";
    if (isInt32Speculation(prediction))
        return "<Int32>";
    if (isInt52AsDoubleSpeculation(prediction))
        return "<Int52AsDouble>";
    if (isInt52Speculation(prediction))
        return "<Int52>";
    if (isMachineIntSpeculation(prediction))
        return "<MachineInt>";
    if (isDoubleSpeculation(prediction))
        return "<Double>";
    if (isFullNumberSpeculation(prediction))
        return "<Number>";
    if (isBooleanSpeculation(prediction))
        return "<Boolean>";
    if (isOtherSpeculation(prediction))
        return "<Other>";
    if (isMiscSpeculation(prediction))
        return "<Misc>";
    return "";
}
Esempio n. 3
0
    void doRoundOfDoubleVoting()
    {
#if DFG_ENABLE(DEBUG_PROPAGATION_VERBOSE)
        dataLog("Voting on double uses of locals [%u]\n", m_count);
#endif
        for (unsigned i = 0; i < m_graph.m_variableAccessData.size(); ++i)
            m_graph.m_variableAccessData[i].find()->clearVotes();
        for (m_compileIndex = 0; m_compileIndex < m_graph.size(); ++m_compileIndex) {
            Node& node = m_graph[m_compileIndex];
            switch (node.op()) {
            case ValueAdd:
            case ArithAdd:
            case ArithSub: {
                SpeculatedType left = m_graph[node.child1()].prediction();
                SpeculatedType right = m_graph[node.child2()].prediction();
                
                DoubleBallot ballot;
                
                if (isNumberSpeculation(left) && isNumberSpeculation(right)
                    && !m_graph.addShouldSpeculateInteger(node))
                    ballot = VoteDouble;
                else
                    ballot = VoteValue;
                
                m_graph.vote(node.child1(), ballot);
                m_graph.vote(node.child2(), ballot);
                break;
            }
                
            case ArithMul: {
                SpeculatedType left = m_graph[node.child1()].prediction();
                SpeculatedType right = m_graph[node.child2()].prediction();
                
                DoubleBallot ballot;
                
                if (isNumberSpeculation(left) && isNumberSpeculation(right)
                    && !m_graph.mulShouldSpeculateInteger(node))
                    ballot = VoteDouble;
                else
                    ballot = VoteValue;
                
                m_graph.vote(node.child1(), ballot);
                m_graph.vote(node.child2(), ballot);
                break;
            }

            case ArithMin:
            case ArithMax:
            case ArithMod:
            case ArithDiv: {
                SpeculatedType left = m_graph[node.child1()].prediction();
                SpeculatedType right = m_graph[node.child2()].prediction();
                
                DoubleBallot ballot;
                
                if (isNumberSpeculation(left) && isNumberSpeculation(right)
                    && !(Node::shouldSpeculateInteger(m_graph[node.child1()], m_graph[node.child1()])
                         && node.canSpeculateInteger()))
                    ballot = VoteDouble;
                else
                    ballot = VoteValue;
                
                m_graph.vote(node.child1(), ballot);
                m_graph.vote(node.child2(), ballot);
                break;
            }
                
            case ArithAbs:
                DoubleBallot ballot;
                if (!(m_graph[node.child1()].shouldSpeculateInteger()
                      && node.canSpeculateInteger()))
                    ballot = VoteDouble;
                else
                    ballot = VoteValue;
                
                m_graph.vote(node.child1(), ballot);
                break;
                
            case ArithSqrt:
                m_graph.vote(node.child1(), VoteDouble);
                break;
                
            case SetLocal: {
                SpeculatedType prediction = m_graph[node.child1()].prediction();
                if (isDoubleSpeculation(prediction))
                    node.variableAccessData()->vote(VoteDouble);
                else if (!isNumberSpeculation(prediction) || isInt32Speculation(prediction))
                    node.variableAccessData()->vote(VoteValue);
                break;
            }
                
            default:
                m_graph.vote(node, VoteValue);
                break;
            }
        }
        for (unsigned i = 0; i < m_graph.m_variableAccessData.size(); ++i) {
            VariableAccessData* variableAccessData = &m_graph.m_variableAccessData[i];
            if (!variableAccessData->isRoot())
                continue;
            if (operandIsArgument(variableAccessData->local())
                || variableAccessData->isCaptured())
                continue;
            m_changed |= variableAccessData->tallyVotesForShouldUseDoubleFormat();
        }
        for (unsigned i = 0; i < m_graph.m_argumentPositions.size(); ++i)
            m_changed |= m_graph.m_argumentPositions[i].mergeArgumentAwareness();
        for (unsigned i = 0; i < m_graph.m_variableAccessData.size(); ++i) {
            VariableAccessData* variableAccessData = &m_graph.m_variableAccessData[i];
            if (!variableAccessData->isRoot())
                continue;
            if (operandIsArgument(variableAccessData->local())
                || variableAccessData->isCaptured())
                continue;
            m_changed |= variableAccessData->makePredictionForDoubleFormat();
        }
    }