| // Copyright 2018 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. |
| |
| #ifndef V8_TEST_COMMON_ASSEMBLER_TESTER_H_ |
| #define V8_TEST_COMMON_ASSEMBLER_TESTER_H_ |
| |
| #include <memory> |
| |
| #include "src/codegen/assembler.h" |
| #include "src/codegen/code-desc.h" |
| |
| namespace v8 { |
| namespace internal { |
| |
| class TestingAssemblerBuffer : public AssemblerBuffer { |
| public: |
| TestingAssemblerBuffer(size_t requested, void* address) { |
| size_t page_size = v8::internal::AllocatePageSize(); |
| size_t alloc_size = RoundUp(requested, page_size); |
| CHECK_GE(kMaxInt, alloc_size); |
| size_ = static_cast<int>(alloc_size); |
| buffer_ = static_cast<byte*>(AllocatePages(GetPlatformPageAllocator(), |
| address, alloc_size, page_size, |
| v8::PageAllocator::kReadWrite)); |
| CHECK_NOT_NULL(buffer_); |
| } |
| |
| ~TestingAssemblerBuffer() { |
| CHECK(FreePages(GetPlatformPageAllocator(), buffer_, size_)); |
| } |
| |
| byte* start() const override { return buffer_; } |
| |
| int size() const override { return size_; } |
| |
| std::unique_ptr<AssemblerBuffer> Grow(int new_size) override { |
| FATAL("Cannot grow TestingAssemblerBuffer"); |
| } |
| |
| std::unique_ptr<AssemblerBuffer> CreateView() const { |
| return ExternalAssemblerBuffer(buffer_, size_); |
| } |
| |
| void MakeExecutable() { |
| // Flush the instruction cache as part of making the buffer executable. |
| // Note: we do this before setting permissions to ReadExecute because on |
| // some older ARM kernels there is a bug which causes an access error on |
| // cache flush instructions to trigger access error on non-writable memory. |
| // See https://bugs.chromium.org/p/v8/issues/detail?id=8157 |
| FlushInstructionCache(buffer_, size_); |
| |
| bool result = SetPermissions(GetPlatformPageAllocator(), buffer_, size_, |
| v8::PageAllocator::kReadExecute); |
| CHECK(result); |
| } |
| |
| void MakeWritable() { |
| bool result = SetPermissions(GetPlatformPageAllocator(), buffer_, size_, |
| v8::PageAllocator::kReadWrite); |
| CHECK(result); |
| } |
| |
| // TODO(wasm): Only needed for the "test-jump-table-assembler.cc" tests. |
| void MakeWritableAndExecutable() { |
| bool result = SetPermissions(GetPlatformPageAllocator(), buffer_, size_, |
| v8::PageAllocator::kReadWriteExecute); |
| CHECK(result); |
| } |
| |
| private: |
| byte* buffer_; |
| int size_; |
| }; |
| |
| static inline std::unique_ptr<TestingAssemblerBuffer> AllocateAssemblerBuffer( |
| size_t requested = v8::internal::AssemblerBase::kDefaultBufferSize, |
| void* address = nullptr) { |
| return std::make_unique<TestingAssemblerBuffer>(requested, address); |
| } |
| |
| } // namespace internal |
| } // namespace v8 |
| |
| #endif // V8_TEST_COMMON_ASSEMBLER_TESTER_H_ |