| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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/memory/tab_manager.h" | 5 #include "chrome/browser/memory/tab_manager.h" |
| 6 | 6 |
| 7 #include <stddef.h> | 7 #include <stddef.h> |
| 8 | 8 |
| 9 #include <algorithm> | 9 #include <algorithm> |
| 10 #include <set> | 10 #include <set> |
| (...skipping 239 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 250 std::sort(stats_list.begin(), stats_list.end(), CompareTabStats); | 250 std::sort(stats_list.begin(), stats_list.end(), CompareTabStats); |
| 251 return stats_list; | 251 return stats_list; |
| 252 } | 252 } |
| 253 | 253 |
| 254 std::vector<content::RenderProcessHost*> TabManager::GetOrderedRenderers() { | 254 std::vector<content::RenderProcessHost*> TabManager::GetOrderedRenderers() { |
| 255 // Get the tab stats. | 255 // Get the tab stats. |
| 256 auto tab_stats = GetTabStats(); | 256 auto tab_stats = GetTabStats(); |
| 257 | 257 |
| 258 std::vector<content::RenderProcessHost*> sorted_renderers; | 258 std::vector<content::RenderProcessHost*> sorted_renderers; |
| 259 std::set<content::RenderProcessHost*> seen_renderers; | 259 std::set<content::RenderProcessHost*> seen_renderers; |
| 260 std::set<content::RenderProcessHost*> visible_renderers; |
| 260 sorted_renderers.reserve(tab_stats.size()); | 261 sorted_renderers.reserve(tab_stats.size()); |
| 261 | 262 |
| 262 // Convert the tab sort order to a process sort order. The process inherits | 263 // Convert the tab sort order to a process sort order. The process inherits |
| 263 // the priority of its highest priority tab. | 264 // the priority of its highest priority tab. |
| 264 for (auto& tab : tab_stats) { | 265 for (auto& tab : tab_stats) { |
| 266 auto renderer = tab.render_process_host; |
| 267 |
| 268 // Skip renderers associated with visible tabs as handling memory pressure |
| 269 // notifications in these processes can cause jank. This code works because |
| 270 // visible tabs always come first in |tab_stats|. |
| 271 if (tab.is_selected) { |
| 272 visible_renderers.insert(renderer); |
| 273 continue; |
| 274 } |
| 275 if (visible_renderers.count(renderer) > 0) |
| 276 continue; |
| 277 |
| 265 // Skip renderers that have already been encountered. This can occur when | 278 // Skip renderers that have already been encountered. This can occur when |
| 266 // multiple tabs are folded into a single renderer process. In this case the | 279 // multiple tabs are folded into a single renderer process. In this case the |
| 267 // process takes the priority of its highest priority contained tab. | 280 // process takes the priority of its highest priority contained tab. |
| 268 auto renderer = tab.render_process_host; | |
| 269 if (!seen_renderers.insert(renderer).second) | 281 if (!seen_renderers.insert(renderer).second) |
| 270 continue; | 282 continue; |
| 271 | 283 |
| 272 sorted_renderers.push_back(renderer); | 284 sorted_renderers.push_back(renderer); |
| 273 } | 285 } |
| 274 | 286 |
| 275 return sorted_renderers; | 287 return sorted_renderers; |
| 276 } | 288 } |
| 277 | 289 |
| 278 bool TabManager::IsTabDiscarded(content::WebContents* contents) const { | 290 bool TabManager::IsTabDiscarded(content::WebContents* contents) const { |
| (...skipping 469 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 748 if (level == base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_NONE) { | 760 if (level == base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_NONE) { |
| 749 under_memory_pressure_ = false; | 761 under_memory_pressure_ = false; |
| 750 notified_renderers_.clear(); | 762 notified_renderers_.clear(); |
| 751 return; | 763 return; |
| 752 } | 764 } |
| 753 | 765 |
| 754 // Get a vector of active renderers, from highest to lowest priority. | 766 // Get a vector of active renderers, from highest to lowest priority. |
| 755 auto renderers = GetOrderedRenderers(); | 767 auto renderers = GetOrderedRenderers(); |
| 756 | 768 |
| 757 // The following code requires at least one renderer to be present or it will | 769 // The following code requires at least one renderer to be present or it will |
| 758 // busyloop. It's possible (however unlikely) for no renderers to exist, so | 770 // busyloop. It's possible for no renderers to exist (we eliminate visible |
| 759 // bail early if that's the case. | 771 // renderers to avoid janking them), so bail early if that's the case. |
| 760 if (renderers.empty()) | 772 if (renderers.empty()) |
| 761 return; | 773 return; |
| 762 | 774 |
| 763 // Notify a single renderer of memory pressure. | 775 // Notify a single renderer of memory pressure. |
| 764 bool notified = false; | 776 bool notified = false; |
| 765 while (!notified) { | 777 while (!notified) { |
| 766 // Notify the lowest priority renderer that hasn't been notified yet. | 778 // Notify the lowest priority renderer that hasn't been notified yet. |
| 767 for (auto rit = renderers.rbegin(); rit != renderers.rend(); ++rit) { | 779 for (auto rit = renderers.rbegin(); rit != renderers.rend(); ++rit) { |
| 768 // If this renderer has already been notified then look at the next one. | 780 // If this renderer has already been notified then look at the next one. |
| 769 if (!notified_renderers_.insert(*rit).second) | 781 if (!notified_renderers_.insert(*rit).second) |
| (...skipping 19 matching lines...) Expand all Loading... |
| 789 // Schedule another notification. Use a weak pointer so this doesn't explode | 801 // Schedule another notification. Use a weak pointer so this doesn't explode |
| 790 // during tear down. | 802 // during tear down. |
| 791 task_runner_->PostDelayedTask( | 803 task_runner_->PostDelayedTask( |
| 792 FROM_HERE, | 804 FROM_HERE, |
| 793 base::Bind(&TabManager::DoChildProcessDispatch, | 805 base::Bind(&TabManager::DoChildProcessDispatch, |
| 794 weak_ptr_factory_.GetWeakPtr()), | 806 weak_ptr_factory_.GetWeakPtr()), |
| 795 base::TimeDelta::FromSeconds(kRendererNotificationDelayInSeconds)); | 807 base::TimeDelta::FromSeconds(kRendererNotificationDelayInSeconds)); |
| 796 } | 808 } |
| 797 | 809 |
| 798 } // namespace memory | 810 } // namespace memory |
| OLD | NEW |