Rework source path parsing.

- As we parse the image's function list, we now track the last source
file we encountered. If it's the first time we encounter the current
file, we parse its source path components up front and then simply walk
the parsed list in order to add the function to its appropriate place in
the model, rather than the previous recursive approach.  This allows us
to reuse the parsed component list for subsequent functions in the same
source file rather than having to reparse the path on every iteration.

- Refactor GetFunctionPath() to make use of the new
_GetSourcePathComponents() parsing function.

Should further improve the time needed to change the active image.
This commit is contained in:
Rene Gollent
2013-05-15 21:10:57 -04:00
parent 66b86c6aee
commit 3938bea1dc
@@ -11,6 +11,8 @@
#include <new> #include <new>
#include <set> #include <set>
#include <StringList.h>
#include <AutoDeleter.h> #include <AutoDeleter.h>
#include "table/TableColumns.h" #include "table/TableColumns.h"
@@ -194,6 +196,8 @@ public:
BReference<SourcePathComponentNode> sourceNodeRef( BReference<SourcePathComponentNode> sourceNodeRef(
sourcelessNode, true); sourcelessNode, true);
LocatableFile* currentFile = NULL;
BStringList pathComponents;
int32 functionCount = fImageDebugInfo->CountFunctions(); int32 functionCount = fImageDebugInfo->CountFunctions();
for (int32 i = 0; i < functionCount; i++) { for (int32 i = 0; i < functionCount; i++) {
FunctionInstance* instance = fImageDebugInfo->FunctionAt(i); FunctionInstance* instance = fImageDebugInfo->FunctionAt(i);
@@ -208,7 +212,22 @@ public:
} }
} }
if (!_BuildFunctionSourcePath(instance, sourcelessNode)) LocatableFile* sourceFile = instance->SourceFile();
if (sourceFile == NULL) {
if (!_AddFunctionNode(sourcelessNode, instance, NULL))
return;
continue;
}
if (sourceFile != currentFile) {
currentFile = sourceFile;
if (!_GetSourcePathComponents(currentFile,
pathComponents)) {
return;
}
}
if (!_AddFunctionByPath(pathComponents, instance, currentFile))
return; return;
} }
@@ -276,30 +295,20 @@ public:
node = fSourcelessNode; node = fSourcelessNode;
_path.AddComponent(fChildPathComponents.IndexOf(node)); _path.AddComponent(fChildPathComponents.IndexOf(node));
} else { } else {
BString sourcePath; BStringList pathComponents;
sourceFile->GetPath(sourcePath); if (!_GetSourcePathComponents(sourceFile, pathComponents))
if (sourcePath.IsEmpty())
return false; return false;
BString searchPath; for (int32 i = 0; i < pathComponents.CountStrings(); i++) {
while (!sourcePath.IsEmpty()) { BString component = pathComponents.StringAt(i);
if (sourcePath[0] == '/')
sourcePath.Remove(0, 1);
int32 separatorIndex = sourcePath.FindFirst('/');
if (separatorIndex == -1) {
searchPath = sourcePath;
sourcePath.Truncate(0);
} else
sourcePath.MoveInto(searchPath, 0, separatorIndex);
if (node == NULL) { if (node == NULL) {
childIndex = fChildPathComponents.BinarySearchIndexByKey( childIndex = fChildPathComponents.BinarySearchIndexByKey(
searchPath, component,
&SourcePathComponentNode::CompareByComponentName); &SourcePathComponentNode::CompareByComponentName);
node = fChildPathComponents.ItemAt(childIndex); node = fChildPathComponents.ItemAt(childIndex);
} else { } else {
childIndex = node->FindChildIndexByName(searchPath); childIndex = node->FindChildIndexByName(component);
node = node->ChildAt(childIndex); node = node->ChildAt(childIndex);
} }
@@ -343,50 +352,59 @@ public:
} }
private: private:
bool _BuildFunctionSourcePath(FunctionInstance* function, bool _GetSourcePathComponents(LocatableFile* currentFile,
SourcePathComponentNode* sourcelessNode) BStringList& pathComponents)
{ {
LocatableFile* sourceFile = function->SourceFile();
if (sourceFile == NULL)
return _AddFunctionNode(sourcelessNode, function, NULL);
BString sourcePath; BString sourcePath;
sourceFile->GetPath(sourcePath); currentFile->GetPath(sourcePath);
if (sourcePath.IsEmpty()) if (sourcePath.IsEmpty())
return false; return false;
return _AddNextPathComponent(NULL, sourcePath, function, sourceFile); pathComponents.MakeEmpty();
int32 startIndex = 0;
if (sourcePath[0] == '/')
startIndex = 1;
while (startIndex < sourcePath.Length()) {
int32 searchIndex = sourcePath.FindFirst('/', startIndex);
BString data;
if (searchIndex < 0)
searchIndex = sourcePath.Length();
sourcePath.CopyInto(data, startIndex, searchIndex - startIndex);
if (!pathComponents.Add(data))
return false;
startIndex = searchIndex + 1;
} }
bool _AddNextPathComponent(SourcePathComponentNode* parent, return true;
BString& childPath, FunctionInstance* function, LocatableFile* file) }
bool _AddFunctionByPath(const BStringList& pathComponents,
FunctionInstance* function, LocatableFile* file)
{ {
if (childPath[0] == '/') SourcePathComponentNode* parentNode = NULL;
childPath.Remove(0, 1);
BString pathComponent;
int32 pathSeparatorIndex = childPath.FindFirst('/');
if (pathSeparatorIndex == -1)
pathComponent = childPath;
else
childPath.MoveInto(pathComponent, 0, pathSeparatorIndex);
SourcePathComponentNode* currentNode = NULL; SourcePathComponentNode* currentNode = NULL;
if (parent == NULL) { for (int32 i = 0; i < pathComponents.CountStrings(); i++) {
currentNode = fChildPathComponents.BinarySearchByKey(pathComponent, const BString pathComponent = pathComponents.StringAt(i);
if (parentNode == NULL) {
currentNode = fChildPathComponents.BinarySearchByKey(
pathComponent,
SourcePathComponentNode::CompareByComponentName); SourcePathComponentNode::CompareByComponentName);
} else } else
currentNode = parent->FindChildByName(pathComponent); currentNode = parentNode->FindChildByName(pathComponent);
if (currentNode == NULL) { if (currentNode == NULL) {
currentNode = new(std::nothrow) SourcePathComponentNode(parent, currentNode = new(std::nothrow) SourcePathComponentNode(
pathComponent, NULL, NULL); parentNode, pathComponent, NULL, NULL);
if (currentNode == NULL) if (currentNode == NULL)
return false; return false;
BReference<SourcePathComponentNode> nodeReference(currentNode, BReference<SourcePathComponentNode> nodeReference(currentNode,
true); true);
if (parent != NULL) { if (parentNode != NULL) {
if (!parent->AddChild(currentNode)) if (!parentNode->AddChild(currentNode))
return false; return false;
} else { } else {
if (!fChildPathComponents.BinaryInsert(currentNode, if (!fChildPathComponents.BinaryInsert(currentNode,
@@ -397,11 +415,10 @@ private:
nodeReference.Detach(); nodeReference.Detach();
} }
} }
parentNode = currentNode;
}
if (pathSeparatorIndex == -1)
return _AddFunctionNode(currentNode, function, file); return _AddFunctionNode(currentNode, function, file);
return _AddNextPathComponent(currentNode, childPath, function, file);
} }
bool _AddFunctionNode(SourcePathComponentNode* parent, bool _AddFunctionNode(SourcePathComponentNode* parent,