diff options
author | Michaël Zasso <targos@protonmail.com> | 2018-03-07 08:54:53 +0100 |
---|---|---|
committer | Michaël Zasso <targos@protonmail.com> | 2018-03-07 16:48:52 +0100 |
commit | 88786fecff336342a56e6f2e7ff3b286be716e47 (patch) | |
tree | 92e6ba5b8ac8dae1a058988d20c9d27bfa654390 /deps/v8/test/unittests/allocation-unittest.cc | |
parent | 4e86f9b5ab83cbabf43839385bf383e6a7ef7d19 (diff) | |
download | node-new-88786fecff336342a56e6f2e7ff3b286be716e47.tar.gz |
deps: update V8 to 6.5.254.31
PR-URL: https://github.com/nodejs/node/pull/18453
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
Reviewed-By: Yang Guo <yangguo@chromium.org>
Reviewed-By: Ali Ijaz Sheikh <ofrobots@google.com>
Reviewed-By: Michael Dawson <michael_dawson@ca.ibm.com>
Diffstat (limited to 'deps/v8/test/unittests/allocation-unittest.cc')
-rw-r--r-- | deps/v8/test/unittests/allocation-unittest.cc | 164 |
1 files changed, 164 insertions, 0 deletions
diff --git a/deps/v8/test/unittests/allocation-unittest.cc b/deps/v8/test/unittests/allocation-unittest.cc new file mode 100644 index 0000000000..42904da149 --- /dev/null +++ b/deps/v8/test/unittests/allocation-unittest.cc @@ -0,0 +1,164 @@ +// Copyright 2017 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/allocation.h" + +#if V8_OS_POSIX +#include <setjmp.h> +#include <signal.h> +#include <unistd.h> // NOLINT +#endif // V8_OS_POSIX + +#include "testing/gtest/include/gtest/gtest.h" + +namespace v8 { +namespace internal { + +// TODO(eholk): Add a windows version of permissions tests. +#if V8_OS_POSIX +namespace { + +// These tests make sure the routines to allocate memory do so with the correct +// permissions. +// +// Unfortunately, there is no API to find the protection of a memory address, +// so instead we test permissions by installing a signal handler, probing a +// memory location and recovering from the fault. +// +// We don't test the execution permission because to do so we'd have to +// dynamically generate code and test if we can execute it. + +class MemoryAllocationPermissionsTest : public ::testing::Test { + static void SignalHandler(int signal, siginfo_t* info, void*) { + siglongjmp(continuation_, 1); + } + struct sigaction old_action_; +// On Mac, sometimes we get SIGBUS instead of SIGSEGV. +#if V8_OS_MACOSX + struct sigaction old_bus_action_; +#endif + + protected: + virtual void SetUp() { + struct sigaction action; + action.sa_sigaction = SignalHandler; + sigemptyset(&action.sa_mask); + action.sa_flags = SA_SIGINFO; + sigaction(SIGSEGV, &action, &old_action_); +#if V8_OS_MACOSX + sigaction(SIGBUS, &action, &old_bus_action_); +#endif + } + + virtual void TearDown() { + // Be a good citizen and restore the old signal handler. + sigaction(SIGSEGV, &old_action_, nullptr); +#if V8_OS_MACOSX + sigaction(SIGBUS, &old_bus_action_, nullptr); +#endif + } + + public: + static sigjmp_buf continuation_; + + enum class MemoryAction { kRead, kWrite }; + + void ProbeMemory(volatile int* buffer, MemoryAction action, + bool should_succeed) { + const int save_sigs = 1; + if (!sigsetjmp(continuation_, save_sigs)) { + switch (action) { + case MemoryAction::kRead: { + // static_cast to remove the reference and force a memory read. + USE(static_cast<int>(*buffer)); + break; + } + case MemoryAction::kWrite: { + *buffer = 0; + break; + } + } + if (should_succeed) { + SUCCEED(); + } else { + FAIL(); + } + return; + } + if (should_succeed) { + FAIL(); + } else { + SUCCEED(); + } + } + + void TestPermissions(PageAllocator::Permission permission, bool can_read, + bool can_write) { + const size_t page_size = AllocatePageSize(); + int* buffer = static_cast<int*>( + AllocatePages(nullptr, page_size, page_size, permission)); + ProbeMemory(buffer, MemoryAction::kRead, can_read); + ProbeMemory(buffer, MemoryAction::kWrite, can_write); + CHECK(FreePages(buffer, page_size)); + } +}; + +sigjmp_buf MemoryAllocationPermissionsTest::continuation_; + +} // namespace + +TEST_F(MemoryAllocationPermissionsTest, DoTest) { + TestPermissions(PageAllocator::Permission::kNoAccess, false, false); + TestPermissions(PageAllocator::Permission::kReadWrite, true, true); + TestPermissions(PageAllocator::Permission::kReadWriteExecute, true, true); +} +#endif // V8_OS_POSIX + +// Basic tests of allocation. + +class AllocationTest : public ::testing::Test {}; + +TEST(AllocationTest, AllocateAndFree) { + size_t page_size = v8::internal::AllocatePageSize(); + CHECK_NE(0, page_size); + + // A large allocation, aligned at native allocation granularity. + const size_t kAllocationSize = 1 * v8::internal::MB; + void* mem_addr = v8::internal::AllocatePages( + v8::internal::GetRandomMmapAddr(), kAllocationSize, page_size, + PageAllocator::Permission::kReadWrite); + CHECK_NOT_NULL(mem_addr); + CHECK(v8::internal::FreePages(mem_addr, kAllocationSize)); + + // A large allocation, aligned significantly beyond native granularity. + const size_t kBigAlignment = 64 * v8::internal::MB; + void* aligned_mem_addr = v8::internal::AllocatePages( + v8::internal::GetRandomMmapAddr(), kAllocationSize, kBigAlignment, + PageAllocator::Permission::kReadWrite); + CHECK_NOT_NULL(aligned_mem_addr); + CHECK_EQ(aligned_mem_addr, AlignedAddress(aligned_mem_addr, kBigAlignment)); + CHECK(v8::internal::FreePages(aligned_mem_addr, kAllocationSize)); +} + +TEST(AllocationTest, ReserveMemory) { + size_t page_size = v8::internal::AllocatePageSize(); + const size_t kAllocationSize = 1 * v8::internal::MB; + void* mem_addr = v8::internal::AllocatePages( + v8::internal::GetRandomMmapAddr(), kAllocationSize, page_size, + PageAllocator::Permission::kReadWrite); + CHECK_NE(0, page_size); + CHECK_NOT_NULL(mem_addr); + size_t commit_size = v8::internal::CommitPageSize(); + CHECK(v8::internal::SetPermissions(mem_addr, commit_size, + PageAllocator::Permission::kReadWrite)); + // Check whether we can write to memory. + int* addr = static_cast<int*>(mem_addr); + addr[v8::internal::KB - 1] = 2; + CHECK(v8::internal::SetPermissions(mem_addr, commit_size, + PageAllocator::Permission::kNoAccess)); + CHECK(v8::internal::FreePages(mem_addr, kAllocationSize)); +} + +} // namespace internal +} // namespace v8 |