v8/test/common/assembler-tester.h
Michael Starzinger 7579b1e3c8 [wasm] Support concurrent patching of jump table.
This adds initial support for concurrently patching jump table slots. It
is needed once different Isolates share code (for the --wasm-shared-code
feature). We need to ensure that instructions holding the target address
within a jump table slot do not cross cache-line boundaries. To do this,
the jump table has been split into consecutive pages.

Note that this also adds a stress test for multiple threads hammering at
a single slot concurrently. The test is currently limited to the ia32
and the x64 architecture, but will be extended to cover others. The test
reliably triggers tearing of the target address on almost every run of
the test and hence serves to prevent regressions.

R=clemensh@chromium.org
TEST=cctest/test-jump-table-assembler
BUG=v8:8018

Change-Id: Ife56bbb61ffcae5d8906ca7b8c604b195603707c
Reviewed-on: https://chromium-review.googlesource.com/1163664
Commit-Queue: Michael Starzinger <mstarzinger@chromium.org>
Reviewed-by: Clemens Hammacher <clemensh@chromium.org>
Cr-Commit-Position: refs/heads/master@{#54942}
2018-08-07 11:20:09 +00:00

47 lines
1.6 KiB
C++

// 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 "src/assembler.h"
namespace v8 {
namespace internal {
static inline uint8_t* AllocateAssemblerBuffer(
size_t* allocated,
size_t requested = v8::internal::AssemblerBase::kMinimalBufferSize,
void* address = nullptr) {
size_t page_size = v8::internal::AllocatePageSize();
size_t alloc_size = RoundUp(requested, page_size);
void* result = v8::internal::AllocatePages(
address, alloc_size, page_size, v8::PageAllocator::kReadWriteExecute);
CHECK(result);
*allocated = alloc_size;
return static_cast<uint8_t*>(result);
}
static inline void MakeAssemblerBufferExecutable(uint8_t* buffer,
size_t allocated) {
bool result = v8::internal::SetPermissions(buffer, allocated,
v8::PageAllocator::kReadExecute);
CHECK(result);
// Flush the instruction cache as part of making the buffer executable.
Assembler::FlushICache(buffer, allocated);
}
static inline void MakeAssemblerBufferWritable(uint8_t* buffer,
size_t allocated) {
bool result = v8::internal::SetPermissions(buffer, allocated,
v8::PageAllocator::kReadWrite);
CHECK(result);
}
} // namespace internal
} // namespace v8
#endif // V8_TEST_COMMON_ASSEMBLER_TESTER_H_