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); } }
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; }
// 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(); }
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"); }