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
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
content / browser / renderer_host / recently_destroyed_hosts.h [blame]
// 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.
#ifndef CONTENT_BROWSER_RENDERER_HOST_RECENTLY_DESTROYED_HOSTS_H_
#define CONTENT_BROWSER_RENDERER_HOST_RECENTLY_DESTROYED_HOSTS_H_
#include "base/containers/flat_set.h"
#include "base/supports_user_data.h"
#include "base/time/time.h"
#include "content/common/content_export.h"
namespace base {
class TimeDelta;
class TimeTicks;
} // namespace base
namespace content {
class BrowserContext;
class ProcessLock;
class RenderProcessHost;
// Stores information about recently destroyed RenderProcessHosts in order to
// determine how often a process is created for a site that a just-destroyed
// host could have hosted. Emits the "SiteIsolation.ReusePendingOrCommittedSite.
// TimeSinceReusableProcessDestroyed" metric, which tracks this.
//
// Experimentally used to delay subframe-process shutdown. This aims to reduce
// process churn by keeping subframe processes alive for a few seconds. See
// GetSubframeProcessShutdownDelay() for details.
class CONTENT_EXPORT RecentlyDestroyedHosts
: public base::SupportsUserData::Data {
public:
// Storage time for information about recently destroyed processes. Intended
// to be long enough to capture a large portion of the process-reuse
// opportunity.
static constexpr base::TimeDelta kRecentlyDestroyedStorageTimeout =
base::Seconds(15);
~RecentlyDestroyedHosts() override;
RecentlyDestroyedHosts(const RecentlyDestroyedHosts& other) = delete;
RecentlyDestroyedHosts& operator=(const RecentlyDestroyedHosts& other) =
delete;
// If a host matching |process_lock| was recently destroyed, records the
// interval between its destruction and |reusable_host_lookup_time|. If not,
// records a sentinel value.
static void RecordMetricIfReusableHostRecentlyDestroyed(
const base::TimeTicks& reusable_host_lookup_time,
const ProcessLock& process_lock,
BrowserContext* browser_context);
// Adds |host|'s process lock to the list of recently destroyed hosts, or
// updates its time if it's already present.
static void Add(RenderProcessHost* host,
const base::TimeDelta& time_spent_running_unload_handlers,
BrowserContext* browser_context);
private:
friend class RecentlyDestroyedHostsTest;
// The |interval| between a renderer process's destruction and the creation of
// another renderer process for the same domain.
struct ReuseInterval {
base::TimeDelta interval;
base::TimeTicks time_added;
bool operator<(const ReuseInterval& rhs) const {
return std::tie(interval, time_added) <
std::tie(rhs.interval, rhs.time_added);
}
};
RecentlyDestroyedHosts();
// Returns the RecentlyDestroyedHosts instance stored in |browser_context|, or
// creates an instance in |browser_context| and returns it if none exists.
static RecentlyDestroyedHosts* GetInstance(BrowserContext* browser_context);
// Removes all entries older than |kRecentlyDestroyedStorageTimeout| from
// |recently_destroyed_hosts_|.
void RemoveExpiredEntries();
void AddReuseInterval(const base::TimeDelta& interval);
// List of recent intervals between renderer-process destruction and the
// creation of a renderer process for the same site. Sorted by interval, from
// shortest to longest. Only a limited number are stored.
base::flat_set<ReuseInterval> reuse_intervals_;
// Map of ProcessLock to destruction time, for RenderProcessHosts destroyed
// in the last |kRecentlyDestroyedStorageTimeout| seconds.
std::map<ProcessLock, base::TimeTicks> recently_destroyed_hosts_;
};
} // namespace content
#endif // CONTENT_BROWSER_RENDERER_HOST_RECENTLY_DESTROYED_HOSTS_H_