summaryrefslogtreecommitdiff
path: root/chromium/content/browser/starscan_load_observer.cc
blob: 6d4b301e7124bb9f708f15a89eaded9b5ac2594d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
// Copyright 2021 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "content/browser/starscan_load_observer.h"

#include "base/allocator/partition_allocator/starscan/pcscan.h"
#include "base/logging.h"
#include "content/browser/renderer_host/frame_tree.h"
#include "content/browser/renderer_host/render_frame_host_impl.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/navigation_handle.h"

namespace content {

namespace {
size_t g_loading_webcontents_ = 0;
}

// Start observing right away.
StarScanLoadObserver::StarScanLoadObserver(WebContents* contents)
    : WebContentsObserver(contents) {}

StarScanLoadObserver::~StarScanLoadObserver() {
  // WebContents can be destructed while loading is still in progress.
  DidStopLoading();
}

void StarScanLoadObserver::ReadyToCommitNavigation(
    NavigationHandle* navigation_handle) {
  DCHECK_CURRENTLY_ON(BrowserThread::UI);

  // We don't disable PCScan for a prerendering page's navigation since
  // it doesn't invoke DidStopLoading.
  RenderFrameHostImpl* rfh = static_cast<RenderFrameHostImpl*>(
      navigation_handle->GetRenderFrameHost());
  if (rfh->frame_tree()->type() == FrameTree::Type::kPrerender)
    return;

  // Protect against ReadyToCommitNavigation() being called twice in a row.
  if (is_loading_)
    return;
  is_loading_ = true;

  if (!g_loading_webcontents_) {
    VLOG(3) << "Disabling *Scan due to loading";
    partition_alloc::internal::PCScan::Disable();
  }
  ++g_loading_webcontents_;

  // Set timer as a fallback if loading is too slow.
  constexpr base::TimeDelta kReenableStarScanDelta = base::Seconds(10);
  timer_.Start(FROM_HERE, kReenableStarScanDelta, this,
               &StarScanLoadObserver::DidStopLoading);
}

void StarScanLoadObserver::DidStopLoading() {
  DCHECK_CURRENTLY_ON(BrowserThread::UI);
  if (is_loading_) {
    DecrementCounterAndReenableStarScanIfNeeded();
    is_loading_ = false;
  }
}

void StarScanLoadObserver::DecrementCounterAndReenableStarScanIfNeeded() {
  CHECK(g_loading_webcontents_);
  --g_loading_webcontents_;
  if (!g_loading_webcontents_) {
    VLOG(3) << "Reenabling *Scan after finishing loading";
    partition_alloc::internal::PCScan::Reenable();
  }
}

}  // namespace content