--- old/src/hotspot/cpu/ppc/globalDefinitions_ppc.hpp 2017-12-28 18:15:44.305762000 +0100 +++ new/src/hotspot/cpu/ppc/globalDefinitions_ppc.hpp 2017-12-28 18:15:44.089726000 +0100 @@ -55,5 +55,6 @@ #define SUPPORT_RESERVED_STACK_AREA #define THREAD_LOCAL_POLL +#define USE_POLL_BIT_ONLY UseSIGTRAP #endif // CPU_PPC_VM_GLOBALDEFINITIONS_PPC_HPP --- old/src/hotspot/cpu/ppc/macroAssembler_ppc.inline.hpp 2017-12-28 18:15:45.094740000 +0100 +++ new/src/hotspot/cpu/ppc/macroAssembler_ppc.inline.hpp 2017-12-28 18:15:44.884733000 +0100 @@ -30,6 +30,7 @@ #include "asm/macroAssembler.hpp" #include "asm/codeBuffer.hpp" #include "code/codeCache.hpp" +#include "runtime/safepointMechanism.hpp" inline bool MacroAssembler::is_ld_largeoffset(address a) { const int inst1 = *(int *)a; @@ -261,7 +262,12 @@ // Read from the polling page, its address is already in a register. inline void MacroAssembler::load_from_polling_page(Register polling_page_address, int offset) { - ld(R0, offset, polling_page_address); + if (SafepointMechanism::uses_thread_local_poll() && USE_POLL_BIT_ONLY) { + int encoding = SafepointMechanism::poll_bit(); + tdi(traptoGreaterThanUnsigned | traptoEqual, polling_page_address, encoding); + } else { + ld(R0, offset, polling_page_address); + } } // Trap-instruction-based checks. --- old/src/hotspot/cpu/ppc/nativeInst_ppc.hpp 2017-12-28 18:15:45.891745000 +0100 +++ new/src/hotspot/cpu/ppc/nativeInst_ppc.hpp 2017-12-28 18:15:45.679745000 +0100 @@ -31,6 +31,7 @@ #include "memory/allocation.hpp" #include "runtime/icache.hpp" #include "runtime/os.hpp" +#include "runtime/safepointMechanism.hpp" // We have interfaces for the following instructions: // @@ -93,6 +94,11 @@ bool is_safepoint_poll() { // Is the current instruction a POTENTIAL read access to the polling page? // The current arguments of the instruction are not checked! + if (SafepointMechanism::uses_thread_local_poll() && USE_POLL_BIT_ONLY) { + int encoding = SafepointMechanism::poll_bit(); + return MacroAssembler::is_tdi(long_at(0), Assembler::traptoGreaterThanUnsigned | Assembler::traptoEqual, + -1, encoding); + } return MacroAssembler::is_load_from_polling_page(long_at(0), NULL); } --- old/src/hotspot/os/aix/safepointMechanism_aix.cpp 2017-12-28 18:15:46.792756000 +0100 +++ new/src/hotspot/os/aix/safepointMechanism_aix.cpp 2017-12-28 18:15:46.583769000 +0100 @@ -30,8 +30,18 @@ #include void SafepointMechanism::pd_initialize() { + // No special code needed if we can use SIGTRAP + if (ThreadLocalHandshakes && USE_POLL_BIT_ONLY) { + default_initialize(); + return; + } + + // Allocate one protected page char* map_address = (char*)MAP_FAILED; const size_t page_size = os::vm_page_size(); + const int prot = PROT_READ; + const int flags = MAP_PRIVATE | MAP_ANONYMOUS; + // Use optimized addresses for the polling page, // e.g. map it to a special 32-bit address. if (OptimizePollingPageLocation) { @@ -58,8 +68,8 @@ // AIX: AIX needs MAP_FIXED if we provide an address and mmap will // fail if the address is already mapped. map_address = (char*) ::mmap(address_wishes[i] - (ssize_t)page_size, - page_size, PROT_READ, - MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED, + page_size, prot, + flags | MAP_FIXED, -1, 0); log_debug(os)("SafePoint Polling Page address: %p (wish) => %p", address_wishes[i], map_address + (ssize_t)page_size); @@ -78,8 +88,16 @@ } } if (map_address == (char*)MAP_FAILED) { - map_address = os::reserve_memory(page_size, NULL, page_size); + map_address = (char*) ::mmap(NULL, page_size, prot, flags, -1, 0); } guarantee(map_address != (char*)MAP_FAILED, "SafepointMechanism::pd_initialize: failed to allocate polling page"); os::set_polling_page((address)(map_address)); + + // Use same page for ThreadLocalHandshakes without SIGTRAP + if (ThreadLocalHandshakes) { + set_uses_thread_local_poll(); + intptr_t bad_page_val = reinterpret_cast(map_address); + _poll_armed_value = reinterpret_cast(bad_page_val | poll_bit()); + _poll_disarmed_value = NULL; // Readable on AIX + } } --- old/src/hotspot/os_cpu/aix_ppc/os_aix_ppc.cpp 2017-12-28 18:15:47.730779000 +0100 +++ new/src/hotspot/os_cpu/aix_ppc/os_aix_ppc.cpp 2017-12-28 18:15:47.511770000 +0100 @@ -47,6 +47,7 @@ #include "runtime/javaCalls.hpp" #include "runtime/mutexLocker.hpp" #include "runtime/osThread.hpp" +#include "runtime/safepointMechanism.hpp" #include "runtime/sharedRuntime.hpp" #include "runtime/stubRoutines.hpp" #include "runtime/thread.inline.hpp" @@ -374,9 +375,12 @@ goto run_stub; } - else if (sig == SIGSEGV && os::is_poll_address(addr)) { + else if ((SafepointMechanism::uses_thread_local_poll() && USE_POLL_BIT_ONLY) + ? (sig == SIGTRAP && ((NativeInstruction*)pc)->is_safepoint_poll()) + : (sig == SIGSEGV && os::is_poll_address(addr))) { if (TraceTraps) { - tty->print_cr("trap: safepoint_poll at " INTPTR_FORMAT " (SIGSEGV)", pc); + tty->print_cr("trap: safepoint_poll at " INTPTR_FORMAT " (%s)", p2i(pc), + (SafepointMechanism::uses_thread_local_poll() && USE_POLL_BIT_ONLY) ? "SIGTRAP" : "SIGSEGV"); } stub = SharedRuntime::get_poll_stub(pc); goto run_stub; --- old/src/hotspot/os_cpu/linux_ppc/os_linux_ppc.cpp 2017-12-28 18:15:48.637777000 +0100 +++ new/src/hotspot/os_cpu/linux_ppc/os_linux_ppc.cpp 2017-12-28 18:15:48.426774000 +0100 @@ -46,6 +46,7 @@ #include "runtime/javaCalls.hpp" #include "runtime/mutexLocker.hpp" #include "runtime/osThread.hpp" +#include "runtime/safepointMechanism.hpp" #include "runtime/sharedRuntime.hpp" #include "runtime/stubRoutines.hpp" #include "runtime/thread.inline.hpp" @@ -382,7 +383,7 @@ stub = SharedRuntime::get_handle_wrong_method_stub(); } - else if (sig == SIGSEGV && + else if (sig == ((SafepointMechanism::uses_thread_local_poll() && USE_POLL_BIT_ONLY) ? SIGTRAP : SIGSEGV) && // A linux-ppc64 kernel before 2.6.6 doesn't set si_addr on some segfaults // in 64bit mode (cf. http://www.kernel.org/pub/linux/kernel/v2.6/ChangeLog-2.6.6), // especially when we try to read from the safepoint polling page. So the check @@ -393,7 +394,8 @@ ((cb = CodeCache::find_blob(pc)) != NULL) && cb->is_compiled()) { if (TraceTraps) { - tty->print_cr("trap: safepoint_poll at " INTPTR_FORMAT " (SIGSEGV)", p2i(pc)); + tty->print_cr("trap: safepoint_poll at " INTPTR_FORMAT " (%s)", p2i(pc), + (SafepointMechanism::uses_thread_local_poll() && USE_POLL_BIT_ONLY) ? "SIGTRAP" : "SIGSEGV"); } stub = SharedRuntime::get_poll_stub(pc); } --- old/src/hotspot/share/runtime/safepointMechanism.cpp 2017-12-28 18:15:49.476788000 +0100 +++ new/src/hotspot/share/runtime/safepointMechanism.cpp 2017-12-28 18:15:49.264843000 +0100 @@ -36,23 +36,39 @@ void SafepointMechanism::default_initialize() { if (ThreadLocalHandshakes) { set_uses_thread_local_poll(); - const size_t page_size = os::vm_page_size(); - const size_t allocation_size = 2 * page_size; - char* polling_page = os::reserve_memory(allocation_size, NULL, page_size); - os::commit_memory_or_exit(polling_page, allocation_size, false, "Unable to commit Safepoint polling page"); - - char* bad_page = polling_page; - char* good_page = polling_page + page_size; - - os::protect_memory(bad_page, page_size, os::MEM_PROT_NONE); - os::protect_memory(good_page, page_size, os::MEM_PROT_READ); - - log_info(os)("SafePoint Polling address, bad (protected) page:" INTPTR_FORMAT ", good (unprotected) page:" INTPTR_FORMAT, p2i(bad_page), p2i(good_page)); - os::set_polling_page((address)(bad_page)); - - intptr_t poll_page_val = reinterpret_cast(bad_page); - _poll_armed_value = reinterpret_cast(poll_page_val | poll_bit()); - _poll_disarmed_value = good_page; + + // Poll bit values + intptr_t poll_armed_value = poll_bit(); + intptr_t poll_disarmed_value = 0; + +#ifdef USE_POLL_BIT_ONLY + if (!USE_POLL_BIT_ONLY) +#endif + { + // Polling page + const size_t page_size = os::vm_page_size(); + const size_t allocation_size = 2 * page_size; + char* polling_page = os::reserve_memory(allocation_size, NULL, page_size); + os::commit_memory_or_exit(polling_page, allocation_size, false, "Unable to commit Safepoint polling page"); + + char* bad_page = polling_page; + char* good_page = polling_page + page_size; + + os::protect_memory(bad_page, page_size, os::MEM_PROT_NONE); + os::protect_memory(good_page, page_size, os::MEM_PROT_READ); + + log_info(os)("SafePoint Polling address, bad (protected) page:" INTPTR_FORMAT ", good (unprotected) page:" INTPTR_FORMAT, p2i(bad_page), p2i(good_page)); + os::set_polling_page((address)(bad_page)); + + // Poll address values + intptr_t bad_page_val = reinterpret_cast(bad_page), + good_page_val = reinterpret_cast(good_page); + poll_armed_value |= bad_page_val; + poll_disarmed_value |= good_page_val; + } + + _poll_armed_value = reinterpret_cast(poll_armed_value); + _poll_disarmed_value = reinterpret_cast(poll_disarmed_value); } else { const size_t page_size = os::vm_page_size(); char* polling_page = os::reserve_memory(page_size, NULL, page_size);