mirror of
https://github.com/openjdk/jdk.git
synced 2025-08-28 07:14:30 +02:00
8220051: Remove global safepoint code
Reviewed-by: mdoerr, dcubed, eosterlund, bulasevich, coleenp
This commit is contained in:
parent
8d84cf5a3b
commit
bf41f548e1
86 changed files with 263 additions and 927 deletions
|
@ -1696,7 +1696,7 @@ void MachEpilogNode::format(PhaseRegAlloc *ra_, outputStream *st) const {
|
||||||
|
|
||||||
if (do_polling() && C->is_method_compilation()) {
|
if (do_polling() && C->is_method_compilation()) {
|
||||||
st->print("# touch polling page\n\t");
|
st->print("# touch polling page\n\t");
|
||||||
st->print("mov rscratch1, #0x%lx\n\t", p2i(os::get_polling_page()));
|
st->print("ldr rscratch1, [rthread],#polling_page_offset\n\t");
|
||||||
st->print("ldr zr, [rscratch1]");
|
st->print("ldr zr, [rscratch1]");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1714,7 +1714,7 @@ void MachEpilogNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (do_polling() && C->is_method_compilation()) {
|
if (do_polling() && C->is_method_compilation()) {
|
||||||
__ read_polling_page(rscratch1, os::get_polling_page(), relocInfo::poll_return_type);
|
__ fetch_and_read_polling_page(rscratch1, relocInfo::poll_return_type);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1732,14 +1732,6 @@ const Pipeline * MachEpilogNode::pipeline() const {
|
||||||
return MachNode::pipeline_class();
|
return MachNode::pipeline_class();
|
||||||
}
|
}
|
||||||
|
|
||||||
// This method seems to be obsolete. It is declared in machnode.hpp
|
|
||||||
// and defined in all *.ad files, but it is never called. Should we
|
|
||||||
// get rid of it?
|
|
||||||
int MachEpilogNode::safepoint_offset() const {
|
|
||||||
assert(do_polling(), "no return for this epilog node");
|
|
||||||
return 4;
|
|
||||||
}
|
|
||||||
|
|
||||||
//=============================================================================
|
//=============================================================================
|
||||||
|
|
||||||
// Figure out which register class each belongs in: rc_int, rc_float or
|
// Figure out which register class each belongs in: rc_int, rc_float or
|
||||||
|
@ -3177,15 +3169,6 @@ encode %{
|
||||||
__ mov(dst_reg, (u_int64_t)1);
|
__ mov(dst_reg, (u_int64_t)1);
|
||||||
%}
|
%}
|
||||||
|
|
||||||
enc_class aarch64_enc_mov_poll_page(iRegP dst, immPollPage src) %{
|
|
||||||
C2_MacroAssembler _masm(&cbuf);
|
|
||||||
address page = (address)$src$$constant;
|
|
||||||
Register dst_reg = as_Register($dst$$reg);
|
|
||||||
unsigned long off;
|
|
||||||
__ adrp(dst_reg, Address(page, relocInfo::poll_type), off);
|
|
||||||
assert(off == 0, "assumed offset == 0");
|
|
||||||
%}
|
|
||||||
|
|
||||||
enc_class aarch64_enc_mov_byte_map_base(iRegP dst, immByteMapBase src) %{
|
enc_class aarch64_enc_mov_byte_map_base(iRegP dst, immByteMapBase src) %{
|
||||||
C2_MacroAssembler _masm(&cbuf);
|
C2_MacroAssembler _masm(&cbuf);
|
||||||
__ load_byte_map_base($dst$$Register);
|
__ load_byte_map_base($dst$$Register);
|
||||||
|
@ -4378,17 +4361,6 @@ operand immP_1()
|
||||||
interface(CONST_INTER);
|
interface(CONST_INTER);
|
||||||
%}
|
%}
|
||||||
|
|
||||||
// Polling Page Pointer Immediate
|
|
||||||
operand immPollPage()
|
|
||||||
%{
|
|
||||||
predicate((address)n->get_ptr() == os::get_polling_page());
|
|
||||||
match(ConP);
|
|
||||||
|
|
||||||
op_cost(0);
|
|
||||||
format %{ %}
|
|
||||||
interface(CONST_INTER);
|
|
||||||
%}
|
|
||||||
|
|
||||||
// Card Table Byte Map Base
|
// Card Table Byte Map Base
|
||||||
operand immByteMapBase()
|
operand immByteMapBase()
|
||||||
%{
|
%{
|
||||||
|
@ -7185,20 +7157,6 @@ instruct loadConP1(iRegPNoSp dst, immP_1 con)
|
||||||
ins_pipe(ialu_imm);
|
ins_pipe(ialu_imm);
|
||||||
%}
|
%}
|
||||||
|
|
||||||
// Load Poll Page Constant
|
|
||||||
|
|
||||||
instruct loadConPollPage(iRegPNoSp dst, immPollPage con)
|
|
||||||
%{
|
|
||||||
match(Set dst con);
|
|
||||||
|
|
||||||
ins_cost(INSN_COST);
|
|
||||||
format %{ "adr $dst, $con\t# Poll Page Ptr" %}
|
|
||||||
|
|
||||||
ins_encode(aarch64_enc_mov_poll_page(dst, con));
|
|
||||||
|
|
||||||
ins_pipe(ialu_imm);
|
|
||||||
%}
|
|
||||||
|
|
||||||
// Load Byte Map Base Constant
|
// Load Byte Map Base Constant
|
||||||
|
|
||||||
instruct loadByteMapBase(iRegPNoSp dst, immByteMapBase con)
|
instruct loadByteMapBase(iRegPNoSp dst, immByteMapBase con)
|
||||||
|
|
|
@ -501,16 +501,13 @@ void LIR_Assembler::return_op(LIR_Opr result) {
|
||||||
__ reserved_stack_check();
|
__ reserved_stack_check();
|
||||||
}
|
}
|
||||||
|
|
||||||
address polling_page(os::get_polling_page());
|
__ fetch_and_read_polling_page(rscratch1, relocInfo::poll_return_type);
|
||||||
__ read_polling_page(rscratch1, polling_page, relocInfo::poll_return_type);
|
|
||||||
__ ret(lr);
|
__ ret(lr);
|
||||||
}
|
}
|
||||||
|
|
||||||
int LIR_Assembler::safepoint_poll(LIR_Opr tmp, CodeEmitInfo* info) {
|
int LIR_Assembler::safepoint_poll(LIR_Opr tmp, CodeEmitInfo* info) {
|
||||||
address polling_page(os::get_polling_page());
|
|
||||||
guarantee(info != NULL, "Shouldn't be NULL");
|
guarantee(info != NULL, "Shouldn't be NULL");
|
||||||
assert(os::is_poll_address(polling_page), "should be");
|
__ get_polling_page(rscratch1, relocInfo::poll_type);
|
||||||
__ get_polling_page(rscratch1, polling_page, relocInfo::poll_type);
|
|
||||||
add_debug_info_for_branch(info); // This isn't just debug info:
|
add_debug_info_for_branch(info); // This isn't just debug info:
|
||||||
// it's the oop map
|
// it's the oop map
|
||||||
__ read_polling_page(rscratch1, relocInfo::poll_type);
|
__ read_polling_page(rscratch1, relocInfo::poll_type);
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 1999, 2019, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 1999, 2020, Oracle and/or its affiliates. All rights reserved.
|
||||||
* Copyright (c) 2014, 2015, Red Hat Inc. All rights reserved.
|
* Copyright (c) 2014, 2015, Red Hat Inc. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
|
@ -56,8 +56,6 @@ const bool CCallingConventionRequiresIntsAsLongs = false;
|
||||||
|
|
||||||
#define SUPPORT_RESERVED_STACK_AREA
|
#define SUPPORT_RESERVED_STACK_AREA
|
||||||
|
|
||||||
#define THREAD_LOCAL_POLL
|
|
||||||
|
|
||||||
#define PREFERRED_METASPACE_ALIGNMENT
|
#define PREFERRED_METASPACE_ALIGNMENT
|
||||||
|
|
||||||
#endif // CPU_AARCH64_GLOBALDEFINITIONS_AARCH64_HPP
|
#endif // CPU_AARCH64_GLOBALDEFINITIONS_AARCH64_HPP
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2003, 2018, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2003, 2020, Oracle and/or its affiliates. All rights reserved.
|
||||||
* Copyright (c) 2014, Red Hat Inc. All rights reserved.
|
* Copyright (c) 2014, Red Hat Inc. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
|
@ -469,8 +469,7 @@ void InterpreterMacroAssembler::dispatch_base(TosState state,
|
||||||
|
|
||||||
Label safepoint;
|
Label safepoint;
|
||||||
address* const safepoint_table = Interpreter::safept_table(state);
|
address* const safepoint_table = Interpreter::safept_table(state);
|
||||||
bool needs_thread_local_poll = generate_poll &&
|
bool needs_thread_local_poll = generate_poll && table != safepoint_table;
|
||||||
SafepointMechanism::uses_thread_local_poll() && table != safepoint_table;
|
|
||||||
|
|
||||||
if (needs_thread_local_poll) {
|
if (needs_thread_local_poll) {
|
||||||
NOT_PRODUCT(block_comment("Thread-local Safepoint poll"));
|
NOT_PRODUCT(block_comment("Thread-local Safepoint poll"));
|
||||||
|
|
|
@ -291,16 +291,8 @@ address MacroAssembler::target_addr_for_insn(address insn_addr, unsigned insn) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void MacroAssembler::safepoint_poll(Label& slow_path) {
|
void MacroAssembler::safepoint_poll(Label& slow_path) {
|
||||||
if (SafepointMechanism::uses_thread_local_poll()) {
|
ldr(rscratch1, Address(rthread, Thread::polling_page_offset()));
|
||||||
ldr(rscratch1, Address(rthread, Thread::polling_page_offset()));
|
tbnz(rscratch1, exact_log2(SafepointMechanism::poll_bit()), slow_path);
|
||||||
tbnz(rscratch1, exact_log2(SafepointMechanism::poll_bit()), slow_path);
|
|
||||||
} else {
|
|
||||||
unsigned long offset;
|
|
||||||
adrp(rscratch1, ExternalAddress(SafepointSynchronize::address_of_state()), offset);
|
|
||||||
ldrw(rscratch1, Address(rscratch1, offset));
|
|
||||||
assert(SafepointSynchronize::_not_synchronized == 0, "rewrite this code");
|
|
||||||
cbnz(rscratch1, slow_path);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Just like safepoint_poll, but use an acquiring load for thread-
|
// Just like safepoint_poll, but use an acquiring load for thread-
|
||||||
|
@ -316,13 +308,9 @@ void MacroAssembler::safepoint_poll(Label& slow_path) {
|
||||||
// racing the code which wakes up from a safepoint.
|
// racing the code which wakes up from a safepoint.
|
||||||
//
|
//
|
||||||
void MacroAssembler::safepoint_poll_acquire(Label& slow_path) {
|
void MacroAssembler::safepoint_poll_acquire(Label& slow_path) {
|
||||||
if (SafepointMechanism::uses_thread_local_poll()) {
|
lea(rscratch1, Address(rthread, Thread::polling_page_offset()));
|
||||||
lea(rscratch1, Address(rthread, Thread::polling_page_offset()));
|
ldar(rscratch1, rscratch1);
|
||||||
ldar(rscratch1, rscratch1);
|
tbnz(rscratch1, exact_log2(SafepointMechanism::poll_bit()), slow_path);
|
||||||
tbnz(rscratch1, exact_log2(SafepointMechanism::poll_bit()), slow_path);
|
|
||||||
} else {
|
|
||||||
safepoint_poll(slow_path);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void MacroAssembler::reset_last_Java_frame(bool clear_fp) {
|
void MacroAssembler::reset_last_Java_frame(bool clear_fp) {
|
||||||
|
@ -4305,22 +4293,15 @@ void MacroAssembler::bang_stack_size(Register size, Register tmp) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Move the address of the polling page into dest.
|
// Move the address of the polling page into dest.
|
||||||
void MacroAssembler::get_polling_page(Register dest, address page, relocInfo::relocType rtype) {
|
void MacroAssembler::get_polling_page(Register dest, relocInfo::relocType rtype) {
|
||||||
if (SafepointMechanism::uses_thread_local_poll()) {
|
ldr(dest, Address(rthread, Thread::polling_page_offset()));
|
||||||
ldr(dest, Address(rthread, Thread::polling_page_offset()));
|
|
||||||
} else {
|
|
||||||
unsigned long off;
|
|
||||||
adrp(dest, Address(page, rtype), off);
|
|
||||||
assert(off == 0, "polling page must be page aligned");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Move the address of the polling page into r, then read the polling
|
// Move the address of the polling page into r, then read the polling
|
||||||
// page.
|
// page.
|
||||||
address MacroAssembler::read_polling_page(Register r, address page, relocInfo::relocType rtype) {
|
address MacroAssembler::fetch_and_read_polling_page(Register r, relocInfo::relocType rtype) {
|
||||||
get_polling_page(r, page, rtype);
|
get_polling_page(r, rtype);
|
||||||
return read_polling_page(r, rtype);
|
return read_polling_page(r, rtype);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 1997, 2019, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 1997, 2020, Oracle and/or its affiliates. All rights reserved.
|
||||||
* Copyright (c) 2014, 2019, Red Hat Inc. All rights reserved.
|
* Copyright (c) 2014, 2019, Red Hat Inc. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
|
@ -1217,9 +1217,9 @@ public:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
address read_polling_page(Register r, address page, relocInfo::relocType rtype);
|
|
||||||
address read_polling_page(Register r, relocInfo::relocType rtype);
|
address read_polling_page(Register r, relocInfo::relocType rtype);
|
||||||
void get_polling_page(Register dest, address page, relocInfo::relocType rtype);
|
void get_polling_page(Register dest, relocInfo::relocType rtype);
|
||||||
|
address fetch_and_read_polling_page(Register r, relocInfo::relocType rtype);
|
||||||
|
|
||||||
// CRC32 code for java.util.zip.CRC32::updateBytes() instrinsic.
|
// CRC32 code for java.util.zip.CRC32::updateBytes() instrinsic.
|
||||||
void update_byte_crc32(Register crc, Register val, Register table);
|
void update_byte_crc32(Register crc, Register val, Register table);
|
||||||
|
|
|
@ -2807,7 +2807,7 @@ SafepointBlob* SharedRuntime::generate_handler_blob(address call_ptr, int poll_t
|
||||||
__ bind(noException);
|
__ bind(noException);
|
||||||
|
|
||||||
Label no_adjust, bail;
|
Label no_adjust, bail;
|
||||||
if (SafepointMechanism::uses_thread_local_poll() && !cause_return) {
|
if (!cause_return) {
|
||||||
// If our stashed return pc was modified by the runtime we avoid touching it
|
// If our stashed return pc was modified by the runtime we avoid touching it
|
||||||
__ ldr(rscratch1, Address(rfp, wordSize));
|
__ ldr(rscratch1, Address(rfp, wordSize));
|
||||||
__ cmp(r20, rscratch1);
|
__ cmp(r20, rscratch1);
|
||||||
|
|
|
@ -367,13 +367,6 @@ const Pipeline * MachEpilogNode::pipeline() const {
|
||||||
return MachNode::pipeline_class();
|
return MachNode::pipeline_class();
|
||||||
}
|
}
|
||||||
|
|
||||||
int MachEpilogNode::safepoint_offset() const {
|
|
||||||
assert( do_polling(), "no return for this epilog node");
|
|
||||||
// return MacroAssembler::size_of_sethi(os::get_polling_page());
|
|
||||||
Unimplemented();
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
//=============================================================================
|
//=============================================================================
|
||||||
|
|
||||||
// Figure out which register class each belongs in: rc_int, rc_float, rc_stack
|
// Figure out which register class each belongs in: rc_int, rc_float, rc_stack
|
||||||
|
@ -2021,15 +2014,6 @@ operand immP0() %{
|
||||||
interface(CONST_INTER);
|
interface(CONST_INTER);
|
||||||
%}
|
%}
|
||||||
|
|
||||||
operand immP_poll() %{
|
|
||||||
predicate(n->get_ptr() != 0 && n->get_ptr() == (intptr_t)os::get_polling_page());
|
|
||||||
match(ConP);
|
|
||||||
|
|
||||||
// formats are generated automatically for constants and base registers
|
|
||||||
format %{ %}
|
|
||||||
interface(CONST_INTER);
|
|
||||||
%}
|
|
||||||
|
|
||||||
// Pointer Immediate
|
// Pointer Immediate
|
||||||
operand immN()
|
operand immN()
|
||||||
%{
|
%{
|
||||||
|
@ -3098,12 +3082,6 @@ pipe_class loadConP( iRegP dst, immP src ) %{
|
||||||
fixed_latency(6);
|
fixed_latency(6);
|
||||||
%}
|
%}
|
||||||
|
|
||||||
// Polling Address
|
|
||||||
pipe_class loadConP_poll( iRegP dst, immP_poll src ) %{
|
|
||||||
dst : E(write);
|
|
||||||
IALU : R;
|
|
||||||
%}
|
|
||||||
|
|
||||||
// Long Constant small
|
// Long Constant small
|
||||||
pipe_class loadConLlo( iRegL dst, immL src ) %{
|
pipe_class loadConLlo( iRegL dst, immL src ) %{
|
||||||
instruction_count(2);
|
instruction_count(2);
|
||||||
|
@ -4286,16 +4264,6 @@ instruct loadConP(iRegP dst, immP src) %{
|
||||||
%}
|
%}
|
||||||
|
|
||||||
|
|
||||||
instruct loadConP_poll(iRegP dst, immP_poll src) %{
|
|
||||||
match(Set dst src);
|
|
||||||
ins_cost(DEFAULT_COST);
|
|
||||||
format %{ "MOV_SLOW $dst,$src\t!ptr" %}
|
|
||||||
ins_encode %{
|
|
||||||
__ mov_slow($dst$$Register, $src$$constant);
|
|
||||||
%}
|
|
||||||
ins_pipe(loadConP_poll);
|
|
||||||
%}
|
|
||||||
|
|
||||||
instruct loadConL(iRegL dst, immL src) %{
|
instruct loadConL(iRegL dst, immL src) %{
|
||||||
match(Set dst src);
|
match(Set dst src);
|
||||||
ins_cost(DEFAULT_COST * 4);
|
ins_cost(DEFAULT_COST * 4);
|
||||||
|
|
|
@ -62,6 +62,4 @@ const bool HaveVFP = true;
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define THREAD_LOCAL_POLL
|
|
||||||
|
|
||||||
#endif // CPU_ARM_GLOBALDEFINITIONS_ARM_HPP
|
#endif // CPU_ARM_GLOBALDEFINITIONS_ARM_HPP
|
||||||
|
|
|
@ -576,8 +576,7 @@ void InterpreterMacroAssembler::dispatch_base(TosState state,
|
||||||
Label safepoint;
|
Label safepoint;
|
||||||
address* const safepoint_table = Interpreter::safept_table(state);
|
address* const safepoint_table = Interpreter::safept_table(state);
|
||||||
address* const table = Interpreter::dispatch_table(state);
|
address* const table = Interpreter::dispatch_table(state);
|
||||||
bool needs_thread_local_poll = generate_poll &&
|
bool needs_thread_local_poll = generate_poll && table != safepoint_table;
|
||||||
SafepointMechanism::uses_thread_local_poll() && table != safepoint_table;
|
|
||||||
|
|
||||||
if (needs_thread_local_poll) {
|
if (needs_thread_local_poll) {
|
||||||
NOT_PRODUCT(block_comment("Thread-local Safepoint poll"));
|
NOT_PRODUCT(block_comment("Thread-local Safepoint poll"));
|
||||||
|
|
|
@ -1920,23 +1920,13 @@ void MacroAssembler::resolve(DecoratorSet decorators, Register obj) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void MacroAssembler::safepoint_poll(Register tmp1, Label& slow_path) {
|
void MacroAssembler::safepoint_poll(Register tmp1, Label& slow_path) {
|
||||||
if (SafepointMechanism::uses_thread_local_poll()) {
|
ldr_u32(tmp1, Address(Rthread, Thread::polling_page_offset()));
|
||||||
ldr_u32(tmp1, Address(Rthread, Thread::polling_page_offset()));
|
tst(tmp1, exact_log2(SafepointMechanism::poll_bit()));
|
||||||
tst(tmp1, exact_log2(SafepointMechanism::poll_bit()));
|
b(slow_path, eq);
|
||||||
b(slow_path, eq);
|
|
||||||
} else {
|
|
||||||
ldr_global_s32(tmp1, SafepointSynchronize::address_of_state());
|
|
||||||
cmp(tmp1, SafepointSynchronize::_not_synchronized);
|
|
||||||
b(slow_path, ne);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void MacroAssembler::get_polling_page(Register dest) {
|
void MacroAssembler::get_polling_page(Register dest) {
|
||||||
if (SafepointMechanism::uses_thread_local_poll()) {
|
ldr(dest, Address(Rthread, Thread::polling_page_offset()));
|
||||||
ldr(dest, Address(Rthread, Thread::polling_page_offset()));
|
|
||||||
} else {
|
|
||||||
mov_address(dest, os::get_polling_page());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void MacroAssembler::read_polling_page(Register dest, relocInfo::relocType rtype) {
|
void MacroAssembler::read_polling_page(Register dest, relocInfo::relocType rtype) {
|
||||||
|
|
|
@ -1802,15 +1802,13 @@ SafepointBlob* SharedRuntime::generate_handler_blob(address call_ptr, int poll_t
|
||||||
__ reset_last_Java_frame(Rtemp); // Rtemp free since scratched by far call
|
__ reset_last_Java_frame(Rtemp); // Rtemp free since scratched by far call
|
||||||
|
|
||||||
if (!cause_return) {
|
if (!cause_return) {
|
||||||
if (SafepointMechanism::uses_thread_local_poll()) {
|
// If our stashed return pc was modified by the runtime we avoid touching it
|
||||||
// If our stashed return pc was modified by the runtime we avoid touching it
|
__ ldr(R3_tmp, Address(Rthread, JavaThread::saved_exception_pc_offset()));
|
||||||
__ ldr(R3_tmp, Address(Rthread, JavaThread::saved_exception_pc_offset()));
|
__ ldr(R2_tmp, Address(SP, RegisterSaver::LR_offset * wordSize));
|
||||||
__ ldr(R2_tmp, Address(SP, RegisterSaver::LR_offset * wordSize));
|
__ cmp(R2_tmp, R3_tmp);
|
||||||
__ cmp(R2_tmp, R3_tmp);
|
// Adjust return pc forward to step over the safepoint poll instruction
|
||||||
// Adjust return pc forward to step over the safepoint poll instruction
|
__ add(R2_tmp, R2_tmp, 4, eq);
|
||||||
__ add(R2_tmp, R2_tmp, 4, eq);
|
__ str(R2_tmp, Address(SP, RegisterSaver::LR_offset * wordSize), eq);
|
||||||
__ str(R2_tmp, Address(SP, RegisterSaver::LR_offset * wordSize), eq);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check for pending exception
|
// Check for pending exception
|
||||||
__ ldr(Rtemp, Address(Rthread, Thread::pending_exception_offset()));
|
__ ldr(Rtemp, Address(Rthread, Thread::pending_exception_offset()));
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2000, 2019, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2000, 2020, Oracle and/or its affiliates. All rights reserved.
|
||||||
* Copyright (c) 2012, 2019, SAP SE. All rights reserved.
|
* Copyright (c) 2012, 2019, SAP SE. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
|
@ -1335,11 +1335,7 @@ void LIR_Assembler::return_op(LIR_Opr result) {
|
||||||
__ pop_frame();
|
__ pop_frame();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (SafepointMechanism::uses_thread_local_poll()) {
|
__ ld(polling_page, in_bytes(Thread::polling_page_offset()), R16_thread);
|
||||||
__ ld(polling_page, in_bytes(Thread::polling_page_offset()), R16_thread);
|
|
||||||
} else {
|
|
||||||
__ load_const_optimized(polling_page, (long)(address) os::get_polling_page(), R0);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Restore return pc relative to callers' sp.
|
// Restore return pc relative to callers' sp.
|
||||||
__ ld(return_pc, _abi(lr), R1_SP);
|
__ ld(return_pc, _abi(lr), R1_SP);
|
||||||
|
@ -1362,11 +1358,7 @@ void LIR_Assembler::return_op(LIR_Opr result) {
|
||||||
|
|
||||||
int LIR_Assembler::safepoint_poll(LIR_Opr tmp, CodeEmitInfo* info) {
|
int LIR_Assembler::safepoint_poll(LIR_Opr tmp, CodeEmitInfo* info) {
|
||||||
const Register poll_addr = tmp->as_register();
|
const Register poll_addr = tmp->as_register();
|
||||||
if (SafepointMechanism::uses_thread_local_poll()) {
|
__ ld(poll_addr, in_bytes(Thread::polling_page_offset()), R16_thread);
|
||||||
__ ld(poll_addr, in_bytes(Thread::polling_page_offset()), R16_thread);
|
|
||||||
} else {
|
|
||||||
__ load_const_optimized(poll_addr, (intptr_t)os::get_polling_page(), R0);
|
|
||||||
}
|
|
||||||
if (info != NULL) {
|
if (info != NULL) {
|
||||||
add_debug_info_for_branch(info);
|
add_debug_info_for_branch(info);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 1999, 2019, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 1999, 2020, Oracle and/or its affiliates. All rights reserved.
|
||||||
* Copyright (c) 2012, 2016 SAP SE. All rights reserved.
|
* Copyright (c) 2012, 2016 SAP SE. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
|
@ -64,7 +64,6 @@ const bool CCallingConventionRequiresIntsAsLongs = true;
|
||||||
|
|
||||||
#define SUPPORT_RESERVED_STACK_AREA
|
#define SUPPORT_RESERVED_STACK_AREA
|
||||||
|
|
||||||
#define THREAD_LOCAL_POLL
|
|
||||||
// If UseSIGTRAP is active, we only use the poll bit and no polling page.
|
// If UseSIGTRAP is active, we only use the poll bit and no polling page.
|
||||||
// Otherwise, we fall back to usage of the polling page in nmethods.
|
// Otherwise, we fall back to usage of the polling page in nmethods.
|
||||||
// Define the condition to use this -XX flag.
|
// Define the condition to use this -XX flag.
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2003, 2018, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2003, 2020, Oracle and/or its affiliates. All rights reserved.
|
||||||
* Copyright (c) 2012, 2018 SAP SE. All rights reserved.
|
* Copyright (c) 2012, 2018 SAP SE. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
|
@ -218,7 +218,7 @@ void InterpreterMacroAssembler::dispatch_Lbyte_code(TosState state, Register byt
|
||||||
// Calc dispatch table address.
|
// Calc dispatch table address.
|
||||||
load_dispatch_table(R11_scratch1, table);
|
load_dispatch_table(R11_scratch1, table);
|
||||||
|
|
||||||
if (SafepointMechanism::uses_thread_local_poll() && generate_poll) {
|
if (generate_poll) {
|
||||||
address *sfpt_tbl = Interpreter::safept_table(state);
|
address *sfpt_tbl = Interpreter::safept_table(state);
|
||||||
if (table != sfpt_tbl) {
|
if (table != sfpt_tbl) {
|
||||||
Label dispatch;
|
Label dispatch;
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 1997, 2019, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 1997, 2020, Oracle and/or its affiliates. All rights reserved.
|
||||||
* Copyright (c) 2012, 2019, SAP SE. All rights reserved.
|
* Copyright (c) 2012, 2019, SAP SE. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
|
@ -1294,7 +1294,7 @@ bool MacroAssembler::is_load_from_polling_page(int instruction, void* ucontext,
|
||||||
if (polling_address_ptr != NULL) {
|
if (polling_address_ptr != NULL) {
|
||||||
*polling_address_ptr = addr;
|
*polling_address_ptr = addr;
|
||||||
}
|
}
|
||||||
return os::is_poll_address(addr);
|
return SafepointMechanism::is_poll_address(addr);
|
||||||
#else
|
#else
|
||||||
// Not on Linux, ucontext must be NULL.
|
// Not on Linux, ucontext must be NULL.
|
||||||
ShouldNotReachHere();
|
ShouldNotReachHere();
|
||||||
|
@ -3037,14 +3037,9 @@ void MacroAssembler::compiler_fast_unlock_object(ConditionRegister flag, Registe
|
||||||
}
|
}
|
||||||
|
|
||||||
void MacroAssembler::safepoint_poll(Label& slow_path, Register temp_reg) {
|
void MacroAssembler::safepoint_poll(Label& slow_path, Register temp_reg) {
|
||||||
if (SafepointMechanism::uses_thread_local_poll()) {
|
ld(temp_reg, in_bytes(Thread::polling_page_offset()), R16_thread);
|
||||||
ld(temp_reg, in_bytes(Thread::polling_page_offset()), R16_thread);
|
// Armed page has poll_bit set.
|
||||||
// Armed page has poll_bit set.
|
andi_(temp_reg, temp_reg, SafepointMechanism::poll_bit());
|
||||||
andi_(temp_reg, temp_reg, SafepointMechanism::poll_bit());
|
|
||||||
} else {
|
|
||||||
lwz(temp_reg, (RegisterOrConstant)(intptr_t)SafepointSynchronize::address_of_state());
|
|
||||||
cmpwi(CCR0, temp_reg, SafepointSynchronize::_not_synchronized);
|
|
||||||
}
|
|
||||||
bne(CCR0, slow_path);
|
bne(CCR0, slow_path);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2002, 2019, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2002, 2020, Oracle and/or its affiliates. All rights reserved.
|
||||||
* Copyright (c) 2012, 2015 SAP SE. All rights reserved.
|
* Copyright (c) 2012, 2015 SAP SE. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
|
@ -267,7 +267,7 @@ inline address MacroAssembler::last_calls_return_pc() {
|
||||||
|
|
||||||
// Read from the polling page, its address is already in a register.
|
// 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) {
|
inline void MacroAssembler::load_from_polling_page(Register polling_page_address, int offset) {
|
||||||
if (SafepointMechanism::uses_thread_local_poll() && USE_POLL_BIT_ONLY) {
|
if (USE_POLL_BIT_ONLY) {
|
||||||
int encoding = SafepointMechanism::poll_bit();
|
int encoding = SafepointMechanism::poll_bit();
|
||||||
tdi(traptoGreaterThanUnsigned | traptoEqual, polling_page_address, encoding);
|
tdi(traptoGreaterThanUnsigned | traptoEqual, polling_page_address, encoding);
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2002, 2019, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2002, 2020, Oracle and/or its affiliates. All rights reserved.
|
||||||
* Copyright (c) 2012, 2018 SAP SE. All rights reserved.
|
* Copyright (c) 2012, 2018 SAP SE. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
|
@ -92,7 +92,7 @@ class NativeInstruction {
|
||||||
bool is_safepoint_poll() {
|
bool is_safepoint_poll() {
|
||||||
// Is the current instruction a POTENTIAL read access to the polling page?
|
// Is the current instruction a POTENTIAL read access to the polling page?
|
||||||
// The current arguments of the instruction are not checked!
|
// The current arguments of the instruction are not checked!
|
||||||
if (SafepointMechanism::uses_thread_local_poll() && USE_POLL_BIT_ONLY) {
|
if (USE_POLL_BIT_ONLY) {
|
||||||
int encoding = SafepointMechanism::poll_bit();
|
int encoding = SafepointMechanism::poll_bit();
|
||||||
return MacroAssembler::is_tdi(long_at(0), Assembler::traptoGreaterThanUnsigned | Assembler::traptoEqual,
|
return MacroAssembler::is_tdi(long_at(0), Assembler::traptoGreaterThanUnsigned | Assembler::traptoEqual,
|
||||||
-1, encoding);
|
-1, encoding);
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
//
|
//
|
||||||
// Copyright (c) 2011, 2019, Oracle and/or its affiliates. All rights reserved.
|
// Copyright (c) 2011, 2020, Oracle and/or its affiliates. All rights reserved.
|
||||||
// Copyright (c) 2012, 2019 SAP SE. All rights reserved.
|
// Copyright (c) 2012, 2019 SAP SE. All rights reserved.
|
||||||
// DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
// DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
//
|
//
|
||||||
|
@ -1589,11 +1589,7 @@ void MachEpilogNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (method_needs_polling) {
|
if (method_needs_polling) {
|
||||||
if (SafepointMechanism::uses_thread_local_poll()) {
|
__ ld(polling_page, in_bytes(JavaThread::polling_page_offset()), R16_thread);
|
||||||
__ ld(polling_page, in_bytes(JavaThread::polling_page_offset()), R16_thread);
|
|
||||||
} else {
|
|
||||||
__ load_const_optimized(polling_page, (long)(address) os::get_polling_page());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!method_is_frameless) {
|
if (!method_is_frameless) {
|
||||||
|
@ -1629,14 +1625,6 @@ const Pipeline * MachEpilogNode::pipeline() const {
|
||||||
return MachNode::pipeline_class();
|
return MachNode::pipeline_class();
|
||||||
}
|
}
|
||||||
|
|
||||||
// This method seems to be obsolete. It is declared in machnode.hpp
|
|
||||||
// and defined in all *.ad files, but it is never called. Should we
|
|
||||||
// get rid of it?
|
|
||||||
int MachEpilogNode::safepoint_offset() const {
|
|
||||||
assert(do_polling(), "no return for this epilog node");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
#if 0 // TODO: PPC port
|
#if 0 // TODO: PPC port
|
||||||
void MachLoadPollAddrLateNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const {
|
void MachLoadPollAddrLateNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const {
|
||||||
C2_MacroAssembler _masm(&cbuf);
|
C2_MacroAssembler _masm(&cbuf);
|
||||||
|
|
|
@ -3228,7 +3228,7 @@ SafepointBlob* SharedRuntime::generate_handler_blob(address call_ptr, int poll_t
|
||||||
// No exception case.
|
// No exception case.
|
||||||
__ BIND(noException);
|
__ BIND(noException);
|
||||||
|
|
||||||
if (SafepointMechanism::uses_thread_local_poll() && !cause_return) {
|
if (!cause_return) {
|
||||||
Label no_adjust;
|
Label no_adjust;
|
||||||
// If our stashed return pc was modified by the runtime we avoid touching it
|
// If our stashed return pc was modified by the runtime we avoid touching it
|
||||||
__ ld(R0, frame_size_in_bytes + _abi(lr), R1_SP);
|
__ ld(R0, frame_size_in_bytes + _abi(lr), R1_SP);
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2014, 2018, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2014, 2020, Oracle and/or its affiliates. All rights reserved.
|
||||||
* Copyright (c) 2013, 2017 SAP SE. All rights reserved.
|
* Copyright (c) 2013, 2017 SAP SE. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
|
@ -2176,7 +2176,7 @@ void TemplateTable::_return(TosState state) {
|
||||||
__ bind(Lskip_register_finalizer);
|
__ bind(Lskip_register_finalizer);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (SafepointMechanism::uses_thread_local_poll() && _desc->bytecode() != Bytecodes::_return_register_finalizer) {
|
if (_desc->bytecode() != Bytecodes::_return_register_finalizer) {
|
||||||
Label no_safepoint;
|
Label no_safepoint;
|
||||||
__ ld(R11_scratch1, in_bytes(Thread::polling_page_offset()), R16_thread);
|
__ ld(R11_scratch1, in_bytes(Thread::polling_page_offset()), R16_thread);
|
||||||
__ andi_(R11_scratch1, R11_scratch1, SafepointMechanism::poll_bit());
|
__ andi_(R11_scratch1, R11_scratch1, SafepointMechanism::poll_bit());
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2016, 2019, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2016, 2020, Oracle and/or its affiliates. All rights reserved.
|
||||||
* Copyright (c) 2016, 2019, SAP SE. All rights reserved.
|
* Copyright (c) 2016, 2019, SAP SE. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
|
@ -1214,12 +1214,7 @@ void LIR_Assembler::return_op(LIR_Opr result) {
|
||||||
(result->is_single_fpu() && result->as_float_reg() == Z_F0) ||
|
(result->is_single_fpu() && result->as_float_reg() == Z_F0) ||
|
||||||
(result->is_double_fpu() && result->as_double_reg() == Z_F0), "convention");
|
(result->is_double_fpu() && result->as_double_reg() == Z_F0), "convention");
|
||||||
|
|
||||||
if (SafepointMechanism::uses_thread_local_poll()) {
|
__ z_lg(Z_R1_scratch, Address(Z_thread, Thread::polling_page_offset()));
|
||||||
__ z_lg(Z_R1_scratch, Address(Z_thread, Thread::polling_page_offset()));
|
|
||||||
} else {
|
|
||||||
AddressLiteral pp(os::get_polling_page());
|
|
||||||
__ load_const_optimized(Z_R1_scratch, pp);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Pop the frame before the safepoint code.
|
// Pop the frame before the safepoint code.
|
||||||
__ pop_frame_restore_retPC(initial_frame_size_in_bytes());
|
__ pop_frame_restore_retPC(initial_frame_size_in_bytes());
|
||||||
|
@ -1238,12 +1233,7 @@ void LIR_Assembler::return_op(LIR_Opr result) {
|
||||||
|
|
||||||
int LIR_Assembler::safepoint_poll(LIR_Opr tmp, CodeEmitInfo* info) {
|
int LIR_Assembler::safepoint_poll(LIR_Opr tmp, CodeEmitInfo* info) {
|
||||||
const Register poll_addr = tmp->as_register_lo();
|
const Register poll_addr = tmp->as_register_lo();
|
||||||
if (SafepointMechanism::uses_thread_local_poll()) {
|
__ z_lg(poll_addr, Address(Z_thread, Thread::polling_page_offset()));
|
||||||
__ z_lg(poll_addr, Address(Z_thread, Thread::polling_page_offset()));
|
|
||||||
} else {
|
|
||||||
AddressLiteral pp(os::get_polling_page());
|
|
||||||
__ load_const_optimized(poll_addr, pp);
|
|
||||||
}
|
|
||||||
guarantee(info != NULL, "Shouldn't be NULL");
|
guarantee(info != NULL, "Shouldn't be NULL");
|
||||||
add_debug_info_for_branch(info);
|
add_debug_info_for_branch(info);
|
||||||
int offset = __ offset();
|
int offset = __ offset();
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2016, 2019, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2016, 2020, Oracle and/or its affiliates. All rights reserved.
|
||||||
* Copyright (c) 2016 SAP SE. All rights reserved.
|
* Copyright (c) 2016 SAP SE. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
|
@ -56,6 +56,4 @@ const bool CCallingConventionRequiresIntsAsLongs = true;
|
||||||
|
|
||||||
#define SUPPORT_RESERVED_STACK_AREA
|
#define SUPPORT_RESERVED_STACK_AREA
|
||||||
|
|
||||||
#define THREAD_LOCAL_POLL
|
|
||||||
|
|
||||||
#endif // CPU_S390_GLOBALDEFINITIONS_S390_HPP
|
#endif // CPU_S390_GLOBALDEFINITIONS_S390_HPP
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2016, 2019, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2016, 2020, Oracle and/or its affiliates. All rights reserved.
|
||||||
* Copyright (c) 2016, 2019 SAP SE. All rights reserved.
|
* Copyright (c) 2016, 2019 SAP SE. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
|
@ -116,7 +116,7 @@ void InterpreterMacroAssembler::dispatch_base(TosState state, address* table, bo
|
||||||
// Dispatch table to use.
|
// Dispatch table to use.
|
||||||
load_absolute_address(Z_tmp_1, (address)table); // Z_tmp_1 = table;
|
load_absolute_address(Z_tmp_1, (address)table); // Z_tmp_1 = table;
|
||||||
|
|
||||||
if (SafepointMechanism::uses_thread_local_poll() && generate_poll) {
|
if (generate_poll) {
|
||||||
address *sfpt_tbl = Interpreter::safept_table(state);
|
address *sfpt_tbl = Interpreter::safept_table(state);
|
||||||
if (table != sfpt_tbl) {
|
if (table != sfpt_tbl) {
|
||||||
Label dispatch;
|
Label dispatch;
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2016, 2019, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2016, 2020, Oracle and/or its affiliates. All rights reserved.
|
||||||
* Copyright (c) 2016, 2019, SAP SE. All rights reserved.
|
* Copyright (c) 2016, 2019, SAP SE. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
|
@ -2684,16 +2684,10 @@ uint MacroAssembler::get_poll_register(address instr_loc) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void MacroAssembler::safepoint_poll(Label& slow_path, Register temp_reg) {
|
void MacroAssembler::safepoint_poll(Label& slow_path, Register temp_reg) {
|
||||||
if (SafepointMechanism::uses_thread_local_poll()) {
|
const Address poll_byte_addr(Z_thread, in_bytes(Thread::polling_page_offset()) + 7 /* Big Endian */);
|
||||||
const Address poll_byte_addr(Z_thread, in_bytes(Thread::polling_page_offset()) + 7 /* Big Endian */);
|
// Armed page has poll_bit set.
|
||||||
// Armed page has poll_bit set.
|
z_tm(poll_byte_addr, SafepointMechanism::poll_bit());
|
||||||
z_tm(poll_byte_addr, SafepointMechanism::poll_bit());
|
z_brnaz(slow_path);
|
||||||
z_brnaz(slow_path);
|
|
||||||
} else {
|
|
||||||
load_const_optimized(temp_reg, SafepointSynchronize::address_of_state());
|
|
||||||
z_cli(/*SafepointSynchronize::sz_state()*/4-1, temp_reg, SafepointSynchronize::_not_synchronized);
|
|
||||||
z_brne(slow_path);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Don't rely on register locking, always use Z_R1 as scratch register instead.
|
// Don't rely on register locking, always use Z_R1 as scratch register instead.
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
//
|
//
|
||||||
// Copyright (c) 2017, 2019, Oracle and/or its affiliates. All rights reserved.
|
// Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved.
|
||||||
// Copyright (c) 2017, 2019 SAP SE. All rights reserved.
|
// Copyright (c) 2017, 2019 SAP SE. All rights reserved.
|
||||||
// DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
// DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
//
|
//
|
||||||
|
@ -949,12 +949,7 @@ void MachEpilogNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const {
|
||||||
|
|
||||||
// Touch the polling page.
|
// Touch the polling page.
|
||||||
if (need_polling) {
|
if (need_polling) {
|
||||||
if (SafepointMechanism::uses_thread_local_poll()) {
|
__ z_lg(Z_R1_scratch, Address(Z_thread, Thread::polling_page_offset()));
|
||||||
__ z_lg(Z_R1_scratch, Address(Z_thread, Thread::polling_page_offset()));
|
|
||||||
} else {
|
|
||||||
AddressLiteral pp(os::get_polling_page());
|
|
||||||
__ load_const_optimized(Z_R1_scratch, pp);
|
|
||||||
}
|
|
||||||
// We need to mark the code position where the load from the safepoint
|
// We need to mark the code position where the load from the safepoint
|
||||||
// polling page was emitted as relocInfo::poll_return_type here.
|
// polling page was emitted as relocInfo::poll_return_type here.
|
||||||
__ relocate(relocInfo::poll_return_type);
|
__ relocate(relocInfo::poll_return_type);
|
||||||
|
@ -976,11 +971,6 @@ const Pipeline * MachEpilogNode::pipeline() const {
|
||||||
return MachNode::pipeline_class();
|
return MachNode::pipeline_class();
|
||||||
}
|
}
|
||||||
|
|
||||||
int MachEpilogNode::safepoint_offset() const {
|
|
||||||
assert(do_polling(), "no return for this epilog node");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
//=============================================================================
|
//=============================================================================
|
||||||
|
|
||||||
// Figure out which register class each belongs in: rc_int, rc_float, rc_stack.
|
// Figure out which register class each belongs in: rc_int, rc_float, rc_stack.
|
||||||
|
|
|
@ -3217,7 +3217,7 @@ SafepointBlob* SharedRuntime::generate_handler_blob(address call_ptr, int poll_t
|
||||||
// Save registers, fpu state, and flags
|
// Save registers, fpu state, and flags
|
||||||
map = RegisterSaver::save_live_registers(masm, RegisterSaver::all_registers);
|
map = RegisterSaver::save_live_registers(masm, RegisterSaver::all_registers);
|
||||||
|
|
||||||
if (SafepointMechanism::uses_thread_local_poll() && !cause_return) {
|
if (!cause_return) {
|
||||||
// Keep a copy of the return pc to detect if it gets modified.
|
// Keep a copy of the return pc to detect if it gets modified.
|
||||||
__ z_lgr(Z_R6, Z_R14);
|
__ z_lgr(Z_R6, Z_R14);
|
||||||
}
|
}
|
||||||
|
@ -3257,7 +3257,7 @@ SafepointBlob* SharedRuntime::generate_handler_blob(address call_ptr, int poll_t
|
||||||
// No exception case
|
// No exception case
|
||||||
__ bind(noException);
|
__ bind(noException);
|
||||||
|
|
||||||
if (SafepointMechanism::uses_thread_local_poll() && !cause_return) {
|
if (!cause_return) {
|
||||||
Label no_adjust;
|
Label no_adjust;
|
||||||
// If our stashed return pc was modified by the runtime we avoid touching it
|
// If our stashed return pc was modified by the runtime we avoid touching it
|
||||||
const int offset_of_return_pc = _z_abi16(return_pc) + RegisterSaver::live_reg_frame_size(RegisterSaver::all_registers);
|
const int offset_of_return_pc = _z_abi16(return_pc) + RegisterSaver::live_reg_frame_size(RegisterSaver::all_registers);
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2016, 2020, Oracle and/or its affiliates. All rights reserved.
|
||||||
* Copyright (c) 2016, 2018 SAP SE. All rights reserved.
|
* Copyright (c) 2016, 2018 SAP SE. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
|
@ -2379,7 +2379,7 @@ void TemplateTable::_return(TosState state) {
|
||||||
__ bind(skip_register_finalizer);
|
__ bind(skip_register_finalizer);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (SafepointMechanism::uses_thread_local_poll() && _desc->bytecode() != Bytecodes::_return_register_finalizer) {
|
if (_desc->bytecode() != Bytecodes::_return_register_finalizer) {
|
||||||
Label no_safepoint;
|
Label no_safepoint;
|
||||||
const Address poll_byte_addr(Z_thread, in_bytes(Thread::polling_page_offset()) + 7 /* Big Endian */);
|
const Address poll_byte_addr(Z_thread, in_bytes(Thread::polling_page_offset()) + 7 /* Big Endian */);
|
||||||
__ z_tm(poll_byte_addr, SafepointMechanism::poll_bit());
|
__ z_tm(poll_byte_addr, SafepointMechanism::poll_bit());
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2000, 2019, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2000, 2020, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
@ -1428,11 +1428,7 @@ void LIR_Assembler::return_op(LIR_Opr result) {
|
||||||
if (StackReservedPages > 0 && compilation()->has_reserved_stack_access()) {
|
if (StackReservedPages > 0 && compilation()->has_reserved_stack_access()) {
|
||||||
__ reserved_stack_check();
|
__ reserved_stack_check();
|
||||||
}
|
}
|
||||||
if (SafepointMechanism::uses_thread_local_poll()) {
|
__ ld_ptr(Address(G2_thread, Thread::polling_page_offset()), L0);
|
||||||
__ ld_ptr(Address(G2_thread, Thread::polling_page_offset()), L0);
|
|
||||||
} else {
|
|
||||||
__ set((intptr_t)os::get_polling_page(), L0);
|
|
||||||
}
|
|
||||||
__ relocate(relocInfo::poll_return_type);
|
__ relocate(relocInfo::poll_return_type);
|
||||||
__ ld_ptr(L0, 0, G0);
|
__ ld_ptr(L0, 0, G0);
|
||||||
__ ret();
|
__ ret();
|
||||||
|
@ -1441,11 +1437,7 @@ void LIR_Assembler::return_op(LIR_Opr result) {
|
||||||
|
|
||||||
|
|
||||||
int LIR_Assembler::safepoint_poll(LIR_Opr tmp, CodeEmitInfo* info) {
|
int LIR_Assembler::safepoint_poll(LIR_Opr tmp, CodeEmitInfo* info) {
|
||||||
if (SafepointMechanism::uses_thread_local_poll()) {
|
__ ld_ptr(Address(G2_thread, Thread::polling_page_offset()), tmp->as_register());
|
||||||
__ ld_ptr(Address(G2_thread, Thread::polling_page_offset()), tmp->as_register());
|
|
||||||
} else {
|
|
||||||
__ set((intptr_t)os::get_polling_page(), tmp->as_register());
|
|
||||||
}
|
|
||||||
if (info != NULL) {
|
if (info != NULL) {
|
||||||
add_debug_info_for_branch(info);
|
add_debug_info_for_branch(info);
|
||||||
}
|
}
|
||||||
|
|
|
@ -56,7 +56,4 @@ const bool CCallingConventionRequiresIntsAsLongs = true;
|
||||||
#define SUPPORT_RESERVED_STACK_AREA
|
#define SUPPORT_RESERVED_STACK_AREA
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// SPARC have implemented the local polling
|
|
||||||
#define THREAD_LOCAL_POLL
|
|
||||||
|
|
||||||
#endif // CPU_SPARC_GLOBALDEFINITIONS_SPARC_HPP
|
#endif // CPU_SPARC_GLOBALDEFINITIONS_SPARC_HPP
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 1997, 2020, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
@ -271,7 +271,7 @@ void InterpreterMacroAssembler::dispatch_Lbyte_code(TosState state, address* tab
|
||||||
AddressLiteral tbl(table);
|
AddressLiteral tbl(table);
|
||||||
Label dispatch;
|
Label dispatch;
|
||||||
|
|
||||||
if (SafepointMechanism::uses_thread_local_poll() && generate_poll) {
|
if (generate_poll) {
|
||||||
AddressLiteral sfpt_tbl(Interpreter::safept_table(state));
|
AddressLiteral sfpt_tbl(Interpreter::safept_table(state));
|
||||||
Label no_safepoint;
|
Label no_safepoint;
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 1997, 2020, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
@ -236,18 +236,10 @@ void MacroAssembler::breakpoint_trap() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void MacroAssembler::safepoint_poll(Label& slow_path, bool a, Register thread_reg, Register temp_reg) {
|
void MacroAssembler::safepoint_poll(Label& slow_path, bool a, Register thread_reg, Register temp_reg) {
|
||||||
if (SafepointMechanism::uses_thread_local_poll()) {
|
ldx(Address(thread_reg, Thread::polling_page_offset()), temp_reg, 0);
|
||||||
ldx(Address(thread_reg, Thread::polling_page_offset()), temp_reg, 0);
|
// Armed page has poll bit set.
|
||||||
// Armed page has poll bit set.
|
and3(temp_reg, SafepointMechanism::poll_bit(), temp_reg);
|
||||||
and3(temp_reg, SafepointMechanism::poll_bit(), temp_reg);
|
br_notnull(temp_reg, a, Assembler::pn, slow_path);
|
||||||
br_notnull(temp_reg, a, Assembler::pn, slow_path);
|
|
||||||
} else {
|
|
||||||
AddressLiteral sync_state(SafepointSynchronize::address_of_state());
|
|
||||||
|
|
||||||
load_contents(sync_state, temp_reg);
|
|
||||||
cmp(temp_reg, SafepointSynchronize::_not_synchronized);
|
|
||||||
br(Assembler::notEqual, a, Assembler::pn, slow_path);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void MacroAssembler::enter() {
|
void MacroAssembler::enter() {
|
||||||
|
|
|
@ -3086,7 +3086,7 @@ SafepointBlob* SharedRuntime::generate_handler_blob(address call_ptr, int poll_t
|
||||||
__ set_last_Java_frame(SP, noreg);
|
__ set_last_Java_frame(SP, noreg);
|
||||||
|
|
||||||
Register saved_O7 = O7->after_save();
|
Register saved_O7 = O7->after_save();
|
||||||
if (!cause_return && SafepointMechanism::uses_thread_local_poll()) {
|
if (!cause_return) {
|
||||||
// Keep a copy of the return pc in L0 to detect if it gets modified
|
// Keep a copy of the return pc in L0 to detect if it gets modified
|
||||||
__ mov(saved_O7, L0);
|
__ mov(saved_O7, L0);
|
||||||
// Adjust and keep a copy of our npc saved by the signal handler
|
// Adjust and keep a copy of our npc saved by the signal handler
|
||||||
|
@ -3117,7 +3117,7 @@ SafepointBlob* SharedRuntime::generate_handler_blob(address call_ptr, int poll_t
|
||||||
__ ld_ptr(G2_thread, in_bytes(Thread::pending_exception_offset()), O1);
|
__ ld_ptr(G2_thread, in_bytes(Thread::pending_exception_offset()), O1);
|
||||||
__ br_notnull_short(O1, Assembler::pn, pending);
|
__ br_notnull_short(O1, Assembler::pn, pending);
|
||||||
|
|
||||||
if (!cause_return && SafepointMechanism::uses_thread_local_poll()) {
|
if (!cause_return) {
|
||||||
// If nobody modified our return pc then we must return to the npc which he saved in L1
|
// If nobody modified our return pc then we must return to the npc which he saved in L1
|
||||||
__ cmp(saved_O7, L0);
|
__ cmp(saved_O7, L0);
|
||||||
__ movcc(Assembler::equal, false, Assembler::ptr_cc, L1, saved_O7);
|
__ movcc(Assembler::equal, false, Assembler::ptr_cc, L1, saved_O7);
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
//
|
//
|
||||||
// Copyright (c) 1998, 2019, Oracle and/or its affiliates. All rights reserved.
|
// Copyright (c) 1998, 2020, Oracle and/or its affiliates. All rights reserved.
|
||||||
// DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
// DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
//
|
//
|
||||||
// This code is free software; you can redistribute it and/or modify it
|
// This code is free software; you can redistribute it and/or modify it
|
||||||
|
@ -1206,11 +1206,7 @@ void MachEpilogNode::format( PhaseRegAlloc *ra_, outputStream *st ) const {
|
||||||
Compile* C = ra_->C;
|
Compile* C = ra_->C;
|
||||||
|
|
||||||
if(do_polling() && ra_->C->is_method_compilation()) {
|
if(do_polling() && ra_->C->is_method_compilation()) {
|
||||||
if (SafepointMechanism::uses_global_page_poll()) {
|
st->print("LDX [R_G2 + #poll_offset],L0\t! Load local polling address\n\t");
|
||||||
st->print("SETHI #PollAddr,L0\t! Load Polling address\n\t");
|
|
||||||
} else {
|
|
||||||
st->print("LDX [R_G2 + #poll_offset],L0\t! Load local polling address\n\t");
|
|
||||||
}
|
|
||||||
st->print("LDX [L0],G0\t!Poll for Safepointing\n\t");
|
st->print("LDX [L0],G0\t!Poll for Safepointing\n\t");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1237,12 +1233,7 @@ void MachEpilogNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const {
|
||||||
|
|
||||||
// If this does safepoint polling, then do it here
|
// If this does safepoint polling, then do it here
|
||||||
if(do_polling() && ra_->C->is_method_compilation()) {
|
if(do_polling() && ra_->C->is_method_compilation()) {
|
||||||
if (SafepointMechanism::uses_thread_local_poll()) {
|
__ ld_ptr(Address(G2_thread, Thread::polling_page_offset()), L0);
|
||||||
__ ld_ptr(Address(G2_thread, Thread::polling_page_offset()), L0);
|
|
||||||
} else {
|
|
||||||
AddressLiteral polling_page(os::get_polling_page());
|
|
||||||
__ sethi(polling_page, L0);
|
|
||||||
}
|
|
||||||
__ relocate(relocInfo::poll_return_type);
|
__ relocate(relocInfo::poll_return_type);
|
||||||
__ ld_ptr(L0, 0, G0);
|
__ ld_ptr(L0, 0, G0);
|
||||||
}
|
}
|
||||||
|
@ -1273,12 +1264,6 @@ const Pipeline * MachEpilogNode::pipeline() const {
|
||||||
return MachNode::pipeline_class();
|
return MachNode::pipeline_class();
|
||||||
}
|
}
|
||||||
|
|
||||||
int MachEpilogNode::safepoint_offset() const {
|
|
||||||
assert(SafepointMechanism::uses_global_page_poll(), "sanity");
|
|
||||||
assert( do_polling(), "no return for this epilog node");
|
|
||||||
return MacroAssembler::insts_for_sethi(os::get_polling_page()) * BytesPerInstWord;
|
|
||||||
}
|
|
||||||
|
|
||||||
//=============================================================================
|
//=============================================================================
|
||||||
|
|
||||||
// Figure out which register class each belongs in: rc_int, rc_float, rc_stack
|
// Figure out which register class each belongs in: rc_int, rc_float, rc_stack
|
||||||
|
@ -3375,15 +3360,6 @@ operand immP0() %{
|
||||||
interface(CONST_INTER);
|
interface(CONST_INTER);
|
||||||
%}
|
%}
|
||||||
|
|
||||||
operand immP_poll() %{
|
|
||||||
predicate(n->get_ptr() != 0 && n->get_ptr() == (intptr_t)os::get_polling_page());
|
|
||||||
match(ConP);
|
|
||||||
|
|
||||||
// formats are generated automatically for constants and base registers
|
|
||||||
format %{ %}
|
|
||||||
interface(CONST_INTER);
|
|
||||||
%}
|
|
||||||
|
|
||||||
// Pointer Immediate
|
// Pointer Immediate
|
||||||
operand immN()
|
operand immN()
|
||||||
%{
|
%{
|
||||||
|
@ -4492,12 +4468,6 @@ pipe_class loadConP( iRegP dst, immP src ) %{
|
||||||
fixed_latency(6);
|
fixed_latency(6);
|
||||||
%}
|
%}
|
||||||
|
|
||||||
// Polling Address
|
|
||||||
pipe_class loadConP_poll( iRegP dst, immP_poll src ) %{
|
|
||||||
instruction_count(0); multiple_bundles;
|
|
||||||
fixed_latency(6);
|
|
||||||
%}
|
|
||||||
|
|
||||||
// Long Constant small
|
// Long Constant small
|
||||||
pipe_class loadConLlo( iRegL dst, immL src ) %{
|
pipe_class loadConLlo( iRegL dst, immL src ) %{
|
||||||
instruction_count(2);
|
instruction_count(2);
|
||||||
|
@ -5883,17 +5853,6 @@ instruct loadConP0(iRegP dst, immP0 src) %{
|
||||||
ins_pipe(ialu_imm);
|
ins_pipe(ialu_imm);
|
||||||
%}
|
%}
|
||||||
|
|
||||||
instruct loadConP_poll(iRegP dst, immP_poll src) %{
|
|
||||||
match(Set dst src);
|
|
||||||
ins_cost(DEFAULT_COST);
|
|
||||||
format %{ "SET $src,$dst\t!ptr" %}
|
|
||||||
ins_encode %{
|
|
||||||
AddressLiteral polling_page(os::get_polling_page());
|
|
||||||
__ sethi(polling_page, reg_to_register_object($dst$$reg));
|
|
||||||
%}
|
|
||||||
ins_pipe(loadConP_poll);
|
|
||||||
%}
|
|
||||||
|
|
||||||
instruct loadConN0(iRegN dst, immN0 src) %{
|
instruct loadConN0(iRegN dst, immN0 src) %{
|
||||||
match(Set dst src);
|
match(Set dst src);
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 1997, 2019, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 1997, 2020, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
@ -2025,7 +2025,7 @@ void TemplateTable::_return(TosState state) {
|
||||||
__ bind(skip_register_finalizer);
|
__ bind(skip_register_finalizer);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (SafepointMechanism::uses_thread_local_poll() && _desc->bytecode() != Bytecodes::_return_register_finalizer) {
|
if (_desc->bytecode() != Bytecodes::_return_register_finalizer) {
|
||||||
Label no_safepoint;
|
Label no_safepoint;
|
||||||
__ ldx(Address(G2_thread, Thread::polling_page_offset()), G3_scratch, 0);
|
__ ldx(Address(G2_thread, Thread::polling_page_offset()), G3_scratch, 0);
|
||||||
__ btst(SafepointMechanism::poll_bit(), G3_scratch);
|
__ btst(SafepointMechanism::poll_bit(), G3_scratch);
|
||||||
|
|
|
@ -7732,15 +7732,6 @@ bool Assembler::reachable(AddressLiteral adr) {
|
||||||
return is_simm32(disp);
|
return is_simm32(disp);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if the polling page is not reachable from the code cache using rip-relative
|
|
||||||
// addressing.
|
|
||||||
bool Assembler::is_polling_page_far() {
|
|
||||||
intptr_t addr = (intptr_t)os::get_polling_page();
|
|
||||||
return ForceUnreachable ||
|
|
||||||
!is_simm32(addr - (intptr_t)CodeCache::low_bound()) ||
|
|
||||||
!is_simm32(addr - (intptr_t)CodeCache::high_bound());
|
|
||||||
}
|
|
||||||
|
|
||||||
void Assembler::emit_data64(jlong data,
|
void Assembler::emit_data64(jlong data,
|
||||||
relocInfo::relocType rtype,
|
relocInfo::relocType rtype,
|
||||||
int format) {
|
int format) {
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 1997, 2019, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 1997, 2020, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
@ -872,7 +872,6 @@ private:
|
||||||
static address locate_next_instruction(address inst);
|
static address locate_next_instruction(address inst);
|
||||||
|
|
||||||
// Utilities
|
// Utilities
|
||||||
static bool is_polling_page_far() NOT_LP64({ return false;});
|
|
||||||
static bool query_compressed_disp_byte(int disp, bool is_evex_inst, int vector_len,
|
static bool query_compressed_disp_byte(int disp, bool is_evex_inst, int vector_len,
|
||||||
int cur_tuple_type, int in_size_in_bits, int cur_encoding);
|
int cur_tuple_type, int in_size_in_bits, int cur_encoding);
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2000, 2019, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2000, 2020, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
@ -536,29 +536,17 @@ void LIR_Assembler::return_op(LIR_Opr result) {
|
||||||
// Note: we do not need to round double result; float result has the right precision
|
// Note: we do not need to round double result; float result has the right precision
|
||||||
// the poll sets the condition code, but no data registers
|
// the poll sets the condition code, but no data registers
|
||||||
|
|
||||||
if (SafepointMechanism::uses_thread_local_poll()) {
|
|
||||||
#ifdef _LP64
|
#ifdef _LP64
|
||||||
const Register poll_addr = rscratch1;
|
const Register poll_addr = rscratch1;
|
||||||
__ movptr(poll_addr, Address(r15_thread, Thread::polling_page_offset()));
|
__ movptr(poll_addr, Address(r15_thread, Thread::polling_page_offset()));
|
||||||
#else
|
#else
|
||||||
const Register poll_addr = rbx;
|
const Register poll_addr = rbx;
|
||||||
assert(FrameMap::is_caller_save_register(poll_addr), "will overwrite");
|
assert(FrameMap::is_caller_save_register(poll_addr), "will overwrite");
|
||||||
__ get_thread(poll_addr);
|
__ get_thread(poll_addr);
|
||||||
__ movptr(poll_addr, Address(poll_addr, Thread::polling_page_offset()));
|
__ movptr(poll_addr, Address(poll_addr, Thread::polling_page_offset()));
|
||||||
#endif
|
#endif
|
||||||
__ relocate(relocInfo::poll_return_type);
|
__ relocate(relocInfo::poll_return_type);
|
||||||
__ testl(rax, Address(poll_addr, 0));
|
__ testl(rax, Address(poll_addr, 0));
|
||||||
} else {
|
|
||||||
AddressLiteral polling_page(os::get_polling_page(), relocInfo::poll_return_type);
|
|
||||||
|
|
||||||
if (Assembler::is_polling_page_far()) {
|
|
||||||
__ lea(rscratch1, polling_page);
|
|
||||||
__ relocate(relocInfo::poll_return_type);
|
|
||||||
__ testl(rax, Address(rscratch1, 0));
|
|
||||||
} else {
|
|
||||||
__ testl(rax, polling_page);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
__ ret(0);
|
__ ret(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -566,35 +554,21 @@ void LIR_Assembler::return_op(LIR_Opr result) {
|
||||||
int LIR_Assembler::safepoint_poll(LIR_Opr tmp, CodeEmitInfo* info) {
|
int LIR_Assembler::safepoint_poll(LIR_Opr tmp, CodeEmitInfo* info) {
|
||||||
guarantee(info != NULL, "Shouldn't be NULL");
|
guarantee(info != NULL, "Shouldn't be NULL");
|
||||||
int offset = __ offset();
|
int offset = __ offset();
|
||||||
if (SafepointMechanism::uses_thread_local_poll()) {
|
|
||||||
#ifdef _LP64
|
#ifdef _LP64
|
||||||
const Register poll_addr = rscratch1;
|
const Register poll_addr = rscratch1;
|
||||||
__ movptr(poll_addr, Address(r15_thread, Thread::polling_page_offset()));
|
__ movptr(poll_addr, Address(r15_thread, Thread::polling_page_offset()));
|
||||||
#else
|
#else
|
||||||
assert(tmp->is_cpu_register(), "needed");
|
assert(tmp->is_cpu_register(), "needed");
|
||||||
const Register poll_addr = tmp->as_register();
|
const Register poll_addr = tmp->as_register();
|
||||||
__ get_thread(poll_addr);
|
__ get_thread(poll_addr);
|
||||||
__ movptr(poll_addr, Address(poll_addr, in_bytes(Thread::polling_page_offset())));
|
__ movptr(poll_addr, Address(poll_addr, in_bytes(Thread::polling_page_offset())));
|
||||||
#endif
|
#endif
|
||||||
add_debug_info_for_branch(info);
|
add_debug_info_for_branch(info);
|
||||||
__ relocate(relocInfo::poll_type);
|
__ relocate(relocInfo::poll_type);
|
||||||
address pre_pc = __ pc();
|
address pre_pc = __ pc();
|
||||||
__ testl(rax, Address(poll_addr, 0));
|
__ testl(rax, Address(poll_addr, 0));
|
||||||
address post_pc = __ pc();
|
address post_pc = __ pc();
|
||||||
guarantee(pointer_delta(post_pc, pre_pc, 1) == 2 LP64_ONLY(+1), "must be exact length");
|
guarantee(pointer_delta(post_pc, pre_pc, 1) == 2 LP64_ONLY(+1), "must be exact length");
|
||||||
} else {
|
|
||||||
AddressLiteral polling_page(os::get_polling_page(), relocInfo::poll_type);
|
|
||||||
if (Assembler::is_polling_page_far()) {
|
|
||||||
__ lea(rscratch1, polling_page);
|
|
||||||
offset = __ offset();
|
|
||||||
add_debug_info_for_branch(info);
|
|
||||||
__ relocate(relocInfo::poll_type);
|
|
||||||
__ testl(rax, Address(rscratch1, 0));
|
|
||||||
} else {
|
|
||||||
add_debug_info_for_branch(info);
|
|
||||||
__ testl(rax, polling_page);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return offset;
|
return offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2005, 2019, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2005, 2020, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
@ -149,7 +149,7 @@ bool LIRGenerator::can_inline_as_constant(LIR_Const* c) const {
|
||||||
|
|
||||||
|
|
||||||
LIR_Opr LIRGenerator::safepoint_poll_register() {
|
LIR_Opr LIRGenerator::safepoint_poll_register() {
|
||||||
NOT_LP64( if (SafepointMechanism::uses_thread_local_poll()) { return new_register(T_ADDRESS); } )
|
NOT_LP64( return new_register(T_ADDRESS); )
|
||||||
return LIR_OprFact::illegalOpr;
|
return LIR_OprFact::illegalOpr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -69,6 +69,4 @@ const bool CCallingConventionRequiresIntsAsLongs = false;
|
||||||
#define SUPPORT_RESERVED_STACK_AREA
|
#define SUPPORT_RESERVED_STACK_AREA
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define THREAD_LOCAL_POLL
|
|
||||||
|
|
||||||
#endif // CPU_X86_GLOBALDEFINITIONS_X86_HPP
|
#endif // CPU_X86_GLOBALDEFINITIONS_X86_HPP
|
||||||
|
|
|
@ -850,7 +850,7 @@ void InterpreterMacroAssembler::dispatch_base(TosState state,
|
||||||
address* const safepoint_table = Interpreter::safept_table(state);
|
address* const safepoint_table = Interpreter::safept_table(state);
|
||||||
#ifdef _LP64
|
#ifdef _LP64
|
||||||
Label no_safepoint, dispatch;
|
Label no_safepoint, dispatch;
|
||||||
if (SafepointMechanism::uses_thread_local_poll() && table != safepoint_table && generate_poll) {
|
if (table != safepoint_table && generate_poll) {
|
||||||
NOT_PRODUCT(block_comment("Thread-local Safepoint poll"));
|
NOT_PRODUCT(block_comment("Thread-local Safepoint poll"));
|
||||||
testb(Address(r15_thread, Thread::polling_page_offset()), SafepointMechanism::poll_bit());
|
testb(Address(r15_thread, Thread::polling_page_offset()), SafepointMechanism::poll_bit());
|
||||||
|
|
||||||
|
@ -866,7 +866,7 @@ void InterpreterMacroAssembler::dispatch_base(TosState state,
|
||||||
|
|
||||||
#else
|
#else
|
||||||
Address index(noreg, rbx, Address::times_ptr);
|
Address index(noreg, rbx, Address::times_ptr);
|
||||||
if (SafepointMechanism::uses_thread_local_poll() && table != safepoint_table && generate_poll) {
|
if (table != safepoint_table && generate_poll) {
|
||||||
NOT_PRODUCT(block_comment("Thread-local Safepoint poll"));
|
NOT_PRODUCT(block_comment("Thread-local Safepoint poll"));
|
||||||
Label no_safepoint;
|
Label no_safepoint;
|
||||||
const Register thread = rcx;
|
const Register thread = rcx;
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2013, 2019, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2013, 2020, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
@ -191,22 +191,9 @@ void CodeInstaller::pd_relocate_JavaMethod(CodeBuffer &, JVMCIObject hotspot_met
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void relocate_poll_near(address pc) {
|
|
||||||
NativeInstruction* ni = nativeInstruction_at(pc);
|
|
||||||
int32_t* disp = (int32_t*) Assembler::locate_operand(pc, Assembler::disp32_operand);
|
|
||||||
int32_t offset = *disp; // The Java code installed the polling page offset into the disp32 operand
|
|
||||||
intptr_t new_disp = (intptr_t) (os::get_polling_page() + offset) - (intptr_t) ni;
|
|
||||||
*disp = (int32_t)new_disp;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void CodeInstaller::pd_relocate_poll(address pc, jint mark, JVMCI_TRAPS) {
|
void CodeInstaller::pd_relocate_poll(address pc, jint mark, JVMCI_TRAPS) {
|
||||||
switch (mark) {
|
switch (mark) {
|
||||||
case POLL_NEAR: {
|
case POLL_NEAR:
|
||||||
relocate_poll_near(pc);
|
|
||||||
_instructions->relocate(pc, relocInfo::poll_type, Assembler::disp32_operand);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case POLL_FAR:
|
case POLL_FAR:
|
||||||
// This is a load from a register so there is no relocatable operand.
|
// This is a load from a register so there is no relocatable operand.
|
||||||
// We just have to ensure that the format is not disp32_operand
|
// We just have to ensure that the format is not disp32_operand
|
||||||
|
@ -214,11 +201,7 @@ void CodeInstaller::pd_relocate_poll(address pc, jint mark, JVMCI_TRAPS) {
|
||||||
// thing (i.e. ignores this relocation record)
|
// thing (i.e. ignores this relocation record)
|
||||||
_instructions->relocate(pc, relocInfo::poll_type, Assembler::imm_operand);
|
_instructions->relocate(pc, relocInfo::poll_type, Assembler::imm_operand);
|
||||||
break;
|
break;
|
||||||
case POLL_RETURN_NEAR: {
|
case POLL_RETURN_NEAR:
|
||||||
relocate_poll_near(pc);
|
|
||||||
_instructions->relocate(pc, relocInfo::poll_return_type, Assembler::disp32_operand);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case POLL_RETURN_FAR:
|
case POLL_RETURN_FAR:
|
||||||
// see comment above for POLL_FAR
|
// see comment above for POLL_FAR
|
||||||
_instructions->relocate(pc, relocInfo::poll_return_type, Assembler::imm_operand);
|
_instructions->relocate(pc, relocInfo::poll_return_type, Assembler::imm_operand);
|
||||||
|
|
|
@ -2705,22 +2705,16 @@ void MacroAssembler::save_rax(Register tmp) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void MacroAssembler::safepoint_poll(Label& slow_path, Register thread_reg, Register temp_reg) {
|
void MacroAssembler::safepoint_poll(Label& slow_path, Register thread_reg, Register temp_reg) {
|
||||||
if (SafepointMechanism::uses_thread_local_poll()) {
|
|
||||||
#ifdef _LP64
|
#ifdef _LP64
|
||||||
assert(thread_reg == r15_thread, "should be");
|
assert(thread_reg == r15_thread, "should be");
|
||||||
#else
|
#else
|
||||||
if (thread_reg == noreg) {
|
if (thread_reg == noreg) {
|
||||||
thread_reg = temp_reg;
|
thread_reg = temp_reg;
|
||||||
get_thread(thread_reg);
|
get_thread(thread_reg);
|
||||||
}
|
|
||||||
#endif
|
|
||||||
testb(Address(thread_reg, Thread::polling_page_offset()), SafepointMechanism::poll_bit());
|
|
||||||
jcc(Assembler::notZero, slow_path); // handshake bit set implies poll
|
|
||||||
} else {
|
|
||||||
cmp32(ExternalAddress(SafepointSynchronize::address_of_state()),
|
|
||||||
SafepointSynchronize::_not_synchronized);
|
|
||||||
jcc(Assembler::notEqual, slow_path);
|
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
testb(Address(thread_reg, Thread::polling_page_offset()), SafepointMechanism::poll_bit());
|
||||||
|
jcc(Assembler::notZero, slow_path); // handshake bit set implies poll
|
||||||
}
|
}
|
||||||
|
|
||||||
// Calls to C land
|
// Calls to C land
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 1997, 2019, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 1997, 2020, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
@ -731,42 +731,15 @@ inline bool NativeInstruction::is_far_jump() { return is_mov_literal64(); }
|
||||||
inline bool NativeInstruction::is_cond_jump() { return (int_at(0) & 0xF0FF) == 0x800F /* long jump */ ||
|
inline bool NativeInstruction::is_cond_jump() { return (int_at(0) & 0xF0FF) == 0x800F /* long jump */ ||
|
||||||
(ubyte_at(0) & 0xF0) == 0x70; /* short jump */ }
|
(ubyte_at(0) & 0xF0) == 0x70; /* short jump */ }
|
||||||
inline bool NativeInstruction::is_safepoint_poll() {
|
inline bool NativeInstruction::is_safepoint_poll() {
|
||||||
if (SafepointMechanism::uses_thread_local_poll()) {
|
|
||||||
#ifdef AMD64
|
#ifdef AMD64
|
||||||
const bool has_rex_prefix = ubyte_at(0) == NativeTstRegMem::instruction_rex_b_prefix;
|
const bool has_rex_prefix = ubyte_at(0) == NativeTstRegMem::instruction_rex_b_prefix;
|
||||||
const int test_offset = has_rex_prefix ? 1 : 0;
|
const int test_offset = has_rex_prefix ? 1 : 0;
|
||||||
#else
|
#else
|
||||||
const int test_offset = 0;
|
const int test_offset = 0;
|
||||||
#endif
|
#endif
|
||||||
const bool is_test_opcode = ubyte_at(test_offset) == NativeTstRegMem::instruction_code_memXregl;
|
const bool is_test_opcode = ubyte_at(test_offset) == NativeTstRegMem::instruction_code_memXregl;
|
||||||
const bool is_rax_target = (ubyte_at(test_offset + 1) & NativeTstRegMem::modrm_mask) == NativeTstRegMem::modrm_reg;
|
const bool is_rax_target = (ubyte_at(test_offset + 1) & NativeTstRegMem::modrm_mask) == NativeTstRegMem::modrm_reg;
|
||||||
return is_test_opcode && is_rax_target;
|
return is_test_opcode && is_rax_target;
|
||||||
}
|
|
||||||
#ifdef AMD64
|
|
||||||
// Try decoding a near safepoint first:
|
|
||||||
if (ubyte_at(0) == NativeTstRegMem::instruction_code_memXregl &&
|
|
||||||
ubyte_at(1) == 0x05) { // 00 rax 101
|
|
||||||
address fault = addr_at(6) + int_at(2);
|
|
||||||
NOT_JVMCI(assert(!Assembler::is_polling_page_far(), "unexpected poll encoding");)
|
|
||||||
return os::is_poll_address(fault);
|
|
||||||
}
|
|
||||||
// Now try decoding a far safepoint:
|
|
||||||
// two cases, depending on the choice of the base register in the address.
|
|
||||||
if (((ubyte_at(0) & NativeTstRegMem::instruction_rex_prefix_mask) == NativeTstRegMem::instruction_rex_prefix &&
|
|
||||||
ubyte_at(1) == NativeTstRegMem::instruction_code_memXregl &&
|
|
||||||
(ubyte_at(2) & NativeTstRegMem::modrm_mask) == NativeTstRegMem::modrm_reg) ||
|
|
||||||
(ubyte_at(0) == NativeTstRegMem::instruction_code_memXregl &&
|
|
||||||
(ubyte_at(1) & NativeTstRegMem::modrm_mask) == NativeTstRegMem::modrm_reg)) {
|
|
||||||
NOT_JVMCI(assert(Assembler::is_polling_page_far(), "unexpected poll encoding");)
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
#else
|
|
||||||
return ( ubyte_at(0) == NativeMovRegMem::instruction_code_mem2reg ||
|
|
||||||
ubyte_at(0) == NativeTstRegMem::instruction_code_memXregl ) &&
|
|
||||||
(ubyte_at(1)&0xC7) == 0x05 && /* Mod R/M == disp32 */
|
|
||||||
(os::is_poll_address((address)int_at(2)));
|
|
||||||
#endif // AMD64
|
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool NativeInstruction::is_mov_literal64() {
|
inline bool NativeInstruction::is_mov_literal64() {
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 1998, 2017, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 1998, 2020, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
@ -182,28 +182,6 @@ address Relocation::pd_get_address_from_code() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void poll_Relocation::fix_relocation_after_move(const CodeBuffer* src, CodeBuffer* dest) {
|
void poll_Relocation::fix_relocation_after_move(const CodeBuffer* src, CodeBuffer* dest) {
|
||||||
#ifdef _LP64
|
|
||||||
typedef Assembler::WhichOperand WhichOperand;
|
|
||||||
WhichOperand which = (WhichOperand) format();
|
|
||||||
#if !INCLUDE_JVMCI
|
|
||||||
if (SafepointMechanism::uses_global_page_poll()) {
|
|
||||||
assert((which == Assembler::disp32_operand) == !Assembler::is_polling_page_far(), "format not set correctly");
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
if (which == Assembler::disp32_operand) {
|
|
||||||
assert(SafepointMechanism::uses_global_page_poll(), "should only have generated such a poll if global polling enabled");
|
|
||||||
address orig_addr = old_addr_for(addr(), src, dest);
|
|
||||||
NativeInstruction* oni = nativeInstruction_at(orig_addr);
|
|
||||||
int32_t* orig_disp = (int32_t*) Assembler::locate_operand(orig_addr, which);
|
|
||||||
// This poll_addr is incorrect by the size of the instruction it is irrelevant
|
|
||||||
intptr_t poll_addr = (intptr_t)oni + *orig_disp;
|
|
||||||
NativeInstruction* ni = nativeInstruction_at(addr());
|
|
||||||
intptr_t new_disp = poll_addr - (intptr_t) ni;
|
|
||||||
|
|
||||||
int32_t* disp = (int32_t*) Assembler::locate_operand(addr(), which);
|
|
||||||
* disp = (int32_t)new_disp;
|
|
||||||
}
|
|
||||||
#endif // _LP64
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void metadata_Relocation::pd_fix_value(address x) {
|
void metadata_Relocation::pd_fix_value(address x) {
|
||||||
|
|
|
@ -3151,7 +3151,7 @@ SafepointBlob* SharedRuntime::generate_handler_blob(address call_ptr, int poll_t
|
||||||
__ bind(noException);
|
__ bind(noException);
|
||||||
|
|
||||||
Label no_adjust, bail, not_special;
|
Label no_adjust, bail, not_special;
|
||||||
if (SafepointMechanism::uses_thread_local_poll() && !cause_return) {
|
if (!cause_return) {
|
||||||
// If our stashed return pc was modified by the runtime we avoid touching it
|
// If our stashed return pc was modified by the runtime we avoid touching it
|
||||||
__ cmpptr(rbx, Address(rbp, wordSize));
|
__ cmpptr(rbx, Address(rbp, wordSize));
|
||||||
__ jccb(Assembler::notEqual, no_adjust);
|
__ jccb(Assembler::notEqual, no_adjust);
|
||||||
|
|
|
@ -3512,7 +3512,7 @@ SafepointBlob* SharedRuntime::generate_handler_blob(address call_ptr, int poll_t
|
||||||
#ifdef ASSERT
|
#ifdef ASSERT
|
||||||
Label bail;
|
Label bail;
|
||||||
#endif
|
#endif
|
||||||
if (SafepointMechanism::uses_thread_local_poll() && !cause_return) {
|
if (!cause_return) {
|
||||||
Label no_prefix, not_special;
|
Label no_prefix, not_special;
|
||||||
|
|
||||||
// If our stashed return pc was modified by the runtime we avoid touching it
|
// If our stashed return pc was modified by the runtime we avoid touching it
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 1997, 2019, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 1997, 2020, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
@ -2655,7 +2655,7 @@ void TemplateTable::_return(TosState state) {
|
||||||
__ bind(skip_register_finalizer);
|
__ bind(skip_register_finalizer);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (SafepointMechanism::uses_thread_local_poll() && _desc->bytecode() != Bytecodes::_return_register_finalizer) {
|
if (_desc->bytecode() != Bytecodes::_return_register_finalizer) {
|
||||||
Label no_safepoint;
|
Label no_safepoint;
|
||||||
NOT_PRODUCT(__ block_comment("Thread-local Safepoint poll"));
|
NOT_PRODUCT(__ block_comment("Thread-local Safepoint poll"));
|
||||||
#ifdef _LP64
|
#ifdef _LP64
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
//
|
//
|
||||||
// Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.
|
// Copyright (c) 1997, 2020, Oracle and/or its affiliates. All rights reserved.
|
||||||
// DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
// DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
//
|
//
|
||||||
// This code is free software; you can redistribute it and/or modify it
|
// This code is free software; you can redistribute it and/or modify it
|
||||||
|
@ -314,12 +314,6 @@ int MachCallRuntimeNode::ret_addr_offset() {
|
||||||
return sizeof_FFree_Float_Stack_All + 5 + pre_call_resets_size();
|
return sizeof_FFree_Float_Stack_All + 5 + pre_call_resets_size();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Indicate if the safepoint node needs the polling page as an input.
|
|
||||||
// Since x86 does have absolute addressing, it doesn't.
|
|
||||||
bool SafePointNode::needs_polling_address_input() {
|
|
||||||
return SafepointMechanism::uses_thread_local_poll();
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// Compute padding required for nodes which need alignment
|
// Compute padding required for nodes which need alignment
|
||||||
//
|
//
|
||||||
|
@ -706,19 +700,12 @@ void MachEpilogNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (do_polling() && C->is_method_compilation()) {
|
if (do_polling() && C->is_method_compilation()) {
|
||||||
if (SafepointMechanism::uses_thread_local_poll()) {
|
Register pollReg = as_Register(EBX_enc);
|
||||||
Register pollReg = as_Register(EBX_enc);
|
MacroAssembler masm(&cbuf);
|
||||||
MacroAssembler masm(&cbuf);
|
masm.get_thread(pollReg);
|
||||||
masm.get_thread(pollReg);
|
masm.movl(pollReg, Address(pollReg, in_bytes(Thread::polling_page_offset())));
|
||||||
masm.movl(pollReg, Address(pollReg, in_bytes(Thread::polling_page_offset())));
|
masm.relocate(relocInfo::poll_return_type);
|
||||||
masm.relocate(relocInfo::poll_return_type);
|
masm.testl(rax, Address(pollReg, 0));
|
||||||
masm.testl(rax, Address(pollReg, 0));
|
|
||||||
} else {
|
|
||||||
cbuf.relocate(cbuf.insts_end(), relocInfo::poll_return_type, 0);
|
|
||||||
emit_opcode(cbuf,0x85);
|
|
||||||
emit_rm(cbuf, 0x0, EAX_enc, 0x5); // EAX
|
|
||||||
emit_d32(cbuf, (intptr_t)os::get_polling_page());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -735,8 +722,6 @@ const Pipeline * MachEpilogNode::pipeline() const {
|
||||||
return MachNode::pipeline_class();
|
return MachNode::pipeline_class();
|
||||||
}
|
}
|
||||||
|
|
||||||
int MachEpilogNode::safepoint_offset() const { return 0; }
|
|
||||||
|
|
||||||
//=============================================================================
|
//=============================================================================
|
||||||
|
|
||||||
enum RC { rc_bad, rc_int, rc_float, rc_xmm, rc_stack };
|
enum RC { rc_bad, rc_int, rc_float, rc_xmm, rc_stack };
|
||||||
|
@ -3148,18 +3133,6 @@ encode %{
|
||||||
encode_RegMem(cbuf, rm_byte_opcode, base, index, scale, displace, disp_reloc);
|
encode_RegMem(cbuf, rm_byte_opcode, base, index, scale, displace, disp_reloc);
|
||||||
%}
|
%}
|
||||||
|
|
||||||
// Safepoint Poll. This polls the safepoint page, and causes an
|
|
||||||
// exception if it is not readable. Unfortunately, it kills the condition code
|
|
||||||
// in the process
|
|
||||||
// We current use TESTL [spp],EDI
|
|
||||||
// A better choice might be TESTB [spp + pagesize() - CacheLineSize()],0
|
|
||||||
|
|
||||||
enc_class Safepoint_Poll() %{
|
|
||||||
cbuf.relocate(cbuf.insts_mark(), relocInfo::poll_type, 0);
|
|
||||||
emit_opcode(cbuf,0x85);
|
|
||||||
emit_rm (cbuf, 0x0, 0x7, 0x5);
|
|
||||||
emit_d32(cbuf, (intptr_t)os::get_polling_page());
|
|
||||||
%}
|
|
||||||
%}
|
%}
|
||||||
|
|
||||||
|
|
||||||
|
@ -13441,28 +13414,7 @@ instruct cmpFastUnlock(eFlagsReg cr, eRegP object, eAXRegP box, eRegP tmp ) %{
|
||||||
|
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
// Safepoint Instruction
|
// Safepoint Instruction
|
||||||
instruct safePoint_poll(eFlagsReg cr) %{
|
|
||||||
predicate(SafepointMechanism::uses_global_page_poll());
|
|
||||||
match(SafePoint);
|
|
||||||
effect(KILL cr);
|
|
||||||
|
|
||||||
// TODO-FIXME: we currently poll at offset 0 of the safepoint polling page.
|
|
||||||
// On SPARC that might be acceptable as we can generate the address with
|
|
||||||
// just a sethi, saving an or. By polling at offset 0 we can end up
|
|
||||||
// putting additional pressure on the index-0 in the D$. Because of
|
|
||||||
// alignment (just like the situation at hand) the lower indices tend
|
|
||||||
// to see more traffic. It'd be better to change the polling address
|
|
||||||
// to offset 0 of the last $line in the polling page.
|
|
||||||
|
|
||||||
format %{ "TSTL #polladdr,EAX\t! Safepoint: poll for GC" %}
|
|
||||||
ins_cost(125);
|
|
||||||
size(6) ;
|
|
||||||
ins_encode( Safepoint_Poll() );
|
|
||||||
ins_pipe( ialu_reg_mem );
|
|
||||||
%}
|
|
||||||
|
|
||||||
instruct safePoint_poll_tls(eFlagsReg cr, eRegP_no_EBP poll) %{
|
instruct safePoint_poll_tls(eFlagsReg cr, eRegP_no_EBP poll) %{
|
||||||
predicate(SafepointMechanism::uses_thread_local_poll());
|
|
||||||
match(SafePoint poll);
|
match(SafePoint poll);
|
||||||
effect(KILL cr, USE poll);
|
effect(KILL cr, USE poll);
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
//
|
//
|
||||||
// Copyright (c) 2003, 2019, Oracle and/or its affiliates. All rights reserved.
|
// Copyright (c) 2003, 2020, Oracle and/or its affiliates. All rights reserved.
|
||||||
// DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
// DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
//
|
//
|
||||||
// This code is free software; you can redistribute it and/or modify it
|
// This code is free software; you can redistribute it and/or modify it
|
||||||
|
@ -459,13 +459,6 @@ int MachCallRuntimeNode::ret_addr_offset() {
|
||||||
return offset;
|
return offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Indicate if the safepoint node needs the polling page as an input,
|
|
||||||
// it does if the polling page is more than disp32 away.
|
|
||||||
bool SafePointNode::needs_polling_address_input()
|
|
||||||
{
|
|
||||||
return SafepointMechanism::uses_thread_local_poll() || Assembler::is_polling_page_far();
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// Compute padding required for nodes which need alignment
|
// Compute padding required for nodes which need alignment
|
||||||
//
|
//
|
||||||
|
@ -939,18 +932,9 @@ void MachEpilogNode::format(PhaseRegAlloc* ra_, outputStream* st) const
|
||||||
st->print_cr("popq rbp");
|
st->print_cr("popq rbp");
|
||||||
if (do_polling() && C->is_method_compilation()) {
|
if (do_polling() && C->is_method_compilation()) {
|
||||||
st->print("\t");
|
st->print("\t");
|
||||||
if (SafepointMechanism::uses_thread_local_poll()) {
|
st->print_cr("movq rscratch1, poll_offset[r15_thread] #polling_page_address\n\t"
|
||||||
st->print_cr("movq rscratch1, poll_offset[r15_thread] #polling_page_address\n\t"
|
"testl rax, [rscratch1]\t"
|
||||||
"testl rax, [rscratch1]\t"
|
"# Safepoint: poll for GC");
|
||||||
"# Safepoint: poll for GC");
|
|
||||||
} else if (Assembler::is_polling_page_far()) {
|
|
||||||
st->print_cr("movq rscratch1, #polling_page_address\n\t"
|
|
||||||
"testl rax, [rscratch1]\t"
|
|
||||||
"# Safepoint: poll for GC");
|
|
||||||
} else {
|
|
||||||
st->print_cr("testl rax, [rip + #offset_to_poll_page]\t"
|
|
||||||
"# Safepoint: poll for GC");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -996,20 +980,9 @@ void MachEpilogNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const
|
||||||
|
|
||||||
if (do_polling() && C->is_method_compilation()) {
|
if (do_polling() && C->is_method_compilation()) {
|
||||||
MacroAssembler _masm(&cbuf);
|
MacroAssembler _masm(&cbuf);
|
||||||
if (SafepointMechanism::uses_thread_local_poll()) {
|
__ movq(rscratch1, Address(r15_thread, Thread::polling_page_offset()));
|
||||||
__ movq(rscratch1, Address(r15_thread, Thread::polling_page_offset()));
|
__ relocate(relocInfo::poll_return_type);
|
||||||
__ relocate(relocInfo::poll_return_type);
|
__ testl(rax, Address(rscratch1, 0));
|
||||||
__ testl(rax, Address(rscratch1, 0));
|
|
||||||
} else {
|
|
||||||
AddressLiteral polling_page(os::get_polling_page(), relocInfo::poll_return_type);
|
|
||||||
if (Assembler::is_polling_page_far()) {
|
|
||||||
__ lea(rscratch1, polling_page);
|
|
||||||
__ relocate(relocInfo::poll_return_type);
|
|
||||||
__ testl(rax, Address(rscratch1, 0));
|
|
||||||
} else {
|
|
||||||
__ testl(rax, polling_page);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1029,11 +1002,6 @@ const Pipeline* MachEpilogNode::pipeline() const
|
||||||
return MachNode::pipeline_class();
|
return MachNode::pipeline_class();
|
||||||
}
|
}
|
||||||
|
|
||||||
int MachEpilogNode::safepoint_offset() const
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
//=============================================================================
|
//=============================================================================
|
||||||
|
|
||||||
enum RC {
|
enum RC {
|
||||||
|
@ -12536,41 +12504,8 @@ instruct cmpFastUnlock(rFlagsReg cr, rRegP object, rax_RegP box, rRegP tmp) %{
|
||||||
|
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
// Safepoint Instructions
|
// Safepoint Instructions
|
||||||
instruct safePoint_poll(rFlagsReg cr)
|
|
||||||
%{
|
|
||||||
predicate(!Assembler::is_polling_page_far() && SafepointMechanism::uses_global_page_poll());
|
|
||||||
match(SafePoint);
|
|
||||||
effect(KILL cr);
|
|
||||||
|
|
||||||
format %{ "testl rax, [rip + #offset_to_poll_page]\t"
|
|
||||||
"# Safepoint: poll for GC" %}
|
|
||||||
ins_cost(125);
|
|
||||||
ins_encode %{
|
|
||||||
AddressLiteral addr(os::get_polling_page(), relocInfo::poll_type);
|
|
||||||
__ testl(rax, addr);
|
|
||||||
%}
|
|
||||||
ins_pipe(ialu_reg_mem);
|
|
||||||
%}
|
|
||||||
|
|
||||||
instruct safePoint_poll_far(rFlagsReg cr, rRegP poll)
|
|
||||||
%{
|
|
||||||
predicate(Assembler::is_polling_page_far() && SafepointMechanism::uses_global_page_poll());
|
|
||||||
match(SafePoint poll);
|
|
||||||
effect(KILL cr, USE poll);
|
|
||||||
|
|
||||||
format %{ "testl rax, [$poll]\t"
|
|
||||||
"# Safepoint: poll for GC" %}
|
|
||||||
ins_cost(125);
|
|
||||||
ins_encode %{
|
|
||||||
__ relocate(relocInfo::poll_type);
|
|
||||||
__ testl(rax, Address($poll$$Register, 0));
|
|
||||||
%}
|
|
||||||
ins_pipe(ialu_reg_mem);
|
|
||||||
%}
|
|
||||||
|
|
||||||
instruct safePoint_poll_tls(rFlagsReg cr, rRegP poll)
|
instruct safePoint_poll_tls(rFlagsReg cr, rRegP poll)
|
||||||
%{
|
%{
|
||||||
predicate(SafepointMechanism::uses_thread_local_poll());
|
|
||||||
match(SafePoint poll);
|
match(SafePoint poll);
|
||||||
effect(KILL cr, USE poll);
|
effect(KILL cr, USE poll);
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 1997, 2019, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 1997, 2020, Oracle and/or its affiliates. All rights reserved.
|
||||||
* Copyright 2009, 2015, Red Hat, Inc.
|
* Copyright 2009, 2015, Red Hat, Inc.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
|
@ -30,8 +30,6 @@
|
||||||
#define SUPPORTS_NATIVE_CX8
|
#define SUPPORTS_NATIVE_CX8
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define THREAD_LOCAL_POLL
|
|
||||||
|
|
||||||
#include <ffi.h>
|
#include <ffi.h>
|
||||||
|
|
||||||
// Indicates whether the C calling conventions require that
|
// Indicates whether the C calling conventions require that
|
||||||
|
|
|
@ -3590,21 +3590,6 @@ jint os::init_2(void) {
|
||||||
return JNI_OK;
|
return JNI_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Mark the polling page as unreadable
|
|
||||||
void os::make_polling_page_unreadable(void) {
|
|
||||||
if (!guard_memory((char*)_polling_page, Aix::page_size())) {
|
|
||||||
fatal("Could not disable polling page");
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// Mark the polling page as readable
|
|
||||||
void os::make_polling_page_readable(void) {
|
|
||||||
// Changed according to os_linux.cpp.
|
|
||||||
if (!checked_mprotect((char *)_polling_page, Aix::page_size(), PROT_READ)) {
|
|
||||||
fatal("Could not enable polling page at " PTR_FORMAT, _polling_page);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
int os::active_processor_count() {
|
int os::active_processor_count() {
|
||||||
// User has overridden the number of active processors
|
// User has overridden the number of active processors
|
||||||
if (ActiveProcessorCount > 0) {
|
if (ActiveProcessorCount > 0) {
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
@ -39,7 +39,8 @@ void SafepointMechanism::pd_initialize() {
|
||||||
|
|
||||||
// Allocate one protected page
|
// Allocate one protected page
|
||||||
char* map_address = (char*)MAP_FAILED;
|
char* map_address = (char*)MAP_FAILED;
|
||||||
const size_t map_size = 2 * os::vm_page_size();
|
const size_t page_size = os::vm_page_size();
|
||||||
|
const size_t map_size = 2 * page_size;
|
||||||
const int prot = PROT_READ;
|
const int prot = PROT_READ;
|
||||||
const int flags = MAP_PRIVATE | MAP_ANONYMOUS;
|
const int flags = MAP_PRIVATE | MAP_ANONYMOUS;
|
||||||
|
|
||||||
|
@ -94,13 +95,15 @@ void SafepointMechanism::pd_initialize() {
|
||||||
guarantee(map_address != (char*)MAP_FAILED && map_address != NULL,
|
guarantee(map_address != (char*)MAP_FAILED && map_address != NULL,
|
||||||
"SafepointMechanism::pd_initialize: failed to allocate polling page");
|
"SafepointMechanism::pd_initialize: failed to allocate polling page");
|
||||||
log_info(os)("SafePoint Polling address: " INTPTR_FORMAT, p2i(map_address));
|
log_info(os)("SafePoint Polling address: " INTPTR_FORMAT, p2i(map_address));
|
||||||
os::set_polling_page((address)(map_address));
|
_polling_page = (address)(map_address);
|
||||||
|
|
||||||
// Register polling page with NMT.
|
// Register polling page with NMT.
|
||||||
MemTracker::record_virtual_memory_reserve_and_commit(map_address, map_size, CALLER_PC, mtSafepoint);
|
MemTracker::record_virtual_memory_reserve_and_commit(map_address, map_size, CALLER_PC, mtSafepoint);
|
||||||
|
|
||||||
// Use same page for thread local handshakes without SIGTRAP
|
// Use same page for thread local handshakes without SIGTRAP
|
||||||
os::make_polling_page_unreadable();
|
if (!os::guard_memory((char*)_polling_page, page_size)) {
|
||||||
|
fatal("Could not protect polling page");
|
||||||
|
}
|
||||||
intptr_t bad_page_val = reinterpret_cast<intptr_t>(map_address),
|
intptr_t bad_page_val = reinterpret_cast<intptr_t>(map_address),
|
||||||
good_page_val = bad_page_val + os::vm_page_size();
|
good_page_val = bad_page_val + os::vm_page_size();
|
||||||
_poll_armed_value = reinterpret_cast<void*>(bad_page_val + poll_bit());
|
_poll_armed_value = reinterpret_cast<void*>(bad_page_val + poll_bit());
|
||||||
|
|
|
@ -3183,20 +3183,6 @@ jint os::init_2(void) {
|
||||||
return JNI_OK;
|
return JNI_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Mark the polling page as unreadable
|
|
||||||
void os::make_polling_page_unreadable(void) {
|
|
||||||
if (!guard_memory((char*)_polling_page, Bsd::page_size())) {
|
|
||||||
fatal("Could not disable polling page");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Mark the polling page as readable
|
|
||||||
void os::make_polling_page_readable(void) {
|
|
||||||
if (!bsd_mprotect((char *)_polling_page, Bsd::page_size(), PROT_READ)) {
|
|
||||||
fatal("Could not enable polling page");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int os::active_processor_count() {
|
int os::active_processor_count() {
|
||||||
// User has overridden the number of active processors
|
// User has overridden the number of active processors
|
||||||
if (ActiveProcessorCount > 0) {
|
if (ActiveProcessorCount > 0) {
|
||||||
|
|
|
@ -5271,20 +5271,6 @@ jint os::init_2(void) {
|
||||||
return JNI_OK;
|
return JNI_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Mark the polling page as unreadable
|
|
||||||
void os::make_polling_page_unreadable(void) {
|
|
||||||
if (!guard_memory((char*)_polling_page, Linux::page_size())) {
|
|
||||||
fatal("Could not disable polling page");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Mark the polling page as readable
|
|
||||||
void os::make_polling_page_readable(void) {
|
|
||||||
if (!linux_mprotect((char *)_polling_page, Linux::page_size(), PROT_READ)) {
|
|
||||||
fatal("Could not enable polling page");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// older glibc versions don't have this macro (which expands to
|
// older glibc versions don't have this macro (which expands to
|
||||||
// an optimized bit-counting function) so we have to roll our own
|
// an optimized bit-counting function) so we have to roll our own
|
||||||
#ifndef CPU_COUNT
|
#ifndef CPU_COUNT
|
||||||
|
|
|
@ -4007,22 +4007,6 @@ jint os::init_2(void) {
|
||||||
return JNI_OK;
|
return JNI_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Mark the polling page as unreadable
|
|
||||||
void os::make_polling_page_unreadable(void) {
|
|
||||||
Events::log(NULL, "Protecting polling page " INTPTR_FORMAT " with PROT_NONE", p2i(_polling_page));
|
|
||||||
if (mprotect((char *)_polling_page, page_size, PROT_NONE) != 0) {
|
|
||||||
fatal("Could not disable polling page");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Mark the polling page as readable
|
|
||||||
void os::make_polling_page_readable(void) {
|
|
||||||
Events::log(NULL, "Protecting polling page " INTPTR_FORMAT " with PROT_READ", p2i(_polling_page));
|
|
||||||
if (mprotect((char *)_polling_page, page_size, PROT_READ) != 0) {
|
|
||||||
fatal("Could not enable polling page");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Is a (classpath) directory empty?
|
// Is a (classpath) directory empty?
|
||||||
bool os::dir_is_empty(const char* path) {
|
bool os::dir_is_empty(const char* path) {
|
||||||
DIR *dir = NULL;
|
DIR *dir = NULL;
|
||||||
|
|
|
@ -56,6 +56,7 @@
|
||||||
#include "runtime/orderAccess.hpp"
|
#include "runtime/orderAccess.hpp"
|
||||||
#include "runtime/osThread.hpp"
|
#include "runtime/osThread.hpp"
|
||||||
#include "runtime/perfMemory.hpp"
|
#include "runtime/perfMemory.hpp"
|
||||||
|
#include "runtime/safepointMechanism.hpp"
|
||||||
#include "runtime/sharedRuntime.hpp"
|
#include "runtime/sharedRuntime.hpp"
|
||||||
#include "runtime/statSampler.hpp"
|
#include "runtime/statSampler.hpp"
|
||||||
#include "runtime/stubRoutines.hpp"
|
#include "runtime/stubRoutines.hpp"
|
||||||
|
@ -2531,7 +2532,7 @@ LONG WINAPI topLevelExceptionFilter(struct _EXCEPTION_POINTERS* exceptionInfo) {
|
||||||
// the rest are checked explicitly now.
|
// the rest are checked explicitly now.
|
||||||
CodeBlob* cb = CodeCache::find_blob(pc);
|
CodeBlob* cb = CodeCache::find_blob(pc);
|
||||||
if (cb != NULL) {
|
if (cb != NULL) {
|
||||||
if (os::is_poll_address(addr)) {
|
if (SafepointMechanism::is_poll_address(addr)) {
|
||||||
address stub = SharedRuntime::get_poll_stub(pc);
|
address stub = SharedRuntime::get_poll_stub(pc);
|
||||||
return Handle_Exception(exceptionInfo, stub);
|
return Handle_Exception(exceptionInfo, stub);
|
||||||
}
|
}
|
||||||
|
@ -4115,24 +4116,6 @@ jint os::init_2(void) {
|
||||||
return JNI_OK;
|
return JNI_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Mark the polling page as unreadable
|
|
||||||
void os::make_polling_page_unreadable(void) {
|
|
||||||
DWORD old_status;
|
|
||||||
if (!VirtualProtect((char *)_polling_page, os::vm_page_size(),
|
|
||||||
PAGE_NOACCESS, &old_status)) {
|
|
||||||
fatal("Could not disable polling page");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Mark the polling page as readable
|
|
||||||
void os::make_polling_page_readable(void) {
|
|
||||||
DWORD old_status;
|
|
||||||
if (!VirtualProtect((char *)_polling_page, os::vm_page_size(),
|
|
||||||
PAGE_READONLY, &old_status)) {
|
|
||||||
fatal("Could not enable polling page");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// combine the high and low DWORD into a ULONGLONG
|
// combine the high and low DWORD into a ULONGLONG
|
||||||
static ULONGLONG make_double_word(DWORD high_word, DWORD low_word) {
|
static ULONGLONG make_double_word(DWORD high_word, DWORD low_word) {
|
||||||
ULONGLONG value = high_word;
|
ULONGLONG value = high_word;
|
||||||
|
|
|
@ -375,12 +375,12 @@ JVM_handle_aix_signal(int sig, siginfo_t* info, void* ucVoid, int abort_if_unrec
|
||||||
goto run_stub;
|
goto run_stub;
|
||||||
}
|
}
|
||||||
|
|
||||||
else if ((SafepointMechanism::uses_thread_local_poll() && USE_POLL_BIT_ONLY)
|
else if (USE_POLL_BIT_ONLY
|
||||||
? (sig == SIGTRAP && ((NativeInstruction*)pc)->is_safepoint_poll())
|
? (sig == SIGTRAP && ((NativeInstruction*)pc)->is_safepoint_poll())
|
||||||
: (sig == SIGSEGV && os::is_poll_address(addr))) {
|
: (sig == SIGSEGV && SafepointMechanism::is_poll_address(addr))) {
|
||||||
if (TraceTraps) {
|
if (TraceTraps) {
|
||||||
tty->print_cr("trap: safepoint_poll at " INTPTR_FORMAT " (%s)", 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");
|
USE_POLL_BIT_ONLY ? "SIGTRAP" : "SIGSEGV");
|
||||||
}
|
}
|
||||||
stub = SharedRuntime::get_poll_stub(pc);
|
stub = SharedRuntime::get_poll_stub(pc);
|
||||||
goto run_stub;
|
goto run_stub;
|
||||||
|
|
|
@ -45,6 +45,7 @@
|
||||||
#include "runtime/javaCalls.hpp"
|
#include "runtime/javaCalls.hpp"
|
||||||
#include "runtime/mutexLocker.hpp"
|
#include "runtime/mutexLocker.hpp"
|
||||||
#include "runtime/osThread.hpp"
|
#include "runtime/osThread.hpp"
|
||||||
|
#include "runtime/safepointMechanism.hpp"
|
||||||
#include "runtime/sharedRuntime.hpp"
|
#include "runtime/sharedRuntime.hpp"
|
||||||
#include "runtime/stubRoutines.hpp"
|
#include "runtime/stubRoutines.hpp"
|
||||||
#include "runtime/thread.inline.hpp"
|
#include "runtime/thread.inline.hpp"
|
||||||
|
@ -573,7 +574,7 @@ JVM_handle_bsd_signal(int sig,
|
||||||
// Java thread running in Java code => find exception handler if any
|
// Java thread running in Java code => find exception handler if any
|
||||||
// a fault inside compiled code, the interpreter, or a stub
|
// a fault inside compiled code, the interpreter, or a stub
|
||||||
|
|
||||||
if ((sig == SIGSEGV || sig == SIGBUS) && os::is_poll_address((address)info->si_addr)) {
|
if ((sig == SIGSEGV || sig == SIGBUS) && SafepointMechanism::is_poll_address((address)info->si_addr)) {
|
||||||
stub = SharedRuntime::get_poll_stub(pc);
|
stub = SharedRuntime::get_poll_stub(pc);
|
||||||
#if defined(__APPLE__)
|
#if defined(__APPLE__)
|
||||||
// 32-bit Darwin reports a SIGBUS for nearly all memory access exceptions.
|
// 32-bit Darwin reports a SIGBUS for nearly all memory access exceptions.
|
||||||
|
|
|
@ -46,6 +46,7 @@
|
||||||
#include "runtime/javaCalls.hpp"
|
#include "runtime/javaCalls.hpp"
|
||||||
#include "runtime/mutexLocker.hpp"
|
#include "runtime/mutexLocker.hpp"
|
||||||
#include "runtime/osThread.hpp"
|
#include "runtime/osThread.hpp"
|
||||||
|
#include "runtime/safepointMechanism.hpp"
|
||||||
#include "runtime/sharedRuntime.hpp"
|
#include "runtime/sharedRuntime.hpp"
|
||||||
#include "runtime/stubRoutines.hpp"
|
#include "runtime/stubRoutines.hpp"
|
||||||
#include "runtime/thread.inline.hpp"
|
#include "runtime/thread.inline.hpp"
|
||||||
|
@ -364,7 +365,7 @@ JVM_handle_linux_signal(int sig,
|
||||||
tty->print_cr("trap: zombie_not_entrant (%s)", (sig == SIGTRAP) ? "SIGTRAP" : "SIGILL");
|
tty->print_cr("trap: zombie_not_entrant (%s)", (sig == SIGTRAP) ? "SIGTRAP" : "SIGILL");
|
||||||
}
|
}
|
||||||
stub = SharedRuntime::get_handle_wrong_method_stub();
|
stub = SharedRuntime::get_handle_wrong_method_stub();
|
||||||
} else if (sig == SIGSEGV && os::is_poll_address((address)info->si_addr)) {
|
} else if (sig == SIGSEGV && SafepointMechanism::is_poll_address((address)info->si_addr)) {
|
||||||
stub = SharedRuntime::get_poll_stub(pc);
|
stub = SharedRuntime::get_poll_stub(pc);
|
||||||
} else if (sig == SIGBUS /* && info->si_code == BUS_OBJERR */) {
|
} else if (sig == SIGBUS /* && info->si_code == BUS_OBJERR */) {
|
||||||
// BugId 4454115: A read from a MappedByteBuffer can fault
|
// BugId 4454115: A read from a MappedByteBuffer can fault
|
||||||
|
|
|
@ -44,6 +44,7 @@
|
||||||
#include "runtime/javaCalls.hpp"
|
#include "runtime/javaCalls.hpp"
|
||||||
#include "runtime/mutexLocker.hpp"
|
#include "runtime/mutexLocker.hpp"
|
||||||
#include "runtime/osThread.hpp"
|
#include "runtime/osThread.hpp"
|
||||||
|
#include "runtime/safepointMechanism.hpp"
|
||||||
#include "runtime/sharedRuntime.hpp"
|
#include "runtime/sharedRuntime.hpp"
|
||||||
#include "runtime/stubRoutines.hpp"
|
#include "runtime/stubRoutines.hpp"
|
||||||
#include "runtime/timer.hpp"
|
#include "runtime/timer.hpp"
|
||||||
|
@ -376,7 +377,7 @@ extern "C" int JVM_handle_linux_signal(int sig, siginfo_t* info,
|
||||||
// Java thread running in Java code => find exception handler if any
|
// Java thread running in Java code => find exception handler if any
|
||||||
// a fault inside compiled code, the interpreter, or a stub
|
// a fault inside compiled code, the interpreter, or a stub
|
||||||
|
|
||||||
if (sig == SIGSEGV && os::is_poll_address((address)info->si_addr)) {
|
if (sig == SIGSEGV && SafepointMechanism::is_poll_address((address)info->si_addr)) {
|
||||||
stub = SharedRuntime::get_poll_stub(pc);
|
stub = SharedRuntime::get_poll_stub(pc);
|
||||||
} else if (sig == SIGBUS) {
|
} else if (sig == SIGBUS) {
|
||||||
// BugId 4454115: A read from a MappedByteBuffer can fault
|
// BugId 4454115: A read from a MappedByteBuffer can fault
|
||||||
|
|
|
@ -410,7 +410,7 @@ JVM_handle_linux_signal(int sig,
|
||||||
stub = SharedRuntime::get_handle_wrong_method_stub();
|
stub = SharedRuntime::get_handle_wrong_method_stub();
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (sig == ((SafepointMechanism::uses_thread_local_poll() && USE_POLL_BIT_ONLY) ? SIGTRAP : SIGSEGV) &&
|
else if ((sig == USE_POLL_BIT_ONLY ? SIGTRAP : SIGSEGV) &&
|
||||||
// A linux-ppc64 kernel before 2.6.6 doesn't set si_addr on some segfaults
|
// 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),
|
// 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
|
// especially when we try to read from the safepoint polling page. So the check
|
||||||
|
@ -422,7 +422,7 @@ JVM_handle_linux_signal(int sig,
|
||||||
cb->is_compiled()) {
|
cb->is_compiled()) {
|
||||||
if (TraceTraps) {
|
if (TraceTraps) {
|
||||||
tty->print_cr("trap: safepoint_poll at " INTPTR_FORMAT " (%s)", 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");
|
USE_POLL_BIT_ONLY ? "SIGTRAP" : "SIGSEGV");
|
||||||
}
|
}
|
||||||
stub = SharedRuntime::get_poll_stub(pc);
|
stub = SharedRuntime::get_poll_stub(pc);
|
||||||
}
|
}
|
||||||
|
|
|
@ -49,6 +49,7 @@
|
||||||
#include "runtime/javaCalls.hpp"
|
#include "runtime/javaCalls.hpp"
|
||||||
#include "runtime/mutexLocker.hpp"
|
#include "runtime/mutexLocker.hpp"
|
||||||
#include "runtime/osThread.hpp"
|
#include "runtime/osThread.hpp"
|
||||||
|
#include "runtime/safepointMechanism.hpp"
|
||||||
#include "runtime/sharedRuntime.hpp"
|
#include "runtime/sharedRuntime.hpp"
|
||||||
#include "runtime/stubRoutines.hpp"
|
#include "runtime/stubRoutines.hpp"
|
||||||
#include "runtime/thread.inline.hpp"
|
#include "runtime/thread.inline.hpp"
|
||||||
|
@ -393,7 +394,7 @@ JVM_handle_linux_signal(int sig,
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (sig == SIGSEGV &&
|
else if (sig == SIGSEGV &&
|
||||||
os::is_poll_address((address)info->si_addr)) {
|
SafepointMechanism::is_poll_address((address)info->si_addr)) {
|
||||||
if (TraceTraps) {
|
if (TraceTraps) {
|
||||||
tty->print_cr("trap: safepoint_poll at " INTPTR_FORMAT " (SIGSEGV)", p2i(pc));
|
tty->print_cr("trap: safepoint_poll at " INTPTR_FORMAT " (SIGSEGV)", p2i(pc));
|
||||||
}
|
}
|
||||||
|
|
|
@ -45,6 +45,7 @@
|
||||||
#include "runtime/javaCalls.hpp"
|
#include "runtime/javaCalls.hpp"
|
||||||
#include "runtime/mutexLocker.hpp"
|
#include "runtime/mutexLocker.hpp"
|
||||||
#include "runtime/osThread.hpp"
|
#include "runtime/osThread.hpp"
|
||||||
|
#include "runtime/safepointMechanism.hpp"
|
||||||
#include "runtime/sharedRuntime.hpp"
|
#include "runtime/sharedRuntime.hpp"
|
||||||
#include "runtime/stubRoutines.hpp"
|
#include "runtime/stubRoutines.hpp"
|
||||||
#include "runtime/thread.inline.hpp"
|
#include "runtime/thread.inline.hpp"
|
||||||
|
@ -372,7 +373,7 @@ inline static bool checkOverflow(sigcontext* uc,
|
||||||
}
|
}
|
||||||
|
|
||||||
inline static bool checkPollingPage(address pc, address fault, address* stub) {
|
inline static bool checkPollingPage(address pc, address fault, address* stub) {
|
||||||
if (os::is_poll_address(fault)) {
|
if (SafepointMechanism::is_poll_address(fault)) {
|
||||||
*stub = SharedRuntime::get_poll_stub(pc);
|
*stub = SharedRuntime::get_poll_stub(pc);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -45,6 +45,7 @@
|
||||||
#include "runtime/javaCalls.hpp"
|
#include "runtime/javaCalls.hpp"
|
||||||
#include "runtime/mutexLocker.hpp"
|
#include "runtime/mutexLocker.hpp"
|
||||||
#include "runtime/osThread.hpp"
|
#include "runtime/osThread.hpp"
|
||||||
|
#include "runtime/safepointMechanism.hpp"
|
||||||
#include "runtime/sharedRuntime.hpp"
|
#include "runtime/sharedRuntime.hpp"
|
||||||
#include "runtime/stubRoutines.hpp"
|
#include "runtime/stubRoutines.hpp"
|
||||||
#include "runtime/thread.inline.hpp"
|
#include "runtime/thread.inline.hpp"
|
||||||
|
@ -423,7 +424,7 @@ JVM_handle_linux_signal(int sig,
|
||||||
// Java thread running in Java code => find exception handler if any
|
// Java thread running in Java code => find exception handler if any
|
||||||
// a fault inside compiled code, the interpreter, or a stub
|
// a fault inside compiled code, the interpreter, or a stub
|
||||||
|
|
||||||
if (sig == SIGSEGV && os::is_poll_address((address)info->si_addr)) {
|
if (sig == SIGSEGV && SafepointMechanism::is_poll_address((address)info->si_addr)) {
|
||||||
stub = SharedRuntime::get_poll_stub(pc);
|
stub = SharedRuntime::get_poll_stub(pc);
|
||||||
} else if (sig == SIGBUS /* && info->si_code == BUS_OBJERR */) {
|
} else if (sig == SIGBUS /* && info->si_code == BUS_OBJERR */) {
|
||||||
// BugId 4454115: A read from a MappedByteBuffer can fault
|
// BugId 4454115: A read from a MappedByteBuffer can fault
|
||||||
|
|
|
@ -46,6 +46,7 @@
|
||||||
#include "runtime/javaCalls.hpp"
|
#include "runtime/javaCalls.hpp"
|
||||||
#include "runtime/mutexLocker.hpp"
|
#include "runtime/mutexLocker.hpp"
|
||||||
#include "runtime/osThread.hpp"
|
#include "runtime/osThread.hpp"
|
||||||
|
#include "runtime/safepointMechanism.hpp"
|
||||||
#include "runtime/sharedRuntime.hpp"
|
#include "runtime/sharedRuntime.hpp"
|
||||||
#include "runtime/stubRoutines.hpp"
|
#include "runtime/stubRoutines.hpp"
|
||||||
#include "runtime/thread.inline.hpp"
|
#include "runtime/thread.inline.hpp"
|
||||||
|
@ -445,7 +446,7 @@ JVM_handle_solaris_signal(int sig, siginfo_t* info, void* ucVoid,
|
||||||
// a fault inside compiled code, the interpreter, or a stub
|
// a fault inside compiled code, the interpreter, or a stub
|
||||||
|
|
||||||
// Support Safepoint Polling
|
// Support Safepoint Polling
|
||||||
if (sig == SIGSEGV && os::is_poll_address((address)info->si_addr)) {
|
if (sig == SIGSEGV && SafepointMechanism::is_poll_address((address)info->si_addr)) {
|
||||||
stub = SharedRuntime::get_poll_stub(pc);
|
stub = SharedRuntime::get_poll_stub(pc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -45,6 +45,7 @@
|
||||||
#include "runtime/javaCalls.hpp"
|
#include "runtime/javaCalls.hpp"
|
||||||
#include "runtime/mutexLocker.hpp"
|
#include "runtime/mutexLocker.hpp"
|
||||||
#include "runtime/osThread.hpp"
|
#include "runtime/osThread.hpp"
|
||||||
|
#include "runtime/safepointMechanism.hpp"
|
||||||
#include "runtime/sharedRuntime.hpp"
|
#include "runtime/sharedRuntime.hpp"
|
||||||
#include "runtime/stubRoutines.hpp"
|
#include "runtime/stubRoutines.hpp"
|
||||||
#include "runtime/thread.inline.hpp"
|
#include "runtime/thread.inline.hpp"
|
||||||
|
@ -529,7 +530,7 @@ JVM_handle_solaris_signal(int sig, siginfo_t* info, void* ucVoid,
|
||||||
|
|
||||||
if (thread->thread_state() == _thread_in_Java) {
|
if (thread->thread_state() == _thread_in_Java) {
|
||||||
// Support Safepoint Polling
|
// Support Safepoint Polling
|
||||||
if ( sig == SIGSEGV && os::is_poll_address((address)info->si_addr)) {
|
if ( sig == SIGSEGV && SafepointMechanism::is_poll_address((address)info->si_addr)) {
|
||||||
stub = SharedRuntime::get_poll_stub(pc);
|
stub = SharedRuntime::get_poll_stub(pc);
|
||||||
}
|
}
|
||||||
else if (sig == SIGBUS && info->si_code == BUS_OBJERR) {
|
else if (sig == SIGBUS && info->si_code == BUS_OBJERR) {
|
||||||
|
|
|
@ -580,7 +580,6 @@ void AOTCodeHeap::link_global_lib_symbols() {
|
||||||
SET_AOT_GLOBAL_SYMBOL_VALUE("_aot_card_table_address", address, (BarrierSet::barrier_set()->is_a(BarrierSet::CardTableBarrierSet) ? ci_card_table_address() : NULL));
|
SET_AOT_GLOBAL_SYMBOL_VALUE("_aot_card_table_address", address, (BarrierSet::barrier_set()->is_a(BarrierSet::CardTableBarrierSet) ? ci_card_table_address() : NULL));
|
||||||
SET_AOT_GLOBAL_SYMBOL_VALUE("_aot_heap_top_address", address, (heap->supports_inline_contig_alloc() ? heap->top_addr() : NULL));
|
SET_AOT_GLOBAL_SYMBOL_VALUE("_aot_heap_top_address", address, (heap->supports_inline_contig_alloc() ? heap->top_addr() : NULL));
|
||||||
SET_AOT_GLOBAL_SYMBOL_VALUE("_aot_heap_end_address", address, (heap->supports_inline_contig_alloc() ? heap->end_addr() : NULL));
|
SET_AOT_GLOBAL_SYMBOL_VALUE("_aot_heap_end_address", address, (heap->supports_inline_contig_alloc() ? heap->end_addr() : NULL));
|
||||||
SET_AOT_GLOBAL_SYMBOL_VALUE("_aot_polling_page", address, os::get_polling_page());
|
|
||||||
SET_AOT_GLOBAL_SYMBOL_VALUE("_aot_narrow_klass_base_address", address, CompressedKlassPointers::base());
|
SET_AOT_GLOBAL_SYMBOL_VALUE("_aot_narrow_klass_base_address", address, CompressedKlassPointers::base());
|
||||||
SET_AOT_GLOBAL_SYMBOL_VALUE("_aot_narrow_oop_base_address", address, CompressedOops::base());
|
SET_AOT_GLOBAL_SYMBOL_VALUE("_aot_narrow_oop_base_address", address, CompressedOops::base());
|
||||||
#if INCLUDE_G1GC
|
#if INCLUDE_G1GC
|
||||||
|
|
|
@ -393,9 +393,7 @@ jint ShenandoahHeap::initialize() {
|
||||||
byte_size_in_proper_unit(max_capacity()), proper_unit_for_byte_size(max_capacity())
|
byte_size_in_proper_unit(max_capacity()), proper_unit_for_byte_size(max_capacity())
|
||||||
);
|
);
|
||||||
|
|
||||||
log_info(gc, init)("Safepointing mechanism: %s",
|
log_info(gc, init)("Safepointing mechanism: thread-local poll");
|
||||||
SafepointMechanism::uses_thread_local_poll() ? "thread-local poll" :
|
|
||||||
(SafepointMechanism::uses_global_page_poll() ? "global-page poll" : "unknown"));
|
|
||||||
|
|
||||||
return JNI_OK;
|
return JNI_OK;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2015, 2019, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2015, 2020, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
@ -454,11 +454,6 @@ bool ZMark::flush(bool at_safepoint) {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ZMark::try_flush(volatile size_t* nflush) {
|
bool ZMark::try_flush(volatile size_t* nflush) {
|
||||||
// Only flush if handshakes are enabled
|
|
||||||
if (!SafepointMechanism::uses_thread_local_poll()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
Atomic::inc(nflush);
|
Atomic::inc(nflush);
|
||||||
|
|
||||||
ZStatTimer timer(ZSubPhaseConcurrentMarkTryFlush);
|
ZStatTimer timer(ZSubPhaseConcurrentMarkTryFlush);
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 1997, 2020, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
@ -1281,9 +1281,6 @@ Node *SafePointNode::peek_monitor_obj() const {
|
||||||
|
|
||||||
// Do we Match on this edge index or not? Match no edges
|
// Do we Match on this edge index or not? Match no edges
|
||||||
uint SafePointNode::match_edge(uint idx) const {
|
uint SafePointNode::match_edge(uint idx) const {
|
||||||
if( !needs_polling_address_input() )
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
return (TypeFunc::Parms == idx);
|
return (TypeFunc::Parms == idx);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 1997, 2020, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
@ -654,8 +654,7 @@ const RegMask &MachSafePointNode::in_RegMask( uint idx ) const {
|
||||||
// _in_rms array of RegMasks.
|
// _in_rms array of RegMasks.
|
||||||
if( idx < TypeFunc::Parms ) return _in_rms[idx];
|
if( idx < TypeFunc::Parms ) return _in_rms[idx];
|
||||||
|
|
||||||
if (SafePointNode::needs_polling_address_input() &&
|
if (idx == TypeFunc::Parms &&
|
||||||
idx == TypeFunc::Parms &&
|
|
||||||
ideal_Opcode() == Op_SafePoint) {
|
ideal_Opcode() == Op_SafePoint) {
|
||||||
return MachNode::in_RegMask(idx);
|
return MachNode::in_RegMask(idx);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 1997, 2019, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 1997, 2020, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
@ -523,9 +523,6 @@ private:
|
||||||
public:
|
public:
|
||||||
bool do_polling() const { return _do_polling; }
|
bool do_polling() const { return _do_polling; }
|
||||||
|
|
||||||
// Offset of safepoint from the beginning of the node
|
|
||||||
int safepoint_offset() const;
|
|
||||||
|
|
||||||
#ifndef PRODUCT
|
#ifndef PRODUCT
|
||||||
virtual const char *Name() const { return "Epilog"; }
|
virtual const char *Name() const { return "Epilog"; }
|
||||||
virtual void format( PhaseRegAlloc *, outputStream *st ) const;
|
virtual void format( PhaseRegAlloc *, outputStream *st ) const;
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 1997, 2019, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 1997, 2020, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
@ -2253,8 +2253,7 @@ void Parse::add_safepoint() {
|
||||||
// See if we can avoid this safepoint. No need for a SafePoint immediately
|
// See if we can avoid this safepoint. No need for a SafePoint immediately
|
||||||
// after a Call (except Leaf Call) or another SafePoint.
|
// after a Call (except Leaf Call) or another SafePoint.
|
||||||
Node *proj = control();
|
Node *proj = control();
|
||||||
bool add_poll_param = SafePointNode::needs_polling_address_input();
|
uint parms = TypeFunc::Parms+1;
|
||||||
uint parms = add_poll_param ? TypeFunc::Parms+1 : TypeFunc::Parms;
|
|
||||||
if( proj->is_Proj() ) {
|
if( proj->is_Proj() ) {
|
||||||
Node *n0 = proj->in(0);
|
Node *n0 = proj->in(0);
|
||||||
if( n0->is_Catch() ) {
|
if( n0->is_Catch() ) {
|
||||||
|
@ -2301,17 +2300,11 @@ void Parse::add_safepoint() {
|
||||||
sfpnt->init_req(TypeFunc::FramePtr , top() );
|
sfpnt->init_req(TypeFunc::FramePtr , top() );
|
||||||
|
|
||||||
// Create a node for the polling address
|
// Create a node for the polling address
|
||||||
if( add_poll_param ) {
|
Node *polladr;
|
||||||
Node *polladr;
|
Node *thread = _gvn.transform(new ThreadLocalNode());
|
||||||
if (SafepointMechanism::uses_thread_local_poll()) {
|
Node *polling_page_load_addr = _gvn.transform(basic_plus_adr(top(), thread, in_bytes(Thread::polling_page_offset())));
|
||||||
Node *thread = _gvn.transform(new ThreadLocalNode());
|
polladr = make_load(control(), polling_page_load_addr, TypeRawPtr::BOTTOM, T_ADDRESS, Compile::AliasIdxRaw, MemNode::unordered);
|
||||||
Node *polling_page_load_addr = _gvn.transform(basic_plus_adr(top(), thread, in_bytes(Thread::polling_page_offset())));
|
sfpnt->init_req(TypeFunc::Parms+0, _gvn.transform(polladr));
|
||||||
polladr = make_load(control(), polling_page_load_addr, TypeRawPtr::BOTTOM, T_ADDRESS, Compile::AliasIdxRaw, MemNode::unordered);
|
|
||||||
} else {
|
|
||||||
polladr = ConPNode::make((address)os::get_polling_page());
|
|
||||||
}
|
|
||||||
sfpnt->init_req(TypeFunc::Parms+0, _gvn.transform(polladr));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Fix up the JVM State edges
|
// Fix up the JVM State edges
|
||||||
add_safepoint_edges(sfpnt);
|
add_safepoint_edges(sfpnt);
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2005, 2019, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2005, 2020, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
@ -666,8 +666,7 @@ BiasedLocking::Condition BiasedLocking::single_revoke_with_handshake(Handle obj,
|
||||||
|
|
||||||
// Caller should have instantiated a ResourceMark object before calling this method
|
// Caller should have instantiated a ResourceMark object before calling this method
|
||||||
void BiasedLocking::walk_stack_and_revoke(oop obj, JavaThread* biased_locker) {
|
void BiasedLocking::walk_stack_and_revoke(oop obj, JavaThread* biased_locker) {
|
||||||
assert(!SafepointSynchronize::is_at_safepoint() || !SafepointMechanism::uses_thread_local_poll(),
|
assert(!SafepointSynchronize::is_at_safepoint(), "this should always be executed outside safepoints");
|
||||||
"if SafepointMechanism::uses_thread_local_poll() is enabled this should always be executed outside safepoints");
|
|
||||||
assert(Thread::current() == biased_locker || Thread::current()->is_VM_thread(), "wrong thread");
|
assert(Thread::current() == biased_locker || Thread::current()->is_VM_thread(), "wrong thread");
|
||||||
|
|
||||||
markWord mark = obj->mark();
|
markWord mark = obj->mark();
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2017, 2019, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
@ -218,33 +218,6 @@ class VM_HandshakeAllThreads: public VM_Handshake {
|
||||||
VMOp_Type type() const { return VMOp_HandshakeAllThreads; }
|
VMOp_Type type() const { return VMOp_HandshakeAllThreads; }
|
||||||
};
|
};
|
||||||
|
|
||||||
class VM_HandshakeFallbackOperation : public VM_Operation {
|
|
||||||
HandshakeClosure* _handshake_cl;
|
|
||||||
Thread* _target_thread;
|
|
||||||
bool _all_threads;
|
|
||||||
bool _executed;
|
|
||||||
public:
|
|
||||||
VM_HandshakeFallbackOperation(HandshakeClosure* cl) :
|
|
||||||
_handshake_cl(cl), _target_thread(NULL), _all_threads(true), _executed(false) {}
|
|
||||||
VM_HandshakeFallbackOperation(HandshakeClosure* cl, Thread* target) :
|
|
||||||
_handshake_cl(cl), _target_thread(target), _all_threads(false), _executed(false) {}
|
|
||||||
|
|
||||||
void doit() {
|
|
||||||
log_trace(handshake)("VMThread executing VM_HandshakeFallbackOperation, operation: %s", name());
|
|
||||||
for (JavaThreadIteratorWithHandle jtiwh; JavaThread *t = jtiwh.next(); ) {
|
|
||||||
if (_all_threads || t == _target_thread) {
|
|
||||||
if (t == _target_thread) {
|
|
||||||
_executed = true;
|
|
||||||
}
|
|
||||||
_handshake_cl->do_thread(t);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
VMOp_Type type() const { return VMOp_HandshakeFallback; }
|
|
||||||
bool executed() const { return _executed; }
|
|
||||||
};
|
|
||||||
|
|
||||||
void HandshakeThreadsOperation::do_handshake(JavaThread* thread) {
|
void HandshakeThreadsOperation::do_handshake(JavaThread* thread) {
|
||||||
jlong start_time_ns = 0;
|
jlong start_time_ns = 0;
|
||||||
if (log_is_enabled(Debug, handshake, task)) {
|
if (log_is_enabled(Debug, handshake, task)) {
|
||||||
|
@ -270,27 +243,16 @@ void HandshakeThreadsOperation::do_handshake(JavaThread* thread) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Handshake::execute(HandshakeClosure* thread_cl) {
|
void Handshake::execute(HandshakeClosure* thread_cl) {
|
||||||
if (SafepointMechanism::uses_thread_local_poll()) {
|
HandshakeThreadsOperation cto(thread_cl);
|
||||||
HandshakeThreadsOperation cto(thread_cl);
|
VM_HandshakeAllThreads handshake(&cto);
|
||||||
VM_HandshakeAllThreads handshake(&cto);
|
VMThread::execute(&handshake);
|
||||||
VMThread::execute(&handshake);
|
|
||||||
} else {
|
|
||||||
VM_HandshakeFallbackOperation op(thread_cl);
|
|
||||||
VMThread::execute(&op);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Handshake::execute(HandshakeClosure* thread_cl, JavaThread* target) {
|
bool Handshake::execute(HandshakeClosure* thread_cl, JavaThread* target) {
|
||||||
if (SafepointMechanism::uses_thread_local_poll()) {
|
HandshakeThreadsOperation cto(thread_cl);
|
||||||
HandshakeThreadsOperation cto(thread_cl);
|
VM_HandshakeOneThread handshake(&cto, target);
|
||||||
VM_HandshakeOneThread handshake(&cto, target);
|
VMThread::execute(&handshake);
|
||||||
VMThread::execute(&handshake);
|
return handshake.executed();
|
||||||
return handshake.executed();
|
|
||||||
} else {
|
|
||||||
VM_HandshakeFallbackOperation op(thread_cl, target);
|
|
||||||
VMThread::execute(&op);
|
|
||||||
return op.executed();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
HandshakeState::HandshakeState() : _operation(NULL), _semaphore(1), _thread_in_process_handshake(false) {
|
HandshakeState::HandshakeState() : _operation(NULL), _semaphore(1), _thread_in_process_handshake(false) {
|
||||||
|
|
|
@ -398,13 +398,6 @@ class os: AllStatic {
|
||||||
static bool can_commit_large_page_memory();
|
static bool can_commit_large_page_memory();
|
||||||
static bool can_execute_large_page_memory();
|
static bool can_execute_large_page_memory();
|
||||||
|
|
||||||
// OS interface to polling page
|
|
||||||
static address get_polling_page() { return _polling_page; }
|
|
||||||
static void set_polling_page(address page) { _polling_page = page; }
|
|
||||||
static bool is_poll_address(address addr) { return addr >= _polling_page && addr < (_polling_page + os::vm_page_size()); }
|
|
||||||
static void make_polling_page_unreadable();
|
|
||||||
static void make_polling_page_readable();
|
|
||||||
|
|
||||||
// Check if pointer points to readable memory (by 4-byte read access)
|
// Check if pointer points to readable memory (by 4-byte read access)
|
||||||
static bool is_readable_pointer(const void* p);
|
static bool is_readable_pointer(const void* p);
|
||||||
static bool is_readable_range(const void* from, const void* to);
|
static bool is_readable_range(const void* from, const void* to);
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 1997, 2019, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 1997, 2020, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
@ -140,7 +140,6 @@ int SafepointSynchronize::_current_jni_active_count = 0;
|
||||||
|
|
||||||
WaitBarrier* SafepointSynchronize::_wait_barrier;
|
WaitBarrier* SafepointSynchronize::_wait_barrier;
|
||||||
|
|
||||||
static volatile bool PageArmed = false; // safepoint polling page is RO|RW vs PROT_NONE
|
|
||||||
static bool timeout_error_printed = false;
|
static bool timeout_error_printed = false;
|
||||||
|
|
||||||
// Statistic related
|
// Statistic related
|
||||||
|
@ -250,13 +249,6 @@ int SafepointSynchronize::synchronize_threads(jlong safepoint_limit_time, int no
|
||||||
if (SafepointTimeout && safepoint_limit_time < os::javaTimeNanos()) {
|
if (SafepointTimeout && safepoint_limit_time < os::javaTimeNanos()) {
|
||||||
print_safepoint_timeout();
|
print_safepoint_timeout();
|
||||||
}
|
}
|
||||||
if (int(iterations) == -1) { // overflow - something is wrong.
|
|
||||||
// We can only overflow here when we are using global
|
|
||||||
// polling pages. We keep this guarantee in its original
|
|
||||||
// form so that searches of the bug database for this
|
|
||||||
// failure mode find the right bugs.
|
|
||||||
guarantee (!PageArmed, "invariant");
|
|
||||||
}
|
|
||||||
|
|
||||||
p_prev = &tss_head;
|
p_prev = &tss_head;
|
||||||
ThreadSafepointState *cur_tss = tss_head;
|
ThreadSafepointState *cur_tss = tss_head;
|
||||||
|
@ -297,9 +289,6 @@ void SafepointSynchronize::arm_safepoint() {
|
||||||
// 1. Running interpreted
|
// 1. Running interpreted
|
||||||
// When executing branching/returning byte codes interpreter
|
// When executing branching/returning byte codes interpreter
|
||||||
// checks if the poll is armed, if so blocks in SS::block().
|
// checks if the poll is armed, if so blocks in SS::block().
|
||||||
// When using global polling the interpreter dispatch table
|
|
||||||
// is changed to force it to check for a safepoint condition
|
|
||||||
// between bytecodes.
|
|
||||||
// 2. Running in native code
|
// 2. Running in native code
|
||||||
// When returning from the native code, a Java thread must check
|
// When returning from the native code, a Java thread must check
|
||||||
// the safepoint _state to see if we must block. If the
|
// the safepoint _state to see if we must block. If the
|
||||||
|
@ -334,26 +323,15 @@ void SafepointSynchronize::arm_safepoint() {
|
||||||
OrderAccess::storestore(); // Ordered with _safepoint_counter
|
OrderAccess::storestore(); // Ordered with _safepoint_counter
|
||||||
_state = _synchronizing;
|
_state = _synchronizing;
|
||||||
|
|
||||||
if (SafepointMechanism::uses_thread_local_poll()) {
|
// Arming the per thread poll while having _state != _not_synchronized means safepointing
|
||||||
// Arming the per thread poll while having _state != _not_synchronized means safepointing
|
log_trace(safepoint)("Setting thread local yield flag for threads");
|
||||||
log_trace(safepoint)("Setting thread local yield flag for threads");
|
OrderAccess::storestore(); // storestore, global state -> local state
|
||||||
OrderAccess::storestore(); // storestore, global state -> local state
|
for (JavaThreadIteratorWithHandle jtiwh; JavaThread *cur = jtiwh.next(); ) {
|
||||||
for (JavaThreadIteratorWithHandle jtiwh; JavaThread *cur = jtiwh.next(); ) {
|
// Make sure the threads start polling, it is time to yield.
|
||||||
// Make sure the threads start polling, it is time to yield.
|
SafepointMechanism::arm_local_poll(cur);
|
||||||
SafepointMechanism::arm_local_poll(cur);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
OrderAccess::fence(); // storestore|storeload, global state -> local state
|
OrderAccess::fence(); // storestore|storeload, global state -> local state
|
||||||
|
|
||||||
if (SafepointMechanism::uses_global_page_poll()) {
|
|
||||||
// Make interpreter safepoint aware
|
|
||||||
Interpreter::notice_safepoints();
|
|
||||||
|
|
||||||
// Make polling safepoint aware
|
|
||||||
guarantee (!PageArmed, "invariant") ;
|
|
||||||
PageArmed = true;
|
|
||||||
os::make_polling_page_unreadable();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Roll all threads forward to a safepoint and suspend them all
|
// Roll all threads forward to a safepoint and suspend them all
|
||||||
|
@ -464,15 +442,6 @@ void SafepointSynchronize::disarm_safepoint() {
|
||||||
}
|
}
|
||||||
#endif // ASSERT
|
#endif // ASSERT
|
||||||
|
|
||||||
if (SafepointMechanism::uses_global_page_poll()) {
|
|
||||||
guarantee (PageArmed, "invariant");
|
|
||||||
// Make polling safepoint aware
|
|
||||||
os::make_polling_page_readable();
|
|
||||||
PageArmed = false;
|
|
||||||
// Remove safepoint check from interpreter
|
|
||||||
Interpreter::ignore_safepoints();
|
|
||||||
}
|
|
||||||
|
|
||||||
OrderAccess::fence(); // keep read and write of _state from floating up
|
OrderAccess::fence(); // keep read and write of _state from floating up
|
||||||
assert(_state == _synchronized, "must be synchronized before ending safepoint synchronization");
|
assert(_state == _synchronized, "must be synchronized before ending safepoint synchronization");
|
||||||
|
|
||||||
|
@ -878,9 +847,6 @@ void SafepointSynchronize::block(JavaThread *thread) {
|
||||||
void SafepointSynchronize::handle_polling_page_exception(JavaThread *thread) {
|
void SafepointSynchronize::handle_polling_page_exception(JavaThread *thread) {
|
||||||
assert(thread->is_Java_thread(), "polling reference encountered by VM thread");
|
assert(thread->is_Java_thread(), "polling reference encountered by VM thread");
|
||||||
assert(thread->thread_state() == _thread_in_Java, "should come from Java code");
|
assert(thread->thread_state() == _thread_in_Java, "should come from Java code");
|
||||||
if (!SafepointMechanism::uses_thread_local_poll()) {
|
|
||||||
assert(SafepointSynchronize::is_synchronizing(), "polling encountered outside safepoint synchronization");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (log_is_enabled(Info, safepoint, stats)) {
|
if (log_is_enabled(Info, safepoint, stats)) {
|
||||||
Atomic::inc(&_nof_threads_hit_polling_page);
|
Atomic::inc(&_nof_threads_hit_polling_page);
|
||||||
|
@ -1049,11 +1015,6 @@ void ThreadSafepointState::print_on(outputStream *st) const {
|
||||||
// Block the thread at poll or poll return for safepoint/handshake.
|
// Block the thread at poll or poll return for safepoint/handshake.
|
||||||
void ThreadSafepointState::handle_polling_page_exception() {
|
void ThreadSafepointState::handle_polling_page_exception() {
|
||||||
|
|
||||||
// If we're using a global poll, then the thread should not be
|
|
||||||
// marked as safepoint safe yet.
|
|
||||||
assert(!SafepointMechanism::uses_global_page_poll() || !_safepoint_safe,
|
|
||||||
"polling page exception on thread safepoint safe");
|
|
||||||
|
|
||||||
// Step 1: Find the nmethod from the return address
|
// Step 1: Find the nmethod from the return address
|
||||||
address real_return_addr = thread()->saved_exception_pc();
|
address real_return_addr = thread()->saved_exception_pc();
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2017, 2019, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
@ -33,53 +33,42 @@
|
||||||
|
|
||||||
void* SafepointMechanism::_poll_armed_value;
|
void* SafepointMechanism::_poll_armed_value;
|
||||||
void* SafepointMechanism::_poll_disarmed_value;
|
void* SafepointMechanism::_poll_disarmed_value;
|
||||||
|
address SafepointMechanism::_polling_page;
|
||||||
|
|
||||||
void SafepointMechanism::default_initialize() {
|
void SafepointMechanism::default_initialize() {
|
||||||
if (uses_thread_local_poll()) {
|
// Poll bit values
|
||||||
|
intptr_t poll_armed_value = poll_bit();
|
||||||
// Poll bit values
|
intptr_t poll_disarmed_value = 0;
|
||||||
intptr_t poll_armed_value = poll_bit();
|
|
||||||
intptr_t poll_disarmed_value = 0;
|
|
||||||
|
|
||||||
#ifdef USE_POLL_BIT_ONLY
|
#ifdef USE_POLL_BIT_ONLY
|
||||||
if (!USE_POLL_BIT_ONLY)
|
if (!USE_POLL_BIT_ONLY)
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
// Polling page
|
// 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");
|
|
||||||
MemTracker::record_virtual_memory_type((address)polling_page, mtSafepoint);
|
|
||||||
|
|
||||||
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<intptr_t>(bad_page),
|
|
||||||
good_page_val = reinterpret_cast<intptr_t>(good_page);
|
|
||||||
poll_armed_value |= bad_page_val;
|
|
||||||
poll_disarmed_value |= good_page_val;
|
|
||||||
}
|
|
||||||
|
|
||||||
_poll_armed_value = reinterpret_cast<void*>(poll_armed_value);
|
|
||||||
_poll_disarmed_value = reinterpret_cast<void*>(poll_disarmed_value);
|
|
||||||
} else {
|
|
||||||
const size_t page_size = os::vm_page_size();
|
const size_t page_size = os::vm_page_size();
|
||||||
char* polling_page = os::reserve_memory(page_size, NULL, page_size);
|
const size_t allocation_size = 2 * page_size;
|
||||||
os::commit_memory_or_exit(polling_page, page_size, false, "Unable to commit Safepoint polling page");
|
char* polling_page = os::reserve_memory(allocation_size, NULL, page_size);
|
||||||
os::protect_memory(polling_page, page_size, os::MEM_PROT_READ);
|
os::commit_memory_or_exit(polling_page, allocation_size, false, "Unable to commit Safepoint polling page");
|
||||||
MemTracker::record_virtual_memory_type((address)polling_page, mtSafepoint);
|
MemTracker::record_virtual_memory_type((address)polling_page, mtSafepoint);
|
||||||
|
|
||||||
log_info(os)("SafePoint Polling address: " INTPTR_FORMAT, p2i(polling_page));
|
char* bad_page = polling_page;
|
||||||
os::set_polling_page((address)(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));
|
||||||
|
_polling_page = (address)(bad_page);
|
||||||
|
|
||||||
|
// Poll address values
|
||||||
|
intptr_t bad_page_val = reinterpret_cast<intptr_t>(bad_page),
|
||||||
|
good_page_val = reinterpret_cast<intptr_t>(good_page);
|
||||||
|
poll_armed_value |= bad_page_val;
|
||||||
|
poll_disarmed_value |= good_page_val;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_poll_armed_value = reinterpret_cast<void*>(poll_armed_value);
|
||||||
|
_poll_disarmed_value = reinterpret_cast<void*>(poll_disarmed_value);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SafepointMechanism::block_or_handshake(JavaThread *thread) {
|
void SafepointMechanism::block_or_handshake(JavaThread *thread) {
|
||||||
|
@ -89,7 +78,7 @@ void SafepointMechanism::block_or_handshake(JavaThread *thread) {
|
||||||
OrderAccess::loadload();
|
OrderAccess::loadload();
|
||||||
SafepointSynchronize::block(thread);
|
SafepointSynchronize::block(thread);
|
||||||
}
|
}
|
||||||
if (uses_thread_local_poll() && thread->has_handshake()) {
|
if (thread->has_handshake()) {
|
||||||
thread->handshake_process_by_self();
|
thread->handshake_process_by_self();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -103,7 +92,7 @@ void SafepointMechanism::block_if_requested_slow(JavaThread *thread) {
|
||||||
|
|
||||||
OrderAccess::loadload();
|
OrderAccess::loadload();
|
||||||
|
|
||||||
if (uses_thread_local_poll() && local_poll_armed(thread)) {
|
if (local_poll_armed(thread)) {
|
||||||
disarm_local_poll_release(thread);
|
disarm_local_poll_release(thread);
|
||||||
// We might have disarmed next safepoint/handshake
|
// We might have disarmed next safepoint/handshake
|
||||||
OrderAccess::storeload();
|
OrderAccess::storeload();
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2017, 2019, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
@ -34,6 +34,7 @@
|
||||||
class SafepointMechanism : public AllStatic {
|
class SafepointMechanism : public AllStatic {
|
||||||
static void* _poll_armed_value;
|
static void* _poll_armed_value;
|
||||||
static void* _poll_disarmed_value;
|
static void* _poll_disarmed_value;
|
||||||
|
static address _polling_page;
|
||||||
|
|
||||||
static void* poll_armed_value() { return _poll_armed_value; }
|
static void* poll_armed_value() { return _poll_armed_value; }
|
||||||
static void* poll_disarmed_value() { return _poll_disarmed_value; }
|
static void* poll_disarmed_value() { return _poll_disarmed_value; }
|
||||||
|
@ -59,14 +60,8 @@ class SafepointMechanism : public AllStatic {
|
||||||
public:
|
public:
|
||||||
static intptr_t poll_bit() { return _poll_bit; }
|
static intptr_t poll_bit() { return _poll_bit; }
|
||||||
|
|
||||||
static bool uses_global_page_poll() { return !uses_thread_local_poll(); }
|
static address get_polling_page() { return _polling_page; }
|
||||||
static bool uses_thread_local_poll() {
|
static bool is_poll_address(address addr) { return addr >= _polling_page && addr < (_polling_page + os::vm_page_size()); }
|
||||||
#ifdef THREAD_LOCAL_POLL
|
|
||||||
return true;
|
|
||||||
#else
|
|
||||||
return false;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
// Call this method to see if this thread should block for a safepoint or process handshake.
|
// Call this method to see if this thread should block for a safepoint or process handshake.
|
||||||
static inline bool should_block(Thread* thread);
|
static inline bool should_block(Thread* thread);
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2017, 2019, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
@ -48,15 +48,11 @@ bool SafepointMechanism::local_poll(Thread* thread) {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SafepointMechanism::should_block(Thread* thread) {
|
bool SafepointMechanism::should_block(Thread* thread) {
|
||||||
if (uses_thread_local_poll()) {
|
return local_poll(thread);
|
||||||
return local_poll(thread);
|
|
||||||
} else {
|
|
||||||
return global_poll();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void SafepointMechanism::block_if_requested(JavaThread *thread) {
|
void SafepointMechanism::block_if_requested(JavaThread *thread) {
|
||||||
if (uses_thread_local_poll() && !local_poll_armed(thread)) {
|
if (!local_poll_armed(thread)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
block_if_requested_slow(thread);
|
block_if_requested_slow(thread);
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 1997, 2019, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 1997, 2020, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
@ -250,12 +250,8 @@ void NMethodSweeper::mark_active_nmethods() {
|
||||||
|
|
||||||
CodeBlobClosure* NMethodSweeper::prepare_mark_active_nmethods() {
|
CodeBlobClosure* NMethodSweeper::prepare_mark_active_nmethods() {
|
||||||
#ifdef ASSERT
|
#ifdef ASSERT
|
||||||
if (SafepointMechanism::uses_thread_local_poll()) {
|
assert(Thread::current()->is_Code_cache_sweeper_thread(), "must be executed under CodeCache_lock and in sweeper thread");
|
||||||
assert(Thread::current()->is_Code_cache_sweeper_thread(), "must be executed under CodeCache_lock and in sweeper thread");
|
assert_lock_strong(CodeCache_lock);
|
||||||
assert_lock_strong(CodeCache_lock);
|
|
||||||
} else {
|
|
||||||
assert(SafepointSynchronize::is_at_safepoint(), "must be executed at a safepoint");
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// If we do not want to reclaim not-entrant or zombie methods there is no need
|
// If we do not want to reclaim not-entrant or zombie methods there is no need
|
||||||
|
@ -317,19 +313,14 @@ CodeBlobClosure* NMethodSweeper::prepare_reset_hotness_counters() {
|
||||||
void NMethodSweeper::do_stack_scanning() {
|
void NMethodSweeper::do_stack_scanning() {
|
||||||
assert(!CodeCache_lock->owned_by_self(), "just checking");
|
assert(!CodeCache_lock->owned_by_self(), "just checking");
|
||||||
if (wait_for_stack_scanning()) {
|
if (wait_for_stack_scanning()) {
|
||||||
if (SafepointMechanism::uses_thread_local_poll()) {
|
CodeBlobClosure* code_cl;
|
||||||
CodeBlobClosure* code_cl;
|
{
|
||||||
{
|
MutexLocker ccl(CodeCache_lock, Mutex::_no_safepoint_check_flag);
|
||||||
MutexLocker ccl(CodeCache_lock, Mutex::_no_safepoint_check_flag);
|
code_cl = prepare_mark_active_nmethods();
|
||||||
code_cl = prepare_mark_active_nmethods();
|
}
|
||||||
}
|
if (code_cl != NULL) {
|
||||||
if (code_cl != NULL) {
|
NMethodMarkingClosure nm_cl(code_cl);
|
||||||
NMethodMarkingClosure nm_cl(code_cl);
|
Handshake::execute(&nm_cl);
|
||||||
Handshake::execute(&nm_cl);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
VM_MarkActiveNMethods op;
|
|
||||||
VMThread::execute(&op);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1700,9 +1700,7 @@ void JavaThread::initialize() {
|
||||||
_popframe_preserved_args_size = 0;
|
_popframe_preserved_args_size = 0;
|
||||||
_frames_to_pop_failed_realloc = 0;
|
_frames_to_pop_failed_realloc = 0;
|
||||||
|
|
||||||
if (SafepointMechanism::uses_thread_local_poll()) {
|
SafepointMechanism::initialize_header(this);
|
||||||
SafepointMechanism::initialize_header(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
_class_to_be_initialized = NULL;
|
_class_to_be_initialized = NULL;
|
||||||
|
|
||||||
|
|
|
@ -39,6 +39,7 @@
|
||||||
#include "runtime/frame.inline.hpp"
|
#include "runtime/frame.inline.hpp"
|
||||||
#include "runtime/init.hpp"
|
#include "runtime/init.hpp"
|
||||||
#include "runtime/os.hpp"
|
#include "runtime/os.hpp"
|
||||||
|
#include "runtime/safepointMechanism.hpp"
|
||||||
#include "runtime/thread.inline.hpp"
|
#include "runtime/thread.inline.hpp"
|
||||||
#include "runtime/threadSMR.hpp"
|
#include "runtime/threadSMR.hpp"
|
||||||
#include "runtime/vmThread.hpp"
|
#include "runtime/vmThread.hpp"
|
||||||
|
@ -918,7 +919,7 @@ void VMError::report(outputStream* st, bool _verbose) {
|
||||||
if (_verbose && Universe::is_fully_initialized()) {
|
if (_verbose && Universe::is_fully_initialized()) {
|
||||||
Universe::heap()->print_on_error(st);
|
Universe::heap()->print_on_error(st);
|
||||||
st->cr();
|
st->cr();
|
||||||
st->print_cr("Polling page: " INTPTR_FORMAT, p2i(os::get_polling_page()));
|
st->print_cr("Polling page: " INTPTR_FORMAT, p2i(SafepointMechanism::get_polling_page()));
|
||||||
st->cr();
|
st->cr();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1120,7 +1121,7 @@ void VMError::print_vm_info(outputStream* st) {
|
||||||
MutexLocker hl(Heap_lock);
|
MutexLocker hl(Heap_lock);
|
||||||
Universe::heap()->print_on_error(st);
|
Universe::heap()->print_on_error(st);
|
||||||
st->cr();
|
st->cr();
|
||||||
st->print_cr("Polling page: " INTPTR_FORMAT, p2i(os::get_polling_page()));
|
st->print_cr("Polling page: " INTPTR_FORMAT, p2i(SafepointMechanism::get_polling_page()));
|
||||||
st->cr();
|
st->cr();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -432,10 +432,6 @@ public final class BinaryContainer implements SymbolTable {
|
||||||
return "_aot_stub_routines_crc_table_adr";
|
return "_aot_stub_routines_crc_table_adr";
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String getPollingPageSymbolName() {
|
|
||||||
return "_aot_polling_page";
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String getResolveStaticEntrySymbolName() {
|
public static String getResolveStaticEntrySymbolName() {
|
||||||
return "_resolve_static_entry";
|
return "_resolve_static_entry";
|
||||||
}
|
}
|
||||||
|
@ -512,7 +508,6 @@ public final class BinaryContainer implements SymbolTable {
|
||||||
createGotSymbol(getHeapEndAddressSymbolName());
|
createGotSymbol(getHeapEndAddressSymbolName());
|
||||||
createGotSymbol(getNarrowKlassBaseAddressSymbolName());
|
createGotSymbol(getNarrowKlassBaseAddressSymbolName());
|
||||||
createGotSymbol(getNarrowOopBaseAddressSymbolName());
|
createGotSymbol(getNarrowOopBaseAddressSymbolName());
|
||||||
createGotSymbol(getPollingPageSymbolName());
|
|
||||||
createGotSymbol(getLogOfHeapRegionGrainBytesSymbolName());
|
createGotSymbol(getLogOfHeapRegionGrainBytesSymbolName());
|
||||||
createGotSymbol(getInlineContiguousAllocationSupportedSymbolName());
|
createGotSymbol(getInlineContiguousAllocationSupportedSymbolName());
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2016, 2020, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
@ -71,10 +71,6 @@ final class MarkProcessor {
|
||||||
case INLINE_CONTIGUOUS_ALLOCATION_SUPPORTED:
|
case INLINE_CONTIGUOUS_ALLOCATION_SUPPORTED:
|
||||||
String vmSymbolName;
|
String vmSymbolName;
|
||||||
switch (markId) {
|
switch (markId) {
|
||||||
case POLL_FAR:
|
|
||||||
case POLL_RETURN_FAR:
|
|
||||||
vmSymbolName = BinaryContainer.getPollingPageSymbolName();
|
|
||||||
break;
|
|
||||||
case CARD_TABLE_ADDRESS:
|
case CARD_TABLE_ADDRESS:
|
||||||
vmSymbolName = BinaryContainer.getCardTableAddressSymbolName();
|
vmSymbolName = BinaryContainer.getCardTableAddressSymbolName();
|
||||||
break;
|
break;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue