Commit cc2829a1 authored by Joe Mason's avatar Joe Mason Committed by Chromium LUCI CQ

[PM] Move WebMemoryAggregator result state into a Visitor helper class

Moves the code that statefully updates the aggregation result into an
AggregationPointVisitor helper class. This will make it easier to
implement new algorithms that gather different information from each
aggregation point (eg. finding the set of processes spanned by all
aggregation points) by subclassing AggregationPointVisitor.

R=siggi

Bug: 1168573
Change-Id: I0b674fdc4282e164e9541ed17ca6b53483bb525e
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2640675
Commit-Queue: Joe Mason <joenotcharles@chromium.org>
Reviewed-by: default avatarSigurður Ásgeirsson <siggi@chromium.org>
Cr-Commit-Position: refs/heads/master@{#845713}
parent 109dcdb8
...@@ -41,10 +41,22 @@ class WebMemoryAggregator { ...@@ -41,10 +41,22 @@ class WebMemoryAggregator {
WebMemoryAggregator(const WebMemoryAggregator& other) = delete; WebMemoryAggregator(const WebMemoryAggregator& other) = delete;
WebMemoryAggregator& operator=(const WebMemoryAggregator& other) = delete; WebMemoryAggregator& operator=(const WebMemoryAggregator& other) = delete;
// Returns the origin of |requesting_node|.
const url::Origin& requesting_origin() const { return requesting_origin_; }
// Performs the aggregation.
mojom::WebMemoryMeasurementPtr AggregateMeasureMemoryResult();
private:
friend class WebMemoryAggregatorTest;
class AggregationPointVisitor;
// The various ways a node can be treated during the aggregation. // The various ways a node can be treated during the aggregation.
enum class NodeAggregationType { enum class NodeAggregationType {
// Node is same-origin to |requesting_node|; will be a new aggregation // Node is same-origin to |requesting_node|; will be a new aggregation
// point with scope "Window". // point with a scope depending on the node type (eg. "Window" or
// "DedicatedWorker").
kSameOriginAggregationPoint, kSameOriginAggregationPoint,
// Node is cross-origin with |requesting_node| but its parent is not; will // Node is cross-origin with |requesting_node| but its parent is not; will
// be a new aggregation point with scope // be a new aggregation point with scope
...@@ -58,9 +70,6 @@ class WebMemoryAggregator { ...@@ -58,9 +70,6 @@ class WebMemoryAggregator {
kInvisible, kInvisible,
}; };
// Returns the origin of |requesting_node|.
const url::Origin& requesting_origin() const { return requesting_origin_; }
// Returns the way that |frame_node| should be treated during the // Returns the way that |frame_node| should be treated during the
// aggregation. |aggregation_start_node_| must be reachable from // aggregation. |aggregation_start_node_| must be reachable from
// |frame_node| by following parent/child or opener links. This will always // |frame_node| by following parent/child or opener links. This will always
...@@ -72,83 +81,69 @@ class WebMemoryAggregator { ...@@ -72,83 +81,69 @@ class WebMemoryAggregator {
const WorkerNode* worker_node, const WorkerNode* worker_node,
NodeAggregationType parent_aggregation_type); NodeAggregationType parent_aggregation_type);
// Performs the aggregation.
mojom::WebMemoryMeasurementPtr AggregateMeasureMemoryResult();
private:
// FrameNodeVisitor that recursively adds |frame_node| and its children to // FrameNodeVisitor that recursively adds |frame_node| and its children to
// the aggregation. |enclosing_aggregation_point| is the aggregation point // the aggregation using |ap_visitor|. Always returns true to continue
// that |frame_node|'s parent or opener is in. Always returns true to // traversal.
// continue traversal. bool VisitFrame(AggregationPointVisitor* ap_visitor,
bool VisitFrame(mojom::WebMemoryBreakdownEntry* enclosing_aggregation_point,
const FrameNode* frame_node); const FrameNode* frame_node);
// WorkerNodeVisitor that recursively adds |worker_node| and its children to // WorkerNodeVisitor that recursively adds |worker_node| and its children to
// the aggregation. |enclosing_aggregation_point| is the aggregation point // the aggregation using |ap_visitor|. |enclosing_aggregation_type| is the
// that |worker_node|'s parent is in. Similarly |enclosing_aggregation_type| // type of the aggregation point that |worker_node|'s parent is in. Always
// is the aggregation type of the parent. // returns true to continue traversal.
// Always returns true to continue traversal. bool VisitWorker(AggregationPointVisitor* ap_visitor,
bool VisitWorker(mojom::WebMemoryBreakdownEntry* enclosing_aggregation_point,
NodeAggregationType enclosing_aggregation_type, NodeAggregationType enclosing_aggregation_type,
const WorkerNode* worker_node); const WorkerNode* worker_node);
// PageNodeVisitor that recursively adds |page_node|'s main frames and their // PageNodeVisitor that recursively adds |page_node|'s main frames and their
// children to the aggregation. |enclosing_aggregation_point| is the // children to the aggregation using |ap_visitor|. Always returns true to
// aggregation point that |page_node|'s opener is in. Always returns true to
// continue traversal. // continue traversal.
bool VisitOpenedPage( bool VisitOpenedPage(AggregationPointVisitor* ap_visitor,
mojom::WebMemoryBreakdownEntry* enclosing_aggregation_point,
const PageNode* page_node); const PageNode* page_node);
// The origin of |requesting_node|. Cached so it doesn't have to be // Static private methods are implementation details, but can be accessed from
// recalculated in each call to VisitFrame. // friend classes for testing.
const url::Origin requesting_origin_;
// The node that the graph traversal should start from, found from // Returns |frame_node|'s parent or opener if the parent or opener is
// |requesting_node| using FindAggregationStartNode. // same-origin with |origin|, nullptr otherwise.
const FrameNode* aggregation_start_node_; static const FrameNode* GetSameOriginParentOrOpener(
const FrameNode* frame_node,
// Stores the result of the aggregation. This is populated by
// AggregateMeasureMemoryResult.
mojom::WebMemoryMeasurementPtr aggregation_result_
GUARDED_BY_CONTEXT(sequence_checker_);
SEQUENCE_CHECKER(sequence_checker_);
};
namespace internal {
// These functions are used in the implementation and exposed in the header for
// testing.
// Returns |frame_node|'s parent or opener if the parent or opener is
// same-origin with |origin|, nullptr otherwise.
const FrameNode* GetSameOriginParentOrOpener(const FrameNode* frame_node,
const url::Origin& origin); const url::Origin& origin);
// Walks back the chain of parents and openers from |requesting_node| to find // Walks back the chain of parents and openers from |requesting_node| to find
// the farthest ancestor that should be visible to it (all intermediate nodes // the farthest ancestor that should be visible to it (all intermediate nodes
// in the chain are same-origin). // in the chain are same-origin).
const FrameNode* FindAggregationStartNode(const FrameNode* requesting_node); static const FrameNode* FindAggregationStartNode(
const FrameNode* requesting_node);
// Creates a new breakdown entry with the given |scope| and |url|, and adds it // Creates a new breakdown entry with the given |scope| and |url|, and adds it
// to the list in |measurement|. Returns a pointer to the newly created entry. // to the list in |measurement|. Returns a pointer to the newly created entry.
mojom::WebMemoryBreakdownEntry* CreateBreakdownEntry( static mojom::WebMemoryBreakdownEntry* CreateBreakdownEntry(
mojom::WebMemoryAttribution::Scope scope, mojom::WebMemoryAttribution::Scope scope,
base::Optional<std::string> url, base::Optional<std::string> url,
mojom::WebMemoryMeasurement* measurement); mojom::WebMemoryMeasurement* measurement);
// Sets the id and src attributes of |breakdown| using those stored in the // Sets the id and src attributes of |breakdown| using those stored in the
// V8ContextTracker for the given |frame_node|. // V8ContextTracker for the given |frame_node|.
void SetBreakdownAttributionFromFrame( static void SetBreakdownAttributionFromFrame(
const FrameNode* frame_node, const FrameNode* frame_node,
mojom::WebMemoryBreakdownEntry* breakdown); mojom::WebMemoryBreakdownEntry* breakdown);
// Copies the id and src attributes from |from| to |to|. // Copies the id and src attributes from |from| to |to|.
void CopyBreakdownAttribution(const mojom::WebMemoryBreakdownEntry* from, static void CopyBreakdownAttribution(
const mojom::WebMemoryBreakdownEntry* from,
mojom::WebMemoryBreakdownEntry* to); mojom::WebMemoryBreakdownEntry* to);
} // namespace internal // The origin of |requesting_node|. Cached so it doesn't have to be
// recalculated in each call to VisitFrame.
const url::Origin requesting_origin_;
// The node that the graph traversal should start from, found from
// |requesting_node| using FindAggregationStartNode.
const FrameNode* aggregation_start_node_;
SEQUENCE_CHECKER(sequence_checker_);
};
} // namespace v8_memory } // namespace v8_memory
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment