mirror of
https://github.com/nodejs/node.git
synced 2025-05-15 08:02:06 +00:00

PR-URL: https://github.com/nodejs/node/pull/51362 Reviewed-By: Matteo Collina <matteo.collina@gmail.com> Reviewed-By: Antoine du Hamel <duhamelantoine1995@gmail.com> Reviewed-By: Rafael Gonzaga <rafael.nunu@hotmail.com>
168 lines
5.4 KiB
C++
168 lines
5.4 KiB
C++
// Copyright 2023 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/common/code-memory-access-inl.h"
|
|
#include "testing/gtest/include/gtest/gtest.h"
|
|
|
|
namespace v8 {
|
|
namespace internal {
|
|
|
|
TEST(ThreadIsolation, ReuseJitPage) {
|
|
ThreadIsolation::Initialize(nullptr);
|
|
|
|
Address address1 = 0x4100000;
|
|
size_t size = 0x1000;
|
|
ThreadIsolation::RegisterJitPage(address1, size);
|
|
|
|
Address address2 = address1 + size;
|
|
ThreadIsolation::RegisterJitPage(address2, size);
|
|
|
|
ThreadIsolation::UnregisterJitPage(address1, size);
|
|
ThreadIsolation::RegisterJitPage(address1, size);
|
|
ThreadIsolation::UnregisterJitPage(address1, size);
|
|
ThreadIsolation::UnregisterJitPage(address2, size);
|
|
|
|
ThreadIsolation::RegisterJitPage(address1, 2 * size);
|
|
ThreadIsolation::UnregisterJitPage(address1, 2 * size);
|
|
}
|
|
|
|
TEST(ThreadIsolation, CatchJitPageOverlap) {
|
|
ThreadIsolation::Initialize(nullptr);
|
|
|
|
Address address1 = 0x4100000;
|
|
size_t size = 0x1000;
|
|
ThreadIsolation::RegisterJitPage(address1, size);
|
|
EXPECT_DEATH_IF_SUPPORTED(
|
|
{ ThreadIsolation::RegisterJitPage(address1 + size - 1, 1); }, "");
|
|
ThreadIsolation::UnregisterJitPage(address1, size);
|
|
}
|
|
|
|
TEST(ThreadIsolation, JitAllocation) {
|
|
ThreadIsolation::Initialize(nullptr);
|
|
|
|
Address address1 = 0x4100000;
|
|
size_t size = 0x1000;
|
|
ThreadIsolation::RegisterJitPage(address1, size);
|
|
|
|
Address address2 = address1 + size;
|
|
ThreadIsolation::RegisterJitPage(address2, size);
|
|
|
|
ThreadIsolation::RegisterJitAllocationForTesting(address2 + size - 1, 1);
|
|
ThreadIsolation::RegisterJitAllocationForTesting(address1, 1);
|
|
// An allocation spanning two pages.
|
|
ThreadIsolation::RegisterJitAllocationForTesting(address2 - 1, 2);
|
|
|
|
ThreadIsolation::UnregisterJitPage(address1, size);
|
|
// The spanning allocation should've been released, try to reuse the memory.
|
|
ThreadIsolation::RegisterJitAllocationForTesting(address2, 1);
|
|
ThreadIsolation::UnregisterJitPage(address2, size);
|
|
}
|
|
|
|
TEST(ThreadIsolation, CatchOOBJitAllocation) {
|
|
ThreadIsolation::Initialize(nullptr);
|
|
|
|
Address address1 = 0x4100000;
|
|
size_t size = 0x1000;
|
|
ThreadIsolation::RegisterJitPage(address1, size);
|
|
EXPECT_DEATH_IF_SUPPORTED(
|
|
{ ThreadIsolation::RegisterJitAllocationForTesting(address1 + size, 1); },
|
|
"");
|
|
ThreadIsolation::UnregisterJitPage(address1, size);
|
|
}
|
|
|
|
TEST(ThreadIsolation, MergeJitPages) {
|
|
ThreadIsolation::Initialize(nullptr);
|
|
|
|
Address address1 = 0x4100000;
|
|
size_t size = 0x1000;
|
|
Address address2 = address1 + size;
|
|
Address address3 = address2 + size;
|
|
|
|
ThreadIsolation::RegisterJitPage(address2, size);
|
|
ThreadIsolation::RegisterJitPage(address1, size);
|
|
ThreadIsolation::RegisterJitPage(address3, size);
|
|
|
|
ThreadIsolation::RegisterJitAllocationForTesting(address1, 3 * size);
|
|
ThreadIsolation::UnregisterJitAllocationForTesting(address1, 3 * size);
|
|
|
|
// Test merge in both directions
|
|
ThreadIsolation::UnregisterJitPage(address2, size);
|
|
ThreadIsolation::RegisterJitPage(address2, size);
|
|
|
|
ThreadIsolation::RegisterJitAllocationForTesting(address1, 3 * size);
|
|
ThreadIsolation::UnregisterJitAllocationForTesting(address1, 3 * size);
|
|
|
|
ThreadIsolation::UnregisterJitPage(address2, size);
|
|
ThreadIsolation::UnregisterJitPage(address1, size);
|
|
ThreadIsolation::UnregisterJitPage(address3, size);
|
|
}
|
|
|
|
TEST(ThreadIsolation, FreeRange) {
|
|
ThreadIsolation::Initialize(nullptr);
|
|
|
|
Address address1 = 0x4100000;
|
|
size_t size = 0x1000;
|
|
Address address2 = address1 + size;
|
|
Address address3 = address2 + size;
|
|
ThreadIsolation::RegisterJitPage(address1, size);
|
|
ThreadIsolation::RegisterJitPage(address2, size);
|
|
ThreadIsolation::RegisterJitPage(address3, size);
|
|
|
|
ThreadIsolation::RegisterJitAllocationForTesting(address2 - 1, 1);
|
|
ThreadIsolation::RegisterJitAllocationForTesting(address2, 1);
|
|
ThreadIsolation::RegisterJitAllocationForTesting(address2 + 1, size - 2);
|
|
ThreadIsolation::RegisterJitAllocationForTesting(address3 - 1, 1);
|
|
ThreadIsolation::RegisterJitAllocationForTesting(address3, 1);
|
|
|
|
{
|
|
WritableJitPage jit_page(address2, size);
|
|
EXPECT_FALSE(jit_page.Empty());
|
|
jit_page.FreeRange(address2, 0);
|
|
EXPECT_FALSE(jit_page.Empty());
|
|
jit_page.FreeRange(address2, size);
|
|
EXPECT_TRUE(jit_page.Empty());
|
|
// Freeing an already free range should not crash.
|
|
jit_page.FreeRange(address2, size);
|
|
}
|
|
{
|
|
WritableJitPage jit_page(address1, size);
|
|
EXPECT_FALSE(jit_page.Empty());
|
|
jit_page.FreeRange(address1, size);
|
|
EXPECT_TRUE(jit_page.Empty());
|
|
}
|
|
{
|
|
WritableJitPage jit_page(address3, size);
|
|
EXPECT_FALSE(jit_page.Empty());
|
|
jit_page.FreeRange(address3, size);
|
|
EXPECT_TRUE(jit_page.Empty());
|
|
}
|
|
|
|
ThreadIsolation::UnregisterJitPage(address1, size);
|
|
ThreadIsolation::UnregisterJitPage(address2, size);
|
|
ThreadIsolation::UnregisterJitPage(address3, size);
|
|
}
|
|
|
|
TEST(ThreadIsolation, InvalidFreeRange) {
|
|
ThreadIsolation::Initialize(nullptr);
|
|
|
|
Address address1 = 0x4100000;
|
|
size_t size = 0x1000;
|
|
ThreadIsolation::RegisterJitPage(address1, size);
|
|
|
|
ThreadIsolation::RegisterJitAllocationForTesting(address1, 2);
|
|
|
|
{
|
|
WritableJitPage jit_page(address1, size);
|
|
EXPECT_FALSE(jit_page.Empty());
|
|
// We should die when trying to partially free an allocation.
|
|
EXPECT_DEATH_IF_SUPPORTED({ jit_page.FreeRange(address1, 1); }, "");
|
|
jit_page.FreeRange(address1, 2);
|
|
}
|
|
|
|
ThreadIsolation::UnregisterJitPage(address1, size);
|
|
}
|
|
|
|
} // namespace internal
|
|
} // namespace v8
|