123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215 |
- // Copyright 2020 The Chromium Authors. All rights reserved.
- // Use of this source code is governed by a BSD-style license that can be
- // found in the LICENSE file.
- #include "components/performance_manager/public/v8_memory/v8_detailed_memory_any_seq.h"
- #include <memory>
- #include <utility>
- #include <vector>
- #include "base/bind.h"
- #include "base/memory/weak_ptr.h"
- #include "base/observer_list.h"
- #include "base/threading/sequenced_task_runner_handle.h"
- #include "components/performance_manager/public/graph/frame_node.h"
- #include "components/performance_manager/public/graph/graph.h"
- #include "components/performance_manager/public/graph/process_node.h"
- #include "components/performance_manager/public/performance_manager.h"
- #include "components/performance_manager/public/render_frame_host_proxy.h"
- #include "content/public/browser/browser_task_traits.h"
- #include "content/public/browser/browser_thread.h"
- namespace performance_manager {
- namespace v8_memory {
- ////////////////////////////////////////////////////////////////////////////////
- // V8DetailedMemoryRequestAnySeq
- V8DetailedMemoryRequestAnySeq::V8DetailedMemoryRequestAnySeq(
- const base::TimeDelta& min_time_between_requests,
- MeasurementMode mode,
- absl::optional<RenderProcessHostId> process_to_measure) {
- absl::optional<base::WeakPtr<ProcessNode>> process_node;
- if (process_to_measure) {
- // GetProcessNodeForRenderProcessHostId must be called from the UI thread.
- auto ui_task_runner = content::GetUIThreadTaskRunner({});
- if (!ui_task_runner->RunsTasksInCurrentSequence()) {
- ui_task_runner->PostTaskAndReplyWithResult(
- FROM_HERE,
- base::BindOnce(
- &PerformanceManager::GetProcessNodeForRenderProcessHostId,
- process_to_measure.value()),
- base::BindOnce(
- &V8DetailedMemoryRequestAnySeq::InitializeWrappedRequest,
- weak_factory_.GetWeakPtr(), min_time_between_requests, mode));
- return;
- }
- process_node = PerformanceManager::GetProcessNodeForRenderProcessHostId(
- process_to_measure.value());
- }
- InitializeWrappedRequest(min_time_between_requests, mode,
- std::move(process_node));
- }
- V8DetailedMemoryRequestAnySeq::~V8DetailedMemoryRequestAnySeq() {
- DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
- PerformanceManager::CallOnGraph(
- FROM_HERE, base::BindOnce(
- [](std::unique_ptr<V8DetailedMemoryRequest> request) {
- request.reset();
- },
- std::move(request_)));
- }
- bool V8DetailedMemoryRequestAnySeq::HasObserver(
- V8DetailedMemoryObserverAnySeq* observer) {
- DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
- return observers_.HasObserver(observer);
- }
- void V8DetailedMemoryRequestAnySeq::AddObserver(
- V8DetailedMemoryObserverAnySeq* observer) {
- DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
- observers_.AddObserver(observer);
- }
- void V8DetailedMemoryRequestAnySeq::RemoveObserver(
- V8DetailedMemoryObserverAnySeq* observer) {
- DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
- DCHECK(observers_.HasObserver(observer));
- observers_.RemoveObserver(observer);
- }
- void V8DetailedMemoryRequestAnySeq::NotifyObserversOnMeasurementAvailable(
- base::PassKey<V8DetailedMemoryRequest>,
- RenderProcessHostId render_process_host_id,
- const V8DetailedMemoryProcessData& process_data,
- const V8DetailedMemoryObserverAnySeq::FrameDataMap& frame_data) const {
- DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
- for (V8DetailedMemoryObserverAnySeq& observer : observers_)
- observer.OnV8MemoryMeasurementAvailable(render_process_host_id,
- process_data, frame_data);
- }
- void V8DetailedMemoryRequestAnySeq::InitializeWrappedRequest(
- const base::TimeDelta& min_time_between_requests,
- MeasurementMode mode,
- absl::optional<base::WeakPtr<ProcessNode>> process_to_measure) {
- DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
- // After construction the V8DetailedMemoryRequest must only be accessed on
- // the graph sequence.
- request_ = std::make_unique<V8DetailedMemoryRequest>(
- base::PassKey<V8DetailedMemoryRequestAnySeq>(), min_time_between_requests,
- mode, std::move(process_to_measure), weak_factory_.GetWeakPtr());
- }
- ////////////////////////////////////////////////////////////////////////////////
- // V8DetailedMemoryRequestOneShotAnySeq
- V8DetailedMemoryRequestOneShotAnySeq::V8DetailedMemoryRequestOneShotAnySeq(
- MeasurementMode mode)
- : mode_(mode) {}
- V8DetailedMemoryRequestOneShotAnySeq::V8DetailedMemoryRequestOneShotAnySeq(
- RenderProcessHostId process_id,
- MeasurementCallback callback,
- MeasurementMode mode)
- : mode_(mode) {
- StartMeasurement(process_id, std::move(callback));
- }
- V8DetailedMemoryRequestOneShotAnySeq::~V8DetailedMemoryRequestOneShotAnySeq() {
- DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
- PerformanceManager::CallOnGraph(
- FROM_HERE,
- base::BindOnce(
- [](std::unique_ptr<V8DetailedMemoryRequestOneShot> request) {
- request.reset();
- },
- std::move(request_)));
- }
- void V8DetailedMemoryRequestOneShotAnySeq::StartMeasurement(
- RenderProcessHostId process_id,
- MeasurementCallback callback) {
- DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
- // GetProcessNodeForRenderProcessHostId must be called from the UI thread.
- auto ui_task_runner = content::GetUIThreadTaskRunner({});
- if (ui_task_runner->RunsTasksInCurrentSequence()) {
- InitializeWrappedRequest(
- std::move(callback), mode_,
- PerformanceManager::GetProcessNodeForRenderProcessHostId(process_id));
- } else {
- ui_task_runner->PostTaskAndReplyWithResult(
- FROM_HERE,
- base::BindOnce(
- &PerformanceManager::GetProcessNodeForRenderProcessHostId,
- process_id),
- base::BindOnce(
- &V8DetailedMemoryRequestOneShotAnySeq::InitializeWrappedRequest,
- weak_factory_.GetWeakPtr(), std::move(callback), mode_));
- }
- }
- void V8DetailedMemoryRequestOneShotAnySeq::InitializeWrappedRequest(
- MeasurementCallback callback,
- MeasurementMode mode,
- base::WeakPtr<ProcessNode> process_node) {
- DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
- // Pass ownership of |callback| to a wrapper, |wrapped_callback|, that will
- // be owned by the wrapped request. The wrapper will be invoked and destroyed
- // on the PM sequence. However, |callback| must be both called and destroyed
- // on this sequence, so indirect all accesses to it through SequenceBound.
- auto wrapped_callback = base::BindOnce(
- &V8DetailedMemoryRequestOneShotAnySeq::OnMeasurementAvailable,
- base::SequenceBound<MeasurementCallback>(
- base::SequencedTaskRunnerHandle::Get(), std::move(callback)));
- // After construction the V8DetailedMemoryRequest must only be accessed on
- // the graph sequence.
- request_ = std::make_unique<V8DetailedMemoryRequestOneShot>(
- base::PassKey<V8DetailedMemoryRequestOneShotAnySeq>(),
- std::move(process_node), std::move(wrapped_callback), mode);
- }
- // static
- void V8DetailedMemoryRequestOneShotAnySeq::OnMeasurementAvailable(
- base::SequenceBound<MeasurementCallback> sequence_bound_callback,
- const ProcessNode* process_node,
- const V8DetailedMemoryProcessData* process_data) {
- DCHECK(process_node);
- DCHECK_ON_GRAPH_SEQUENCE(process_node->GetGraph());
- using FrameAndData = std::pair<content::GlobalRenderFrameHostId,
- V8DetailedMemoryExecutionContextData>;
- std::vector<FrameAndData> all_frame_data;
- process_node->VisitFrameNodes(base::BindRepeating(
- [](std::vector<FrameAndData>* all_frame_data,
- const FrameNode* frame_node) {
- const auto* frame_data =
- V8DetailedMemoryExecutionContextData::ForFrameNode(frame_node);
- if (frame_data) {
- all_frame_data->push_back(std::make_pair(
- frame_node->GetRenderFrameHostProxy().global_frame_routing_id(),
- *frame_data));
- }
- return true;
- },
- base::Unretained(&all_frame_data)));
- sequence_bound_callback.PostTaskWithThisObject(
- base::BindOnce(
- [](RenderProcessHostId process_id,
- const V8DetailedMemoryProcessData& process_data,
- const FrameDataMap& frame_data, MeasurementCallback* callback) {
- std::move(*callback).Run(process_id, process_data, frame_data);
- },
- process_node->GetRenderProcessHostId(), *process_data,
- std::move(all_frame_data)));
- }
- } // namespace v8_memory
- } // namespace performance_manager
|