Commit 4f4b4f74 authored by Omer Katz's avatar Omer Katz Committed by V8 LUCI CQ

cppgc-js: Add unittest for CollectCustomSpaceStatisticsAtLastGC

Drive-by: fix delayed task implementation in cpp-heap.cc.

Bug: chromium:1056170
Change-Id: Ie92d909056532047b378ebfafeb98273997e60e9
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2883618
Commit-Queue: Omer Katz <omerkatz@chromium.org>
Reviewed-by: 's avatarMichael Lippautz <mlippautz@chromium.org>
Cr-Commit-Position: refs/heads/master@{#74530}
parent e348fe2f
...@@ -521,14 +521,18 @@ class CollectCustomSpaceStatisticsAtLastGCTask final : public v8::Task { ...@@ -521,14 +521,18 @@ class CollectCustomSpaceStatisticsAtLastGCTask final : public v8::Task {
void Run() final { void Run() final {
cppgc::internal::Sweeper& sweeper = heap_.sweeper(); cppgc::internal::Sweeper& sweeper = heap_.sweeper();
if (sweeper.PerformSweepOnMutatorThread(kStepSizeMs.InSecondsF())) { if (sweeper.PerformSweepOnMutatorThread(
heap_.platform()->MonotonicallyIncreasingTime() +
kStepSizeMs.InSecondsF())) {
// Sweeping is done.
DCHECK(!sweeper.IsSweepingInProgress());
ReportCustomSpaceStatistics(heap_.raw_heap(), std::move(custom_spaces_),
std::move(receiver_));
} else {
heap_.platform()->GetForegroundTaskRunner()->PostDelayedTask( heap_.platform()->GetForegroundTaskRunner()->PostDelayedTask(
std::make_unique<CollectCustomSpaceStatisticsAtLastGCTask>( std::make_unique<CollectCustomSpaceStatisticsAtLastGCTask>(
heap_, std::move(custom_spaces_), std::move(receiver_)), heap_, std::move(custom_spaces_), std::move(receiver_)),
kTaskDelayMs.InSecondsF()); kTaskDelayMs.InSecondsF());
} else {
ReportCustomSpaceStatistics(heap_.raw_heap(), std::move(custom_spaces_),
std::move(receiver_));
} }
} }
......
...@@ -2,15 +2,20 @@ ...@@ -2,15 +2,20 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
#include <memory>
#include "include/cppgc/allocation.h" #include "include/cppgc/allocation.h"
#include "include/cppgc/garbage-collected.h" #include "include/cppgc/garbage-collected.h"
#include "include/cppgc/persistent.h" #include "include/cppgc/persistent.h"
#include "include/cppgc/platform.h" #include "include/cppgc/platform.h"
#include "include/cppgc/testing.h" #include "include/cppgc/testing.h"
#include "include/libplatform/libplatform.h"
#include "include/v8-cppgc.h" #include "include/v8-cppgc.h"
#include "include/v8.h" #include "include/v8.h"
#include "src/api/api-inl.h" #include "src/api/api-inl.h"
#include "src/base/platform/time.h"
#include "src/heap/cppgc-js/cpp-heap.h" #include "src/heap/cppgc-js/cpp-heap.h"
#include "src/heap/cppgc/heap-object-header.h"
#include "src/heap/cppgc/sweeper.h" #include "src/heap/cppgc/sweeper.h"
#include "src/objects/objects-inl.h" #include "src/objects/objects-inl.h"
#include "test/unittests/heap/heap-utils.h" #include "test/unittests/heap/heap-utils.h"
...@@ -191,3 +196,132 @@ TEST_F(UnifiedHeapDetachedTest, StandaloneTestingHeap) { ...@@ -191,3 +196,132 @@ TEST_F(UnifiedHeapDetachedTest, StandaloneTestingHeap) {
} // namespace internal } // namespace internal
} // namespace v8 } // namespace v8
namespace cppgc {
class CustomSpaceForTest : public CustomSpace<CustomSpaceForTest> {
public:
static constexpr size_t kSpaceIndex = 0;
};
constexpr size_t CustomSpaceForTest::kSpaceIndex;
} // namespace cppgc
namespace v8 {
namespace internal {
namespace {
class StatisticsReceiver final : public CustomSpaceStatisticsReceiver {
public:
static size_t num_calls_;
StatisticsReceiver(cppgc::CustomSpaceIndex space_index, size_t bytes)
: expected_space_index_(space_index), expected_bytes_(bytes) {}
void AllocatedBytes(cppgc::CustomSpaceIndex space_index, size_t bytes) final {
EXPECT_EQ(expected_space_index_.value, space_index.value);
EXPECT_EQ(expected_bytes_, bytes);
++num_calls_;
}
private:
const cppgc::CustomSpaceIndex expected_space_index_;
const size_t expected_bytes_;
};
size_t StatisticsReceiver::num_calls_ = 0u;
class GCed final : public cppgc::GarbageCollected<GCed> {
public:
~GCed() {
// Force a finalizer to guarantee sweeping can't finish without the main
// thread.
USE(data_);
}
static size_t GetAllocatedSize() {
return sizeof(GCed) + sizeof(cppgc::internal::HeapObjectHeader);
}
void Trace(cppgc::Visitor*) const {}
private:
char data_[KB];
};
} // namespace
} // namespace internal
} // namespace v8
namespace cppgc {
template <>
struct SpaceTrait<v8::internal::GCed> {
using Space = CustomSpaceForTest;
};
} // namespace cppgc
namespace v8 {
namespace internal {
namespace {
class UnifiedHeapWithCustomSpaceTest : public UnifiedHeapTest {
public:
static std::vector<std::unique_ptr<cppgc::CustomSpaceBase>>
GetCustomSpaces() {
std::vector<std::unique_ptr<cppgc::CustomSpaceBase>> custom_spaces;
custom_spaces.emplace_back(std::make_unique<cppgc::CustomSpaceForTest>());
return custom_spaces;
}
UnifiedHeapWithCustomSpaceTest() : UnifiedHeapTest(GetCustomSpaces()) {}
};
} // namespace
TEST_F(UnifiedHeapWithCustomSpaceTest, CollectCustomSpaceStatisticsAtLastGC) {
StatisticsReceiver::num_calls_ = 0;
// Initial state.
cpp_heap().CollectCustomSpaceStatisticsAtLastGC(
{cppgc::CustomSpaceForTest::kSpaceIndex},
std::make_unique<StatisticsReceiver>(
cppgc::CustomSpaceForTest::kSpaceIndex, 0u));
EXPECT_EQ(1u, StatisticsReceiver::num_calls_);
// State unpdated only after GC.
cppgc::Persistent<GCed> live_obj =
cppgc::MakeGarbageCollected<GCed>(allocation_handle());
cppgc::MakeGarbageCollected<GCed>(allocation_handle());
cpp_heap().CollectCustomSpaceStatisticsAtLastGC(
{cppgc::CustomSpaceForTest::kSpaceIndex},
std::make_unique<StatisticsReceiver>(
cppgc::CustomSpaceForTest::kSpaceIndex, 0u));
EXPECT_EQ(2u, StatisticsReceiver::num_calls_);
// Check state after GC.
CollectGarbageWithoutEmbedderStack(cppgc::Heap::SweepingType::kAtomic);
cpp_heap().CollectCustomSpaceStatisticsAtLastGC(
{cppgc::CustomSpaceForTest::kSpaceIndex},
std::make_unique<StatisticsReceiver>(
cppgc::CustomSpaceForTest::kSpaceIndex, GCed::GetAllocatedSize()));
EXPECT_EQ(3u, StatisticsReceiver::num_calls_);
// State callback delayed during sweeping.
cppgc::Persistent<GCed> another_live_obj =
cppgc::MakeGarbageCollected<GCed>(allocation_handle());
CollectGarbageWithoutEmbedderStack(
cppgc::Heap::SweepingType::kIncrementalAndConcurrent);
DCHECK(cpp_heap().sweeper().IsSweepingInProgress());
cpp_heap().CollectCustomSpaceStatisticsAtLastGC(
{cppgc::CustomSpaceForTest::kSpaceIndex},
std::make_unique<StatisticsReceiver>(
cppgc::CustomSpaceForTest::kSpaceIndex,
2 * GCed::GetAllocatedSize()));
while (v8::platform::PumpMessageLoop(
V8::GetCurrentPlatform(), v8_isolate(),
v8::platform::MessageLoopBehavior::kWaitForWork)) {
// Execute tasks until sweeping is done.
if (!cpp_heap().sweeper().IsSweepingInProgress()) break;
}
EXPECT_EQ(4u, StatisticsReceiver::num_calls_);
}
} // namespace internal
} // namespace v8
...@@ -15,9 +15,14 @@ namespace v8 { ...@@ -15,9 +15,14 @@ namespace v8 {
namespace internal { namespace internal {
UnifiedHeapTest::UnifiedHeapTest() UnifiedHeapTest::UnifiedHeapTest()
: UnifiedHeapTest(std::vector<std::unique_ptr<cppgc::CustomSpaceBase>>()) {}
UnifiedHeapTest::UnifiedHeapTest(
std::vector<std::unique_ptr<cppgc::CustomSpaceBase>> custom_spaces)
: cpp_heap_(v8::CppHeap::Create( : cpp_heap_(v8::CppHeap::Create(
V8::GetCurrentPlatform(), V8::GetCurrentPlatform(),
CppHeapCreateParams{{}, WrapperHelper::DefaultWrapperDescriptor()})) { CppHeapCreateParams{std::move(custom_spaces),
WrapperHelper::DefaultWrapperDescriptor()})) {
isolate()->heap()->AttachCppHeap(cpp_heap_.get()); isolate()->heap()->AttachCppHeap(cpp_heap_.get());
} }
......
...@@ -21,6 +21,8 @@ class CppHeap; ...@@ -21,6 +21,8 @@ class CppHeap;
class UnifiedHeapTest : public TestWithHeapInternals { class UnifiedHeapTest : public TestWithHeapInternals {
public: public:
UnifiedHeapTest(); UnifiedHeapTest();
explicit UnifiedHeapTest(
std::vector<std::unique_ptr<cppgc::CustomSpaceBase>>);
~UnifiedHeapTest() override = default; ~UnifiedHeapTest() override = default;
void CollectGarbageWithEmbedderStack(cppgc::Heap::SweepingType sweeping_type = void CollectGarbageWithEmbedderStack(cppgc::Heap::SweepingType sweeping_type =
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment