blob: fa870affe36b4d6e64f032958f1953b0fe26ba1a [file] [log] [blame]
Zack Rusin20b1f6d2011-09-06 11:50:07 -04001#include "traceloader.h"
2
Zack Rusin3176ebe2011-09-06 21:11:36 -04003#include "apitrace.h"
Zack Rusin20b1f6d2011-09-06 11:50:07 -04004#include <QDebug>
5#include <QFile>
6
7#define FRAMES_TO_CACHE 100
8
9static ApiTraceCall *
José Fonsecab4a3d142011-10-27 07:43:19 +010010apiCallFromTraceCall(const trace::Call *call,
Zack Rusin20b1f6d2011-09-06 11:50:07 -040011 const QHash<QString, QUrl> &helpHash,
Zack Rusinebf971e2011-09-06 17:44:43 -040012 ApiTraceFrame *frame,
Zack Rusind9d9d222013-10-11 18:02:26 -040013 ApiTraceCall *parentCall,
Zack Rusinebf971e2011-09-06 17:44:43 -040014 TraceLoader *loader)
Zack Rusin20b1f6d2011-09-06 11:50:07 -040015{
Zack Rusind9d9d222013-10-11 18:02:26 -040016 ApiTraceCall *apiCall;
17
18 if (parentCall)
19 apiCall = new ApiTraceCall(parentCall, loader, call);
20 else
21 apiCall = new ApiTraceCall(frame, loader, call);
Zack Rusin20b1f6d2011-09-06 11:50:07 -040022
23 apiCall->setHelpUrl(helpHash.value(apiCall->name()));
24
25 return apiCall;
26}
27
Zack Rusinebf971e2011-09-06 17:44:43 -040028TraceLoader::TraceLoader(QObject *parent)
José Fonseca5cd8d992012-03-25 23:12:20 +010029 : QObject(parent)
Zack Rusin20b1f6d2011-09-06 11:50:07 -040030{
31}
32
33TraceLoader::~TraceLoader()
34{
35 m_parser.close();
Zack Rusin081e59d2011-09-21 00:25:03 -040036 qDeleteAll(m_signatures);
Zack Rusin20b1f6d2011-09-06 11:50:07 -040037}
38
39void TraceLoader::loadTrace(const QString &filename)
40{
41 if (m_helpHash.isEmpty()) {
42 loadHelpFile();
43 }
44
Zack Rusindaf82af2011-09-24 13:42:53 -040045 if (!m_frameBookmarks.isEmpty()) {
46 qDeleteAll(m_signatures);
Zack Rusindaf82af2011-09-24 13:42:53 -040047 m_signatures.clear();
Zack Rusindaf82af2011-09-24 13:42:53 -040048 m_frameBookmarks.clear();
49 m_createdFrames.clear();
50 m_parser.close();
51 }
52
Zack Rusin20b1f6d2011-09-06 11:50:07 -040053 if (!m_parser.open(filename.toLatin1())) {
54 qDebug() << "error: failed to open " << filename;
55 return;
56 }
Zack Rusin59b79552011-09-21 00:37:03 -040057
Jose Fonseca8f0846c2015-11-10 19:53:55 +000058 if (!m_parser.supportsOffsets()) {
59 emit parseProblem(
60 "This trace in compressed in a format that does not allow random seeking.\n"
61 "Please repack the trace with `apitrace repack`."
62 );
63 m_parser.close();
64 return;
65 }
66
Zack Rusin20b1f6d2011-09-06 11:50:07 -040067 emit startedParsing();
68
Jose Fonsecaf009c982015-11-10 19:59:34 +000069 scanTrace();
70
José Fonseca67964382012-03-27 23:54:30 +010071 emit guessedApi(static_cast<int>(m_parser.api));
Zack Rusin20b1f6d2011-09-06 11:50:07 -040072 emit finishedParsing();
73}
74
Zack Rusin3176ebe2011-09-06 21:11:36 -040075void TraceLoader::loadFrame(ApiTraceFrame *currentFrame)
Zack Rusin20b1f6d2011-09-06 11:50:07 -040076{
Zack Rusin8f98c3a2011-09-11 18:21:29 -040077 fetchFrameContents(currentFrame);
Zack Rusin20b1f6d2011-09-06 11:50:07 -040078}
79
Zack Rusin20b1f6d2011-09-06 11:50:07 -040080int TraceLoader::numberOfFrames() const
81{
José Fonseca61e61f72011-09-11 16:53:34 +010082 return m_frameBookmarks.size();
Zack Rusin20b1f6d2011-09-06 11:50:07 -040083}
84
85int TraceLoader::numberOfCallsInFrame(int frameIdx) const
86{
José Fonseca6bfa32f2012-03-22 16:26:47 +000087 if (frameIdx >= m_frameBookmarks.size()) {
Zack Rusin20b1f6d2011-09-06 11:50:07 -040088 return 0;
89 }
José Fonseca61e61f72011-09-11 16:53:34 +010090 FrameBookmarks::const_iterator itr =
91 m_frameBookmarks.find(frameIdx);
Zack Rusin20b1f6d2011-09-06 11:50:07 -040092 return itr->numberOfCalls;
93}
94
95void TraceLoader::loadHelpFile()
96{
Zack Rusinac92a212011-09-06 18:25:34 -040097 QFile file(":/resources/glreference.tsv");
98 if (file.open(QIODevice::ReadOnly | QIODevice::Text)) {
99 QString line;
100 while (!file.atEnd()) {
101 line = file.readLine();
102 QString function = line.section('\t', 0, 0).trimmed();
103 QUrl url = QUrl(line.section('\t', 1, 1).trimmed());
104 //qDebug()<<"function = "<<function<<", url = "<<url.toString();
105 m_helpHash.insert(function, url);
106 }
107 } else {
108 qWarning() << "Couldn't open reference file "
109 << file.fileName();
110 }
111 file.close();
Zack Rusin20b1f6d2011-09-06 11:50:07 -0400112}
113
114void TraceLoader::scanTrace()
115{
Zack Rusinac92a212011-09-06 18:25:34 -0400116 QList<ApiTraceFrame*> frames;
117 ApiTraceFrame *currentFrame = 0;
Zack Rusin20b1f6d2011-09-06 11:50:07 -0400118
José Fonsecab4a3d142011-10-27 07:43:19 +0100119 trace::Call *call;
120 trace::ParseBookmark startBookmark;
Zack Rusinac92a212011-09-06 18:25:34 -0400121 int numOfFrames = 0;
122 int numOfCalls = 0;
Zack Rusinac92a212011-09-06 18:25:34 -0400123 int lastPercentReport = 0;
Zack Rusin20b1f6d2011-09-06 11:50:07 -0400124
José Fonseca61e61f72011-09-11 16:53:34 +0100125 m_parser.getBookmark(startBookmark);
Zack Rusin20b1f6d2011-09-06 11:50:07 -0400126
Zack Rusinac92a212011-09-06 18:25:34 -0400127 while ((call = m_parser.scan_call())) {
128 ++numOfCalls;
Zack Rusin20b1f6d2011-09-06 11:50:07 -0400129
José Fonseca5cd8d992012-03-25 23:12:20 +0100130 if (call->flags & trace::CALL_FLAG_END_FRAME) {
José Fonseca61e61f72011-09-11 16:53:34 +0100131 FrameBookmark frameBookmark(startBookmark);
132 frameBookmark.numberOfCalls = numOfCalls;
Zack Rusin20b1f6d2011-09-06 11:50:07 -0400133
Zack Rusinac92a212011-09-06 18:25:34 -0400134 currentFrame = new ApiTraceFrame();
135 currentFrame->number = numOfFrames;
136 currentFrame->setNumChildren(numOfCalls);
Zack Rusin851d0b02011-09-14 22:04:07 -0400137 currentFrame->setLastCallIndex(call->no);
Zack Rusinac92a212011-09-06 18:25:34 -0400138 frames.append(currentFrame);
Zack Rusin20b1f6d2011-09-06 11:50:07 -0400139
Zack Rusin8f98c3a2011-09-11 18:21:29 -0400140 m_createdFrames.append(currentFrame);
José Fonseca61e61f72011-09-11 16:53:34 +0100141 m_frameBookmarks[numOfFrames] = frameBookmark;
Zack Rusinac92a212011-09-06 18:25:34 -0400142 ++numOfFrames;
Zack Rusin20b1f6d2011-09-06 11:50:07 -0400143
Zack Rusinac92a212011-09-06 18:25:34 -0400144 if (m_parser.percentRead() - lastPercentReport >= 5) {
145 emit parsed(m_parser.percentRead());
146 lastPercentReport = m_parser.percentRead();
147 }
José Fonseca61e61f72011-09-11 16:53:34 +0100148 m_parser.getBookmark(startBookmark);
Zack Rusinac92a212011-09-06 18:25:34 -0400149 numOfCalls = 0;
150 }
Zack Rusinac92a212011-09-06 18:25:34 -0400151 delete call;
152 }
Zack Rusin20b1f6d2011-09-06 11:50:07 -0400153
Zack Rusinac92a212011-09-06 18:25:34 -0400154 if (numOfCalls) {
José Fonsecab4a3d142011-10-27 07:43:19 +0100155 //trace::File::Bookmark endBookmark = m_parser.currentBookmark();
José Fonseca61e61f72011-09-11 16:53:34 +0100156 FrameBookmark frameBookmark(startBookmark);
157 frameBookmark.numberOfCalls = numOfCalls;
Zack Rusin20b1f6d2011-09-06 11:50:07 -0400158
Zack Rusinac92a212011-09-06 18:25:34 -0400159 currentFrame = new ApiTraceFrame();
160 currentFrame->number = numOfFrames;
161 currentFrame->setNumChildren(numOfCalls);
162 frames.append(currentFrame);
Zack Rusin20b1f6d2011-09-06 11:50:07 -0400163
Zack Rusin8f98c3a2011-09-11 18:21:29 -0400164 m_createdFrames.append(currentFrame);
José Fonseca61e61f72011-09-11 16:53:34 +0100165 m_frameBookmarks[numOfFrames] = frameBookmark;
Zack Rusinac92a212011-09-06 18:25:34 -0400166 ++numOfFrames;
167 }
Zack Rusin20b1f6d2011-09-06 11:50:07 -0400168
Zack Rusinac92a212011-09-06 18:25:34 -0400169 emit parsed(100);
Zack Rusin20b1f6d2011-09-06 11:50:07 -0400170
Zack Rusinac92a212011-09-06 18:25:34 -0400171 emit framesLoaded(frames);
Zack Rusin20b1f6d2011-09-06 11:50:07 -0400172}
173
Zack Rusin20b1f6d2011-09-06 11:50:07 -0400174
Zack Rusinebf971e2011-09-06 17:44:43 -0400175ApiTraceCallSignature * TraceLoader::signature(unsigned id)
176{
177 if (id >= m_signatures.count()) {
178 m_signatures.resize(id + 1);
179 return NULL;
180 } else {
181 return m_signatures[id];
182 }
183}
184
185void TraceLoader::addSignature(unsigned id, ApiTraceCallSignature *signature)
186{
187 m_signatures[id] = signature;
188}
189
Zack Rusinad513b32011-09-25 14:33:41 -0400190void TraceLoader::searchNext(const ApiTrace::SearchRequest &request)
Zack Rusin8f98c3a2011-09-11 18:21:29 -0400191{
192 Q_ASSERT(m_parser.supportsOffsets());
Jose Fonsecaf009c982015-11-10 19:59:34 +0000193 int startFrame = m_createdFrames.indexOf(request.frame);
194 const FrameBookmark &frameBookmark = m_frameBookmarks[startFrame];
195 m_parser.setBookmark(frameBookmark.start);
196 trace::Call *call = 0;
197 while ((call = m_parser.parse_call())) {
Zack Rusin8f98c3a2011-09-11 18:21:29 -0400198
Ruslan Kabatsayev75d69052019-02-20 13:41:18 +0300199 if (callContains(call, request.text, request.cs, request.useRegex)) {
Jose Fonsecaf009c982015-11-10 19:59:34 +0000200 unsigned frameIdx = callInFrame(call->no);
201 ApiTraceFrame *frame = m_createdFrames[frameIdx];
202 const QVector<ApiTraceCall*> calls =
203 fetchFrameContents(frame);
204 for (int i = 0; i < calls.count(); ++i) {
205 if (calls[i]->index() == call->no) {
206 emit searchResult(request, ApiTrace::SearchResult_Found,
207 calls[i]);
208 break;
Zack Rusin8f98c3a2011-09-11 18:21:29 -0400209 }
Zack Rusin8f98c3a2011-09-11 18:21:29 -0400210 }
Zack Rusin8f98c3a2011-09-11 18:21:29 -0400211 delete call;
Jose Fonsecaf009c982015-11-10 19:59:34 +0000212 return;
Zack Rusin8f98c3a2011-09-11 18:21:29 -0400213 }
Jose Fonsecaf009c982015-11-10 19:59:34 +0000214
215 delete call;
Zack Rusin8f98c3a2011-09-11 18:21:29 -0400216 }
Zack Rusinad513b32011-09-25 14:33:41 -0400217 emit searchResult(request, ApiTrace::SearchResult_NotFound, 0);
Zack Rusin8f98c3a2011-09-11 18:21:29 -0400218}
219
Zack Rusinad513b32011-09-25 14:33:41 -0400220void TraceLoader::searchPrev(const ApiTrace::SearchRequest &request)
Zack Rusin8f98c3a2011-09-11 18:21:29 -0400221{
Zack Rusin121e3162011-09-13 01:35:12 -0400222 Q_ASSERT(m_parser.supportsOffsets());
Jose Fonsecaf009c982015-11-10 19:59:34 +0000223 int startFrame = m_createdFrames.indexOf(request.frame);
224 trace::Call *call = 0;
225 QList<trace::Call*> frameCalls;
226 int frameIdx = startFrame;
Zack Rusin121e3162011-09-13 01:35:12 -0400227
Jose Fonsecaf009c982015-11-10 19:59:34 +0000228 const FrameBookmark &frameBookmark = m_frameBookmarks[frameIdx];
229 int numCallsToParse = frameBookmark.numberOfCalls;
230 m_parser.setBookmark(frameBookmark.start);
Zack Rusin121e3162011-09-13 01:35:12 -0400231
Jose Fonsecaf009c982015-11-10 19:59:34 +0000232 while ((call = m_parser.parse_call())) {
Zack Rusin121e3162011-09-13 01:35:12 -0400233
Jose Fonsecaf009c982015-11-10 19:59:34 +0000234 frameCalls.append(call);
235 --numCallsToParse;
Zack Rusin121e3162011-09-13 01:35:12 -0400236
Jose Fonsecaf009c982015-11-10 19:59:34 +0000237 if (numCallsToParse == 0) {
238 bool foundCall = searchCallsBackwards(frameCalls,
239 frameIdx,
240 request);
Zack Rusin121e3162011-09-13 01:35:12 -0400241
Jose Fonsecaf009c982015-11-10 19:59:34 +0000242 qDeleteAll(frameCalls);
243 frameCalls.clear();
244 if (foundCall) {
245 return;
246 }
Zack Rusin121e3162011-09-13 01:35:12 -0400247
Jose Fonsecaf009c982015-11-10 19:59:34 +0000248 --frameIdx;
Zack Rusin121e3162011-09-13 01:35:12 -0400249
Jose Fonsecaf009c982015-11-10 19:59:34 +0000250 if (frameIdx >= 0) {
251 const FrameBookmark &frameBookmark =
252 m_frameBookmarks[frameIdx];
253 m_parser.setBookmark(frameBookmark.start);
254 numCallsToParse = frameBookmark.numberOfCalls;
Zack Rusin121e3162011-09-13 01:35:12 -0400255 }
256 }
257 }
Zack Rusinad513b32011-09-25 14:33:41 -0400258 emit searchResult(request, ApiTrace::SearchResult_NotFound, 0);
Zack Rusin121e3162011-09-13 01:35:12 -0400259}
260
José Fonsecab4a3d142011-10-27 07:43:19 +0100261bool TraceLoader::searchCallsBackwards(const QList<trace::Call*> &calls,
Zack Rusin121e3162011-09-13 01:35:12 -0400262 int frameIdx,
Zack Rusinad513b32011-09-25 14:33:41 -0400263 const ApiTrace::SearchRequest &request)
Zack Rusin121e3162011-09-13 01:35:12 -0400264{
265 for (int i = calls.count() - 1; i >= 0; --i) {
José Fonsecab4a3d142011-10-27 07:43:19 +0100266 trace::Call *call = calls[i];
Ruslan Kabatsayev75d69052019-02-20 13:41:18 +0300267 if (callContains(call, request.text, request.cs, request.useRegex)) {
Zack Rusin121e3162011-09-13 01:35:12 -0400268 ApiTraceFrame *frame = m_createdFrames[frameIdx];
269 const QVector<ApiTraceCall*> apiCalls =
270 fetchFrameContents(frame);
271 for (int i = 0; i < apiCalls.count(); ++i) {
272 if (apiCalls[i]->index() == call->no) {
Zack Rusinad513b32011-09-25 14:33:41 -0400273 emit searchResult(request,
274 ApiTrace::SearchResult_Found,
275 apiCalls[i]);
Zack Rusin121e3162011-09-13 01:35:12 -0400276 break;
277 }
278 }
279 return true;
280 }
281 }
282 return false;
Zack Rusin8f98c3a2011-09-11 18:21:29 -0400283}
284
285int TraceLoader::callInFrame(int callIdx) const
286{
287 unsigned numCalls = 0;
288
José Fonseca6bfa32f2012-03-22 16:26:47 +0000289 for (int frameIdx = 0; frameIdx < m_frameBookmarks.size(); ++frameIdx) {
Zack Rusin8f98c3a2011-09-11 18:21:29 -0400290 const FrameBookmark &frameBookmark = m_frameBookmarks[frameIdx];
291 unsigned firstCall = numCalls;
292 unsigned endCall = numCalls + frameBookmark.numberOfCalls;
293 if (firstCall <= callIdx && endCall > callIdx) {
294 return frameIdx;
295 }
296 numCalls = endCall;
297 }
298 Q_ASSERT(!"call not in the trace");
299 return 0;
300}
301
José Fonsecab4a3d142011-10-27 07:43:19 +0100302bool TraceLoader::callContains(trace::Call *call,
Zack Rusin8f98c3a2011-09-11 18:21:29 -0400303 const QString &str,
Ruslan Kabatsayev75d69052019-02-20 13:41:18 +0300304 Qt::CaseSensitivity sensitivity,
305 bool useRegex)
Zack Rusin8f98c3a2011-09-11 18:21:29 -0400306{
José Fonsecacb7c76f2014-03-27 16:57:22 +0000307 /*
308 * FIXME: do string comparison directly on trace::Call
309 */
310 ApiTraceCall *apiCall = apiCallFromTraceCall(call, m_helpHash,
311 0, 0, this);
Ruslan Kabatsayev75d69052019-02-20 13:41:18 +0300312 bool result = apiCall->contains(str, sensitivity, useRegex);
José Fonsecacb7c76f2014-03-27 16:57:22 +0000313 delete apiCall;
314 return result;
Zack Rusin8f98c3a2011-09-11 18:21:29 -0400315}
316
317QVector<ApiTraceCall*>
318TraceLoader::fetchFrameContents(ApiTraceFrame *currentFrame)
319{
320 Q_ASSERT(currentFrame);
Zack Rusin99f84fa2011-09-19 23:44:25 -0400321
Zack Rusin447f4a52011-09-19 23:45:39 -0400322 if (currentFrame->isLoaded()) {
Zack Rusin99f84fa2011-09-19 23:44:25 -0400323 return currentFrame->calls();
324 }
325
Jose Fonsecaf009c982015-11-10 19:59:34 +0000326 unsigned frameIdx = currentFrame->number;
327 int numOfCalls = numberOfCallsInFrame(frameIdx);
Zack Rusin8f98c3a2011-09-11 18:21:29 -0400328
Jose Fonsecaf009c982015-11-10 19:59:34 +0000329 if (numOfCalls) {
330 const FrameBookmark &frameBookmark = m_frameBookmarks[frameIdx];
Zack Rusin8f98c3a2011-09-11 18:21:29 -0400331
Jose Fonsecaf009c982015-11-10 19:59:34 +0000332 m_parser.setBookmark(frameBookmark.start);
Zack Rusin8f98c3a2011-09-11 18:21:29 -0400333
Jose Fonsecaf009c982015-11-10 19:59:34 +0000334 FrameContents frameCalls(numOfCalls);
335 frameCalls.load(this, currentFrame, m_helpHash, m_parser);
336 if (frameCalls.topLevelCount() == frameCalls.allCallsCount()) {
337 emit frameContentsLoaded(currentFrame,
338 frameCalls.allCalls(),
339 frameCalls.allCalls(),
340 frameCalls.binaryDataSize());
341 } else {
342 emit frameContentsLoaded(currentFrame,
343 frameCalls.topLevelCalls(),
344 frameCalls.allCalls(),
345 frameCalls.binaryDataSize());
Zack Rusin8f98c3a2011-09-11 18:21:29 -0400346 }
Jose Fonsecaf009c982015-11-10 19:59:34 +0000347 return frameCalls.allCalls();
Zack Rusin8f98c3a2011-09-11 18:21:29 -0400348 }
349 return QVector<ApiTraceCall*>();
350}
351
Zack Rusin93e4d152011-09-13 02:23:39 -0400352void TraceLoader::findFrameStart(ApiTraceFrame *frame)
353{
Zack Rusin99f84fa2011-09-19 23:44:25 -0400354 if (!frame->isLoaded()) {
355 loadFrame(frame);
356 }
Zack Rusin93e4d152011-09-13 02:23:39 -0400357 emit foundFrameStart(frame);
358}
359
360void TraceLoader::findFrameEnd(ApiTraceFrame *frame)
361{
Zack Rusin99f84fa2011-09-19 23:44:25 -0400362 if (!frame->isLoaded()) {
363 loadFrame(frame);
364 }
Zack Rusin93e4d152011-09-13 02:23:39 -0400365 emit foundFrameEnd(frame);
366}
367
Zack Rusinda7579b2011-09-13 17:33:05 -0400368void TraceLoader::findCallIndex(int index)
369{
370 int frameIdx = callInFrame(index);
371 ApiTraceFrame *frame = m_createdFrames[frameIdx];
372 QVector<ApiTraceCall*> calls = fetchFrameContents(frame);
373 QVector<ApiTraceCall*>::const_iterator itr;
374 ApiTraceCall *call = 0;
375 for (itr = calls.constBegin(); itr != calls.constEnd(); ++itr) {
376 if ((*itr)->index() == index) {
377 call = *itr;
Lawrence L Love53a40802014-02-12 15:26:55 -0800378 break;
Zack Rusinda7579b2011-09-13 17:33:05 -0400379 }
380 }
José Fonsecacaa84282013-04-11 18:54:06 +0100381 if (call) {
382 emit foundCallIndex(call);
383 }
Zack Rusinda7579b2011-09-13 17:33:05 -0400384}
385
Zack Rusinad513b32011-09-25 14:33:41 -0400386void TraceLoader::search(const ApiTrace::SearchRequest &request)
387{
388 if (request.direction == ApiTrace::SearchRequest::Next) {
389 searchNext(request);
390 } else {
391 searchPrev(request);
392 }
393}
394
Lawrence L Love59befce2014-03-20 18:47:39 -0700395TraceLoader::FrameContents::FrameContents(int numOfCalls)
396 : m_allCalls(numOfCalls),
397 m_binaryDataSize(0),
398 m_parsedCalls(0)
399{}
400
401
402void
403TraceLoader::FrameContents::reset()
404{
405 m_groups.clear();
406 m_allCalls.clear();
407 m_topLevelItems.clear();
408 m_binaryDataSize = 0;
409}
410
411int
412TraceLoader::FrameContents::topLevelCount() const
413{
414 return m_topLevelItems.count();
415}
416
417int
418TraceLoader::FrameContents::allCallsCount() const
419{
420 return m_allCalls.count();
421}
422
423quint64
424TraceLoader::FrameContents::binaryDataSize() const
425{
426 return m_binaryDataSize;
427}
428QVector<ApiTraceCall*>
429TraceLoader::FrameContents::topLevelCalls() const
430{
431 return m_topLevelItems;
432}
433
434QVector<ApiTraceCall*>
435TraceLoader::FrameContents::allCalls() const
436{
437 return m_allCalls;
438}
439
440bool
441TraceLoader::FrameContents::isEmpty()
442{
443 return (m_allCalls.count() == 0);
444}
445
446bool
447TraceLoader::FrameContents::load(TraceLoader *loader,
448 ApiTraceFrame *currentFrame,
449 QHash<QString, QUrl> helpHash,
450 trace::Parser &parser)
451{
452 bool bEndFrameReached = false;
453 int initNumOfCalls = m_allCalls.count();
454 trace::Call *call;
455 ApiTraceCall *apiCall = NULL;
456
457 while ((call = parser.parse_call())) {
458
459 apiCall = apiCallFromTraceCall(call, helpHash, currentFrame,
460 m_groups.isEmpty() ? 0 : m_groups.top(),
461 loader);
462 Q_ASSERT(apiCall);
463 if (initNumOfCalls) {
464 Q_ASSERT(m_parsedCalls < m_allCalls.size());
465 m_allCalls[m_parsedCalls++] = apiCall;
466 } else {
467 m_allCalls.append(apiCall);
468 }
469 if (m_groups.count() == 0) {
470 m_topLevelItems.append(apiCall);
471 } else {
472 m_groups.top()->addChild(apiCall);
473 }
474 if (call->flags & trace::CALL_FLAG_MARKER_PUSH) {
475 m_groups.push(apiCall);
476 } else if (call->flags & trace::CALL_FLAG_MARKER_POP) {
477 if (m_groups.count()) {
478 m_groups.top()->finishedAddingChildren();
479 m_groups.pop();
480 }
481 }
482 if (apiCall->hasBinaryData()) {
483 QByteArray data =
484 apiCall->arguments()[apiCall->binaryDataIndex()].
485 toByteArray();
486 m_binaryDataSize += data.size();
487 }
488
489 delete call;
490
491 if (apiCall->flags() & trace::CALL_FLAG_END_FRAME) {
492 bEndFrameReached = true;
493 break;
494 }
495 }
496 if (initNumOfCalls) {
497 // There can be fewer parsed calls when call in different
498 // threads cross the frame boundary
499 Q_ASSERT(m_parsedCalls <= initNumOfCalls);
500 Q_ASSERT(m_parsedCalls <= m_allCalls.size());
501 m_allCalls.resize(m_parsedCalls);
502 Q_ASSERT(m_parsedCalls <= currentFrame->numChildrenToLoad());
503 }
504 m_allCalls.squeeze();
505 m_topLevelItems.squeeze();
506
507 return bEndFrameReached;
508}
509
Zack Rusin20b1f6d2011-09-06 11:50:07 -0400510#include "traceloader.moc"