blob: e3e033c5ac838ee3a5d1d49646b31c5ed90137f8 (
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
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
|
// Copyright 2018 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "third_party/blink/renderer/controller/crash_memory_metrics_reporter_impl.h"
#include <utility>
#include "base/allocator/partition_allocator/oom_callback.h"
#include "base/metrics/histogram_macros.h"
#include "base/process/memory.h"
#include "third_party/blink/public/platform/platform.h"
#include "third_party/blink/renderer/platform/bindings/v8_per_isolate_data.h"
#include "third_party/blink/renderer/platform/wtf/allocator/partitions.h"
namespace blink {
// static
void CrashMemoryMetricsReporterImpl::Bind(
mojo::PendingReceiver<mojom::blink::CrashMemoryMetricsReporter> receiver) {
// This should be called only once per process on RenderProcessWillLaunch.
DCHECK(!CrashMemoryMetricsReporterImpl::Instance().receiver_.is_bound());
CrashMemoryMetricsReporterImpl::Instance().receiver_.Bind(
std::move(receiver));
}
CrashMemoryMetricsReporterImpl& CrashMemoryMetricsReporterImpl::Instance() {
DEFINE_STATIC_LOCAL(CrashMemoryMetricsReporterImpl,
crash_memory_metrics_reporter_impl, ());
return crash_memory_metrics_reporter_impl;
}
CrashMemoryMetricsReporterImpl::CrashMemoryMetricsReporterImpl() {
::partition_alloc::SetPartitionAllocOomCallback(
CrashMemoryMetricsReporterImpl::OnOOMCallback);
}
CrashMemoryMetricsReporterImpl::~CrashMemoryMetricsReporterImpl() {
MemoryUsageMonitor::Instance().RemoveObserver(this);
}
void CrashMemoryMetricsReporterImpl::SetSharedMemory(
base::UnsafeSharedMemoryRegion shared_metrics_buffer) {
// This method should be called only once per process.
DCHECK(!shared_metrics_mapping_.IsValid());
shared_metrics_mapping_ = shared_metrics_buffer.Map();
MemoryUsageMonitor::Instance().AddObserver(this);
}
void CrashMemoryMetricsReporterImpl::OnMemoryPing(MemoryUsage usage) {
DCHECK(IsMainThread());
last_reported_metrics_ =
CrashMemoryMetricsReporterImpl::MemoryUsageToMetrics(usage);
WriteIntoSharedMemory();
}
void CrashMemoryMetricsReporterImpl::WriteIntoSharedMemory() {
if (!shared_metrics_mapping_.IsValid())
return;
auto* metrics_shared =
shared_metrics_mapping_.GetMemoryAs<OomInterventionMetrics>();
*metrics_shared = last_reported_metrics_;
}
void CrashMemoryMetricsReporterImpl::OnOOMCallback() {
// TODO(yuzus: Support allocation failures on other threads as well.
if (!IsMainThread())
return;
CrashMemoryMetricsReporterImpl& instance =
CrashMemoryMetricsReporterImpl::Instance();
// If shared_metrics_mapping_ is not set, it means OnNoMemory happened before
// initializing render process host sets the shared memory.
if (!instance.shared_metrics_mapping_.IsValid())
return;
// Else, we can send the allocation_failed bool.
// TODO(yuzus): Report this UMA on all the platforms. Currently this is only
// reported on Android.
instance.last_reported_metrics_.allocation_failed = 1; // true
instance.WriteIntoSharedMemory();
}
// static
OomInterventionMetrics CrashMemoryMetricsReporterImpl::MemoryUsageToMetrics(
MemoryUsage usage) {
OomInterventionMetrics metrics;
DCHECK(!std::isnan(usage.private_footprint_bytes));
DCHECK(!std::isnan(usage.swap_bytes));
DCHECK(!std::isnan(usage.vm_size_bytes));
metrics.current_blink_usage_kb =
(usage.v8_bytes + usage.blink_gc_bytes + usage.partition_alloc_bytes) /
1024;
DCHECK(!std::isnan(usage.private_footprint_bytes));
DCHECK(!std::isnan(usage.swap_bytes));
DCHECK(!std::isnan(usage.vm_size_bytes));
metrics.current_private_footprint_kb = usage.private_footprint_bytes / 1024;
metrics.current_swap_kb = usage.swap_bytes / 1024;
metrics.current_vm_size_kb = usage.vm_size_bytes / 1024;
metrics.allocation_failed = 0; // false
return metrics;
}
} // namespace blink
|