Commit dce9562f authored by Joe Mason's avatar Joe Mason Committed by Commit Bot

[PM] Add a method to measure V8 memory for a single process.

* Add a StartMeasurementForProcess method to V8PerFrameMemoryRequest
* Add a MeasurementRequestQueue helper class that holds separate lists
  of lazy and bounded requests.
* Add per-process MeasurementRequestQueue's as well as the existing
  global MeasurementRequestQueue.

R=chrisha

Bug: 1080672
Change-Id: I0257ad72482bff8fe5e478b19d8545947da483c5
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2440695
Commit-Queue: Joe Mason <joenotcharles@chromium.org>
Reviewed-by: default avatarChris Hamilton <chrisha@chromium.org>
Cr-Commit-Position: refs/heads/master@{#812732}
parent 6739deb6
...@@ -248,6 +248,11 @@ class V8PerFrameMemoryDecorator ...@@ -248,6 +248,11 @@ class V8PerFrameMemoryDecorator
public ProcessNode::ObserverDefaultImpl, public ProcessNode::ObserverDefaultImpl,
public NodeDataDescriberDefaultImpl { public NodeDataDescriberDefaultImpl {
public: public:
// A priority queue of memory requests. The decorator will hold a global
// queue of requests that measure every process, and each ProcessNode will
// have a queue of requests that measure only that process.
class MeasurementRequestQueue;
V8PerFrameMemoryDecorator(); V8PerFrameMemoryDecorator();
~V8PerFrameMemoryDecorator() override; ~V8PerFrameMemoryDecorator() override;
...@@ -261,23 +266,27 @@ class V8PerFrameMemoryDecorator ...@@ -261,23 +266,27 @@ class V8PerFrameMemoryDecorator
// ProcessNodeObserver overrides. // ProcessNodeObserver overrides.
void OnProcessNodeAdded(const ProcessNode* process_node) override; void OnProcessNodeAdded(const ProcessNode* process_node) override;
void OnBeforeProcessNodeRemoved(const ProcessNode* process_node) override;
// NodeDataDescriber overrides. // NodeDataDescriber overrides.
base::Value DescribeFrameNodeData(const FrameNode* node) const override; base::Value DescribeFrameNodeData(const FrameNode* node) const override;
base::Value DescribeProcessNodeData(const ProcessNode* node) const override; base::Value DescribeProcessNodeData(const ProcessNode* node) const override;
// Returns the next measurement request that should be scheduled. // Returns the next measurement request that should be scheduled.
V8PerFrameMemoryRequest* GetNextRequest() const; const V8PerFrameMemoryRequest* GetNextRequest() const;
// Returns the next measurement request with mode kBounded or // Returns the next measurement request with mode kBounded or
// kEagerForTesting that should be scheduled. // kEagerForTesting that should be scheduled.
V8PerFrameMemoryRequest* GetNextBoundedRequest() const; const V8PerFrameMemoryRequest* GetNextBoundedRequest() const;
// Implementation details below this point. // Implementation details below this point.
// V8PerFrameMemoryRequest objects register themselves with the decorator. // V8PerFrameMemoryRequest objects register themselves with the decorator.
// If |process_node| is null, the request will be sent to every process,
// otherwise it will be sent only to |process_node|.
void AddMeasurementRequest(util::PassKey<V8PerFrameMemoryRequest>, void AddMeasurementRequest(util::PassKey<V8PerFrameMemoryRequest>,
V8PerFrameMemoryRequest* request); V8PerFrameMemoryRequest* request,
const ProcessNode* process_node = nullptr);
void RemoveMeasurementRequest(util::PassKey<V8PerFrameMemoryRequest>, void RemoveMeasurementRequest(util::PassKey<V8PerFrameMemoryRequest>,
V8PerFrameMemoryRequest* request); V8PerFrameMemoryRequest* request);
...@@ -289,13 +298,18 @@ class V8PerFrameMemoryDecorator ...@@ -289,13 +298,18 @@ class V8PerFrameMemoryDecorator
const ProcessNode* process_node) const; const ProcessNode* process_node) const;
private: private:
using RequestQueueCallback =
base::RepeatingCallback<void(MeasurementRequestQueue*)>;
// Runs the given |callback| for every MeasurementRequestQueue (global and
// per-process).
void ApplyToAllRequestQueues(RequestQueueCallback callback) const;
void UpdateProcessMeasurementSchedules() const; void UpdateProcessMeasurementSchedules() const;
Graph* graph_ = nullptr; Graph* graph_ = nullptr;
// Lists of requests sorted by min_time_between_requests (lowest first). std::unique_ptr<MeasurementRequestQueue> measurement_requests_;
std::vector<V8PerFrameMemoryRequest*> bounded_measurement_requests_;
std::vector<V8PerFrameMemoryRequest*> lazy_measurement_requests_;
SEQUENCE_CHECKER(sequence_checker_); SEQUENCE_CHECKER(sequence_checker_);
}; };
...@@ -354,10 +368,16 @@ class V8PerFrameMemoryRequest { ...@@ -354,10 +368,16 @@ class V8PerFrameMemoryRequest {
MeasurementMode mode() const { return mode_; } MeasurementMode mode() const { return mode_; }
// Requests measurements for all ProcessNode's in |graph|. This must only be // Requests measurements for all ProcessNode's in |graph|. There must be at
// called once for each V8PerFrameMemoryRequest. // most one call to this or StartMeasurementForProcess for each
// V8PerFrameMemoryRequest.
void StartMeasurement(Graph* graph); void StartMeasurement(Graph* graph);
// Requests measurements only for the given |process_node|, which must be a
// renderer process. There must be at most one call to this or
// StartMeasurement for each V8PerFrameMemoryRequest.
void StartMeasurementForProcess(const ProcessNode* process_node);
// Adds/removes an observer. // Adds/removes an observer.
void AddObserver(V8PerFrameMemoryObserver* observer); void AddObserver(V8PerFrameMemoryObserver* observer);
void RemoveObserver(V8PerFrameMemoryObserver* observer); void RemoveObserver(V8PerFrameMemoryObserver* observer);
...@@ -374,17 +394,21 @@ class V8PerFrameMemoryRequest { ...@@ -374,17 +394,21 @@ class V8PerFrameMemoryRequest {
MeasurementMode mode, MeasurementMode mode,
base::WeakPtr<V8PerFrameMemoryRequestAnySeq> off_sequence_request); base::WeakPtr<V8PerFrameMemoryRequestAnySeq> off_sequence_request);
// V8PerFrameMemoryDecorator calls OnDecoratorUnregistered when it is removed // V8PerFrameMemoryDecorator::MeasurementRequestQueue calls
// from the graph. // OnOwnerUnregistered for all requests in the queue when the owning
void OnDecoratorUnregistered(util::PassKey<V8PerFrameMemoryDecorator>); // decorator or process node is removed from the graph.
void OnOwnerUnregistered(
util::PassKey<V8PerFrameMemoryDecorator::MeasurementRequestQueue>);
// V8PerFrameMemoryDecorator calls NotifyObserversOnMeasurementAvailable when // V8PerFrameMemoryDecorator::MeasurementRequestQueue calls
// a measurement is received. // NotifyObserversOnMeasurementAvailable when a measurement is received.
void NotifyObserversOnMeasurementAvailable( void NotifyObserversOnMeasurementAvailable(
util::PassKey<V8PerFrameMemoryDecorator>, util::PassKey<V8PerFrameMemoryDecorator::MeasurementRequestQueue>,
const ProcessNode* process_node) const; const ProcessNode* process_node) const;
private: private:
void StartMeasurementImpl(Graph* graph, const ProcessNode* process_node);
base::TimeDelta min_time_between_requests_; base::TimeDelta min_time_between_requests_;
MeasurementMode mode_; MeasurementMode mode_;
V8PerFrameMemoryDecorator* decorator_ = nullptr; V8PerFrameMemoryDecorator* decorator_ = nullptr;
......
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