void QmlProfilerRangeModel::findBindingLoops()
{
    typedef QPair<int, int> CallStackEntry;
    QStack<CallStackEntry> callStack;

    for (int i = 0; i < count(); ++i) {
        int potentialParent = callStack.isEmpty() ? -1 : callStack.top().second;

        while (potentialParent != -1 && !(endTime(potentialParent) > startTime(i))) {
            callStack.pop();
            potentialParent = callStack.isEmpty() ? -1 : callStack.top().second;
        }

        // check whether event is already in stack
        for (int ii = 0; ii < callStack.size(); ++ii) {
            if (callStack.at(ii).first == typeId(i)) {
                m_data[i].bindingLoopHead = callStack.at(ii).second;
                break;
            }
        }

        CallStackEntry newEntry(typeId(i), i);
        callStack.push(newEntry);
    }

}
Example #2
0
static const QString context()
{
    QString context(yyPackage);
    bool innerClass = false;
    for (int i = 0; i < yyScope.size(); ++i) {
        if (yyScope.at(i)->type == Scope::Clazz) {
            if (innerClass)
                context.append(QLatin1String("$"));
            else
                context.append(QLatin1String("."));

            context.append(yyScope.at(i)->name);
            innerClass = true;
        }
    }
    return context.isEmpty() ? yyDefaultContext : context;
}
Example #3
0
// traverses to the top to check all of the parent contexes.
bool XLIFFHandler::hasContext(XliffContext ctx) const
{
    for (int i = m_contextStack.count() - 1; i >= 0; --i) {
        if (m_contextStack.at(i) == ctx)
            return true;
    }
    return false;
}
void QmlProfilerEventsModelProxy::loadData(qint64 rangeStart, qint64 rangeEnd)
{
    clear();

    qint64 qmlTime = 0;
    qint64 lastEndTime = 0;
    QHash <int, QVector<qint64> > durations;

    const bool checkRanges = (rangeStart != -1) && (rangeEnd != -1);

    const QVector<QmlProfilerDataModel::QmlEventData> &eventList
            = d->modelManager->qmlModel()->getEvents();
    const QVector<QmlProfilerDataModel::QmlEventTypeData> &typesList
            = d->modelManager->qmlModel()->getEventTypes();

    // used by binding loop detection
    QStack<const QmlProfilerDataModel::QmlEventData*> callStack;
    callStack.push(0); // artificial root

    for (int i = 0; i < eventList.size(); ++i) {
        const QmlProfilerDataModel::QmlEventData *event = &eventList[i];
        const QmlProfilerDataModel::QmlEventTypeData *type = &typesList[event->typeIndex];

        if (!d->acceptedTypes.contains(type->rangeType))
            continue;

        if (checkRanges) {
            if ((event->startTime + event->duration < rangeStart)
                    || (event->startTime > rangeEnd))
                continue;
        }

        // update stats
        QmlEventStats *stats = &d->data[event->typeIndex];

        stats->duration += event->duration;
        if (event->duration < stats->minTime)
            stats->minTime = event->duration;
        if (event->duration > stats->maxTime)
            stats->maxTime = event->duration;
        stats->calls++;

        // for median computing
        durations[event->typeIndex].append(event->duration);

        // qml time computation
        if (event->startTime > lastEndTime) { // assume parent event if starts before last end
            qmlTime += event->duration;
            lastEndTime = event->startTime + event->duration;
        }


        //
        // binding loop detection
        //
        const QmlProfilerDataModel::QmlEventData *potentialParent = callStack.top();
        while (potentialParent
               && !(potentialParent->startTime + potentialParent->duration > event->startTime)) {
            callStack.pop();
            potentialParent = callStack.top();
        }

        // check whether event is already in stack
        for (int ii = 1; ii < callStack.size(); ++ii) {
            if (callStack.at(ii)->typeIndex == event->typeIndex) {
                d->eventsInBindingLoop.insert(event->typeIndex);
                break;
            }
        }

        callStack.push(event);

        d->modelManager->modelProxyCountUpdated(d->modelId, i, eventList.count()*2);
    }

    // post-process: calc mean time, median time, percentoftime
    int i = d->data.size();
    int total = i * 2;

    for (QHash<int, QmlEventStats>::iterator it = d->data.begin(); it != d->data.end(); ++it) {
        QmlEventStats* stats = &it.value();
        if (stats->calls > 0)
            stats->timePerCall = stats->duration / (double)stats->calls;

        QVector<qint64> eventDurations = durations[it.key()];
        if (!eventDurations.isEmpty()) {
            Utils::sort(eventDurations);
            stats->medianTime = eventDurations.at(eventDurations.count()/2);
        }

        stats->percentOfTime = stats->duration * 100.0 / qmlTime;
        d->modelManager->modelProxyCountUpdated(d->modelId, i++, total);
    }

    // set binding loop flag
    foreach (int typeIndex, d->eventsInBindingLoop)
        d->data[typeIndex].isBindingLoop = true;

    // insert root event
    QmlEventStats rootEvent;
    rootEvent.duration = rootEvent.minTime = rootEvent.maxTime = rootEvent.timePerCall
                       = rootEvent.medianTime = qmlTime + 1;
    rootEvent.calls = 1;
    rootEvent.percentOfTime = 100.0;

    d->data.insert(-1, rootEvent);

    d->modelManager->modelProxyCountUpdated(d->modelId, 1, 1);
    emit dataAvailable();
}
void QmlProfilerEventsModelProxy::loadData(qint64 rangeStart, qint64 rangeEnd)
{
    clear();

    qint64 qmlTime = 0;
    qint64 lastEndTime = 0;
    QHash <QString, QVector<qint64> > durations;

    const bool checkRanges = (rangeStart != -1) && (rangeEnd != -1);

    const QVector<QmlProfilerDataModel::QmlEventData> eventList
            = d->modelManager->qmlModel()->getEvents();

    // used by binding loop detection
    typedef QPair<QString, const QmlProfilerDataModel::QmlEventData*> CallStackEntry;
    QStack<CallStackEntry> callStack;
    callStack.push(CallStackEntry(QString(), 0)); // artificial root

    for (int i = 0; i < eventList.size(); ++i) {
        const QmlProfilerDataModel::QmlEventData *event = &eventList[i];

        if (!d->acceptedTypes.contains((QmlDebug::QmlEventType)event->eventType))
            continue;

        if (checkRanges) {
            if ((event->startTime + event->duration < rangeStart)
                    || (event->startTime > rangeEnd))
                continue;
        }

        // put event in hash
        QString hash = QmlProfilerDataModel::getHashString(*event);
        if (!d->data.contains(hash)) {
            QmlEventStats stats = {
                event->displayName,
                hash,
                event->data.join(QLatin1String(" ")),
                event->location,
                event->eventType,
                event->bindingType,
                event->duration,
                1, //calls
                event->duration, //minTime
                event->duration, // maxTime
                0, //timePerCall
                0, //percentOfTime
                0, //medianTime
                false //isBindingLoop
            };

            d->data.insert(hash, stats);

            // for median computing
            durations.insert(hash, QVector<qint64>());
            durations[hash].append(event->duration);
        } else {
            // update stats
            QmlEventStats *stats = &d->data[hash];

            stats->duration += event->duration;
            if (event->duration < stats->minTime)
                stats->minTime = event->duration;
            if (event->duration > stats->maxTime)
                stats->maxTime = event->duration;
            stats->calls++;

            // for median computing
            durations[hash].append(event->duration);
        }

        // qml time computation
        if (event->startTime > lastEndTime) { // assume parent event if starts before last end
            qmlTime += event->duration;
            lastEndTime = event->startTime + event->duration;
        }


        //
        // binding loop detection
        //
        const QmlProfilerDataModel::QmlEventData *potentialParent = callStack.top().second;
        while (potentialParent
               && !(potentialParent->startTime + potentialParent->duration > event->startTime)) {
            callStack.pop();
            potentialParent = callStack.top().second;
        }

        // check whether event is already in stack
        bool inLoop = false;
        for (int ii = 1; ii < callStack.size(); ++ii) {
            if (callStack.at(ii).first == hash)
                inLoop = true;
            if (inLoop)
                d->eventsInBindingLoop.insert(hash);
        }


        CallStackEntry newEntry(hash, event);
        callStack.push(newEntry);

        d->modelManager->modelProxyCountUpdated(d->modelId, i, eventList.count()*2);
    }

    // post-process: calc mean time, median time, percentoftime
    int i = d->data.size();
    int total = i * 2;
    foreach (const QString &hash, d->data.keys()) {
        QmlEventStats* stats = &d->data[hash];
        if (stats->calls > 0)
            stats->timePerCall = stats->duration / (double)stats->calls;

        QVector<qint64> eventDurations = durations.value(hash);
        if (!eventDurations.isEmpty()) {
            qSort(eventDurations);
            stats->medianTime = eventDurations.at(eventDurations.count()/2);
        }

        stats->percentOfTime = stats->duration * 100.0 / qmlTime;
        d->modelManager->modelProxyCountUpdated(d->modelId, i++, total);
    }

    // set binding loop flag
    foreach (const QString &eventHash, d->eventsInBindingLoop)
        d->data[eventHash].isBindingLoop = true;

    QString rootEventName = tr("<program>");
    QmlDebug::QmlEventLocation rootEventLocation(rootEventName, 1, 1);

    // insert root event
    QmlEventStats rootEvent = {
        rootEventName, //event.displayName,
        rootEventName, // hash
        tr("Main Program"), //event.details,
        rootEventLocation, // location
        (int)QmlDebug::Binding, // event type
        0, // binding type
        qmlTime + 1,
        1, //calls
        qmlTime + 1, //minTime
        qmlTime + 1, // maxTime
        qmlTime + 1, //timePerCall
        100.0, //percentOfTime
        qmlTime + 1, //medianTime;
        false
    };

    d->data.insert(rootEventName, rootEvent);

    d->modelManager->modelProxyCountUpdated(d->modelId, 1, 1);
    emit dataAvailable();
}
Example #6
0
Constante* Eval::getValue() const {
    Expression* exp = dynamic_cast<Expression*>(c);
    QStack<Constante*> p;
    if (exp != NULL){
        int i = 0;
        QString s = exp->getExp();
        Constante * result = 0;
        while(i<s.length()){
            //on passe les espaces;
            if(s[i] == ' '){
                if(result != 0){
                    p.push(result);
                    result = 0;
                }
            }
            else if(s[i] >= '0' && s[i] <= '9'){
                if(result == 0)result = Addition(Rationnel(0),Rationnel(0),mModeConstante, mModeComplexes).getValue();
                result->addChiffre(s[i].toAscii() - '0');
            }
            else if(s[i] == '$'){
                if(result == 0) throw EvalException("$ mal placé");
                result->setDollarEntre();
            }
            else if(s[i] == '/'){
                if(result != 0){
                    result->setSlashEntre();
                }
                else{
                    if(p.size() < 2) throw EvalException("Pas assez d'opérandes pour /");
                    Constante *op2 = p.pop(),  *op1 = p.pop();
                    try{
                        result = Division(*op1,*op2,mModeConstante,mModeComplexes).getValue();
                    }
                    catch(DivException e){
                        throw EvalException("division par zéro");
                    }

                    delete op1;
                    delete op2;
                    p.push(result);
                    result = 0;
                }
            }
            else if(s[i] == ',' || s[i] == '.'){
                if(result == 0) throw EvalException(", ou . mal placé");
                result->setVirguleEntree();
            }
            else if(s[i] == '+'){
                if(result!=0){
                    p.push(result);
                    result = 0;
                }
                if(p.size() < 2) throw EvalException("Pas assez d'opérandes pour +");
                Constante *op1 = p.pop(),  *op2 = p.pop();
                result = Addition(*op1,*op2,mModeConstante,mModeComplexes).getValue();
                delete op1;
                delete op2;
                p.push(result);
                result = 0;
            }
            else if(s[i] == '-'){
                if(result!=0){
                    p.push(result);
                    result = 0;
                }
                if(p.size() < 2) throw EvalException("Pas assez d'opérandes pour -");
                Constante *op2 = p.pop(),  *op1 = p.pop();
                result = Soustraction(*op1,*op2,mModeConstante,mModeComplexes).getValue();
                delete op1;
                delete op2;
                p.push(result);
                result = 0;
            }
            else if(s[i] == '*'){
                if(result!=0){
                    p.push(result);
                    result = 0;
                }
                if(p.size() < 2) throw EvalException("Pas assez d'opérandes pour *");
                Constante *op2 = p.pop(),  *op1 = p.pop();
                result = Multiplication(*op1,*op2,mModeConstante,mModeComplexes).getValue();
                delete op1;
                delete op2;
                p.push(result);
                result = 0;
            }
            else{
                throw EvalException("Caractère inconnu");
            }
            i++;
        }
        if(result!=0)p.push(result);
        if(p.size() > 1) throw EvalException("Il manque un opérateur.");
        if(p.size() < 1) throw EvalException("Pile d'évaluation vide.");
        return p.at(0);
    }
    else throw TypeConstanteException("Ceci n'est pas une expression");
}