Skip to content

8328306: Allow VM to run with X memory execute by default #25862

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 2 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions src/hotspot/cpu/aarch64/downcallLinker_aarch64.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
#include "prims/downcallLinker.hpp"
#include "runtime/globals.hpp"
#include "runtime/stubCodeGenerator.hpp"
#include "runtime/threadWXSetters.inline.hpp"

#define __ _masm->

Expand All @@ -47,6 +48,9 @@ RuntimeStub* DowncallLinker::make_downcall_stub(BasicType* signature,
bool needs_return_buffer,
int captured_state_mask,
bool needs_transition) {
#if INCLUDE_WX_NEW
auto _wx = WXWriteMark(Thread::current());
#endif
int code_size = native_invoker_code_base_size + (num_args * native_invoker_size_per_arg);
int locs_size = 1; // must be non-zero
CodeBuffer code("nep_invoker_blob", code_size, locs_size);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
#include "runtime/javaThread.hpp"
#include "runtime/registerMap.hpp"
#include "runtime/sharedRuntime.hpp"
#include "runtime/threadWXSetters.inline.hpp"
#include "utilities/align.hpp"
#include "utilities/debug.hpp"
#include "utilities/formatBuffer.hpp"
Expand Down Expand Up @@ -118,6 +119,10 @@ class NativeNMethodBarrier {
}

void set_value(int value) {
#if INCLUDE_WX_NEW
auto _wx = WXWriteMark(Thread::current());
#endif
REQUIRE_THREAD_WX_MODE_WRITE
Atomic::release_store(guard_addr(), value);
}

Expand Down
6 changes: 3 additions & 3 deletions src/hotspot/cpu/aarch64/jniFastGetField_aarch64.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ static const Register result = r7;
// (8262896). So each FastGetXXXField is wrapped into a C++ statically
// compiled template function that optionally switches to WXExec if necessary.

#ifdef __APPLE__
#if INCLUDE_WX_OLD

static address generated_fast_get_field[T_LONG + 1 - T_BOOLEAN];

Expand Down Expand Up @@ -86,14 +86,14 @@ address JNI_FastGetField::generate_fast_get_int_field1() {
return (address)static_fast_get_field_wrapper<BType>;
}

#else // __APPLE__
#else // INCLUDE_WX_OLD

template<int BType>
address JNI_FastGetField::generate_fast_get_int_field1() {
return generate_fast_get_int_field0((BasicType)BType);
}

#endif // __APPLE__
#endif // INCLUDE_WX_OLD

address JNI_FastGetField::generate_fast_get_int_field0(BasicType type) {
const char *name;
Expand Down
2 changes: 2 additions & 0 deletions src/hotspot/cpu/aarch64/nativeInst_aarch64.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,8 @@ void NativeCall::set_destination_mt_safe(address dest) {
CompiledICLocker::is_safe(addr_at(0)),
"concurrent code patching");

REQUIRE_THREAD_WX_MODE_WRITE

address addr_call = addr_at(0);
bool reachable = Assembler::reachable_from_branch_at(addr_call, dest);
assert(NativeCall::is_call_at(addr_call), "unexpected code at call site");
Expand Down
3 changes: 3 additions & 0 deletions src/hotspot/cpu/aarch64/upcallLinker_aarch64.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,9 @@ address UpcallLinker::make_upcall_stub(jobject receiver, Symbol* signature,
BasicType ret_type,
jobject jabi, jobject jconv,
bool needs_return_buffer, int ret_buf_size) {
#if INCLUDE_WX_NEW
auto _wx = WXWriteMark(Thread::current());
#endif
ResourceMark rm;
const ABIDescriptor abi = ForeignGlobals::parse_abi_descriptor(jabi);
const CallRegs call_regs = ForeignGlobals::parse_call_regs(jconv);
Expand Down
8 changes: 7 additions & 1 deletion src/hotspot/os/bsd/globals_bsd.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,13 @@
\
AARCH64_ONLY(develop(bool, AssertWXAtThreadSync, true, \
"Conservatively check W^X thread state at possible safepoint" \
"or handshake"))
"or handshake")) \
AARCH64_ONLY(develop(bool, AssertWX, false, \
"Enable extra W^X state checking.")) \
AARCH64_ONLY(develop(bool, UseOldWX, false WX_OLD_ONLY(|| true), \
"Choose old W^X implementation.")) \
AARCH64_ONLY(develop(bool, UseNewWX, false WX_NEW_ONLY(|| true), \
"Choose new W^X implementation.")) \

// end of RUNTIME_OS_FLAGS

Expand Down
33 changes: 31 additions & 2 deletions src/hotspot/os_cpu/bsd_aarch64/os_bsd_aarch64.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,9 @@
#include "os_posix.hpp"
#include "prims/jniFastGetField.hpp"
#include "prims/jvm_misc.hpp"
#if 1
#include "runtime/atomic.hpp"
#endif
#include "runtime/arguments.hpp"
#include "runtime/frame.inline.hpp"
#include "runtime/interfaceSupport.inline.hpp"
Expand Down Expand Up @@ -199,9 +202,11 @@ NOINLINE frame os::current_frame() {

bool PosixSignals::pd_hotspot_signal_handler(int sig, siginfo_t* info,
ucontext_t* uc, JavaThread* thread) {
#if INCLUDE_WX_OLD
// Enable WXWrite: this function is called by the signal handler at arbitrary
// point of execution.
ThreadWXEnable wx(WXWrite, thread);
#endif

// decide if this trap can be handled by a stub
address stub = nullptr;
Expand All @@ -210,6 +215,12 @@ bool PosixSignals::pd_hotspot_signal_handler(int sig, siginfo_t* info,

//%note os_trap_1
if (info != nullptr && uc != nullptr && thread != nullptr) {
#if INCLUDE_WX_NEW
// Enable WXExec: this function is called by the signal handler at arbitrary
// point of execution.
auto _wx = WXExecMark(thread);
#endif

pc = (address) os::Posix::ucontext_get_pc(uc);

// Handle ALL stack overflow variations here
Expand Down Expand Up @@ -488,8 +499,26 @@ int os::extra_bang_size_in_bytes() {
return 0;
}

void os::current_thread_enable_wx(WXMode mode) {
pthread_jit_write_protect_np(mode == WXExec);
#ifndef PRODUCT
static uint _wx_changes[2] = {0};
static uint _wx_changes_total = 0;
#endif

void os::current_thread_enable_wx(WXMode mode, bool use_new_code) {
#ifndef PRODUCT
Atomic::inc(&_wx_changes[use_new_code ? 1 : 0]);
Atomic::inc(&_wx_changes_total);
if (is_power_of_2(_wx_changes_total)) {
log_develop_info(wx, perf)("WX transitions: old %d new %d total %d %.1f:%.1f",
_wx_changes[0], _wx_changes[1], _wx_changes_total,
100.0 * _wx_changes[0] / _wx_changes_total,
100.0 * _wx_changes[1] / _wx_changes_total);
}
#endif

if (use_new_code ? UseNewWX : UseOldWX && !UseNewWX) {
pthread_jit_write_protect_np(mode == WXExec);
}
}

static inline void atomic_copy64(const volatile void *src, volatile void *dst) {
Expand Down
20 changes: 20 additions & 0 deletions src/hotspot/os_cpu/linux_aarch64/os_linux_aarch64.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -469,3 +469,23 @@ extern "C" {
memmove(to, from, count * 8);
}
};

#if WX_EMUL
#ifndef PRODUCT
static uint _wx_changes[2] = {0};
static uint _wx_changes_total = 0;
#endif

void os::current_thread_enable_wx(WXMode mode, bool use_new_code) {
#ifndef PRODUCT
Atomic::inc(&_wx_changes[use_new_code ? 1 : 0]);
Atomic::inc(&_wx_changes_total);
if (is_power_of_2(_wx_changes_total)) {
log_develop_info(wx, perf)("WX transitions: old %d new %d total %d %.1f:%.1f",
_wx_changes[0], _wx_changes[1], _wx_changes_total,
100.0 * _wx_changes[0] / _wx_changes_total,
100.0 * _wx_changes[1] / _wx_changes_total);
}
#endif
}
#endif
13 changes: 8 additions & 5 deletions src/hotspot/share/asm/codeBuffer.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
#include "utilities/growableArray.hpp"
#include "utilities/linkedlist.hpp"
#include "utilities/resizeableResourceHash.hpp"
#include "runtime/threadWXSetters.inline.hpp"
#include "utilities/macros.hpp"

template <typename T>
Expand Down Expand Up @@ -155,6 +156,8 @@ class CodeSection {
_skipped_instructions_size = cs->_skipped_instructions_size;
}

address writable_end() const { REQUIRE_THREAD_WX_MODE_WRITE return _end; }

public:
address start() const { return _start; }
address mark() const { return _mark; }
Expand Down Expand Up @@ -220,24 +223,24 @@ class CodeSection {

// Code emission
void emit_int8(uint8_t x1) {
address curr = end();
address curr = writable_end();
*((uint8_t*) curr++) = x1;
set_end(curr);
}

template <typename T>
void emit_native(T x) { put_native(end(), x); set_end(end() + sizeof x); }
void emit_native(T x) { put_native(writable_end(), x); set_end(end() + sizeof x); }

void emit_int16(uint16_t x) { emit_native(x); }
void emit_int16(uint8_t x1, uint8_t x2) {
address curr = end();
address curr = writable_end();
*((uint8_t*) curr++) = x1;
*((uint8_t*) curr++) = x2;
set_end(curr);
}

void emit_int24(uint8_t x1, uint8_t x2, uint8_t x3) {
address curr = end();
address curr = writable_end();
*((uint8_t*) curr++) = x1;
*((uint8_t*) curr++) = x2;
*((uint8_t*) curr++) = x3;
Expand All @@ -246,7 +249,7 @@ class CodeSection {

void emit_int32(uint32_t x) { emit_native(x); }
void emit_int32(uint8_t x1, uint8_t x2, uint8_t x3, uint8_t x4) {
address curr = end();
address curr = writable_end();
*((uint8_t*) curr++) = x1;
*((uint8_t*) curr++) = x2;
*((uint8_t*) curr++) = x3;
Expand Down
4 changes: 4 additions & 0 deletions src/hotspot/share/c1/c1_Compilation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -386,6 +386,10 @@ int Compilation::compile_java_method() {
BAILOUT_("mdo allocation failed", no_frame_size);
}

#if INCLUDE_WX_NEW
auto _wx = WXWriteMark(Thread::current());
#endif

{
PhaseTraceTime timeit(_t_buildIR);
build_hir();
Expand Down
5 changes: 5 additions & 0 deletions src/hotspot/share/c1/c1_Compiler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
#include "memory/resourceArea.hpp"
#include "runtime/interfaceSupport.inline.hpp"
#include "runtime/sharedRuntime.hpp"
#include "runtime/threadWXSetters.inline.hpp"
#include "runtime/vm_version.hpp"
#include "utilities/bitMap.inline.hpp"
#include "utilities/macros.hpp"
Expand All @@ -64,6 +65,10 @@ bool Compiler::init_c1_runtime() {


void Compiler::initialize() {
#if INCLUDE_WX_NEW
auto _wx = WXWriteMark(Thread::current());
#endif

// Buffer blob must be allocated per C1 compiler thread at startup
BufferBlob* buffer_blob = init_buffer_blob();

Expand Down
2 changes: 1 addition & 1 deletion src/hotspot/share/c1/c1_Runtime1.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1321,7 +1321,7 @@ void Runtime1::patch_code(JavaThread* current, C1StubId stub_id) {

// Enable WXWrite: the function is called by c1 stub as a runtime function
// (see another implementation above).
MACOS_AARCH64_ONLY(ThreadWXEnable wx(WXWrite, current));
WX_OLD_ONLY(ThreadWXEnable wx(WXWrite, current));

if (TracePatching) {
tty->print_cr("Deoptimizing because patch is needed");
Expand Down
4 changes: 4 additions & 0 deletions src/hotspot/share/ci/ciEnv.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1059,6 +1059,10 @@ void ciEnv::register_method(ciMethod* target,
assert(offsets->value(CodeOffsets::Deopt) != -1, "must have deopt entry");
assert(offsets->value(CodeOffsets::Exceptions) != -1, "must have exception entry");

#if INCLUDE_WX_NEW
auto _wx = WXWriteMark(THREAD);
#endif

nm = nmethod::new_nmethod(method,
compile_id(),
entry_bci,
Expand Down
4 changes: 4 additions & 0 deletions src/hotspot/share/classfile/classLoader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@
#include "runtime/os.hpp"
#include "runtime/perfData.hpp"
#include "runtime/threadCritical.hpp"
#include "runtime/threadWXSetters.inline.hpp"
#include "runtime/timer.hpp"
#include "runtime/vm_version.hpp"
#include "services/management.hpp"
Expand Down Expand Up @@ -686,6 +687,9 @@ void ClassLoader::add_to_exploded_build_list(JavaThread* current, Symbol* module
}

jzfile* ClassLoader::open_zip_file(const char* canonical_path, char** error_msg, JavaThread* thread) {
#if INCLUDE_WX_NEW
auto _wx = WXExecMark(thread);
#endif
// enable call to C land
ThreadToNativeFromVM ttn(thread);
HandleMark hm(thread);
Expand Down
5 changes: 5 additions & 0 deletions src/hotspot/share/classfile/classLoaderDataGraph.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -412,6 +412,11 @@ bool ClassLoaderDataGraph::do_unloading() {
uint loaders_processed = 0;
uint loaders_removed = 0;

// Anticipate nmethod::is_unloading()
#if INCLUDE_WX_NEW
auto _wx = WXLazyMark(Thread::current());
#endif

for (ClassLoaderData* data = _head; data != nullptr; data = data->next()) {
if (data->is_alive()) {
prev = data;
Expand Down
14 changes: 12 additions & 2 deletions src/hotspot/share/code/codeBlob.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -319,6 +319,9 @@ RuntimeBlob::RuntimeBlob(
void RuntimeBlob::free(RuntimeBlob* blob) {
assert(blob != nullptr, "caller must check for nullptr");
ThreadInVMfromUnknown __tiv; // get to VM state in case we block on CodeCache_lock
#if INCLUDE_WX_NEW
auto _wx = WXWriteMark(Thread::current());
#endif
blob->purge();
{
MutexLocker mu(CodeCache_lock, Mutex::_no_safepoint_check_flag);
Expand Down Expand Up @@ -376,6 +379,9 @@ BufferBlob::BufferBlob(const char* name, CodeBlobKind kind, int size)

BufferBlob* BufferBlob::create(const char* name, uint buffer_size) {
ThreadInVMfromUnknown __tiv; // get to VM state in case we block on CodeCache_lock
#if INCLUDE_WX_NEW
auto _wx = WXWriteMark(Thread::current());
#endif

BufferBlob* blob = nullptr;
unsigned int size = sizeof(BufferBlob);
Expand All @@ -401,6 +407,9 @@ BufferBlob::BufferBlob(const char* name, CodeBlobKind kind, CodeBuffer* cb, int
// Used by gtest
BufferBlob* BufferBlob::create(const char* name, CodeBuffer* cb) {
ThreadInVMfromUnknown __tiv; // get to VM state in case we block on CodeCache_lock
#if INCLUDE_WX_NEW
auto _wx = WXWriteMark(Thread::current());
#endif

BufferBlob* blob = nullptr;
unsigned int size = CodeBlob::allocation_size(cb, sizeof(BufferBlob));
Expand Down Expand Up @@ -467,8 +476,6 @@ VtableBlob::VtableBlob(const char* name, int size) :
}

VtableBlob* VtableBlob::create(const char* name, int buffer_size) {
assert(JavaThread::current()->thread_state() == _thread_in_vm, "called with the wrong state");

VtableBlob* blob = nullptr;
unsigned int size = sizeof(VtableBlob);
// align the size to CodeEntryAlignment
Expand All @@ -489,6 +496,9 @@ VtableBlob* VtableBlob::create(const char* name, int buffer_size) {
// eventually.
return nullptr;
}
#if INCLUDE_WX_NEW
auto _wx = WXWriteMark(Thread::current());
#endif
blob = new (size) VtableBlob(name, size);
CodeCache_lock->unlock();
}
Expand Down
Loading