| OLD | NEW |
| 1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "chrome/browser/renderer_host/render_process_host.h" | 5 #include "chrome/browser/renderer_host/render_process_host.h" |
| 6 | 6 |
| 7 #include "base/rand_util.h" | 7 #include "base/rand_util.h" |
| 8 #include "base/sys_info.h" | 8 #include "base/sys_info.h" |
| 9 #include "chrome/browser/child_process_security_policy.h" |
| 9 #include "chrome/common/chrome_constants.h" | 10 #include "chrome/common/chrome_constants.h" |
| 10 #include "chrome/common/notification_service.h" | 11 #include "chrome/common/notification_service.h" |
| 11 | 12 |
| 12 namespace { | 13 namespace { |
| 13 | 14 |
| 14 unsigned int GetMaxRendererProcessCount() { | 15 size_t GetMaxRendererProcessCount() { |
| 15 // Defines the maximum number of renderer processes according to the | 16 // Defines the maximum number of renderer processes according to the |
| 16 // amount of installed memory as reported by the OS. The table | 17 // amount of installed memory as reported by the OS. The table |
| 17 // values are calculated by assuming that you want the renderers to | 18 // values are calculated by assuming that you want the renderers to |
| 18 // use half of the installed ram and assuming that each tab uses | 19 // use half of the installed ram and assuming that each tab uses |
| 19 // ~40MB, however the curve is not linear but piecewise linear with | 20 // ~40MB, however the curve is not linear but piecewise linear with |
| 20 // interleaved slopes of 3 and 2. | 21 // interleaved slopes of 3 and 2. |
| 21 // If you modify this table you need to adjust browser\browser_uitest.cc | 22 // If you modify this table you need to adjust browser\browser_uitest.cc |
| 22 // to match the expected number of processes. | 23 // to match the expected number of processes. |
| 23 | 24 |
| 24 static const int kMaxRenderersByRamTier[] = { | 25 static const size_t kMaxRenderersByRamTier[] = { |
| 25 3, // less than 256MB | 26 3, // less than 256MB |
| 26 6, // 256MB | 27 6, // 256MB |
| 27 9, // 512MB | 28 9, // 512MB |
| 28 12, // 768MB | 29 12, // 768MB |
| 29 14, // 1024MB | 30 14, // 1024MB |
| 30 18, // 1280MB | 31 18, // 1280MB |
| 31 20, // 1536MB | 32 20, // 1536MB |
| 32 22, // 1792MB | 33 22, // 1792MB |
| 33 24, // 2048MB | 34 24, // 2048MB |
| 34 26, // 2304MB | 35 26, // 2304MB |
| 35 29, // 2560MB | 36 29, // 2560MB |
| 36 32, // 2816MB | 37 32, // 2816MB |
| 37 35, // 3072MB | 38 35, // 3072MB |
| 38 38, // 3328MB | 39 38, // 3328MB |
| 39 40 // 3584MB | 40 40 // 3584MB |
| 40 }; | 41 }; |
| 41 | 42 |
| 42 static unsigned int max_count = 0; | 43 static size_t max_count = 0; |
| 43 if (!max_count) { | 44 if (!max_count) { |
| 44 size_t memory_tier = base::SysInfo::AmountOfPhysicalMemoryMB() / 256; | 45 size_t memory_tier = base::SysInfo::AmountOfPhysicalMemoryMB() / 256; |
| 45 if (memory_tier >= arraysize(kMaxRenderersByRamTier)) | 46 if (memory_tier >= arraysize(kMaxRenderersByRamTier)) |
| 46 max_count = chrome::kMaxRendererProcessCount; | 47 max_count = chrome::kMaxRendererProcessCount; |
| 47 else | 48 else |
| 48 max_count = kMaxRenderersByRamTier[memory_tier]; | 49 max_count = kMaxRenderersByRamTier[memory_tier]; |
| 49 } | 50 } |
| 50 return max_count; | 51 return max_count; |
| 51 } | 52 } |
| 52 | 53 |
| 53 // Returns true if the given host is suitable for launching a new view | 54 // Returns true if the given host is suitable for launching a new view |
| 54 // associated with the given profile. | 55 // associated with the given profile. |
| 55 static bool IsSuitableHost(Profile* profile, RenderProcessHost* host) { | 56 static bool IsSuitableHost(RenderProcessHost* host, Profile* profile, |
| 56 return host->profile() == profile; | 57 RenderProcessHost::Type type) { |
| 58 // If the host doesn't have a PID yet, we don't know what it will be used |
| 59 // for, so just say it's unsuitable to be safe. |
| 60 if (host->pid() == -1) |
| 61 return false; |
| 62 |
| 63 if (host->profile() != profile) |
| 64 return false; |
| 65 |
| 66 RenderProcessHost::Type host_type = RenderProcessHost::TYPE_NORMAL; |
| 67 if (ChildProcessSecurityPolicy::GetInstance()->HasDOMUIBindings(host->pid())) |
| 68 host_type = RenderProcessHost::TYPE_DOMUI; |
| 69 if (ChildProcessSecurityPolicy::GetInstance()-> |
| 70 HasExtensionBindings(host->pid())) |
| 71 host_type = RenderProcessHost::TYPE_EXTENSION; |
| 72 |
| 73 return host_type == type; |
| 57 } | 74 } |
| 58 | 75 |
| 59 // the global list of all renderer processes | 76 // the global list of all renderer processes |
| 60 IDMap<RenderProcessHost> all_hosts; | 77 IDMap<RenderProcessHost> all_hosts; |
| 61 | 78 |
| 62 } // namespace | 79 } // namespace |
| 63 | 80 |
| 64 bool RenderProcessHost::run_renderer_in_process_ = false; | 81 bool RenderProcessHost::run_renderer_in_process_ = false; |
| 65 | 82 |
| 66 RenderProcessHost::RenderProcessHost(Profile* profile) | 83 RenderProcessHost::RenderProcessHost(Profile* profile) |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 120 return all_hosts.size(); | 137 return all_hosts.size(); |
| 121 } | 138 } |
| 122 | 139 |
| 123 // static | 140 // static |
| 124 RenderProcessHost* RenderProcessHost::FromID(int render_process_id) { | 141 RenderProcessHost* RenderProcessHost::FromID(int render_process_id) { |
| 125 return all_hosts.Lookup(render_process_id); | 142 return all_hosts.Lookup(render_process_id); |
| 126 } | 143 } |
| 127 | 144 |
| 128 // static | 145 // static |
| 129 bool RenderProcessHost::ShouldTryToUseExistingProcessHost() { | 146 bool RenderProcessHost::ShouldTryToUseExistingProcessHost() { |
| 130 unsigned int renderer_process_count = | 147 size_t renderer_process_count = all_hosts.size(); |
| 131 static_cast<unsigned int>(all_hosts.size()); | |
| 132 | 148 |
| 133 // NOTE: Sometimes it's necessary to create more render processes than | 149 // NOTE: Sometimes it's necessary to create more render processes than |
| 134 // GetMaxRendererProcessCount(), for instance when we want to create | 150 // GetMaxRendererProcessCount(), for instance when we want to create |
| 135 // a renderer process for a profile that has no existing renderers. | 151 // a renderer process for a profile that has no existing renderers. |
| 136 // This is OK in moderation, since the GetMaxRendererProcessCount() | 152 // This is OK in moderation, since the GetMaxRendererProcessCount() |
| 137 // is conservative. | 153 // is conservative. |
| 138 | 154 |
| 139 return run_renderer_in_process() || | 155 return run_renderer_in_process() || |
| 140 (renderer_process_count >= GetMaxRendererProcessCount()); | 156 (renderer_process_count >= GetMaxRendererProcessCount()); |
| 141 } | 157 } |
| 142 | 158 |
| 143 // static | 159 // static |
| 144 RenderProcessHost* RenderProcessHost::GetExistingProcessHost(Profile* profile) { | 160 RenderProcessHost* RenderProcessHost::GetExistingProcessHost(Profile* profile, |
| 161 Type type) { |
| 145 // First figure out which existing renderers we can use. | 162 // First figure out which existing renderers we can use. |
| 146 std::vector<RenderProcessHost*> suitable_renderers; | 163 std::vector<RenderProcessHost*> suitable_renderers; |
| 147 suitable_renderers.reserve(size()); | 164 suitable_renderers.reserve(size()); |
| 148 | 165 |
| 149 for (iterator iter = begin(); iter != end(); ++iter) { | 166 for (iterator iter = begin(); iter != end(); ++iter) { |
| 150 if (IsSuitableHost(profile, iter->second)) | 167 if (run_renderer_in_process() || |
| 168 IsSuitableHost(iter->second, profile, type)) |
| 151 suitable_renderers.push_back(iter->second); | 169 suitable_renderers.push_back(iter->second); |
| 152 } | 170 } |
| 153 | 171 |
| 154 // Now pick a random suitable renderer, if we have any. | 172 // Now pick a random suitable renderer, if we have any. |
| 155 if (!suitable_renderers.empty()) { | 173 if (!suitable_renderers.empty()) { |
| 156 int suitable_count = static_cast<int>(suitable_renderers.size()); | 174 int suitable_count = static_cast<int>(suitable_renderers.size()); |
| 157 int random_index = base::RandInt(0, suitable_count - 1); | 175 int random_index = base::RandInt(0, suitable_count - 1); |
| 158 return suitable_renderers[random_index]; | 176 return suitable_renderers[random_index]; |
| 159 } | 177 } |
| 160 | 178 |
| 161 return NULL; | 179 return NULL; |
| 162 } | 180 } |
| 163 | 181 |
| 164 void RenderProcessHost::SetProcessID(int pid) { | 182 void RenderProcessHost::SetProcessID(int pid) { |
| 165 if (pid_ != -1) { | 183 if (pid_ != -1) { |
| 166 // This object is being reused after a renderer crash. Remove the old pid. | 184 // This object is being reused after a renderer crash. Remove the old pid. |
| 167 all_hosts.Remove(pid_); | 185 all_hosts.Remove(pid_); |
| 168 } | 186 } |
| 169 | 187 |
| 170 pid_ = pid; | 188 pid_ = pid; |
| 171 all_hosts.AddWithID(this, pid); | 189 all_hosts.AddWithID(this, pid); |
| 172 } | 190 } |
| 191 |
| 192 void RenderProcessHost::RemoveFromList() { |
| 193 if (all_hosts.Lookup(pid_)) |
| 194 all_hosts.Remove(pid_); |
| 195 } |
| OLD | NEW |