// Copyright 2014 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. #ifdef __linux__ #include #undef MAP_TYPE #endif // __linux__ #include "src/heap/heap-inl.h" #include "src/heap/spaces-inl.h" #include "src/isolate.h" #include "test/unittests/test-utils.h" #include "testing/gtest/include/gtest/gtest.h" namespace v8 { namespace internal { class SequentialUnmapperTest : public TestWithIsolate { public: SequentialUnmapperTest() = default; ~SequentialUnmapperTest() override = default; static void SetUpTestCase() { old_flag_ = i::FLAG_concurrent_sweeping; i::FLAG_concurrent_sweeping = false; TestWithIsolate::SetUpTestCase(); } static void TearDownTestCase() { TestWithIsolate::TearDownTestCase(); i::FLAG_concurrent_sweeping = old_flag_; } Heap* heap() { return isolate()->heap(); } MemoryAllocator* allocator() { return heap()->memory_allocator(); } MemoryAllocator::Unmapper* unmapper() { return allocator()->unmapper(); } private: static bool old_flag_; DISALLOW_COPY_AND_ASSIGN(SequentialUnmapperTest); }; bool SequentialUnmapperTest::old_flag_; #ifdef __linux__ // See v8:5945. TEST_F(SequentialUnmapperTest, UnmapOnTeardownAfterAlreadyFreeingPooled) { Page* page = allocator()->AllocatePage(MemoryAllocator::PageAreaSize(OLD_SPACE), static_cast(heap()->old_space()), Executability::NOT_EXECUTABLE); heap()->old_space()->UnlinkFreeListCategories(page); EXPECT_NE(nullptr, page); const int page_size = getpagesize(); void* start_address = static_cast(page->address()); EXPECT_EQ(0, msync(start_address, page_size, MS_SYNC)); allocator()->Free(page); EXPECT_EQ(0, msync(start_address, page_size, MS_SYNC)); unmapper()->FreeQueuedChunks(); EXPECT_EQ(0, msync(start_address, page_size, MS_SYNC)); unmapper()->TearDown(); EXPECT_EQ(-1, msync(start_address, page_size, MS_SYNC)); } // See v8:5945. TEST_F(SequentialUnmapperTest, UnmapOnTeardown) { Page* page = allocator()->AllocatePage(MemoryAllocator::PageAreaSize(OLD_SPACE), static_cast(heap()->old_space()), Executability::NOT_EXECUTABLE); heap()->old_space()->UnlinkFreeListCategories(page); EXPECT_NE(nullptr, page); const int page_size = getpagesize(); void* start_address = static_cast(page->address()); EXPECT_EQ(0, msync(start_address, page_size, MS_SYNC)); allocator()->Free(page); EXPECT_EQ(0, msync(start_address, page_size, MS_SYNC)); unmapper()->TearDown(); EXPECT_EQ(-1, msync(start_address, page_size, MS_SYNC)); } #endif // __linux__ } // namespace internal } // namespace v8