tree: 96b06883f2e0914968293d69682aac7eda8524b8 [search]
  1. closing_page_voter.cc
  2. closing_page_voter.h
  3. closing_page_voter_unittest.cc
  4. extension_service_worker_voter.cc
  5. extension_service_worker_voter.h
  6. extension_service_worker_voter_unittest.cc
  7. force_foreground_voter.cc
  8. force_foreground_voter.h
  9. force_foreground_voter_for_urls.cc
  10. force_foreground_voter_for_urls.h
  11. force_foreground_voter_for_urls_unittest.cc
  12. force_foreground_voter_unittest.cc
  13. frame_audible_voter.cc
  14. frame_audible_voter.h
  15. frame_audible_voter_unittest.cc
  16. frame_capturing_media_stream_voter.cc
  17. frame_capturing_media_stream_voter.h
  18. frame_capturing_media_stream_voter_unittest.cc
  19. frame_visibility_voter.cc
  20. frame_visibility_voter.h
  21. frame_visibility_voter_unittest.cc
  22. glic_actuation_priority_voter.cc
  23. glic_actuation_priority_voter.h
  24. glic_actuation_priority_voter_unittest.cc
  25. inherit_client_priority_voter.cc
  26. inherit_client_priority_voter.h
  27. inherit_client_priority_voter_unittest.cc
  28. inherit_parent_priority_voter.cc
  29. inherit_parent_priority_voter.h
  30. inherit_parent_priority_voter_unittest.cc
  31. loading_page_voter.cc
  32. loading_page_voter.h
  33. loading_page_voter_unittest.cc
  34. max_vote_aggregator.cc
  35. max_vote_aggregator_unittest.cc
  36. page_to_frame_vote_expander.cc
  37. page_to_frame_vote_expander.h
  38. priority.cc
  39. priority_setter.cc
  40. priority_setter.h
  41. priority_unittest.cc
  42. priority_voting_system.cc
  43. priority_voting_system_unittest.cc
  44. README.md
  45. withheld_from_view_voter.cc
  46. withheld_from_view_voter.h
  47. withheld_from_view_voter_unittest.cc
components/performance_manager/priority/README.md

The PriorityVotingSystem is responsible for assigning the priority of the votable nodes in the graph.

This is done through a system of voting where each voter can independently increase the priority of a graph node, and the vote with the highest priority determines which priority that graph node will be assigned.

A VoteContext identifies the graph node that a vote targets. It is a std::variant that explicitly lists the votable node types (currently FrameNode, WorkerNode, PageNode and ProcessNode). Voting on any other node type fails to compile.

Vote flow

Frames
======

PageToFrameVoteExpander -+
                         +-> MaxVoteAggregator -> PrioritySetter -> FrameNode -> ProcessPriorityAggregator
           Other voters -+

Workers
=======

Voters -> MaxVoteAggregator -> PrioritySetter -> WorkerNode -> ProcessPriorityAggregator

Processes
=========

ProcessPriorityAggregator -+
                           +-> MaxVoteAggregator -> PrioritySetter -> ProcessNode
             Other voters -+

Pages
=====

Voters -> MaxVoteAggregator -> PageToFrameVoteExpander

Every vote goes into a single MaxVoteAggregator, through a voting channel. The top vote of a node in the aggregator is therefore its final priority.

Each voter tracks a single property of a vote context and casts their vote via their voting channel to the MaxVoteAggregator.

The observers of the MaxVoteAggregator are:

  • The PrioritySetter assigns the top vote of frames, workers and (renderer) processes to their priority, or their default priority when they have no vote.
  • The PageToFrameVoteExpander casts the top vote of pages on every frame of the page, back into the MaxVoteAggregator, where it is aggregated with the frames' own votes.

The ProcessPriorityAggregator follows the priority of every frame and worker (as set by the PrioritySetter), and casts the highest priority of the frames and workers hosted by a process as a vote on that process, where it is aggregated with the votes cast directly on the process. This vote is cast even when it is the lowest priority, so that a process drops from its initial high priority once it hosts a frame or worker.

The PriorityVotingSystem owns the MaxVoteAggregator, and builds each of these from it. It also verifies that no votes are leaked.

Invariants

  • No cycles: Derived votes only flow from pages to frames, and from frames and workers to processes. Processes never cast votes. The MaxVoteAggregator CHECKs that the top vote for a node doesn't change while its observers are being notified, which catches any cycle.
  • Re-entrancy: Votes can be cast while the MaxVoteAggregator is notifying its observers, both by voters (e.g. the InheritParentPriorityVoter votes on child frames when the PrioritySetter sets the priority of a frame) and by the PageToFrameVoteExpander and the ProcessPriorityAggregator, so the aggregator supports being re-entered.
  • Timing: The PriorityVotingSystem must be added to the graph before any node (this is CHECKed), so that the ProcessPriorityAggregator sees every frame and worker being added. The priority of a frame or worker is taken into account in the vote on its process once it is added to the graph, and is followed until it is removed. Page votes can't change while a frame of the page is being removed (this is CHECKed).
  • No leaks: Voters must remove their votes on a node before it is removed from the graph (this is CHECKed).

Voters vs. derived votes

Some voters (e.g. InheritClientPriorityVoter) also derive votes from the priority of other nodes. They are voters because they implement an optional policy. The derived votes cast on frames (from their page) and on processes (from their frames and workers) are part of the voting system itself: they are always needed for the priorities to be correct.