Beispiel #1
0
TypedArrayType typedArrayTypeFromSpeculation(SpeculatedType type)
{
    if (isInt8ArraySpeculation(type))
        return TypeInt8;
        
    if (isInt16ArraySpeculation(type))
        return TypeInt16;
        
    if (isInt32ArraySpeculation(type))
        return TypeInt32;
        
    if (isUint8ArraySpeculation(type))
        return TypeUint8;
        
    if (isUint8ClampedArraySpeculation(type))
        return TypeUint8Clamped;
        
    if (isUint16ArraySpeculation(type))
        return TypeUint16;
        
    if (isUint32ArraySpeculation(type))
        return TypeUint32;
        
    if (isFloat32ArraySpeculation(type))
        return TypeFloat32;
        
    if (isFloat64ArraySpeculation(type))
        return TypeFloat64;
    
    return NotTypedArray;
}
Beispiel #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 "";
}
Beispiel #3
0
ArrayMode ArrayMode::refine(
    Graph& graph, CodeOrigin codeOrigin,
    SpeculatedType base, SpeculatedType index, SpeculatedType value,
    NodeFlags flags) const
{
    if (!base || !index) {
        // It can be that we had a legitimate arrayMode but no incoming predictions. That'll
        // happen if we inlined code based on, say, a global variable watchpoint, but later
        // realized that the callsite could not have possibly executed. It may be worthwhile
        // to fix that, but for now I'm leaving it as-is.
        return ArrayMode(Array::ForceExit);
    }
    
    if (!isInt32Speculation(index))
        return ArrayMode(Array::Generic);
    
    // Note: our profiling currently doesn't give us good information in case we have
    // an unlikely control flow path that sets the base to a non-cell value. Value
    // profiling and prediction propagation will probably tell us that the value is
    // either a cell or not, but that doesn't tell us which is more likely: that this
    // is an array access on a cell (what we want and can optimize) or that the user is
    // doing a crazy by-val access on a primitive (we can't easily optimize this and
    // don't want to). So, for now, we assume that if the base is not a cell according
    // to value profiling, but the array profile tells us something else, then we
    // should just trust the array profile.
    
    switch (type()) {
    case Array::Unprofiled:
        return ArrayMode(Array::ForceExit);
        
    case Array::Undecided:
        if (!value)
            return withType(Array::ForceExit);
        if (isInt32Speculation(value))
            return withTypeAndConversion(Array::Int32, Array::Convert);
        if (isFullNumberSpeculation(value))
            return withTypeAndConversion(Array::Double, Array::Convert);
        return withTypeAndConversion(Array::Contiguous, Array::Convert);
        
    case Array::Int32:
        if (!value || isInt32Speculation(value))
            return *this;
        if (isFullNumberSpeculation(value))
            return withTypeAndConversion(Array::Double, Array::Convert);
        return withTypeAndConversion(Array::Contiguous, Array::Convert);
        
    case Array::Double:
        if (flags & NodeBytecodeUsesAsInt)
            return withTypeAndConversion(Array::Contiguous, Array::RageConvert);
        if (!value || isFullNumberSpeculation(value))
            return *this;
        return withTypeAndConversion(Array::Contiguous, Array::Convert);
        
    case Array::Contiguous:
        if (doesConversion() && (flags & NodeBytecodeUsesAsInt))
            return withConversion(Array::RageConvert);
        return *this;
        
    case Array::SelectUsingPredictions: {
        base &= ~SpecOther;
        
        if (isStringSpeculation(base))
            return withType(Array::String);
        
        if (isArgumentsSpeculation(base))
            return withType(Array::Arguments);
        
        ArrayMode result;
        if (graph.hasExitSite(codeOrigin, OutOfBounds) || !isInBounds())
            result = withSpeculation(Array::OutOfBounds);
        else
            result = withSpeculation(Array::InBounds);
        
        if (isInt8ArraySpeculation(base))
            return result.withType(Array::Int8Array);
        
        if (isInt16ArraySpeculation(base))
            return result.withType(Array::Int16Array);
        
        if (isInt32ArraySpeculation(base))
            return result.withType(Array::Int32Array);
        
        if (isUint8ArraySpeculation(base))
            return result.withType(Array::Uint8Array);
        
        if (isUint8ClampedArraySpeculation(base))
            return result.withType(Array::Uint8ClampedArray);
        
        if (isUint16ArraySpeculation(base))
            return result.withType(Array::Uint16Array);
        
        if (isUint32ArraySpeculation(base))
            return result.withType(Array::Uint32Array);
        
        if (isFloat32ArraySpeculation(base))
            return result.withType(Array::Float32Array);
        
        if (isFloat64ArraySpeculation(base))
            return result.withType(Array::Float64Array);

        return ArrayMode(Array::Generic);
    }

    default:
        return *this;
    }
}
Beispiel #4
0
ArrayMode ArrayMode::refine(SpeculatedType base, SpeculatedType index, SpeculatedType value, NodeFlags flags) const
{
    if (!base || !index) {
        // It can be that we had a legitimate arrayMode but no incoming predictions. That'll
        // happen if we inlined code based on, say, a global variable watchpoint, but later
        // realized that the callsite could not have possibly executed. It may be worthwhile
        // to fix that, but for now I'm leaving it as-is.
        return ArrayMode(Array::ForceExit);
    }
    
    if (!isInt32Speculation(index) || !isCellSpeculation(base))
        return ArrayMode(Array::Generic);
    
    switch (type()) {
    case Array::Unprofiled:
        return ArrayMode(Array::ForceExit);
        
    case Array::Undecided:
        if (!value)
            return withType(Array::ForceExit);
        if (isInt32Speculation(value))
            return withTypeAndConversion(Array::Int32, Array::Convert);
        if (isNumberSpeculation(value))
            return withTypeAndConversion(Array::Double, Array::Convert);
        return withTypeAndConversion(Array::Contiguous, Array::Convert);
        
    case Array::Int32:
        if (!value || isInt32Speculation(value))
            return *this;
        if (isNumberSpeculation(value))
            return withTypeAndConversion(Array::Double, Array::Convert);
        return withTypeAndConversion(Array::Contiguous, Array::Convert);
        
    case Array::Double:
        if (flags & NodeUsedAsIntLocally)
            return withTypeAndConversion(Array::Contiguous, Array::RageConvert);
        if (!value || isNumberSpeculation(value))
            return *this;
        return withTypeAndConversion(Array::Contiguous, Array::Convert);
        
    case Array::Contiguous:
        if (doesConversion() && (flags & NodeUsedAsIntLocally))
            return withConversion(Array::RageConvert);
        return *this;
        
    case Array::SelectUsingPredictions:
        if (isStringSpeculation(base))
            return ArrayMode(Array::String);
        
        if (isArgumentsSpeculation(base))
            return ArrayMode(Array::Arguments);
        
        if (isInt8ArraySpeculation(base))
            return ArrayMode(Array::Int8Array);
        
        if (isInt16ArraySpeculation(base))
            return ArrayMode(Array::Int16Array);
        
        if (isInt32ArraySpeculation(base))
            return ArrayMode(Array::Int32Array);
        
        if (isUint8ArraySpeculation(base))
            return ArrayMode(Array::Uint8Array);
        
        if (isUint8ClampedArraySpeculation(base))
            return ArrayMode(Array::Uint8ClampedArray);
        
        if (isUint16ArraySpeculation(base))
            return ArrayMode(Array::Uint16Array);
        
        if (isUint32ArraySpeculation(base))
            return ArrayMode(Array::Uint32Array);
        
        if (isFloat32ArraySpeculation(base))
            return ArrayMode(Array::Float32Array);
        
        if (isFloat64ArraySpeculation(base))
            return ArrayMode(Array::Float64Array);

        return ArrayMode(Array::Generic);

    default:
        return *this;
    }
}