aboutsummaryrefslogtreecommitdiffstats
path: root/src/lib/corelib/buildgraph
diff options
context:
space:
mode:
authorChristian Kandeler <christian.kandeler@qt.io>2017-11-13 17:19:32 +0100
committerChristian Kandeler <christian.kandeler@qt.io>2017-11-30 16:12:55 +0000
commitc03f79f3af806cdec5c938d267486d338eaaab5d (patch)
tree763949fc5edda34de287a19d4a04461f588e3987 /src/lib/corelib/buildgraph
parenta5cc49f2c62cfd4094c6a8bccd7741ca9ee7e072 (diff)
Remove as many dynamic_casts as possible
According to our benchmarker, this speeds up rule execution by three per cent. Change-Id: Iaf146ba6073b897d19e0fe470d7b0dc4a04d264c Reviewed-by: Jake Petroules <jake.petroules@qt.io>
Diffstat (limited to 'src/lib/corelib/buildgraph')
-rw-r--r--src/lib/corelib/buildgraph/artifact.cpp5
-rw-r--r--src/lib/corelib/buildgraph/artifact.h1
-rw-r--r--src/lib/corelib/buildgraph/buildgraph.cpp21
-rw-r--r--src/lib/corelib/buildgraph/buildgraphloader.cpp11
-rw-r--r--src/lib/corelib/buildgraph/depscanner.cpp5
-rw-r--r--src/lib/corelib/buildgraph/executor.cpp26
-rw-r--r--src/lib/corelib/buildgraph/filedependency.h5
-rw-r--r--src/lib/corelib/buildgraph/inputartifactscanner.cpp38
-rw-r--r--src/lib/corelib/buildgraph/projectbuilddata.cpp43
9 files changed, 94 insertions, 61 deletions
diff --git a/src/lib/corelib/buildgraph/artifact.cpp b/src/lib/corelib/buildgraph/artifact.cpp
index de9c5b7b6..b2ccdf55c 100644
--- a/src/lib/corelib/buildgraph/artifact.cpp
+++ b/src/lib/corelib/buildgraph/artifact.cpp
@@ -121,10 +121,9 @@ const TypeFilter<Artifact> Artifact::childArtifacts() const
void Artifact::onChildDisconnected(BuildGraphNode *child)
{
- Artifact *childArtifact = dynamic_cast<Artifact *>(child);
- if (!childArtifact)
+ if (child->type() != BuildGraphNode::ArtifactNodeType)
return;
- childrenAddedByScanner.remove(childArtifact);
+ childrenAddedByScanner.remove(static_cast<Artifact *>(child));
}
void Artifact::load(PersistentPool &pool)
diff --git a/src/lib/corelib/buildgraph/artifact.h b/src/lib/corelib/buildgraph/artifact.h
index e08b4181e..fc75427d2 100644
--- a/src/lib/corelib/buildgraph/artifact.h
+++ b/src/lib/corelib/buildgraph/artifact.h
@@ -71,6 +71,7 @@ public:
~Artifact();
Type type() const { return ArtifactNodeType; }
+ FileType fileType() const override { return FileTypeArtifact; }
void accept(BuildGraphVisitor *visitor);
QString toString() const;
diff --git a/src/lib/corelib/buildgraph/buildgraph.cpp b/src/lib/corelib/buildgraph/buildgraph.cpp
index a7d7f9c8e..39687f623 100644
--- a/src/lib/corelib/buildgraph/buildgraph.cpp
+++ b/src/lib/corelib/buildgraph/buildgraph.cpp
@@ -376,7 +376,8 @@ void connect(BuildGraphNode *p, BuildGraphNode *c)
{
QBS_CHECK(p != c);
qCDebug(lcBuildGraph) << "connect" << p->toString() << "->" << c->toString();
- if (Artifact *ac = dynamic_cast<Artifact *>(c)) {
+ if (c->type() == BuildGraphNode::ArtifactNodeType) {
+ Artifact * const ac = static_cast<Artifact *>(c);
for (const Artifact *child : filterByType<Artifact>(p->children)) {
if (child == ac)
return;
@@ -486,11 +487,14 @@ Artifact *lookupArtifact(const ResolvedProductConstPtr &product,
= projectBuildData->lookupFiles(dirPath, fileName);
for (QList<FileResourceBase *>::const_iterator it = lookupResults.constBegin();
it != lookupResults.constEnd(); ++it) {
- Artifact *artifact = dynamic_cast<Artifact *>(*it);
- if (artifact && (compareByName
- ? artifact->product->uniqueName() == product->uniqueName()
- : artifact->product == product))
+ if ((*it)->fileType() != FileResourceBase::FileTypeArtifact)
+ continue;
+ Artifact *artifact = static_cast<Artifact *>(*it);
+ if (compareByName
+ ? artifact->product->uniqueName() == product->uniqueName()
+ : artifact->product == product) {
return artifact;
+ }
}
return nullptr;
}
@@ -581,10 +585,11 @@ static void doSanityChecksForProduct(const ResolvedProductConstPtr &product,
QBS_CHECK(allProducts.contains(child->product.lock()));
}
- Artifact * const artifact = dynamic_cast<Artifact *>(node);
+ Artifact * const artifact = node->type() == BuildGraphNode::ArtifactNodeType
+ ? static_cast<Artifact *>(node) : nullptr;
if (!artifact) {
- RuleNode * const ruleNode = dynamic_cast<RuleNode *>(node);
- QBS_CHECK(ruleNode);
+ QBS_CHECK(node->type() == BuildGraphNode::RuleNodeType);
+ RuleNode * const ruleNode = static_cast<RuleNode *>(node);
QBS_CHECK(ruleNode->rule());
QBS_CHECK(ruleNode->rule()->product);
QBS_CHECK(ruleNode->rule()->product == ruleNode->product.get());
diff --git a/src/lib/corelib/buildgraph/buildgraphloader.cpp b/src/lib/corelib/buildgraph/buildgraphloader.cpp
index d459a1a10..a636bf6df 100644
--- a/src/lib/corelib/buildgraph/buildgraphloader.cpp
+++ b/src/lib/corelib/buildgraph/buildgraphloader.cpp
@@ -93,8 +93,10 @@ static void restoreBackPointers(const ResolvedProjectPtr &project)
if (!product->buildData)
continue;
for (BuildGraphNode * const n : qAsConst(product->buildData->nodes)) {
- if (Artifact *a = dynamic_cast<Artifact *>(n))
- project->topLevelProject()->buildData->insertIntoLookupTable(a);
+ if (n->type() == BuildGraphNode::ArtifactNodeType) {
+ project->topLevelProject()->buildData
+ ->insertIntoLookupTable(static_cast<Artifact *>(n));
+ }
}
}
@@ -436,9 +438,8 @@ void BuildGraphLoader::trackProjectChanges()
.removeEmptyParentDirectories(m_artifactsRemovedFromDisk);
for (FileResourceBase * const f : qAsConst(m_objectsToDelete)) {
- Artifact * const a = dynamic_cast<Artifact *>(f);
- if (a)
- a->product.reset(); // To help with the sanity checks.
+ if (f->fileType() == FileResourceBase::FileTypeArtifact)
+ static_cast<Artifact *>(f)->product.reset(); // To help with the sanity checks.
}
doSanityChecks(m_result.newlyResolvedProject, m_logger);
}
diff --git a/src/lib/corelib/buildgraph/depscanner.cpp b/src/lib/corelib/buildgraph/depscanner.cpp
index 0efe4af47..d20c301f7 100644
--- a/src/lib/corelib/buildgraph/depscanner.cpp
+++ b/src/lib/corelib/buildgraph/depscanner.cpp
@@ -175,10 +175,9 @@ QStringList UserDependencyScanner::collectDependencies(FileResourceBase *file, c
{
Q_UNUSED(fileTags);
// ### support user dependency scanners for file deps
- Artifact *artifact = dynamic_cast<Artifact *>(file);
- if (!artifact)
+ if (file->fileType() != FileResourceBase::FileTypeArtifact)
return QStringList();
- return evaluate(artifact, m_scanner->scanScript);
+ return evaluate(static_cast<Artifact *>(file), m_scanner->scanScript);
}
bool UserDependencyScanner::recursive() const
diff --git a/src/lib/corelib/buildgraph/executor.cpp b/src/lib/corelib/buildgraph/executor.cpp
index 890e85abd..c109d9a01 100644
--- a/src/lib/corelib/buildgraph/executor.cpp
+++ b/src/lib/corelib/buildgraph/executor.cpp
@@ -231,8 +231,10 @@ void Executor::doBuild()
const QList<FileResourceBase *> &files
= m_project->buildData->lookupFiles(fileToConsider);
for (const FileResourceBase * const file : files) {
- const Artifact * const artifact = dynamic_cast<const Artifact *>(file);
- if (artifact && m_productsToBuild.contains(artifact->product.lock())) {
+ if (file->fileType() != FileResourceBase::FileTypeArtifact)
+ continue;
+ const Artifact * const artifact = static_cast<const Artifact *>(file);
+ if (m_productsToBuild.contains(artifact->product.lock())) {
m_tagsOfFilesToConsider.unite(artifact->fileTags());
m_productsOfFilesToConsider << artifact->product.lock();
}
@@ -309,9 +311,11 @@ void Executor::updateLeaves(BuildGraphNode *node, NodeSet &seenNodes)
// prepareBuildGraph() has been called, must be initialized.
if (node->buildState == BuildGraphNode::Untouched) {
node->buildState = BuildGraphNode::Buildable;
- Artifact *artifact = dynamic_cast<Artifact *>(node);
- if (artifact && artifact->artifactType == Artifact::SourceFile)
- retrieveSourceFileTimestamp(artifact);
+ if (node->type() == BuildGraphNode::ArtifactNodeType) {
+ Artifact * const artifact = static_cast<Artifact *>(node);
+ if (artifact->artifactType == Artifact::SourceFile)
+ retrieveSourceFileTimestamp(artifact);
+ }
}
bool isLeaf = true;
@@ -496,16 +500,16 @@ void Executor::executeRuleNode(RuleNode *ruleNode)
Set<RuleNode *> parentRules;
if (!result.createdNodes.empty()) {
for (BuildGraphNode *parent : qAsConst(ruleNode->parents)) {
- if (RuleNode *parentRule = dynamic_cast<RuleNode *>(parent))
- parentRules += parentRule;
+ if (parent->type() == BuildGraphNode::RuleNodeType)
+ parentRules += static_cast<RuleNode *>(parent);
}
}
for (BuildGraphNode *node : qAsConst(result.createdNodes)) {
qCDebug(lcExec) << "rule created" << node->toString();
Internal::connect(node, ruleNode);
- Artifact *outputArtifact = dynamic_cast<Artifact *>(node);
- if (!outputArtifact)
+ if (node->type() != BuildGraphNode::ArtifactNodeType)
continue;
+ Artifact * const outputArtifact = static_cast<Artifact *>(node);
if (outputArtifact->fileTags().intersects(product->fileTags))
product->buildData->roots += outputArtifact;
@@ -776,7 +780,7 @@ void Executor::rescueOldBuildData(Artifact *artifact, bool *childrenAdded = 0)
break;
}
const auto depFinder = [](const FileResourceBase *f) {
- return dynamic_cast<const FileDependency *>(f);
+ return f->fileType() == FileResourceBase::FileTypeDependency;
};
const auto depIt = std::find_if(depList.cbegin(), depList.cend(), depFinder);
if (depIt == depList.cend()) {
@@ -785,7 +789,7 @@ void Executor::rescueOldBuildData(Artifact *artifact, bool *childrenAdded = 0)
<< "not in the project's list of dependencies anymore.";
break;
}
- artifact->fileDependencies.insert(dynamic_cast<FileDependency *>(*depIt));
+ artifact->fileDependencies.insert(static_cast<FileDependency *>(*depIt));
}
if (canRescue) {
diff --git a/src/lib/corelib/buildgraph/filedependency.h b/src/lib/corelib/buildgraph/filedependency.h
index b4ff93816..871667376 100644
--- a/src/lib/corelib/buildgraph/filedependency.h
+++ b/src/lib/corelib/buildgraph/filedependency.h
@@ -54,6 +54,9 @@ protected:
public:
~FileResourceBase();
+ enum FileType { FileTypeDependency, FileTypeArtifact };
+ virtual FileType fileType() const = 0;
+
void setTimestamp(const FileTime &t);
const FileTime &timestamp() const;
void clearTimestamp() { m_timestamp.clear(); }
@@ -79,6 +82,8 @@ class FileDependency : public FileResourceBase
public:
FileDependency();
~FileDependency();
+
+ FileType fileType() const override { return FileTypeDependency; }
};
} // namespace Internal
diff --git a/src/lib/corelib/buildgraph/inputartifactscanner.cpp b/src/lib/corelib/buildgraph/inputartifactscanner.cpp
index 13314eb52..177d1dfc8 100644
--- a/src/lib/corelib/buildgraph/inputartifactscanner.cpp
+++ b/src/lib/corelib/buildgraph/inputartifactscanner.cpp
@@ -79,14 +79,21 @@ static void resolveDepencency(const RawScannedDependency &dependency,
Artifact *dependencyInOtherProduct = nullptr;
for (FileResourceBase *lookupResult : project->topLevelProject()
->buildData->lookupFiles(absDirPath, dependency.fileName())) {
- if ((fileDependencyArtifact = dynamic_cast<FileDependency *>(lookupResult)))
- continue;
- Artifact * const foundArtifact = dynamic_cast<Artifact *>(lookupResult);
- if (foundArtifact->product == product) {
- dependencyInProduct = foundArtifact;
+ switch (lookupResult->fileType()) {
+ case FileResourceBase::FileTypeDependency:
+ fileDependencyArtifact = static_cast<FileDependency *>(lookupResult);
+ break;
+ case FileResourceBase::FileTypeArtifact: {
+ Artifact * const foundArtifact = static_cast<Artifact *>(lookupResult);
+ if (foundArtifact->product == product)
+ dependencyInProduct = foundArtifact;
+ else
+ dependencyInOtherProduct = foundArtifact;
break;
}
- dependencyInOtherProduct = foundArtifact;
+ }
+ if (dependencyInProduct)
+ break;
}
// prioritize found artifacts
@@ -266,8 +273,10 @@ unresolved:
resolved:
handleDependency(resolvedDependency);
if (artifactsToScan && resolvedDependency.file) {
- if (Artifact *artifactDependency = dynamic_cast<Artifact *>(resolvedDependency.file)) {
+ if (resolvedDependency.file->fileType() == FileResourceBase::FileTypeArtifact) {
// Do not scan an artifact that is not built yet: Its contents might still change.
+ Artifact * const artifactDependency
+ = static_cast<Artifact *>(resolvedDependency.file);
if (artifactDependency->artifactType == Artifact::SourceFile
|| artifactDependency->buildState == BuildGraphNode::Built) {
artifactsToScan->push_back(artifactDependency);
@@ -286,9 +295,18 @@ void InputArtifactScanner::handleDependency(ResolvedDependency &dependency)
QBS_CHECK(m_artifact->artifactType == Artifact::Generated);
QBS_CHECK(product);
- Artifact *artifactDependency = dynamic_cast<Artifact *>(dependency.file);
- FileDependency *fileDependency
- = artifactDependency ? 0 : dynamic_cast<FileDependency *>(dependency.file);
+ Artifact *artifactDependency = nullptr;
+ FileDependency *fileDependency = nullptr;
+ if (dependency.file) {
+ switch (dependency.file->fileType()) {
+ case FileResourceBase::FileTypeArtifact:
+ artifactDependency = static_cast<Artifact *>(dependency.file);
+ break;
+ case FileResourceBase::FileTypeDependency:
+ fileDependency = static_cast<FileDependency *>(dependency.file);
+ break;
+ }
+ }
QBS_CHECK(!dependency.file || artifactDependency || fileDependency);
if (!dependency.file) {
diff --git a/src/lib/corelib/buildgraph/projectbuilddata.cpp b/src/lib/corelib/buildgraph/projectbuilddata.cpp
index cb247d6ef..ba8ed801d 100644
--- a/src/lib/corelib/buildgraph/projectbuilddata.cpp
+++ b/src/lib/corelib/buildgraph/projectbuilddata.cpp
@@ -99,22 +99,23 @@ void ProjectBuildData::insertIntoLookupTable(FileResourceBase *fileres)
{
QList<FileResourceBase *> &lst
= m_artifactLookupTable[fileres->fileName()][fileres->dirPath()];
- const auto * const artifact = dynamic_cast<Artifact *>(fileres);
+ const auto * const artifact = fileres->fileType() == FileResourceBase::FileTypeArtifact
+ ? static_cast<Artifact *>(fileres) : nullptr;
if (artifact && artifact->artifactType == Artifact::Generated) {
for (const auto *file : lst) {
- const auto * const otherArtifact = dynamic_cast<const Artifact *>(file);
- if (otherArtifact) {
- ErrorInfo error;
- error.append(Tr::tr("Conflicting artifacts for file path '%1'.")
- .arg(artifact->filePath()));
- error.append(Tr::tr("The first artifact comes from product '%1'.")
- .arg(otherArtifact->product->fullDisplayName()),
- otherArtifact->product->location);
- error.append(Tr::tr("The second artifact comes from product '%1'.")
- .arg(artifact->product->fullDisplayName()),
- artifact->product->location);
- throw error;
- }
+ if (file->fileType() != FileResourceBase::FileTypeArtifact)
+ continue;
+ const auto * const otherArtifact = static_cast<const Artifact *>(file);
+ ErrorInfo error;
+ error.append(Tr::tr("Conflicting artifacts for file path '%1'.")
+ .arg(artifact->filePath()));
+ error.append(Tr::tr("The first artifact comes from product '%1'.")
+ .arg(otherArtifact->product->fullDisplayName()),
+ otherArtifact->product->location);
+ error.append(Tr::tr("The second artifact comes from product '%1'.")
+ .arg(artifact->product->fullDisplayName()),
+ artifact->product->location);
+ throw error;
}
}
QBS_CHECK(!lst.contains(fileres));
@@ -164,13 +165,13 @@ static void disconnectArtifactParents(Artifact *artifact)
qCDebug(lcBuildGraph) << "disconnect parents of" << relativeArtifactFileName(artifact);
for (BuildGraphNode * const parent : qAsConst(artifact->parents)) {
parent->children.remove(artifact);
- Artifact *parentArtifact = dynamic_cast<Artifact *>(parent);
- if (parentArtifact) {
- QBS_CHECK(parentArtifact->transformer);
- parentArtifact->childrenAddedByScanner.remove(artifact);
- parentArtifact->transformer->inputs.remove(artifact);
- parentArtifact->product->registerArtifactWithChangedInputs(parentArtifact);
- }
+ if (parent->type() != BuildGraphNode::ArtifactNodeType)
+ continue;
+ Artifact * const parentArtifact = static_cast<Artifact *>(parent);
+ QBS_CHECK(parentArtifact->transformer);
+ parentArtifact->childrenAddedByScanner.remove(artifact);
+ parentArtifact->transformer->inputs.remove(artifact);
+ parentArtifact->product->registerArtifactWithChangedInputs(parentArtifact);
}
artifact->parents.clear();