Commit 135c449c authored by Christiaan Janssen's avatar Christiaan Janssen
Browse files

QmlProfiler: merging Callers, Callees and Events



Change-Id: I9e50710a8ddf91e143110cd8bc43a528aa4ee863
Reviewed-by: default avatarKai Koehne <kai.koehne@nokia.com>
parent fd26ab22
......@@ -58,24 +58,6 @@ const char *const TYPE_HANDLINGSIGNAL_STR = "HandlingSignal";
#define MIN_LEVEL 1
// description
struct QmlEventDescription {
QmlEventDescription() : displayname(0), location(0), filename(0), details(0) {}
~QmlEventDescription() {
delete displayname;
delete location;
delete filename;
delete details;
}
QString *displayname;
QString *location;
QString *filename;
QString *details;
int eventType;
int line;
};
// endtimedata
struct QmlEventEndTimeData {
qint64 endTime;
......@@ -235,6 +217,24 @@ QList <QmlEventData *> QmlProfilerEventList::getEventDescriptions() const
return d->m_eventDescriptions.values();
}
QmlEventData *QmlProfilerEventList::eventDescription(int eventId) const
{
foreach (QmlEventData *event, d->m_eventDescriptions.values()) {
if (event->eventId == eventId)
return event;
}
return 0;
}
QV8EventData *QmlProfilerEventList::v8EventDescription(int eventId) const
{
foreach (QV8EventData *event, d->m_v8EventList) {
if (event->eventId == eventId)
return event;
}
return 0;
}
const QV8EventDescriptions& QmlProfilerEventList::getV8Events() const
{
return d->m_v8EventList;
......@@ -276,7 +276,7 @@ void QmlProfilerEventList::addRangedEvent(int type, qint64 startTime, qint64 len
details = details.mid(details.lastIndexOf(QChar('/')) + 1);
}
newEvent = new QmlEventData;
newEvent = new QmlEventData();
newEvent->displayname = displayName;
newEvent->filename = fileName;
newEvent->location = location;
......@@ -363,6 +363,10 @@ void QmlProfilerEventList::QmlProfilerEventListPrivate::collectV8Statistics()
v8event->totalPercent = v8event->totalTime * 100.0 / totalTimes;
v8event->selfPercent = v8event->selfTime * 100.0 / selfTimes;
}
int index = 0;
foreach (QV8EventData *v8event, m_v8EventList)
v8event->eventId = index++;
}
void QmlProfilerEventList::setTraceEndTime( qint64 time )
......@@ -423,14 +427,10 @@ void QmlProfilerEventList::compileStatistics()
// compute percentages
double totalTime = 0;
foreach (QmlEventData *binding, d->m_eventDescriptions.values()) {
if (binding->filename.isEmpty())
continue;
totalTime += binding->cumulatedDuration;
}
foreach (QmlEventData *binding, d->m_eventDescriptions.values()) {
if (binding->filename.isEmpty())
continue;
binding->percentOfTime = binding->cumulatedDuration * 100.0 / totalTime;
binding->timePerCall = binding->calls > 0 ? double(binding->cumulatedDuration) / binding->calls : 0;
}
......@@ -452,7 +452,7 @@ void QmlProfilerEventList::compileStatistics()
// generate numeric ids
int ndx = 0;
foreach (QmlEventData *binding, d->m_eventDescriptions.values()) {
binding->numericHash = ndx++;
binding->eventId = ndx++;
}
// collect type counts
......@@ -465,8 +465,8 @@ void QmlProfilerEventList::compileStatistics()
if (eventStartData.nestingLevel > d->m_typeCounts[typeNumber]->nestingCount) {
d->m_typeCounts[typeNumber]->nestingCount = eventStartData.nestingLevel;
}
if (!d->m_typeCounts[typeNumber]->eventIds.contains(eventStartData.description->numericHash))
d->m_typeCounts[typeNumber]->eventIds << eventStartData.description->numericHash;
if (!d->m_typeCounts[typeNumber]->eventIds.contains(eventStartData.description->eventId))
d->m_typeCounts[typeNumber]->eventIds << eventStartData.description->eventId;
}
// continue postprocess
......@@ -1001,7 +1001,7 @@ void QmlProfilerEventList::load()
if (attributes.hasAttribute("index")) {
int ndx = attributes.value("index").toString().toInt();
if (!descriptionBuffer.value(ndx))
descriptionBuffer[ndx] = new QmlEventData;
descriptionBuffer[ndx] = new QmlEventData();
currentEvent = descriptionBuffer[ndx];
} else {
currentEvent = 0;
......@@ -1209,8 +1209,8 @@ QString QmlProfilerEventList::getDetails(int index) const {
return d->m_startTimeSortedList[index].description->details;
}
int QmlProfilerEventList::getHash(int index) const {
return d->m_startTimeSortedList[index].description->numericHash;
int QmlProfilerEventList::getEventId(int index) const {
return d->m_startTimeSortedList[index].description->eventId;
}
int QmlProfilerEventList::uniqueEventsOfType(int type) const {
......@@ -1233,7 +1233,7 @@ QString QmlProfilerEventList::eventTextForType(int type, int index) const {
int QmlProfilerEventList::eventPosInType(int index) const {
int eventType = d->m_startTimeSortedList[index].description->eventType;
return d->m_typeCounts[eventType]->eventIds.indexOf(d->m_startTimeSortedList[index].description->numericHash);
return d->m_typeCounts[eventType]->eventIds.indexOf(d->m_startTimeSortedList[index].description->eventId);
}
} // namespace QmlJsDebugClient
......@@ -43,6 +43,7 @@ namespace QmlJsDebugClient {
struct QMLJSDEBUGCLIENT_EXPORT QmlEventData
{
QmlEventData():line(-1),cumulatedDuration(0),calls(0),eventId(-1){}
QString displayname;
QString filename;
QString location;
......@@ -58,7 +59,7 @@ struct QMLJSDEBUGCLIENT_EXPORT QmlEventData
double timePerCall;
double percentOfTime;
qint64 medianTime;
int numericHash;
int eventId;
};
struct QMLJSDEBUGCLIENT_EXPORT QV8EventData
......@@ -73,6 +74,7 @@ struct QMLJSDEBUGCLIENT_EXPORT QV8EventData
double selfPercent;
QList< QV8EventData *> parentList;
QList< QV8EventData *> childrenList;
int eventId;
};
typedef QHash<QString, QmlEventData *> QmlEventHash;
......@@ -97,7 +99,9 @@ public:
~QmlProfilerEventList();
QmlEventDescriptions getEventDescriptions() const;
QmlEventData *eventDescription(int eventId) const;
const QV8EventDescriptions& getV8Events() const;
QV8EventData *v8EventDescription(int eventId) const;
int findFirstIndex(qint64 startTime) const;
int findFirstIndexNoParents(qint64 startTime) const;
......@@ -119,7 +123,7 @@ public:
Q_INVOKABLE QString getFilename(int index) const;
Q_INVOKABLE int getLine(int index) const;
Q_INVOKABLE QString getDetails(int index) const;
Q_INVOKABLE int getHash(int index) const;
Q_INVOKABLE int getEventId(int index) const;
// per-type data
Q_INVOKABLE int uniqueEventsOfType(int type) const;
......
......@@ -33,23 +33,56 @@
#ifndef QMLPROFILEREVENTVIEW_H
#define QMLPROFILEREVENTVIEW_H
#include <QTreeView>
#include <QtGui/QTreeView>
#include <qmljsdebugclient/qmlprofilereventtypes.h>
#include <qmljsdebugclient/qmlprofilereventlist.h>
#include <QtGui/QStandardItemModel>
namespace QmlProfiler {
namespace Internal {
class QmlProfilerEventsMainView;
class QmlProfilerEventsParentsAndChildrenView;
typedef QHash<QString, QmlJsDebugClient::QmlEventData *> QmlEventHash;
typedef QList<QmlJsDebugClient::QmlEventData *> QmlEventList;
enum ItemRole {
LocationRole = Qt::UserRole+1,
FilenameRole = Qt::UserRole+2,
LineRole = Qt::UserRole+3
LineRole = Qt::UserRole+3,
EventIdRole = Qt::UserRole+4
};
class QmlProfilerEventsView : public QTreeView
class QmlProfilerEventsWidget : public QWidget
{
Q_OBJECT
public:
explicit QmlProfilerEventsWidget(QmlJsDebugClient::QmlProfilerEventList *model, QWidget *parent);
~QmlProfilerEventsWidget();
void switchToV8View();
void clear();
QModelIndex selectedItem() const;
bool mouseOnTable(const QPoint &position) const;
void copyTableToClipboard() const;
void copyRowToClipboard() const;
signals:
void gotoSourceLocation(const QString &fileName, int lineNumber);
void contextMenuRequested(const QPoint &position);
protected:
void contextMenuEvent(QContextMenuEvent *ev);
private:
QmlProfilerEventsMainView *m_eventTree;
QmlProfilerEventsParentsAndChildrenView *m_eventChildren;
QmlProfilerEventsParentsAndChildrenView *m_eventParents;
};
class QmlProfilerEventsMainView : public QTreeView
{
Q_OBJECT
public:
......@@ -81,8 +114,8 @@ public:
MaxViewTypes
};
explicit QmlProfilerEventsView(QWidget *parent, QmlJsDebugClient::QmlProfilerEventList *model);
~QmlProfilerEventsView();
explicit QmlProfilerEventsMainView(QmlJsDebugClient::QmlProfilerEventList *model, QWidget *parent);
~QmlProfilerEventsMainView();
void setEventStatisticsModel(QmlJsDebugClient::QmlProfilerEventList *model);
void setFieldViewable(Fields field, bool show);
......@@ -90,26 +123,62 @@ public:
void setShowAnonymousEvents( bool showThem );
QModelIndex selectedItem() const;
void copyTableToClipboard();
void copyRowToClipboard();
void copyTableToClipboard() const;
void copyRowToClipboard() const;
static QString nameForType(int typeNumber);
signals:
void gotoSourceLocation(const QString &fileName, int lineNumber);
void contextMenuRequested(const QPoint &position);
void eventSelected(int eventId);
public slots:
void clear();
void jumpToItem(const QModelIndex &index);
void selectEvent(int eventId);
void buildModel();
private:
void setHeaderLabels();
void contextMenuEvent(QContextMenuEvent *ev);
private:
class QmlProfilerEventsViewPrivate;
QmlProfilerEventsViewPrivate *d;
class QmlProfilerEventsMainViewPrivate;
QmlProfilerEventsMainViewPrivate *d;
};
class QmlProfilerEventsParentsAndChildrenView : public QTreeView
{
Q_OBJECT
public:
enum SubViewType {
ParentsView,
ChildrenView,
V8ParentsView,
V8ChildrenView,
MaxSubtableTypes
};
explicit QmlProfilerEventsParentsAndChildrenView(QmlJsDebugClient::QmlProfilerEventList *model, SubViewType subtableType, QWidget *parent);
~QmlProfilerEventsParentsAndChildrenView();
void setViewType(SubViewType type);
signals:
void eventClicked(int eventId);
public slots:
void displayEvent(int eventId);
void jumpToItem(const QModelIndex &);
void clear();
private:
void rebuildTree(void *eventList);
void updateHeader();
QStandardItemModel *treeModel();
QmlJsDebugClient::QmlProfilerEventList *m_eventList;
SubViewType m_subtableType;
};
} // namespace Internal
......
......@@ -100,10 +100,8 @@ public:
QTimer m_connectionTimer;
int m_connectionAttempts;
TraceWindow *m_traceWindow;
QmlProfilerEventsView *m_eventsView;
QmlProfilerEventsView *m_calleeView;
QmlProfilerEventsView *m_callerView;
QmlProfilerEventsView *m_v8profilerView;
QmlProfilerEventsWidget *m_eventsView;
QmlProfilerEventsWidget *m_v8profilerView;
Utils::FileInProjectFinder m_projectFinder;
RunConfiguration *m_runConfiguration;
bool m_isAttached;
......@@ -175,7 +173,7 @@ IAnalyzerTool::ToolMode QmlProfilerTool::toolMode() const
void QmlProfilerTool::showContextMenu(const QPoint &position)
{
QmlProfilerEventsView *senderView = qobject_cast<QmlProfilerEventsView *>(sender());
QmlProfilerEventsWidget *eventView = qobject_cast<QmlProfilerEventsWidget *>(sender());
TraceWindow *traceView = qobject_cast<TraceWindow *>(sender());
QMenu menu;
......@@ -184,11 +182,12 @@ void QmlProfilerTool::showContextMenu(const QPoint &position)
QAction *copyRowAction = 0;
QAction *copyTableAction = 0;
QAction *viewAllAction = 0;
if (senderView) {
if (senderView->selectedItem().isValid())
if (eventView && eventView->mouseOnTable(position)) {
if (eventView->selectedItem().isValid())
copyRowAction = menu.addAction(tr("Copy Row"));
copyTableAction = menu.addAction(tr("Copy Table"));
}
if (traceView) {
if (traceView->getEventList()->count() > 0) {
menu.addSeparator();
......@@ -204,9 +203,9 @@ void QmlProfilerTool::showContextMenu(const QPoint &position)
if (selectedAction == saveAction)
showSaveDialog();
if (selectedAction == copyRowAction)
senderView->copyRowToClipboard();
eventView->copyRowToClipboard();
if (selectedAction == copyTableAction)
senderView->copyTableToClipboard();
eventView->copyTableToClipboard();
if (selectedAction == viewAllAction)
traceView->viewAll();
}
......@@ -315,27 +314,12 @@ QWidget *QmlProfilerTool::createWidgets()
connect(d->m_traceWindow, SIGNAL(contextMenuRequested(QPoint)), this, SLOT(showContextMenu(QPoint)));
connect(d->m_traceWindow->getEventList(), SIGNAL(error(QString)), this, SLOT(showErrorDialog(QString)));
d->m_eventsView = new QmlProfilerEventsView(mw, d->m_traceWindow->getEventList());
d->m_eventsView->setViewType(QmlProfilerEventsView::EventsView);
connect(d->m_eventsView, SIGNAL(gotoSourceLocation(QString,int)),
this, SLOT(gotoSourceLocation(QString,int)));
d->m_eventsView = new QmlProfilerEventsWidget(d->m_traceWindow->getEventList(), mw);
connect(d->m_eventsView, SIGNAL(gotoSourceLocation(QString,int)), this, SLOT(gotoSourceLocation(QString,int)));
connect(d->m_eventsView, SIGNAL(contextMenuRequested(QPoint)), this, SLOT(showContextMenu(QPoint)));
d->m_calleeView = new QmlProfilerEventsView(mw, d->m_traceWindow->getEventList());
d->m_calleeView->setViewType(QmlProfilerEventsView::CalleesView);
connect(d->m_calleeView, SIGNAL(gotoSourceLocation(QString,int)),
this, SLOT(gotoSourceLocation(QString,int)));
connect(d->m_calleeView, SIGNAL(contextMenuRequested(QPoint)), this, SLOT(showContextMenu(QPoint)));
d->m_callerView = new QmlProfilerEventsView(mw, d->m_traceWindow->getEventList());
d->m_callerView->setViewType(QmlProfilerEventsView::CallersView);
connect(d->m_callerView, SIGNAL(gotoSourceLocation(QString,int)),
this, SLOT(gotoSourceLocation(QString,int)));
connect(d->m_callerView, SIGNAL(contextMenuRequested(QPoint)), this, SLOT(showContextMenu(QPoint)));
d->m_v8profilerView = new QmlProfilerEventsView(mw, d->m_traceWindow->getEventList());
d->m_v8profilerView->setViewType(QmlProfilerEventsView::V8ProfileView);
d->m_v8profilerView = new QmlProfilerEventsWidget(d->m_traceWindow->getEventList(), mw);
d->m_v8profilerView->switchToV8View();
connect(d->m_v8profilerView, SIGNAL(gotoSourceLocation(QString,int)), this, SLOT(gotoSourceLocation(QString,int)));
connect(d->m_v8profilerView, SIGNAL(contextMenuRequested(QPoint)), this, SLOT(showContextMenu(QPoint)));
......@@ -343,24 +327,16 @@ QWidget *QmlProfilerTool::createWidgets()
(this, tr("Events"), d->m_eventsView, Qt::BottomDockWidgetArea);
QDockWidget *timelineDock = AnalyzerManager::createDockWidget
(this, tr("Timeline"), d->m_traceWindow, Qt::BottomDockWidgetArea);
QDockWidget *calleeDock = AnalyzerManager::createDockWidget
(this, tr("Callees"), d->m_calleeView, Qt::BottomDockWidgetArea);
QDockWidget *callerDock = AnalyzerManager::createDockWidget
(this, tr("Callers"), d->m_callerView, Qt::BottomDockWidgetArea);
QDockWidget *v8profilerDock = AnalyzerManager::createDockWidget
(this, tr("JavaScript"), d->m_v8profilerView, Qt::BottomDockWidgetArea);
eventsDock->show();
timelineDock->show();
calleeDock->show();
callerDock->show();
v8profilerDock->show();
mw->splitDockWidget(mw->toolBarDockWidget(), eventsDock, Qt::Vertical);
mw->tabifyDockWidget(eventsDock, timelineDock);
mw->tabifyDockWidget(timelineDock, calleeDock);
mw->tabifyDockWidget(calleeDock, callerDock);
mw->tabifyDockWidget(callerDock, v8profilerDock);
mw->tabifyDockWidget(timelineDock, v8profilerDock);
//
// Toolbar
......@@ -514,8 +490,6 @@ void QmlProfilerTool::clearDisplay()
{
d->m_traceWindow->clearDisplay();
d->m_eventsView->clear();
d->m_calleeView->clear();
d->m_callerView->clear();
d->m_v8profilerView->clear();
}
......
......@@ -116,13 +116,13 @@ void TimelineView::paint(QPainter *p, const QStyleOptionGraphicsItem *, QWidget
QColor TimelineView::colorForItem(int itemIndex)
{
int ndx = m_eventList->getHash(itemIndex);
int ndx = m_eventList->getEventId(itemIndex);
return QColor::fromHsl((ndx*25)%360, 76, 166);
}
QLinearGradient *TimelineView::gradientForItem(int itemIndex)
{
int ndx = m_eventList->getHash(itemIndex);
int ndx = m_eventList->getEventId(itemIndex);
if (!m_hashedGradients.contains(ndx)) {
QLinearGradient *linearGrad = new QLinearGradient(0,0,0,DefaultRowHeight);
linearGrad->setColorAt(0, colorForItem(itemIndex));
......@@ -165,7 +165,7 @@ void TimelineView::drawSelectionBoxes(QPainter *p)
int fromIndex = m_eventList->findFirstIndex(m_startTime);
int toIndex = m_eventList->findLastIndex(m_endTime);
int id = m_eventList->getHash(m_selectedItem);
int id = m_eventList->getEventId(m_selectedItem);
p->setBrush(Qt::transparent);
QPen strongPen(QBrush(Qt::blue), 3);
......@@ -174,7 +174,7 @@ void TimelineView::drawSelectionBoxes(QPainter *p)
int x, y, width, eventType;
for (int i = fromIndex; i <= toIndex; i++) {
if (m_eventList->getHash(i) != id)
if (m_eventList->getEventId(i) != id)
continue;
if (i == m_selectedItem)
......@@ -340,14 +340,14 @@ void TimelineView::selectNext()
return;
if (m_selectionLocked && m_selectedItem !=-1 ) {
// find next item with same hashId
int hashId = m_eventList->getHash(m_selectedItem);
// find next item with same eventId
int eventId = m_eventList->getEventId(m_selectedItem);
int i = m_selectedItem+1;
while (i<m_eventList->count() && m_eventList->getHash(i) != hashId)
while (i<m_eventList->count() && m_eventList->getEventId(i) != eventId)
i++;
if (i == m_eventList->count()) {
i = 0;
while (i<m_selectedItem && m_eventList->getHash(i) != hashId)
while (i<m_selectedItem && m_eventList->getEventId(i) != eventId)
i++;
}
setSelectedItem(i);
......@@ -368,14 +368,14 @@ void TimelineView::selectPrev()
return;
if (m_selectionLocked && m_selectedItem !=-1) {
// find previous item with same hashId
int hashId = m_eventList->getHash(m_selectedItem);
// find previous item with same eventId
int eventId = m_eventList->getEventId(m_selectedItem);
int i = m_selectedItem-1;
while (i>-1 && m_eventList->getHash(i) != hashId)
while (i>-1 && m_eventList->getEventId(i) != eventId)
i--;
if (i == -1) {
i = m_eventList->count()-1;
while (i>m_selectedItem && m_eventList->getHash(i) != hashId)
while (i>m_selectedItem && m_eventList->getEventId(i) != eventId)
i--;
}
setSelectedItem(i);
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment