summaryrefslogtreecommitdiffstats
path: root/chrome/browser/profiles/profile_dependency_manager.cc
diff options
context:
space:
mode:
authorerg@chromium.org <erg@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-01-24 00:41:43 +0000
committererg@chromium.org <erg@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-01-24 00:41:43 +0000
commit4f6944c63cd597ea42968a03e1a54623a2b914c3 (patch)
tree8fdfd6c5021bc8f3e76184a36a3cfcb9625d70bf /chrome/browser/profiles/profile_dependency_manager.cc
parentf069e841e7f515bde48bb5f5c9203db4cad3b6d6 (diff)
downloadchromium_src-4f6944c63cd597ea42968a03e1a54623a2b914c3.zip
chromium_src-4f6944c63cd597ea42968a03e1a54623a2b914c3.tar.gz
chromium_src-4f6944c63cd597ea42968a03e1a54623a2b914c3.tar.bz2
Profiles: Add a --dump-profile-graph option when !NDEBUG.
--dump-profile-graph will create a text file in the profile directory in graphviz format. The graph is the dumped dependency graph. BUG=none R=mirandac TBR=jhawkins,sky,abodenha,tim Review URL: http://codereview.chromium.org/9200017 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@118765 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser/profiles/profile_dependency_manager.cc')
-rw-r--r--chrome/browser/profiles/profile_dependency_manager.cc71
1 files changed, 68 insertions, 3 deletions
diff --git a/chrome/browser/profiles/profile_dependency_manager.cc b/chrome/browser/profiles/profile_dependency_manager.cc
index d6617e5..0d53c7b 100644
--- a/chrome/browser/profiles/profile_dependency_manager.cc
+++ b/chrome/browser/profiles/profile_dependency_manager.cc
@@ -32,6 +32,12 @@
#include "chrome/browser/ui/global_error_service_factory.h"
#include "chrome/browser/ui/webui/ntp/ntp_resource_cache_factory.h"
+#ifndef NDEBUG
+#include "base/command_line.h"
+#include "base/file_util.h"
+#include "chrome/common/chrome_switches.h"
+#endif
+
class Profile;
void ProfileDependencyManager::AddComponent(
@@ -78,7 +84,7 @@ void ProfileDependencyManager::CreateProfileServices(Profile* profile,
AssertFactoriesBuilt();
if (destruction_order_.empty())
- BuildDestructionOrder();
+ BuildDestructionOrder(profile);
// Iterate in reverse destruction order for creation.
for (std::vector<ProfileKeyedServiceFactory*>::reverse_iterator rit =
@@ -101,7 +107,7 @@ void ProfileDependencyManager::CreateProfileServices(Profile* profile,
void ProfileDependencyManager::DestroyProfileServices(Profile* profile) {
if (destruction_order_.empty())
- BuildDestructionOrder();
+ BuildDestructionOrder(profile);
for (std::vector<ProfileKeyedServiceFactory*>::const_iterator it =
destruction_order_.begin(); it != destruction_order_.end(); ++it) {
@@ -182,7 +188,19 @@ void ProfileDependencyManager::AssertFactoriesBuilt() {
built_factories_ = true;
}
-void ProfileDependencyManager::BuildDestructionOrder() {
+void ProfileDependencyManager::BuildDestructionOrder(Profile* profile) {
+#if !defined(NDEBUG)
+ // Whenever we try to build a destruction ordering, we should also dump a
+ // dependency graph to "/path/to/profile/profile-dependencies.dot".
+ if (CommandLine::ForCurrentProcess()->HasSwitch(
+ switches::kDumpProfileDependencyGraph)) {
+ FilePath dot_file =
+ profile->GetPath().AppendASCII("profile-dependencies.dot");
+ std::string contents = DumpGraphvizDependency();
+ file_util::WriteFile(dot_file, contents.c_str(), contents.size());
+ }
+#endif
+
// Step 1: Build a set of nodes with no incoming edges.
std::deque<ProfileKeyedServiceFactory*> queue;
std::copy(all_components_.begin(),
@@ -233,3 +251,50 @@ void ProfileDependencyManager::BuildDestructionOrder() {
std::reverse(output.begin(), output.end());
destruction_order_ = output;
}
+
+#if !defined(NDEBUG)
+
+std::string ProfileDependencyManager::DumpGraphvizDependency() {
+ std::string result("digraph {\n");
+
+ // Make a copy of all components.
+ std::deque<ProfileKeyedServiceFactory*> components;
+ std::copy(all_components_.begin(),
+ all_components_.end(),
+ std::back_inserter(components));
+
+ // State all dependencies and remove |second| so we don't generate an
+ // implicit dependency on the Profile hard coded node.
+ std::deque<ProfileKeyedServiceFactory*>::iterator components_end =
+ components.end();
+ result.append(" /* Dependencies */\n");
+ for (EdgeMap::const_iterator it = edges_.begin(); it != edges_.end(); ++it) {
+ result.append(" ");
+ result.append(it->second->name());
+ result.append(" -> ");
+ result.append(it->first->name());
+ result.append(";\n");
+
+ components_end = std::remove(components.begin(), components_end,
+ it->second);
+ }
+ components.erase(components_end, components.end());
+
+ // Every node that doesn't depend on anything else will implicitly depend on
+ // the Profile.
+ result.append("\n /* Toplevel attachments */\n");
+ for (std::deque<ProfileKeyedServiceFactory*>::const_iterator it =
+ components.begin(); it != components.end(); ++it) {
+ result.append(" ");
+ result.append((*it)->name());
+ result.append(" -> Profile;\n");
+ }
+
+ result.append("\n /* Toplevel profile */\n");
+ result.append(" Profile [shape=box];\n");
+
+ result.append("}\n");
+ return result;
+}
+
+#endif