void CachegrindLoader::setCalledFunction(const QString& name) { // if called object/file not set, use current object/file if (!currentCalledObject) { currentCalledObject = currentObject; currentCalledPartObject = currentPartObject; } if (!currentCalledFile) { // !=0 as functions needs file currentCalledFile = currentFile; currentCalledPartFile = currentPartFile; } currentCalledFunction = compressedFunction(name, currentCalledFile, currentCalledObject); if (!currentCalledFunction) { error(QStringLiteral("Invalid called function, setting to unknown")); currentCalledFunction = _data->function(_emptyString, currentCalledFile, currentCalledObject); } currentCalledPartFunction = currentCalledFunction->partFunction(_part, currentCalledPartFile, currentCalledPartObject); }
void CachegrindLoader::setFunction(const QString& name) { ensureFile(); ensureObject(); currentFunction = compressedFunction( name, currentFile, currentObject); if (!currentFunction) { error(QStringLiteral("Invalid function specification, setting to unknown")); currentFunction = _data->function(_emptyString, currentFile, currentObject); } currentPartFunction = currentFunction->partFunction(_part, currentPartFile, currentPartObject); currentFunctionSource = 0; currentLine = 0; currentPartLine = 0; }
// make sure that a valid function is set, at least dummy with empty name void CachegrindLoader::ensureFunction() { if (currentFunction) return; error(QStringLiteral("Function not specified, setting to unknown")); ensureFile(); ensureObject(); currentFunction = _data->function(_emptyString, currentFile, currentObject); currentPartFunction = currentFunction->partFunction(_part, currentPartFile, currentPartObject); }
// Note: Callgrind gives different IDs even for same function // when parts of the function are from different source files. // Thus, it is no error when multiple indexes map to same function. TraceFunction* CachegrindLoader::compressedFunction(const QString& name, TraceFile* file, TraceObject* object) { if ((name[0] != '(') || !name[1].isDigit()) return _data->function(checkUnknown(name), file, object); // compressed format using _functionVector int p = name.indexOf(')'); if (p<2) { error(QStringLiteral("Invalid compressed function ('%1')").arg(name)); return 0; } int index = name.midRef(1, p-1).toUInt(); TraceFunction* f = 0; p++; while((name.length()>p) && name.at(p).isSpace()) p++; if (name.length()>p) { if (_functionVector.size() <= index) { int newSize = index * 2; #if TRACE_LOADER qDebug() << " CachegrindLoader::functionVector enlarged to " << newSize; #endif _functionVector.resize(newSize); } QString realName = checkUnknown(name.mid(p)); f = (TraceFunction*) _functionVector.at(index); if (f && (f->name() != realName)) { error(QStringLiteral("Redefinition of compressed function index %1 (was '%2') to %3") .arg(index).arg(f->name()).arg(realName)); } f = _data->function(realName, file, object); _functionVector.replace(index, f); #if TRACE_LOADER qDebug() << "compressedFunction: Inserted at Index " << index << "\n " << f->fullName() << "\n in " << f->cls()->fullName() << "\n in " << f->file()->fullName() << "\n in " << f->object()->fullName(); #endif } else { if ((_functionVector.size() <= index) || ( (f=(TraceFunction*)_functionVector.at(index)) == 0)) { error(QStringLiteral("Undefined compressed function index %1").arg(index)); return 0; } // there was a check if the used function (returned from KCachegrinds // model) has the same object and file as here given to us, but that was wrong: // that holds only if we make this assumption on the model... } return f; }