From fd49db9b33c0f54255d92c0d882a4f18c20a5ef3 Mon Sep 17 00:00:00 2001 From: Joerg Bornemann Date: Thu, 24 Jul 2014 19:12:16 +0200 Subject: fix calculation of old inputs for dynamic rules Instead of deducing the old inputs of a rule from the inputs of its created transformers, we hold a dedicated list of old inputs, because the former approach doesn't work for dynamic rules. This fixes a speed regression introduced in 32c4d3d7. The outputArtifacts script of dynamic rules was always run on compatible inputs that were not input of transformers, e.g. C++ sources that don't have a Q_OBJECT macro. Change-Id: I2d43fa7c91ed9084bd27dc9b948c06152bfce726 Reviewed-by: Christian Kandeler --- src/lib/corelib/buildgraph/artifactset.cpp | 6 ++++ src/lib/corelib/buildgraph/artifactset.h | 3 ++ src/lib/corelib/buildgraph/projectbuilddata.cpp | 45 +++++++++++++++++++++++++ src/lib/corelib/buildgraph/rulenode.cpp | 30 +++-------------- src/lib/corelib/buildgraph/rulenode.h | 4 +-- src/lib/corelib/tools/persistence.cpp | 2 +- 6 files changed, 62 insertions(+), 28 deletions(-) (limited to 'src') diff --git a/src/lib/corelib/buildgraph/artifactset.cpp b/src/lib/corelib/buildgraph/artifactset.cpp index c44f5e4b9..0010e81fe 100644 --- a/src/lib/corelib/buildgraph/artifactset.cpp +++ b/src/lib/corelib/buildgraph/artifactset.cpp @@ -47,6 +47,12 @@ ArtifactSet::ArtifactSet(const QSet &other) { } +ArtifactSet &ArtifactSet::unite(const ArtifactSet &other) +{ + QSet::unite(other); + return *this; +} + ArtifactSet ArtifactSet::fromNodeSet(const NodeSet &nodes) { ArtifactSet result; diff --git a/src/lib/corelib/buildgraph/artifactset.h b/src/lib/corelib/buildgraph/artifactset.h index 092e9e8a2..696859649 100644 --- a/src/lib/corelib/buildgraph/artifactset.h +++ b/src/lib/corelib/buildgraph/artifactset.h @@ -44,6 +44,9 @@ public: ArtifactSet(); ArtifactSet(const ArtifactSet &other); ArtifactSet(const QSet &other); + + ArtifactSet &unite(const ArtifactSet &other); + static ArtifactSet fromNodeSet(const NodeSet &nodes); static ArtifactSet fromNodeList(const QList &lst); }; diff --git a/src/lib/corelib/buildgraph/projectbuilddata.cpp b/src/lib/corelib/buildgraph/projectbuilddata.cpp index 2a4fc812f..6af68caa3 100644 --- a/src/lib/corelib/buildgraph/projectbuilddata.cpp +++ b/src/lib/corelib/buildgraph/projectbuilddata.cpp @@ -261,6 +261,49 @@ void ProjectBuildData::removeArtifactAndExclusiveDependents(Artifact *artifact, removeArtifact(artifact, logger, removeFromDisk, removeFromProduct); } +template +void forEachRuleNode(BuildGraphNode *n, const Func &f) +{ + if (n->type() != BuildGraphNode::RuleNodeType) + return; + f(static_cast(n)); + foreach (BuildGraphNode *c, n->children) + forEachRuleNode(c, f); +} + +template +void forEachRuleNode(const TopLevelProject *project, const Func &f) +{ + foreach (const ResolvedProductPtr &product, project->allProducts()) { + if (!product->buildData) + continue; + foreach (BuildGraphNode *n, product->buildData->roots) + forEachRuleNode(n, f); + } +} + +class RemoveOldInputArtifactFromRuleNode +{ +public: + RemoveOldInputArtifactFromRuleNode(Artifact *artifact, const Logger &logger) + : m_artifact(artifact), m_logger(logger) + { + } + + void operator()(RuleNode *ruleNode) const + { + if (m_logger.traceEnabled()) { + m_logger.qbsTrace() << "[BG] remove old input " << m_artifact->filePath() + << " from rule " << ruleNode->rule()->toString(); + } + ruleNode->removeOldInputArtifact(m_artifact); + } + +private: + Artifact * const m_artifact; + const Logger &m_logger; +}; + void ProjectBuildData::removeArtifact(Artifact *artifact, const Logger &logger, bool removeFromDisk, bool removeFromProduct) { @@ -275,6 +318,8 @@ void ProjectBuildData::removeArtifact(Artifact *artifact, artifact->product->buildData->roots.remove(artifact); removeArtifactFromSet(artifact, artifact->product->buildData->artifactsByFileTag); } + forEachRuleNode(artifact->product->topLevelProject(), + RemoveOldInputArtifactFromRuleNode(artifact, logger)); disconnectArtifact(artifact, logger); if (artifact->transformer) { diff --git a/src/lib/corelib/buildgraph/rulenode.cpp b/src/lib/corelib/buildgraph/rulenode.cpp index 00454d080..3ea324238 100644 --- a/src/lib/corelib/buildgraph/rulenode.cpp +++ b/src/lib/corelib/buildgraph/rulenode.cpp @@ -65,10 +65,9 @@ QString RuleNode::toString() const void RuleNode::apply(const Logger &logger, const ArtifactSet &changedInputs, ApplicationResult *result) { - const ArtifactSet oldInputs = oldInputArtifacts(); ArtifactSet allCompatibleInputs = currentInputArtifacts(); - const ArtifactSet addedInputs = allCompatibleInputs - oldInputs; - const ArtifactSet removedInputs = oldInputs - allCompatibleInputs; + const ArtifactSet addedInputs = allCompatibleInputs - m_oldInputArtifacts; + const ArtifactSet removedInputs = m_oldInputArtifacts - allCompatibleInputs; result->upToDate = changedInputs.isEmpty() && addedInputs.isEmpty() && removedInputs.isEmpty(); ArtifactSet inputs = changedInputs; @@ -108,6 +107,7 @@ void RuleNode::apply(const Logger &logger, const ArtifactSet &changedInputs, if (!inputs.isEmpty()) { RulesApplicator applicator(product, logger); result->createdNodes = applicator.applyRuleInEvaluationContext(m_rule, inputs); + m_oldInputArtifacts.unite(inputs); } } @@ -115,34 +115,14 @@ void RuleNode::load(PersistentPool &pool) { BuildGraphNode::load(pool); m_rule = pool.idLoadS(); + pool.loadContainer(m_oldInputArtifacts); } void RuleNode::store(PersistentPool &pool) const { BuildGraphNode::store(pool); pool.store(m_rule); -} - -QList RuleNode::createdTransformers() const -{ - QList lst; - foreach (BuildGraphNode *parent, parents) { - if (parent->type() != ArtifactNodeType) - continue; - Artifact *artifact = static_cast(parent); - if (!artifact->transformer || artifact->transformer->rule != m_rule) - continue; - lst.append(artifact->transformer); - } - return lst; -} - -ArtifactSet RuleNode::oldInputArtifacts() const -{ - ArtifactSet s; - foreach (const TransformerPtr &t, createdTransformers()) - s += t->inputs; - return s; + pool.storeContainer(m_oldInputArtifacts); } ArtifactSet RuleNode::currentInputArtifacts() const diff --git a/src/lib/corelib/buildgraph/rulenode.h b/src/lib/corelib/buildgraph/rulenode.h index 027094211..fcc0076c6 100644 --- a/src/lib/corelib/buildgraph/rulenode.h +++ b/src/lib/corelib/buildgraph/rulenode.h @@ -60,17 +60,17 @@ public: }; void apply(const Logger &logger, const ArtifactSet &changedInputs, ApplicationResult *result); + void removeOldInputArtifact(Artifact *artifact) { m_oldInputArtifacts.remove(artifact); } protected: void load(PersistentPool &pool); void store(PersistentPool &pool) const; private: - QList createdTransformers() const; - ArtifactSet oldInputArtifacts() const; ArtifactSet currentInputArtifacts() const; RuleConstPtr m_rule; + ArtifactSet m_oldInputArtifacts; }; } // namespace Internal diff --git a/src/lib/corelib/tools/persistence.cpp b/src/lib/corelib/tools/persistence.cpp index 09834943c..0264353d3 100644 --- a/src/lib/corelib/tools/persistence.cpp +++ b/src/lib/corelib/tools/persistence.cpp @@ -40,7 +40,7 @@ namespace qbs { namespace Internal { -static const char QBS_PERSISTENCE_MAGIC[] = "QBSPERSISTENCE-73"; +static const char QBS_PERSISTENCE_MAGIC[] = "QBSPERSISTENCE-74"; PersistentPool::PersistentPool(const Logger &logger) : m_logger(logger) { -- cgit v1.2.3