mirror of
https://github.com/nodejs/node.git
synced 2025-05-15 17:51:35 +00:00

PR-URL: https://github.com/nodejs/node/pull/49639 Reviewed-By: Jiawen Geng <technicalcute@gmail.com> Reviewed-By: Rafael Gonzaga <rafael.nunu@hotmail.com> Reviewed-By: Antoine du Hamel <duhamelantoine1995@gmail.com>
149 lines
6.7 KiB
C++
149 lines
6.7 KiB
C++
// 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/base/incremental-marking-schedule.h"
|
|
|
|
#include "src/base/platform/time.h"
|
|
#include "testing/gtest/include/gtest/gtest.h"
|
|
|
|
namespace heap::base {
|
|
|
|
namespace {
|
|
|
|
constexpr size_t kZeroBytesStep = 0;
|
|
|
|
class IncrementalMarkingScheduleTest : public ::testing::Test {
|
|
public:
|
|
static constexpr size_t kEstimatedLiveSize =
|
|
100 *
|
|
IncrementalMarkingSchedule::kDefaultMinimumMarkedBytesPerIncrementalStep;
|
|
};
|
|
|
|
const v8::base::TimeDelta kHalfEstimatedMarkingTime =
|
|
v8::base::TimeDelta::FromMillisecondsD(
|
|
IncrementalMarkingSchedule::kEstimatedMarkingTime.InMillisecondsF() *
|
|
0.5);
|
|
|
|
} // namespace
|
|
|
|
TEST_F(IncrementalMarkingScheduleTest, FirstStepReturnsDefaultDuration) {
|
|
auto schedule =
|
|
IncrementalMarkingSchedule::CreateWithDefaultMinimumMarkedBytesPerStep();
|
|
schedule->NotifyIncrementalMarkingStart();
|
|
schedule->SetElapsedTimeForTesting(v8::base::TimeDelta::FromMilliseconds(0));
|
|
EXPECT_EQ(
|
|
IncrementalMarkingSchedule::kDefaultMinimumMarkedBytesPerIncrementalStep,
|
|
schedule->GetNextIncrementalStepDuration(kEstimatedLiveSize));
|
|
}
|
|
|
|
TEST_F(IncrementalMarkingScheduleTest, EmptyStepDuration) {
|
|
auto schedule =
|
|
IncrementalMarkingSchedule::CreateWithZeroMinimumMarkedBytesPerStep();
|
|
schedule->NotifyIncrementalMarkingStart();
|
|
schedule->SetElapsedTimeForTesting(v8::base::TimeDelta::FromMilliseconds(0));
|
|
// Make some progress on the marker to avoid returning step size for no
|
|
// progress.
|
|
schedule->UpdateMutatorThreadMarkedBytes(
|
|
IncrementalMarkingSchedule::kStepSizeWhenNotMakingProgress);
|
|
EXPECT_EQ(kZeroBytesStep,
|
|
schedule->GetNextIncrementalStepDuration(kEstimatedLiveSize));
|
|
}
|
|
|
|
// If marking is not behind schedule and very small time passed between steps
|
|
// the oracle should return the minimum step duration.
|
|
TEST_F(IncrementalMarkingScheduleTest, NoTimePassedReturnsMinimumDuration) {
|
|
auto schedule =
|
|
IncrementalMarkingSchedule::CreateWithDefaultMinimumMarkedBytesPerStep();
|
|
schedule->NotifyIncrementalMarkingStart();
|
|
// Add incrementally marked bytes to tell oracle this is not the first step.
|
|
schedule->UpdateMutatorThreadMarkedBytes(
|
|
IncrementalMarkingSchedule::kDefaultMinimumMarkedBytesPerIncrementalStep);
|
|
schedule->SetElapsedTimeForTesting(v8::base::TimeDelta::FromMilliseconds(0));
|
|
EXPECT_EQ(
|
|
IncrementalMarkingSchedule::kDefaultMinimumMarkedBytesPerIncrementalStep,
|
|
schedule->GetNextIncrementalStepDuration(kEstimatedLiveSize));
|
|
}
|
|
|
|
TEST_F(IncrementalMarkingScheduleTest, OracleDoesntExccedMaximumStepDuration) {
|
|
auto schedule =
|
|
IncrementalMarkingSchedule::CreateWithDefaultMinimumMarkedBytesPerStep();
|
|
schedule->NotifyIncrementalMarkingStart();
|
|
// Add incrementally marked bytes to tell oracle this is not the first step.
|
|
// Add at least `kStepSizeWhenNotMakingProgress` bytes or otherwise we'd get
|
|
// the step size for not making progress.
|
|
static constexpr size_t kMarkedBytes =
|
|
IncrementalMarkingSchedule::kStepSizeWhenNotMakingProgress;
|
|
schedule->UpdateMutatorThreadMarkedBytes(kMarkedBytes);
|
|
schedule->SetElapsedTimeForTesting(
|
|
IncrementalMarkingSchedule::kEstimatedMarkingTime);
|
|
EXPECT_EQ(kEstimatedLiveSize - kMarkedBytes,
|
|
schedule->GetNextIncrementalStepDuration(kEstimatedLiveSize));
|
|
}
|
|
|
|
TEST_F(IncrementalMarkingScheduleTest, AheadOfScheduleReturnsMinimumDuration) {
|
|
auto schedule =
|
|
IncrementalMarkingSchedule::CreateWithDefaultMinimumMarkedBytesPerStep();
|
|
schedule->NotifyIncrementalMarkingStart();
|
|
// Add incrementally marked bytes to tell oracle this is not the first step.
|
|
schedule->UpdateMutatorThreadMarkedBytes(
|
|
IncrementalMarkingSchedule::kDefaultMinimumMarkedBytesPerIncrementalStep);
|
|
schedule->AddConcurrentlyMarkedBytes(0.6 * kEstimatedLiveSize);
|
|
schedule->SetElapsedTimeForTesting(kHalfEstimatedMarkingTime);
|
|
EXPECT_EQ(
|
|
IncrementalMarkingSchedule::kDefaultMinimumMarkedBytesPerIncrementalStep,
|
|
schedule->GetNextIncrementalStepDuration(kEstimatedLiveSize));
|
|
}
|
|
|
|
TEST_F(IncrementalMarkingScheduleTest,
|
|
AheadOfScheduleReturnsMinimumDurationZeroStep) {
|
|
auto schedule =
|
|
IncrementalMarkingSchedule::CreateWithZeroMinimumMarkedBytesPerStep();
|
|
schedule->NotifyIncrementalMarkingStart();
|
|
// Add incrementally marked bytes to tell oracle this is not the first step.
|
|
schedule->UpdateMutatorThreadMarkedBytes(
|
|
IncrementalMarkingSchedule::kDefaultMinimumMarkedBytesPerIncrementalStep);
|
|
schedule->AddConcurrentlyMarkedBytes(0.6 * kEstimatedLiveSize);
|
|
schedule->SetElapsedTimeForTesting(kHalfEstimatedMarkingTime);
|
|
EXPECT_EQ(kZeroBytesStep,
|
|
schedule->GetNextIncrementalStepDuration(kEstimatedLiveSize));
|
|
}
|
|
|
|
TEST_F(IncrementalMarkingScheduleTest, BehindScheduleReturnsDelta) {
|
|
auto schedule =
|
|
IncrementalMarkingSchedule::CreateWithDefaultMinimumMarkedBytesPerStep();
|
|
schedule->NotifyIncrementalMarkingStart();
|
|
schedule->UpdateMutatorThreadMarkedBytes(0.1 * kEstimatedLiveSize);
|
|
schedule->AddConcurrentlyMarkedBytes(0.25 * kEstimatedLiveSize);
|
|
schedule->SetElapsedTimeForTesting(kHalfEstimatedMarkingTime);
|
|
EXPECT_EQ(0.15 * kEstimatedLiveSize,
|
|
schedule->GetNextIncrementalStepDuration(kEstimatedLiveSize));
|
|
schedule->AddConcurrentlyMarkedBytes(0.05 * kEstimatedLiveSize);
|
|
schedule->SetElapsedTimeForTesting(kHalfEstimatedMarkingTime);
|
|
EXPECT_EQ(0.1 * kEstimatedLiveSize,
|
|
schedule->GetNextIncrementalStepDuration(kEstimatedLiveSize));
|
|
schedule->AddConcurrentlyMarkedBytes(0.05 * kEstimatedLiveSize);
|
|
schedule->SetElapsedTimeForTesting(kHalfEstimatedMarkingTime);
|
|
EXPECT_EQ(0.05 * kEstimatedLiveSize,
|
|
schedule->GetNextIncrementalStepDuration(kEstimatedLiveSize));
|
|
}
|
|
|
|
TEST_F(IncrementalMarkingScheduleTest, GetCurrentStepInfo) {
|
|
auto schedule =
|
|
IncrementalMarkingSchedule::CreateWithDefaultMinimumMarkedBytesPerStep();
|
|
schedule->NotifyIncrementalMarkingStart();
|
|
schedule->UpdateMutatorThreadMarkedBytes(0.3 * kEstimatedLiveSize);
|
|
schedule->AddConcurrentlyMarkedBytes(0.4 * kEstimatedLiveSize);
|
|
schedule->SetElapsedTimeForTesting(kHalfEstimatedMarkingTime);
|
|
schedule->GetNextIncrementalStepDuration(kEstimatedLiveSize);
|
|
const auto step_info = schedule->GetCurrentStepInfo();
|
|
EXPECT_EQ(step_info.elapsed_time, kHalfEstimatedMarkingTime);
|
|
EXPECT_EQ(step_info.mutator_marked_bytes, 0.3 * kEstimatedLiveSize);
|
|
EXPECT_EQ(step_info.concurrent_marked_bytes, 0.4 * kEstimatedLiveSize);
|
|
EXPECT_EQ(step_info.marked_bytes(), 0.7 * kEstimatedLiveSize);
|
|
EXPECT_EQ(step_info.estimated_live_bytes, kEstimatedLiveSize);
|
|
EXPECT_NE(step_info.scheduled_delta_bytes(), 0);
|
|
}
|
|
|
|
} // namespace heap::base
|