2021-01-22 14:16:15 +00:00
|
|
|
// Copyright 2020 the V8 project 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 "src/heap/cppgc/metric-recorder.h"
|
|
|
|
|
|
|
|
#include "src/heap/cppgc/stats-collector.h"
|
|
|
|
#include "test/unittests/heap/cppgc/tests.h"
|
|
|
|
|
|
|
|
namespace cppgc {
|
|
|
|
namespace internal {
|
|
|
|
|
|
|
|
namespace {
|
|
|
|
class MetricRecorderImpl final : public MetricRecorder {
|
|
|
|
public:
|
2021-01-27 22:47:52 +00:00
|
|
|
void AddMainThreadEvent(const CppGCFullCycle& event) final {
|
|
|
|
CppGCFullCycle_event = event;
|
|
|
|
CppGCFullCycle_callcount++;
|
2021-01-22 14:16:15 +00:00
|
|
|
}
|
2021-01-27 22:47:52 +00:00
|
|
|
void AddMainThreadEvent(const CppGCMainThreadIncrementalMark& event) final {
|
|
|
|
CppGCMainThreadIncrementalMark_event = event;
|
|
|
|
CppGCMainThreadIncrementalMark_callcount++;
|
2021-01-22 14:16:15 +00:00
|
|
|
}
|
2021-01-27 22:47:52 +00:00
|
|
|
void AddMainThreadEvent(const CppGCMainThreadIncrementalSweep& event) final {
|
|
|
|
CppGCMainThreadIncrementalSweep_event = event;
|
|
|
|
CppGCMainThreadIncrementalSweep_callcount++;
|
2021-01-22 14:16:15 +00:00
|
|
|
}
|
|
|
|
|
2021-01-27 22:47:52 +00:00
|
|
|
static size_t CppGCFullCycle_callcount;
|
|
|
|
static CppGCFullCycle CppGCFullCycle_event;
|
|
|
|
static size_t CppGCMainThreadIncrementalMark_callcount;
|
|
|
|
static CppGCMainThreadIncrementalMark CppGCMainThreadIncrementalMark_event;
|
|
|
|
static size_t CppGCMainThreadIncrementalSweep_callcount;
|
|
|
|
static CppGCMainThreadIncrementalSweep CppGCMainThreadIncrementalSweep_event;
|
2021-01-22 14:16:15 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
// static
|
2021-01-27 22:47:52 +00:00
|
|
|
size_t MetricRecorderImpl::CppGCFullCycle_callcount = 0u;
|
|
|
|
MetricRecorderImpl::CppGCFullCycle MetricRecorderImpl::CppGCFullCycle_event;
|
|
|
|
size_t MetricRecorderImpl::CppGCMainThreadIncrementalMark_callcount = 0u;
|
|
|
|
MetricRecorderImpl::CppGCMainThreadIncrementalMark
|
|
|
|
MetricRecorderImpl::CppGCMainThreadIncrementalMark_event;
|
|
|
|
size_t MetricRecorderImpl::CppGCMainThreadIncrementalSweep_callcount = 0u;
|
|
|
|
MetricRecorderImpl::CppGCMainThreadIncrementalSweep
|
|
|
|
MetricRecorderImpl::CppGCMainThreadIncrementalSweep_event;
|
2021-01-22 14:16:15 +00:00
|
|
|
|
|
|
|
class MetricRecorderTest : public testing::TestWithHeap {
|
|
|
|
public:
|
|
|
|
MetricRecorderTest() : stats(Heap::From(GetHeap())->stats_collector()) {
|
|
|
|
stats->SetMetricRecorderForTesting(std::make_unique<MetricRecorderImpl>());
|
|
|
|
}
|
|
|
|
|
|
|
|
void StartGC() {
|
|
|
|
stats->NotifyMarkingStarted(
|
|
|
|
GarbageCollector::Config::CollectionType::kMajor,
|
|
|
|
GarbageCollector::Config::IsForcedGC::kNotForced);
|
|
|
|
}
|
|
|
|
void EndGC(size_t marked_bytes) {
|
|
|
|
stats->NotifyMarkingCompleted(marked_bytes);
|
|
|
|
stats->NotifySweepingCompleted();
|
|
|
|
}
|
|
|
|
|
|
|
|
StatsCollector* stats;
|
|
|
|
};
|
|
|
|
} // namespace
|
|
|
|
|
|
|
|
TEST_F(MetricRecorderTest, IncrementalScopesReportedImmediately) {
|
2021-01-27 22:47:52 +00:00
|
|
|
MetricRecorderImpl::CppGCFullCycle_callcount = 0u;
|
|
|
|
MetricRecorderImpl::CppGCMainThreadIncrementalMark_callcount = 0u;
|
|
|
|
MetricRecorderImpl::CppGCMainThreadIncrementalSweep_callcount = 0u;
|
2021-01-22 14:16:15 +00:00
|
|
|
StartGC();
|
|
|
|
{
|
2021-01-27 22:47:52 +00:00
|
|
|
EXPECT_EQ(0u, MetricRecorderImpl::CppGCMainThreadIncrementalMark_callcount);
|
2021-01-22 14:16:15 +00:00
|
|
|
{
|
2021-02-15 16:13:38 +00:00
|
|
|
StatsCollector::EnabledScope scope(
|
|
|
|
Heap::From(GetHeap())->stats_collector(),
|
|
|
|
StatsCollector::kIncrementalMark);
|
2021-01-22 14:16:15 +00:00
|
|
|
scope.DecreaseStartTimeForTesting(
|
|
|
|
v8::base::TimeDelta::FromMilliseconds(1));
|
|
|
|
}
|
2021-01-27 22:47:52 +00:00
|
|
|
EXPECT_EQ(1u, MetricRecorderImpl::CppGCMainThreadIncrementalMark_callcount);
|
2021-01-22 14:16:15 +00:00
|
|
|
EXPECT_LT(
|
|
|
|
0u,
|
2021-01-27 22:47:52 +00:00
|
|
|
MetricRecorderImpl::CppGCMainThreadIncrementalMark_event.duration_us);
|
2021-01-22 14:16:15 +00:00
|
|
|
}
|
|
|
|
{
|
|
|
|
EXPECT_EQ(0u,
|
2021-01-27 22:47:52 +00:00
|
|
|
MetricRecorderImpl::CppGCMainThreadIncrementalSweep_callcount);
|
2021-01-22 14:16:15 +00:00
|
|
|
{
|
2021-02-15 16:13:38 +00:00
|
|
|
StatsCollector::EnabledScope scope(
|
|
|
|
Heap::From(GetHeap())->stats_collector(),
|
|
|
|
StatsCollector::kIncrementalSweep);
|
2021-01-22 14:16:15 +00:00
|
|
|
scope.DecreaseStartTimeForTesting(
|
|
|
|
v8::base::TimeDelta::FromMilliseconds(1));
|
|
|
|
}
|
|
|
|
EXPECT_EQ(1u,
|
2021-01-27 22:47:52 +00:00
|
|
|
MetricRecorderImpl::CppGCMainThreadIncrementalSweep_callcount);
|
|
|
|
EXPECT_LT(
|
|
|
|
0u,
|
|
|
|
MetricRecorderImpl::CppGCMainThreadIncrementalSweep_event.duration_us);
|
2021-01-22 14:16:15 +00:00
|
|
|
}
|
2021-01-27 22:47:52 +00:00
|
|
|
EXPECT_EQ(0u, MetricRecorderImpl::CppGCFullCycle_callcount);
|
2021-01-22 14:16:15 +00:00
|
|
|
EndGC(0);
|
|
|
|
}
|
|
|
|
|
2021-01-27 22:47:52 +00:00
|
|
|
TEST_F(MetricRecorderTest, NonIncrementlaScopesNotReportedImmediately) {
|
|
|
|
MetricRecorderImpl::CppGCFullCycle_callcount = 0u;
|
|
|
|
MetricRecorderImpl::CppGCMainThreadIncrementalMark_callcount = 0u;
|
|
|
|
MetricRecorderImpl::CppGCMainThreadIncrementalSweep_callcount = 0u;
|
2021-01-22 14:16:15 +00:00
|
|
|
StartGC();
|
|
|
|
{
|
2021-02-15 16:13:38 +00:00
|
|
|
StatsCollector::EnabledScope scope(Heap::From(GetHeap())->stats_collector(),
|
2021-01-22 14:16:15 +00:00
|
|
|
StatsCollector::kAtomicMark);
|
|
|
|
}
|
|
|
|
{
|
2021-02-15 16:13:38 +00:00
|
|
|
StatsCollector::EnabledScope scope(Heap::From(GetHeap())->stats_collector(),
|
2021-01-22 14:16:15 +00:00
|
|
|
StatsCollector::kAtomicWeak);
|
|
|
|
}
|
|
|
|
{
|
2021-02-15 16:13:38 +00:00
|
|
|
StatsCollector::EnabledScope scope(Heap::From(GetHeap())->stats_collector(),
|
2021-01-22 14:16:15 +00:00
|
|
|
StatsCollector::kAtomicCompact);
|
|
|
|
}
|
|
|
|
{
|
2021-02-15 16:13:38 +00:00
|
|
|
StatsCollector::EnabledScope scope(Heap::From(GetHeap())->stats_collector(),
|
2021-01-22 14:16:15 +00:00
|
|
|
StatsCollector::kAtomicSweep);
|
|
|
|
}
|
2021-01-27 22:47:52 +00:00
|
|
|
{
|
|
|
|
StatsCollector::EnabledConcurrentScope scope(
|
2021-02-15 16:13:38 +00:00
|
|
|
Heap::From(GetHeap())->stats_collector(),
|
|
|
|
StatsCollector::kConcurrentMark);
|
2021-01-27 22:47:52 +00:00
|
|
|
}
|
|
|
|
{
|
|
|
|
StatsCollector::EnabledConcurrentScope scope(
|
2021-02-15 16:13:38 +00:00
|
|
|
Heap::From(GetHeap())->stats_collector(),
|
|
|
|
StatsCollector::kConcurrentSweep);
|
2021-01-27 22:47:52 +00:00
|
|
|
}
|
|
|
|
EXPECT_EQ(0u, MetricRecorderImpl::CppGCMainThreadIncrementalMark_callcount);
|
|
|
|
EXPECT_EQ(0u, MetricRecorderImpl::CppGCMainThreadIncrementalSweep_callcount);
|
|
|
|
EXPECT_EQ(0u, MetricRecorderImpl::CppGCFullCycle_callcount);
|
2021-01-22 14:16:15 +00:00
|
|
|
EndGC(0);
|
|
|
|
}
|
|
|
|
|
2021-01-22 16:34:29 +00:00
|
|
|
TEST_F(MetricRecorderTest, CycleEndMetricsReportedOnGcEnd) {
|
2021-01-27 22:47:52 +00:00
|
|
|
MetricRecorderImpl::CppGCFullCycle_callcount = 0u;
|
|
|
|
MetricRecorderImpl::CppGCMainThreadIncrementalMark_callcount = 0u;
|
|
|
|
MetricRecorderImpl::CppGCMainThreadIncrementalSweep_callcount = 0u;
|
2021-01-22 14:16:15 +00:00
|
|
|
StartGC();
|
|
|
|
EndGC(0);
|
2021-01-27 22:47:52 +00:00
|
|
|
EXPECT_EQ(0u, MetricRecorderImpl::CppGCMainThreadIncrementalMark_callcount);
|
|
|
|
EXPECT_EQ(0u, MetricRecorderImpl::CppGCMainThreadIncrementalSweep_callcount);
|
|
|
|
EXPECT_EQ(1u, MetricRecorderImpl::CppGCFullCycle_callcount);
|
2021-01-22 14:16:15 +00:00
|
|
|
}
|
|
|
|
|
2021-01-27 22:47:52 +00:00
|
|
|
TEST_F(MetricRecorderTest, CycleEndHistogramReportsCorrectValues) {
|
|
|
|
StartGC();
|
|
|
|
EndGC(1000);
|
|
|
|
StartGC();
|
2021-01-22 14:16:15 +00:00
|
|
|
{
|
2021-02-15 16:13:38 +00:00
|
|
|
StatsCollector::EnabledScope scope(Heap::From(GetHeap())->stats_collector(),
|
2021-01-27 22:47:52 +00:00
|
|
|
StatsCollector::kIncrementalMark);
|
|
|
|
scope.DecreaseStartTimeForTesting(
|
|
|
|
v8::base::TimeDelta::FromMilliseconds(10));
|
2021-01-22 14:16:15 +00:00
|
|
|
}
|
|
|
|
{
|
2021-02-15 16:13:38 +00:00
|
|
|
StatsCollector::EnabledScope scope(Heap::From(GetHeap())->stats_collector(),
|
2021-01-27 22:47:52 +00:00
|
|
|
StatsCollector::kIncrementalSweep);
|
|
|
|
scope.DecreaseStartTimeForTesting(
|
|
|
|
v8::base::TimeDelta::FromMilliseconds(20));
|
2021-01-22 14:16:15 +00:00
|
|
|
}
|
|
|
|
{
|
2021-02-15 16:13:38 +00:00
|
|
|
StatsCollector::EnabledScope scope(Heap::From(GetHeap())->stats_collector(),
|
2021-01-27 22:47:52 +00:00
|
|
|
StatsCollector::kAtomicMark);
|
|
|
|
scope.DecreaseStartTimeForTesting(
|
|
|
|
v8::base::TimeDelta::FromMilliseconds(30));
|
2021-01-22 14:16:15 +00:00
|
|
|
}
|
|
|
|
{
|
2021-02-15 16:13:38 +00:00
|
|
|
StatsCollector::EnabledScope scope(Heap::From(GetHeap())->stats_collector(),
|
2021-01-27 22:47:52 +00:00
|
|
|
StatsCollector::kAtomicWeak);
|
|
|
|
scope.DecreaseStartTimeForTesting(
|
|
|
|
v8::base::TimeDelta::FromMilliseconds(50));
|
2021-01-22 14:16:15 +00:00
|
|
|
}
|
|
|
|
{
|
2021-02-15 16:13:38 +00:00
|
|
|
StatsCollector::EnabledScope scope(Heap::From(GetHeap())->stats_collector(),
|
2021-01-27 22:47:52 +00:00
|
|
|
StatsCollector::kAtomicCompact);
|
|
|
|
scope.DecreaseStartTimeForTesting(
|
|
|
|
v8::base::TimeDelta::FromMilliseconds(60));
|
2021-01-22 14:16:15 +00:00
|
|
|
}
|
|
|
|
{
|
2021-02-15 16:13:38 +00:00
|
|
|
StatsCollector::EnabledScope scope(Heap::From(GetHeap())->stats_collector(),
|
2021-01-27 22:47:52 +00:00
|
|
|
StatsCollector::kAtomicSweep);
|
|
|
|
scope.DecreaseStartTimeForTesting(
|
|
|
|
v8::base::TimeDelta::FromMilliseconds(70));
|
2021-01-22 14:16:15 +00:00
|
|
|
}
|
|
|
|
{
|
2021-01-27 22:47:52 +00:00
|
|
|
StatsCollector::EnabledConcurrentScope scope(
|
2021-02-15 16:13:38 +00:00
|
|
|
Heap::From(GetHeap())->stats_collector(),
|
|
|
|
StatsCollector::kConcurrentMark);
|
2021-01-27 22:47:52 +00:00
|
|
|
scope.DecreaseStartTimeForTesting(
|
|
|
|
v8::base::TimeDelta::FromMilliseconds(80));
|
2021-01-22 14:16:15 +00:00
|
|
|
}
|
|
|
|
{
|
2021-01-27 22:47:52 +00:00
|
|
|
StatsCollector::EnabledConcurrentScope scope(
|
2021-02-15 16:13:38 +00:00
|
|
|
Heap::From(GetHeap())->stats_collector(),
|
|
|
|
StatsCollector::kConcurrentSweep);
|
2021-01-27 22:47:52 +00:00
|
|
|
scope.DecreaseStartTimeForTesting(
|
|
|
|
v8::base::TimeDelta::FromMilliseconds(100));
|
2021-01-22 14:16:15 +00:00
|
|
|
}
|
2021-01-27 22:47:52 +00:00
|
|
|
EndGC(300);
|
|
|
|
// Check durations.
|
2021-01-29 10:27:42 +00:00
|
|
|
static constexpr int64_t kDurationComparisonTolerance = 500;
|
2021-01-27 22:47:52 +00:00
|
|
|
EXPECT_LT(std::abs(MetricRecorderImpl::CppGCFullCycle_event
|
|
|
|
.main_thread_incremental.mark_duration_us -
|
|
|
|
10000),
|
|
|
|
kDurationComparisonTolerance);
|
|
|
|
EXPECT_LT(std::abs(MetricRecorderImpl::CppGCFullCycle_event
|
|
|
|
.main_thread_incremental.sweep_duration_us -
|
|
|
|
20000),
|
|
|
|
kDurationComparisonTolerance);
|
|
|
|
EXPECT_LT(std::abs(MetricRecorderImpl::CppGCFullCycle_event.main_thread_atomic
|
|
|
|
.mark_duration_us -
|
|
|
|
30000),
|
|
|
|
kDurationComparisonTolerance);
|
|
|
|
EXPECT_LT(std::abs(MetricRecorderImpl::CppGCFullCycle_event.main_thread_atomic
|
|
|
|
.weak_duration_us -
|
|
|
|
50000),
|
|
|
|
kDurationComparisonTolerance);
|
|
|
|
EXPECT_LT(std::abs(MetricRecorderImpl::CppGCFullCycle_event.main_thread_atomic
|
|
|
|
.compact_duration_us -
|
|
|
|
60000),
|
|
|
|
kDurationComparisonTolerance);
|
|
|
|
EXPECT_LT(std::abs(MetricRecorderImpl::CppGCFullCycle_event.main_thread_atomic
|
|
|
|
.sweep_duration_us -
|
|
|
|
70000),
|
|
|
|
kDurationComparisonTolerance);
|
|
|
|
EXPECT_LT(std::abs(MetricRecorderImpl::CppGCFullCycle_event.main_thread
|
|
|
|
.mark_duration_us -
|
|
|
|
40000),
|
|
|
|
kDurationComparisonTolerance);
|
|
|
|
EXPECT_LT(std::abs(MetricRecorderImpl::CppGCFullCycle_event.main_thread
|
|
|
|
.weak_duration_us -
|
|
|
|
50000),
|
|
|
|
kDurationComparisonTolerance);
|
|
|
|
EXPECT_LT(std::abs(MetricRecorderImpl::CppGCFullCycle_event.main_thread
|
|
|
|
.compact_duration_us -
|
|
|
|
60000),
|
|
|
|
kDurationComparisonTolerance);
|
|
|
|
EXPECT_LT(std::abs(MetricRecorderImpl::CppGCFullCycle_event.main_thread
|
|
|
|
.sweep_duration_us -
|
|
|
|
90000),
|
|
|
|
kDurationComparisonTolerance);
|
|
|
|
EXPECT_LT(
|
|
|
|
std::abs(MetricRecorderImpl::CppGCFullCycle_event.total.mark_duration_us -
|
|
|
|
120000),
|
|
|
|
kDurationComparisonTolerance);
|
|
|
|
EXPECT_LT(
|
|
|
|
std::abs(MetricRecorderImpl::CppGCFullCycle_event.total.weak_duration_us -
|
|
|
|
50000),
|
|
|
|
kDurationComparisonTolerance);
|
|
|
|
EXPECT_LT(
|
|
|
|
std::abs(
|
|
|
|
MetricRecorderImpl::CppGCFullCycle_event.total.compact_duration_us -
|
|
|
|
60000),
|
|
|
|
kDurationComparisonTolerance);
|
|
|
|
EXPECT_LT(
|
|
|
|
std::abs(
|
|
|
|
MetricRecorderImpl::CppGCFullCycle_event.total.sweep_duration_us -
|
|
|
|
190000),
|
|
|
|
kDurationComparisonTolerance);
|
|
|
|
// Check collection rate and efficiency.
|
|
|
|
EXPECT_DOUBLE_EQ(
|
|
|
|
0.3, MetricRecorderImpl::CppGCFullCycle_event.collection_rate_in_percent);
|
|
|
|
static constexpr double kEfficiencyComparisonTolerance = 0.00001;
|
|
|
|
EXPECT_LT(
|
|
|
|
std::abs(
|
|
|
|
MetricRecorderImpl::CppGCFullCycle_event.efficiency_in_bytes_per_us -
|
|
|
|
(700.0 / (120000 + 50000 + 60000 + 190000))),
|
|
|
|
kEfficiencyComparisonTolerance);
|
|
|
|
EXPECT_LT(std::abs(MetricRecorderImpl::CppGCFullCycle_event
|
|
|
|
.main_thread_efficiency_in_bytes_per_us -
|
|
|
|
(700.0 / (40000 + 50000 + 60000 + 90000))),
|
|
|
|
kEfficiencyComparisonTolerance);
|
2021-01-22 14:16:15 +00:00
|
|
|
}
|
|
|
|
|
2021-01-22 16:34:29 +00:00
|
|
|
TEST_F(MetricRecorderTest, ObjectSizeMetricsNoAllocations) {
|
|
|
|
// Populate previous event.
|
|
|
|
StartGC();
|
|
|
|
EndGC(1000);
|
|
|
|
// Populate current event.
|
|
|
|
StartGC();
|
|
|
|
EndGC(800);
|
2021-01-27 22:47:52 +00:00
|
|
|
EXPECT_EQ(1000u,
|
|
|
|
MetricRecorderImpl::CppGCFullCycle_event.objects.before_bytes);
|
|
|
|
EXPECT_EQ(800u, MetricRecorderImpl::CppGCFullCycle_event.objects.after_bytes);
|
|
|
|
EXPECT_EQ(200u, MetricRecorderImpl::CppGCFullCycle_event.objects.freed_bytes);
|
|
|
|
EXPECT_EQ(0u, MetricRecorderImpl::CppGCFullCycle_event.memory.before_bytes);
|
|
|
|
EXPECT_EQ(0u, MetricRecorderImpl::CppGCFullCycle_event.memory.after_bytes);
|
|
|
|
EXPECT_EQ(0u, MetricRecorderImpl::CppGCFullCycle_event.memory.freed_bytes);
|
2021-01-22 16:34:29 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
TEST_F(MetricRecorderTest, ObjectSizeMetricsWithAllocations) {
|
|
|
|
// Populate previous event.
|
|
|
|
StartGC();
|
|
|
|
EndGC(1000);
|
|
|
|
// Populate current event.
|
|
|
|
StartGC();
|
|
|
|
stats->NotifyAllocation(300);
|
2021-01-27 14:12:56 +00:00
|
|
|
stats->NotifyAllocatedMemory(1400);
|
2021-01-22 16:34:29 +00:00
|
|
|
stats->NotifyFreedMemory(700);
|
|
|
|
stats->NotifyMarkingCompleted(800);
|
|
|
|
stats->NotifyAllocation(150);
|
2021-01-27 14:12:56 +00:00
|
|
|
stats->NotifyAllocatedMemory(1000);
|
2021-01-22 16:34:29 +00:00
|
|
|
stats->NotifyFreedMemory(400);
|
|
|
|
stats->NotifySweepingCompleted();
|
2021-01-27 22:47:52 +00:00
|
|
|
EXPECT_EQ(1300u,
|
|
|
|
MetricRecorderImpl::CppGCFullCycle_event.objects.before_bytes);
|
|
|
|
EXPECT_EQ(800, MetricRecorderImpl::CppGCFullCycle_event.objects.after_bytes);
|
|
|
|
EXPECT_EQ(500u, MetricRecorderImpl::CppGCFullCycle_event.objects.freed_bytes);
|
|
|
|
EXPECT_EQ(700u, MetricRecorderImpl::CppGCFullCycle_event.memory.before_bytes);
|
|
|
|
EXPECT_EQ(300u, MetricRecorderImpl::CppGCFullCycle_event.memory.after_bytes);
|
|
|
|
EXPECT_EQ(400u, MetricRecorderImpl::CppGCFullCycle_event.memory.freed_bytes);
|
2021-01-22 16:34:29 +00:00
|
|
|
}
|
|
|
|
|
2021-01-22 14:16:15 +00:00
|
|
|
} // namespace internal
|
|
|
|
} // namespace cppgc
|