Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/nodejs/node.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'deps/v8/test/unittests/heap/cppgc/gc-info-unittest.cc')
-rw-r--r--deps/v8/test/unittests/heap/cppgc/gc-info-unittest.cc153
1 files changed, 153 insertions, 0 deletions
diff --git a/deps/v8/test/unittests/heap/cppgc/gc-info-unittest.cc b/deps/v8/test/unittests/heap/cppgc/gc-info-unittest.cc
new file mode 100644
index 00000000000..199b42daca7
--- /dev/null
+++ b/deps/v8/test/unittests/heap/cppgc/gc-info-unittest.cc
@@ -0,0 +1,153 @@
+// 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 "include/cppgc/internal/gc-info.h"
+
+#include "include/cppgc/platform.h"
+#include "src/base/page-allocator.h"
+#include "src/base/platform/platform.h"
+#include "src/heap/cppgc/gc-info-table.h"
+#include "test/unittests/heap/cppgc/tests.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace cppgc {
+namespace internal {
+
+TEST(GCInfoTableTest, InitialEmpty) {
+ v8::base::PageAllocator page_allocator;
+ GCInfoTable table(&page_allocator);
+ EXPECT_EQ(GCInfoTable::kMinIndex, table.NumberOfGCInfosForTesting());
+}
+
+TEST(GCInfoTableTest, ResizeToMaxIndex) {
+ v8::base::PageAllocator page_allocator;
+ GCInfoTable table(&page_allocator);
+ GCInfo info = {nullptr, false};
+ for (GCInfoIndex i = GCInfoTable::kMinIndex; i < GCInfoTable::kMaxIndex;
+ i++) {
+ GCInfoIndex index = table.RegisterNewGCInfo(info);
+ EXPECT_EQ(i, index);
+ }
+}
+
+TEST(GCInfoTableDeathTest, MoreThanMaxIndexInfos) {
+ v8::base::PageAllocator page_allocator;
+ GCInfoTable table(&page_allocator);
+ GCInfo info = {nullptr, false};
+ // Create GCInfoTable::kMaxIndex entries.
+ for (GCInfoIndex i = GCInfoTable::kMinIndex; i < GCInfoTable::kMaxIndex;
+ i++) {
+ table.RegisterNewGCInfo(info);
+ }
+ EXPECT_DEATH_IF_SUPPORTED(table.RegisterNewGCInfo(info), "");
+}
+
+TEST(GCInfoTableDeathTest, OldTableAreaIsReadOnly) {
+ v8::base::PageAllocator page_allocator;
+ GCInfoTable table(&page_allocator);
+ GCInfo info = {nullptr, false};
+ // Use up all slots until limit.
+ GCInfoIndex limit = table.LimitForTesting();
+ // Bail out if initial limit is already the maximum because of large committed
+ // pages. In this case, nothing can be comitted as read-only.
+ if (limit == GCInfoTable::kMaxIndex) {
+ return;
+ }
+ for (GCInfoIndex i = GCInfoTable::kMinIndex; i < limit; i++) {
+ table.RegisterNewGCInfo(info);
+ }
+ EXPECT_EQ(limit, table.LimitForTesting());
+ table.RegisterNewGCInfo(info);
+ EXPECT_NE(limit, table.LimitForTesting());
+ // Old area is now read-only.
+ auto& first_slot = table.TableSlotForTesting(GCInfoTable::kMinIndex);
+ EXPECT_DEATH_IF_SUPPORTED(first_slot.finalize = nullptr, "");
+}
+
+namespace {
+
+class ThreadRegisteringGCInfoObjects final : public v8::base::Thread {
+ public:
+ ThreadRegisteringGCInfoObjects(GCInfoTable* table,
+ GCInfoIndex num_registrations)
+ : v8::base::Thread(Options("Thread registering GCInfo objects.")),
+ table_(table),
+ num_registrations_(num_registrations) {}
+
+ void Run() final {
+ GCInfo info = {nullptr, false};
+ for (GCInfoIndex i = 0; i < num_registrations_; i++) {
+ table_->RegisterNewGCInfo(info);
+ }
+ }
+
+ private:
+ GCInfoTable* table_;
+ GCInfoIndex num_registrations_;
+};
+
+} // namespace
+
+TEST(GCInfoTableTest, MultiThreadedResizeToMaxIndex) {
+ constexpr size_t num_threads = 4;
+ constexpr size_t main_thread_initialized = 2;
+ constexpr size_t gc_infos_to_register =
+ (GCInfoTable::kMaxIndex - 1) -
+ (GCInfoTable::kMinIndex + main_thread_initialized);
+ static_assert(gc_infos_to_register % num_threads == 0,
+ "must sum up to kMaxIndex");
+ constexpr size_t gc_infos_per_thread = gc_infos_to_register / num_threads;
+
+ v8::base::PageAllocator page_allocator;
+ GCInfoTable table(&page_allocator);
+ GCInfo info = {nullptr, false};
+ for (size_t i = 0; i < main_thread_initialized; i++) {
+ table.RegisterNewGCInfo(info);
+ }
+
+ v8::base::Thread* threads[num_threads];
+ for (size_t i = 0; i < num_threads; i++) {
+ threads[i] =
+ new ThreadRegisteringGCInfoObjects(&table, gc_infos_per_thread);
+ }
+ for (size_t i = 0; i < num_threads; i++) {
+ CHECK(threads[i]->Start());
+ }
+ for (size_t i = 0; i < num_threads; i++) {
+ threads[i]->Join();
+ delete threads[i];
+ }
+}
+
+// Tests using the global table and GCInfoTrait.
+
+namespace {
+
+class GCInfoTraitTest : public testing::TestWithPlatform {};
+
+class BasicType final {};
+class OtherBasicType final {};
+
+} // namespace
+
+TEST_F(GCInfoTraitTest, IndexInBounds) {
+ const GCInfoIndex index = GCInfoTrait<BasicType>::Index();
+ EXPECT_GT(GCInfoTable::kMaxIndex, index);
+ EXPECT_LE(GCInfoTable::kMinIndex, index);
+}
+
+TEST_F(GCInfoTraitTest, TraitReturnsSameIndexForSameType) {
+ const GCInfoIndex index1 = GCInfoTrait<BasicType>::Index();
+ const GCInfoIndex index2 = GCInfoTrait<BasicType>::Index();
+ EXPECT_EQ(index1, index2);
+}
+
+TEST_F(GCInfoTraitTest, TraitReturnsDifferentIndexForDifferentTypes) {
+ const GCInfoIndex index1 = GCInfoTrait<BasicType>::Index();
+ const GCInfoIndex index2 = GCInfoTrait<OtherBasicType>::Index();
+ EXPECT_NE(index1, index2);
+}
+
+} // namespace internal
+} // namespace cppgc