| OLD | NEW |
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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/oom_priority_manager.h" | 5 #include "chrome/browser/oom_priority_manager.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 #include <vector> | 8 #include <vector> |
| 9 | 9 |
| 10 #include "base/process.h" | 10 #include "base/process.h" |
| 11 #include "base/process_util.h" | 11 #include "base/process_util.h" |
| 12 #include "base/string_number_conversions.h" |
| 12 #include "base/string16.h" | 13 #include "base/string16.h" |
| 13 #include "base/synchronization/lock.h" | 14 #include "base/synchronization/lock.h" |
| 14 #include "base/threading/thread.h" | 15 #include "base/threading/thread.h" |
| 15 #include "base/timer.h" | 16 #include "base/timer.h" |
| 17 #include "base/utf_string_conversions.h" |
| 16 #include "build/build_config.h" | 18 #include "build/build_config.h" |
| 17 #include "chrome/browser/tabs/tab_strip_model.h" | 19 #include "chrome/browser/tabs/tab_strip_model.h" |
| 18 #include "chrome/browser/ui/browser_list.h" | 20 #include "chrome/browser/ui/browser_list.h" |
| 19 #include "chrome/browser/ui/tab_contents/tab_contents_wrapper.h" | 21 #include "chrome/browser/ui/tab_contents/tab_contents_wrapper.h" |
| 20 #include "chrome/common/chrome_constants.h" | 22 #include "chrome/common/chrome_constants.h" |
| 21 #include "content/browser/browser_thread.h" | 23 #include "content/browser/browser_thread.h" |
| 22 #include "content/browser/renderer_host/render_process_host.h" | 24 #include "content/browser/renderer_host/render_process_host.h" |
| 23 #include "content/browser/renderer_host/render_widget_host.h" | 25 #include "content/browser/renderer_host/render_widget_host.h" |
| 24 #include "content/browser/tab_contents/tab_contents.h" | 26 #include "content/browser/tab_contents/tab_contents.h" |
| 25 #include "content/browser/zygote_host_linux.h" | 27 #include "content/browser/zygote_host_linux.h" |
| 28 #include "content/common/content_notification_types.h" |
| 26 #include "content/common/notification_service.h" | 29 #include "content/common/notification_service.h" |
| 27 | 30 |
| 28 #if !defined(OS_CHROMEOS) | 31 #if !defined(OS_CHROMEOS) |
| 29 #error This file only meant to be compiled on ChromeOS | 32 #error This file only meant to be compiled on ChromeOS |
| 30 #endif | 33 #endif |
| 31 | 34 |
| 32 using base::TimeDelta; | 35 using base::TimeDelta; |
| 33 using base::TimeTicks; | 36 using base::TimeTicks; |
| 34 using base::ProcessHandle; | 37 using base::ProcessHandle; |
| 35 using base::ProcessMetrics; | 38 using base::ProcessMetrics; |
| 36 | 39 |
| 40 namespace { |
| 41 |
| 42 // Returns a unique ID for a TabContents. Do not cast back to a pointer, as |
| 43 // the TabContents could be deleted if the user closed the tab. |
| 44 int64 IdFromTabContents(TabContents* tab_contents) { |
| 45 return reinterpret_cast<int64>(tab_contents); |
| 46 } |
| 47 |
| 48 } // namespace |
| 49 |
| 37 namespace browser { | 50 namespace browser { |
| 38 | 51 |
| 39 // The default interval in seconds after which to adjust the oom_score_adj | 52 // The default interval in seconds after which to adjust the oom_score_adj |
| 40 // value. | 53 // value. |
| 41 #define ADJUSTMENT_INTERVAL_SECONDS 10 | 54 #define ADJUSTMENT_INTERVAL_SECONDS 10 |
| 42 | 55 |
| 43 // The default interval in minutes for considering activation times | |
| 44 // "equal". | |
| 45 #define BUCKET_INTERVAL_MINUTES 10 | |
| 46 | |
| 47 // The default interval in milliseconds to wait before setting the score of | 56 // The default interval in milliseconds to wait before setting the score of |
| 48 // currently focused tab. | 57 // currently focused tab. |
| 49 #define FOCUSED_TAB_SCORE_ADJUST_INTERVAL_MS 500 | 58 #define FOCUSED_TAB_SCORE_ADJUST_INTERVAL_MS 500 |
| 50 | 59 |
| 51 OomPriorityManager::RendererStats::RendererStats() | 60 OomPriorityManager::TabStats::TabStats() |
| 52 : is_pinned(false), | 61 : is_pinned(false), |
| 53 is_selected(false), | 62 is_selected(false), |
| 54 memory_used(0), | 63 renderer_handle(0), |
| 55 renderer_handle(0) { | 64 tab_contents_id(0) { |
| 56 } | 65 } |
| 57 | 66 |
| 58 OomPriorityManager::RendererStats::~RendererStats() { | 67 OomPriorityManager::TabStats::~TabStats() { |
| 59 } | 68 } |
| 60 | 69 |
| 61 OomPriorityManager::OomPriorityManager() | 70 OomPriorityManager::OomPriorityManager() |
| 62 : focused_tab_pid_(0) { | 71 : focused_tab_pid_(0) { |
| 63 renderer_stats_.reserve(32); // 99% of users have < 30 tabs open | |
| 64 registrar_.Add(this, | 72 registrar_.Add(this, |
| 65 content::NOTIFICATION_RENDERER_PROCESS_CLOSED, | 73 content::NOTIFICATION_RENDERER_PROCESS_CLOSED, |
| 66 NotificationService::AllSources()); | 74 NotificationService::AllSources()); |
| 67 registrar_.Add(this, | 75 registrar_.Add(this, |
| 68 content::NOTIFICATION_RENDERER_PROCESS_TERMINATED, | 76 content::NOTIFICATION_RENDERER_PROCESS_TERMINATED, |
| 69 NotificationService::AllSources()); | 77 NotificationService::AllSources()); |
| 70 registrar_.Add(this, | 78 registrar_.Add(this, |
| 71 content::NOTIFICATION_RENDER_WIDGET_VISIBILITY_CHANGED, | 79 content::NOTIFICATION_RENDER_WIDGET_VISIBILITY_CHANGED, |
| 72 NotificationService::AllSources()); | 80 NotificationService::AllSources()); |
| 73 } | 81 } |
| 74 | 82 |
| 75 OomPriorityManager::~OomPriorityManager() { | 83 OomPriorityManager::~OomPriorityManager() { |
| 76 Stop(); | 84 Stop(); |
| 77 } | 85 } |
| 78 | 86 |
| 79 void OomPriorityManager::Start() { | 87 void OomPriorityManager::Start() { |
| 80 if (!timer_.IsRunning()) { | 88 if (!timer_.IsRunning()) { |
| 81 timer_.Start(FROM_HERE, | 89 timer_.Start(FROM_HERE, |
| 82 TimeDelta::FromSeconds(ADJUSTMENT_INTERVAL_SECONDS), | 90 TimeDelta::FromSeconds(ADJUSTMENT_INTERVAL_SECONDS), |
| 83 this, | 91 this, |
| 84 &OomPriorityManager::AdjustOomPriorities); | 92 &OomPriorityManager::AdjustOomPriorities); |
| 85 } | 93 } |
| 86 } | 94 } |
| 87 | 95 |
| 88 void OomPriorityManager::Stop() { | 96 void OomPriorityManager::Stop() { |
| 89 timer_.Stop(); | 97 timer_.Stop(); |
| 90 } | 98 } |
| 91 | 99 |
| 92 std::vector<string16> OomPriorityManager::GetTabTitles() { | 100 std::vector<string16> OomPriorityManager::GetTabTitles() { |
| 93 base::AutoLock renderer_stats_autolock(renderer_stats_lock_); | 101 TabStatsList stats = GetTabStatsOnUIThread(); |
| 102 base::AutoLock pid_to_oom_score_autolock(pid_to_oom_score_lock_); |
| 94 std::vector<string16> titles; | 103 std::vector<string16> titles; |
| 95 titles.reserve(renderer_stats_.size()); | 104 titles.reserve(stats.size()); |
| 96 StatsList::iterator it = renderer_stats_.begin(); | 105 TabStatsList::iterator it = stats.begin(); |
| 97 for ( ; it != renderer_stats_.end(); ++it) { | 106 for ( ; it != stats.end(); ++it) { |
| 98 titles.push_back(it->title); | 107 string16 str = it->title; |
| 108 str += ASCIIToUTF16(" ("); |
| 109 int score = pid_to_oom_score_[it->renderer_handle]; |
| 110 str += base::IntToString16(score); |
| 111 str += ASCIIToUTF16(")"); |
| 112 titles.push_back(str); |
| 99 } | 113 } |
| 100 return titles; | 114 return titles; |
| 101 } | 115 } |
| 102 | 116 |
| 117 void OomPriorityManager::DiscardTab() { |
| 118 TabStatsList stats = GetTabStatsOnUIThread(); |
| 119 if (stats.empty()) |
| 120 return; |
| 121 std::sort(stats.begin(), stats.end(), CompareTabStats); |
| 122 TabStatsList::const_reverse_iterator rit = stats.rbegin(); |
| 123 int64 least_important_tab_id = rit->tab_contents_id; |
| 124 for (BrowserList::const_iterator browser_iterator = BrowserList::begin(); |
| 125 browser_iterator != BrowserList::end(); ++browser_iterator) { |
| 126 Browser* browser = *browser_iterator; |
| 127 TabStripModel* model = browser->tabstrip_model(); |
| 128 for (int idx = 0; idx < model->count(); idx++) { |
| 129 TabContents* tab_contents = model->GetTabContentsAt(idx)->tab_contents(); |
| 130 int64 tab_contents_id = IdFromTabContents(tab_contents); |
| 131 if (tab_contents_id == least_important_tab_id) { |
| 132 model->CloseTabContentsAt(idx, |
| 133 TabStripModel::CLOSE_CREATE_HISTORICAL_TAB); |
| 134 } |
| 135 } |
| 136 } |
| 137 } |
| 138 |
| 103 // Returns true if |first| is considered less desirable to be killed | 139 // Returns true if |first| is considered less desirable to be killed |
| 104 // than |second|. | 140 // than |second|. |
| 105 bool OomPriorityManager::CompareRendererStats(RendererStats first, | 141 bool OomPriorityManager::CompareTabStats(TabStats first, |
| 106 RendererStats second) { | 142 TabStats second) { |
| 107 // The size of the slop in comparing activation times. [This is | |
| 108 // allocated here to avoid static initialization at startup time.] | |
| 109 static const int64 kTimeBucketInterval = | |
| 110 TimeDelta::FromMinutes(BUCKET_INTERVAL_MINUTES).ToInternalValue(); | |
| 111 | |
| 112 // Being currently selected is most important. | 143 // Being currently selected is most important. |
| 113 if (first.is_selected != second.is_selected) | 144 if (first.is_selected != second.is_selected) |
| 114 return first.is_selected == true; | 145 return first.is_selected == true; |
| 115 | 146 |
| 116 // Being pinned is second most important. | 147 // Being pinned is second most important. |
| 117 if (first.is_pinned != second.is_pinned) | 148 if (first.is_pinned != second.is_pinned) |
| 118 return first.is_pinned == true; | 149 return first.is_pinned == true; |
| 119 | 150 |
| 120 // We want to be a little "fuzzy" when we compare these, because | 151 // Being more recently selected is more important. |
| 121 // it's not really possible for the times to be identical, but if | 152 return first.last_selected > second.last_selected; |
| 122 // the user selected two tabs at about the same time, we still want | |
| 123 // to take the one that uses more memory. | |
| 124 if (abs((first.last_selected - second.last_selected).ToInternalValue()) < | |
| 125 kTimeBucketInterval) | |
| 126 return first.last_selected > second.last_selected; | |
| 127 | |
| 128 return first.memory_used < second.memory_used; | |
| 129 } | 153 } |
| 130 | 154 |
| 131 void OomPriorityManager::AdjustFocusedTabScore() { | 155 void OomPriorityManager::AdjustFocusedTabScoreOnFileThread() { |
| 156 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); |
| 132 base::AutoLock pid_to_oom_score_autolock(pid_to_oom_score_lock_); | 157 base::AutoLock pid_to_oom_score_autolock(pid_to_oom_score_lock_); |
| 133 ZygoteHost::GetInstance()->AdjustRendererOOMScore( | 158 ZygoteHost::GetInstance()->AdjustRendererOOMScore( |
| 134 focused_tab_pid_, chrome::kLowestRendererOomScore); | 159 focused_tab_pid_, chrome::kLowestRendererOomScore); |
| 135 pid_to_oom_score_[focused_tab_pid_] = chrome::kLowestRendererOomScore; | 160 pid_to_oom_score_[focused_tab_pid_] = chrome::kLowestRendererOomScore; |
| 136 } | 161 } |
| 137 | 162 |
| 138 void OomPriorityManager::OnFocusTabScoreAdjustmentTimeout() { | 163 void OomPriorityManager::OnFocusTabScoreAdjustmentTimeout() { |
| 139 BrowserThread::PostTask( | 164 BrowserThread::PostTask( |
| 140 BrowserThread::FILE, FROM_HERE, | 165 BrowserThread::FILE, FROM_HERE, |
| 141 NewRunnableMethod(this, &OomPriorityManager::AdjustFocusedTabScore)); | 166 NewRunnableMethod( |
| 167 this, &OomPriorityManager::AdjustFocusedTabScoreOnFileThread)); |
| 142 } | 168 } |
| 143 | 169 |
| 144 void OomPriorityManager::Observe(int type, const NotificationSource& source, | 170 void OomPriorityManager::Observe(int type, const NotificationSource& source, |
| 145 const NotificationDetails& details) { | 171 const NotificationDetails& details) { |
| 146 base::ProcessHandle handle = 0; | 172 base::ProcessHandle handle = 0; |
| 147 base::AutoLock pid_to_oom_score_autolock(pid_to_oom_score_lock_); | 173 base::AutoLock pid_to_oom_score_autolock(pid_to_oom_score_lock_); |
| 148 switch (type) { | 174 switch (type) { |
| 149 case content::NOTIFICATION_RENDERER_PROCESS_CLOSED: | 175 case content::NOTIFICATION_RENDERER_PROCESS_CLOSED: |
| 150 case content::NOTIFICATION_RENDERER_PROCESS_TERMINATED: { | 176 case content::NOTIFICATION_RENDERER_PROCESS_TERMINATED: { |
| 151 handle = Source<RenderProcessHost>(source)->GetHandle(); | 177 handle = Source<RenderProcessHost>(source)->GetHandle(); |
| 152 pid_to_oom_score_.erase(handle); | 178 pid_to_oom_score_.erase(handle); |
| 153 break; | 179 break; |
| 154 } | 180 } |
| 155 case content::NOTIFICATION_RENDER_WIDGET_VISIBILITY_CHANGED: { | 181 case content::NOTIFICATION_RENDER_WIDGET_VISIBILITY_CHANGED: { |
| (...skipping 30 matching lines...) Expand all Loading... |
| 186 | 212 |
| 187 // Here we collect most of the information we need to sort the | 213 // Here we collect most of the information we need to sort the |
| 188 // existing renderers in priority order, and hand out oom_score_adj | 214 // existing renderers in priority order, and hand out oom_score_adj |
| 189 // scores based on that sort order. | 215 // scores based on that sort order. |
| 190 // | 216 // |
| 191 // Things we need to collect on the browser thread (because | 217 // Things we need to collect on the browser thread (because |
| 192 // TabStripModel isn't thread safe): | 218 // TabStripModel isn't thread safe): |
| 193 // 1) whether or not a tab is pinned | 219 // 1) whether or not a tab is pinned |
| 194 // 2) last time a tab was selected | 220 // 2) last time a tab was selected |
| 195 // 3) is the tab currently selected | 221 // 3) is the tab currently selected |
| 196 // | |
| 197 // We also need to collect: | |
| 198 // 4) size in memory of a tab | |
| 199 // But we do that in DoAdjustOomPriorities on the FILE thread so that | |
| 200 // we avoid jank, because it accesses /proc. | |
| 201 void OomPriorityManager::AdjustOomPriorities() { | 222 void OomPriorityManager::AdjustOomPriorities() { |
| 202 if (BrowserList::size() == 0) | 223 if (BrowserList::size() == 0) |
| 203 return; | 224 return; |
| 225 TabStatsList stats_list = GetTabStatsOnUIThread(); |
| 226 BrowserThread::PostTask( |
| 227 BrowserThread::FILE, FROM_HERE, |
| 228 NewRunnableMethod(this, |
| 229 &OomPriorityManager::AdjustOomPrioritiesOnFileThread, |
| 230 stats_list)); |
| 231 } |
| 204 | 232 |
| 205 { | 233 OomPriorityManager::TabStatsList OomPriorityManager::GetTabStatsOnUIThread() { |
| 206 base::AutoLock renderer_stats_autolock(renderer_stats_lock_); | 234 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 207 renderer_stats_.clear(); | 235 TabStatsList stats_list; |
| 208 for (BrowserList::const_iterator browser_iterator = BrowserList::begin(); | 236 stats_list.reserve(32); // 99% of users have < 30 tabs open |
| 209 browser_iterator != BrowserList::end(); ++browser_iterator) { | 237 for (BrowserList::const_iterator browser_iterator = BrowserList::begin(); |
| 210 Browser* browser = *browser_iterator; | 238 browser_iterator != BrowserList::end(); ++browser_iterator) { |
| 211 const TabStripModel* model = browser->tabstrip_model(); | 239 Browser* browser = *browser_iterator; |
| 212 for (int i = 0; i < model->count(); i++) { | 240 const TabStripModel* model = browser->tabstrip_model(); |
| 213 TabContents* contents = model->GetTabContentsAt(i)->tab_contents(); | 241 for (int i = 0; i < model->count(); i++) { |
| 214 if (!contents->is_crashed()) { | 242 TabContents* contents = model->GetTabContentsAt(i)->tab_contents(); |
| 215 RendererStats stats; | 243 if (!contents->is_crashed()) { |
| 216 stats.last_selected = contents->last_selected_time(); | 244 TabStats stats; |
| 217 stats.renderer_handle = contents->GetRenderProcessHost()->GetHandle(); | 245 stats.last_selected = contents->last_selected_time(); |
| 218 stats.is_pinned = model->IsTabPinned(i); | 246 stats.renderer_handle = contents->GetRenderProcessHost()->GetHandle(); |
| 219 stats.memory_used = 0; // Calculated in DoAdjustOomPriorities. | 247 stats.is_pinned = model->IsTabPinned(i); |
| 220 stats.is_selected = model->IsTabSelected(i); | 248 stats.is_selected = model->IsTabSelected(i); |
| 221 stats.title = contents->GetTitle(); | 249 stats.title = contents->GetTitle(); |
| 222 renderer_stats_.push_back(stats); | 250 stats.tab_contents_id = IdFromTabContents(contents); |
| 223 } | 251 stats_list.push_back(stats); |
| 224 } | 252 } |
| 225 } | 253 } |
| 226 } | 254 } |
| 227 | 255 // Sort the data we collected so that least desirable to be |
| 228 BrowserThread::PostTask( | 256 // killed is first, most desirable is last. |
| 229 BrowserThread::FILE, FROM_HERE, | 257 std::sort(stats_list.begin(), stats_list.end(), CompareTabStats); |
| 230 NewRunnableMethod(this, &OomPriorityManager::DoAdjustOomPriorities)); | 258 return stats_list; |
| 231 } | 259 } |
| 232 | 260 |
| 233 void OomPriorityManager::DoAdjustOomPriorities() { | 261 void OomPriorityManager::AdjustOomPrioritiesOnFileThread( |
| 262 TabStatsList stats_list) { |
| 234 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); | 263 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); |
| 235 base::AutoLock renderer_stats_autolock(renderer_stats_lock_); | |
| 236 base::AutoLock pid_to_oom_score_autolock(pid_to_oom_score_lock_); | 264 base::AutoLock pid_to_oom_score_autolock(pid_to_oom_score_lock_); |
| 237 for (StatsList::iterator stats_iter = renderer_stats_.begin(); | |
| 238 stats_iter != renderer_stats_.end(); ++stats_iter) { | |
| 239 scoped_ptr<ProcessMetrics> metrics(ProcessMetrics::CreateProcessMetrics( | |
| 240 stats_iter->renderer_handle)); | |
| 241 | |
| 242 base::WorkingSetKBytes working_set_kbytes; | |
| 243 if (metrics->GetWorkingSetKBytes(&working_set_kbytes)) { | |
| 244 // We use the proportional set size (PSS) to calculate memory | |
| 245 // usage "badness" on Linux. | |
| 246 stats_iter->memory_used = working_set_kbytes.shared * 1024; | |
| 247 } else { | |
| 248 // and if for some reason we can't get PSS, we revert to using | |
| 249 // resident set size (RSS). This will be zero if the process | |
| 250 // has already gone away, but we can live with that, since the | |
| 251 // process is gone anyhow. | |
| 252 stats_iter->memory_used = metrics->GetWorkingSetSize(); | |
| 253 } | |
| 254 } | |
| 255 | |
| 256 // Now we sort the data we collected so that least desirable to be | |
| 257 // killed is first, most desirable is last. | |
| 258 std::sort(renderer_stats_.begin(), | |
| 259 renderer_stats_.end(), | |
| 260 OomPriorityManager::CompareRendererStats); | |
| 261 | 265 |
| 262 // Now we assign priorities based on the sorted list. We're | 266 // Now we assign priorities based on the sorted list. We're |
| 263 // assigning priorities in the range of kLowestRendererOomScore to | 267 // assigning priorities in the range of kLowestRendererOomScore to |
| 264 // kHighestRendererOomScore (defined in chrome_constants.h). | 268 // kHighestRendererOomScore (defined in chrome_constants.h). |
| 265 // oom_score_adj takes values from -1000 to 1000. Negative values | 269 // oom_score_adj takes values from -1000 to 1000. Negative values |
| 266 // are reserved for system processes, and we want to give some room | 270 // are reserved for system processes, and we want to give some room |
| 267 // below the range we're using to allow for things that want to be | 271 // below the range we're using to allow for things that want to be |
| 268 // above the renderers in priority, so the defined range gives us | 272 // above the renderers in priority, so the defined range gives us |
| 269 // some variation in priority without taking up the whole range. In | 273 // some variation in priority without taking up the whole range. In |
| 270 // the end, however, it's a pretty arbitrary range to use. Higher | 274 // the end, however, it's a pretty arbitrary range to use. Higher |
| 271 // values are more likely to be killed by the OOM killer. | 275 // values are more likely to be killed by the OOM killer. |
| 272 // | 276 // |
| 273 // We also remove any duplicate PIDs, leaving the most important | 277 // We also remove any duplicate PIDs, leaving the most important |
| 274 // (least likely to be killed) of the duplicates, so that a | 278 // (least likely to be killed) of the duplicates, so that a |
| 275 // particular renderer process takes on the oom_score_adj of the | 279 // particular renderer process takes on the oom_score_adj of the |
| 276 // least likely tab to be killed. | 280 // least likely tab to be killed. |
| 277 const int kPriorityRange = chrome::kHighestRendererOomScore - | 281 const int kPriorityRange = chrome::kHighestRendererOomScore - |
| 278 chrome::kLowestRendererOomScore; | 282 chrome::kLowestRendererOomScore; |
| 279 float priority_increment = | 283 float priority_increment = |
| 280 static_cast<float>(kPriorityRange) / renderer_stats_.size(); | 284 static_cast<float>(kPriorityRange) / stats_list.size(); |
| 281 float priority = chrome::kLowestRendererOomScore; | 285 float priority = chrome::kLowestRendererOomScore; |
| 282 std::set<base::ProcessHandle> already_seen; | 286 std::set<base::ProcessHandle> already_seen; |
| 283 int score = 0; | 287 int score = 0; |
| 284 ProcessScoreMap::iterator it; | 288 ProcessScoreMap::iterator it; |
| 285 for (StatsList::iterator iterator = renderer_stats_.begin(); | 289 for (TabStatsList::iterator iterator = stats_list.begin(); |
| 286 iterator != renderer_stats_.end(); ++iterator) { | 290 iterator != stats_list.end(); ++iterator) { |
| 287 if (already_seen.find(iterator->renderer_handle) == already_seen.end()) { | 291 if (already_seen.find(iterator->renderer_handle) == already_seen.end()) { |
| 288 already_seen.insert(iterator->renderer_handle); | 292 already_seen.insert(iterator->renderer_handle); |
| 289 // If a process has the same score as the newly calculated value, | 293 // If a process has the same score as the newly calculated value, |
| 290 // do not set it. | 294 // do not set it. |
| 291 score = static_cast<int>(priority + 0.5f); | 295 score = static_cast<int>(priority + 0.5f); |
| 292 it = pid_to_oom_score_.find(iterator->renderer_handle); | 296 it = pid_to_oom_score_.find(iterator->renderer_handle); |
| 293 if (it == pid_to_oom_score_.end() || it->second != score) { | 297 if (it == pid_to_oom_score_.end() || it->second != score) { |
| 294 ZygoteHost::GetInstance()->AdjustRendererOOMScore( | 298 ZygoteHost::GetInstance()->AdjustRendererOOMScore( |
| 295 iterator->renderer_handle, score); | 299 iterator->renderer_handle, score); |
| 296 pid_to_oom_score_[iterator->renderer_handle] = score; | 300 pid_to_oom_score_[iterator->renderer_handle] = score; |
| 297 } | 301 } |
| 298 priority += priority_increment; | 302 priority += priority_increment; |
| 299 } | 303 } |
| 300 } | 304 } |
| 301 } | 305 } |
| 302 | 306 |
| 303 } // namespace browser | 307 } // namespace browser |
| OLD | NEW |