[cctest][mac] Enable MAP_JIT on tests that need RWX memory.

The icache and jump-table-assembler tests need memory that is both
writable and executable. On Mac, to do this we need to pass MAP_JIT to
mmap which is wired with the VirtualMemory::JitPermission flag.

Change-Id: If8236fa8983a4a59ef39fe777f26a02103dc6f75
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2637227
Reviewed-by: Jakob Kummerow <jkummerow@chromium.org>
Commit-Queue: Pierre Langlois <pierre.langlois@arm.com>
Cr-Commit-Position: refs/heads/master@{#72217}
This commit is contained in:
Pierre Langlois 2021-01-19 12:21:14 +00:00 committed by Commit Bot
parent 34e89a6ba8
commit 251feceb65
3 changed files with 26 additions and 22 deletions

View File

@ -173,7 +173,8 @@ TEST(TestFlushICacheOfWritableAndExecutable) {
HandleScope handles(isolate);
for (int i = 0; i < kNumIterations; ++i) {
auto buffer = AllocateAssemblerBuffer(kBufferSize);
auto buffer = AllocateAssemblerBuffer(kBufferSize, nullptr,
VirtualMemory::kMapAsJittable);
// Allow calling the function from C++.
auto f = GeneratedCode<F0>::FromBuffer(isolate, buffer->start());

View File

@ -232,7 +232,8 @@ TEST(JumpTablePatchingStress) {
constexpr int kNumberOfPatcherThreads = 3;
STATIC_ASSERT(kAssemblerBufferSize >= kJumpTableSize);
auto buffer = AllocateAssemblerBuffer(kAssemblerBufferSize);
auto buffer = AllocateAssemblerBuffer(kAssemblerBufferSize, nullptr,
VirtualMemory::kMapAsJittable);
byte* thunk_slot_buffer = buffer->start() + kBufferSlotStartOffset;
std::bitset<kAvailableBufferSlots> used_thunk_slots;

View File

@ -15,31 +15,32 @@ namespace internal {
class TestingAssemblerBuffer : public AssemblerBuffer {
public:
TestingAssemblerBuffer(size_t requested, void* address) {
TestingAssemblerBuffer(
size_t requested, void* address,
VirtualMemory::JitPermission jit_permission = VirtualMemory::kNoJit) {
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_);
reservation_ = VirtualMemory(GetPlatformPageAllocator(), alloc_size,
address, page_size, jit_permission);
CHECK(reservation_.IsReserved());
MakeWritable();
}
~TestingAssemblerBuffer() {
CHECK(FreePages(GetPlatformPageAllocator(), buffer_, size_));
~TestingAssemblerBuffer() { reservation_.Free(); }
byte* start() const override {
return reinterpret_cast<byte*>(reservation_.address());
}
byte* start() const override { return buffer_; }
int size() const override { return size_; }
int size() const override { return static_cast<int>(reservation_.size()); }
std::unique_ptr<AssemblerBuffer> Grow(int new_size) override {
FATAL("Cannot grow TestingAssemblerBuffer");
}
std::unique_ptr<AssemblerBuffer> CreateView() const {
return ExternalAssemblerBuffer(buffer_, size_);
return ExternalAssemblerBuffer(start(), size());
}
void MakeExecutable() {
@ -48,35 +49,36 @@ class TestingAssemblerBuffer : public AssemblerBuffer {
// 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_);
FlushInstructionCache(start(), size());
bool result = SetPermissions(GetPlatformPageAllocator(), buffer_, size_,
bool result = SetPermissions(GetPlatformPageAllocator(), start(), size(),
v8::PageAllocator::kReadExecute);
CHECK(result);
}
void MakeWritable() {
bool result = SetPermissions(GetPlatformPageAllocator(), buffer_, size_,
bool result = SetPermissions(GetPlatformPageAllocator(), start(), 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_,
bool result = SetPermissions(GetPlatformPageAllocator(), start(), size(),
v8::PageAllocator::kReadWriteExecute);
CHECK(result);
}
private:
byte* buffer_;
int size_;
VirtualMemory reservation_;
};
static inline std::unique_ptr<TestingAssemblerBuffer> AllocateAssemblerBuffer(
size_t requested = v8::internal::AssemblerBase::kDefaultBufferSize,
void* address = nullptr) {
return std::make_unique<TestingAssemblerBuffer>(requested, address);
void* address = nullptr,
VirtualMemory::JitPermission jit_permission = VirtualMemory::kNoJit) {
return std::make_unique<TestingAssemblerBuffer>(requested, address,
jit_permission);
}
} // namespace internal