8221554: aarch64 cross-modifying code

Reviewed-by: rehn, aph
This commit is contained in:
Alan Hayward 2020-11-19 12:27:22 +00:00 committed by Nick Gasson
parent f626ed6a43
commit d183fc7faa
26 changed files with 134 additions and 49 deletions

View file

@ -2922,7 +2922,6 @@ void LIR_Assembler::rt_call(LIR_Opr result, address dest, const LIR_OprList* arg
if (info != NULL) { if (info != NULL) {
add_call_info_here(info); add_call_info_here(info);
} }
__ maybe_isb();
} }
void LIR_Assembler::volatile_move_op(LIR_Opr src, LIR_Opr dest, BasicType type, CodeEmitInfo* info) { void LIR_Assembler::volatile_move_op(LIR_Opr src, LIR_Opr dest, BasicType type, CodeEmitInfo* info) {

View file

@ -80,7 +80,6 @@ int StubAssembler::call_RT(Register oop_result1, Register metadata_result, addre
pop(r0, sp); pop(r0, sp);
#endif #endif
reset_last_Java_frame(true); reset_last_Java_frame(true);
maybe_isb();
// check for pending exceptions // check for pending exceptions
{ Label L; { Label L;

View file

@ -1617,7 +1617,7 @@ void InterpreterMacroAssembler::call_VM_base(Register oop_result,
Label L; Label L;
ldr(rscratch1, Address(rfp, frame::interpreter_frame_last_sp_offset * wordSize)); ldr(rscratch1, Address(rfp, frame::interpreter_frame_last_sp_offset * wordSize));
cbz(rscratch1, L); cbz(rscratch1, L);
stop("InterpreterMacroAssembler::call_VM_leaf_base:" stop("InterpreterMacroAssembler::call_VM_base:"
" last_sp != NULL"); " last_sp != NULL");
bind(L); bind(L);
} }

View file

@ -159,7 +159,6 @@ address JNI_FastGetField::generate_fast_get_int_field0(BasicType type) {
__ enter(); __ enter();
__ lea(rscratch1, ExternalAddress(slow_case_addr)); __ lea(rscratch1, ExternalAddress(slow_case_addr));
__ blr(rscratch1); __ blr(rscratch1);
__ maybe_isb();
__ leave(); __ leave();
__ ret(lr); __ ret(lr);
} }

View file

@ -1381,7 +1381,6 @@ void MacroAssembler::call_VM_leaf_base(address entry_point,
bind(*retaddr); bind(*retaddr);
ldp(rscratch1, rmethod, Address(post(sp, 2 * wordSize))); ldp(rscratch1, rmethod, Address(post(sp, 2 * wordSize)));
maybe_isb();
} }
void MacroAssembler::call_VM_leaf(address entry_point, int number_of_arguments) { void MacroAssembler::call_VM_leaf(address entry_point, int number_of_arguments) {
@ -4387,10 +4386,15 @@ void MacroAssembler::get_polling_page(Register dest, relocInfo::relocType rtype)
// Read the polling page. The address of the polling page must // Read the polling page. The address of the polling page must
// already be in r. // already be in r.
address MacroAssembler::read_polling_page(Register r, relocInfo::relocType rtype) { address MacroAssembler::read_polling_page(Register r, relocInfo::relocType rtype) {
address mark;
{
InstructionMark im(this); InstructionMark im(this);
code_section()->relocate(inst_mark(), rtype); code_section()->relocate(inst_mark(), rtype);
ldrw(zr, Address(r, 0)); ldrw(zr, Address(r, 0));
return inst_mark(); mark = inst_mark();
}
verify_cross_modify_fence_not_required();
return mark;
} }
void MacroAssembler::adrp(Register reg1, const Address &dest, uint64_t &byte_offset) { void MacroAssembler::adrp(Register reg1, const Address &dest, uint64_t &byte_offset) {
@ -4455,6 +4459,7 @@ void MacroAssembler::build_frame(int framesize) {
sub(sp, sp, rscratch1); sub(sp, sp, rscratch1);
} }
} }
verify_cross_modify_fence_not_required();
} }
void MacroAssembler::remove_frame(int framesize) { void MacroAssembler::remove_frame(int framesize) {
@ -5315,3 +5320,29 @@ void MacroAssembler::verify_ptrue() {
stop("Error: the preserved predicate register (p7) elements are not all true"); stop("Error: the preserved predicate register (p7) elements are not all true");
bind(verify_ok); bind(verify_ok);
} }
void MacroAssembler::safepoint_isb() {
isb();
#ifndef PRODUCT
if (VerifyCrossModifyFence) {
// Clear the thread state.
strb(zr, Address(rthread, in_bytes(JavaThread::requires_cross_modify_fence_offset())));
}
#endif
}
#ifndef PRODUCT
void MacroAssembler::verify_cross_modify_fence_not_required() {
if (VerifyCrossModifyFence) {
// Check if thread needs a cross modify fence.
ldrb(rscratch1, Address(rthread, in_bytes(JavaThread::requires_cross_modify_fence_offset())));
Label fence_not_required;
cbz(rscratch1, fence_not_required);
// If it does then fail.
lea(rscratch1, CAST_FROM_FN_PTR(address, JavaThread::verify_cross_modify_fence_failure));
mov(c_rarg0, rthread);
blr(rscratch1);
bind(fence_not_required);
}
}
#endif

View file

@ -1315,8 +1315,9 @@ public:
Register zlen, Register tmp1, Register tmp2, Register tmp3, Register zlen, Register tmp1, Register tmp2, Register tmp3,
Register tmp4, Register tmp5, Register tmp6, Register tmp7); Register tmp4, Register tmp5, Register tmp6, Register tmp7);
void mul_add(Register out, Register in, Register offs, Register len, Register k); void mul_add(Register out, Register in, Register offs, Register len, Register k);
// ISB may be needed because of a safepoint
void maybe_isb() { isb(); } // Place an ISB after code may have been modified due to a safepoint.
void safepoint_isb();
private: private:
// Return the effective address r + (r1 << ext) + offset. // Return the effective address r + (r1 << ext) + offset.
@ -1392,6 +1393,11 @@ public:
} }
void cache_wb(Address line); void cache_wb(Address line);
void cache_wbsync(bool is_pre); void cache_wbsync(bool is_pre);
private:
// Check the current thread doesn't need a cross modify fence.
void verify_cross_modify_fence_not_required() PRODUCT_RETURN;
}; };
#ifdef ASSERT #ifdef ASSERT

View file

@ -373,7 +373,10 @@ static void patch_callers_callsite(MacroAssembler *masm) {
__ mov(c_rarg1, lr); __ mov(c_rarg1, lr);
__ lea(rscratch1, RuntimeAddress(CAST_FROM_FN_PTR(address, SharedRuntime::fixup_callers_callsite))); __ lea(rscratch1, RuntimeAddress(CAST_FROM_FN_PTR(address, SharedRuntime::fixup_callers_callsite)));
__ blr(rscratch1); __ blr(rscratch1);
__ maybe_isb();
// Explicit isb required because fixup_callers_callsite may change the code
// stream.
__ safepoint_isb();
__ pop_CPU_state(); __ pop_CPU_state();
// restore sp // restore sp
@ -1150,7 +1153,6 @@ static void rt_call(MacroAssembler* masm, address dest) {
} else { } else {
__ lea(rscratch1, RuntimeAddress(dest)); __ lea(rscratch1, RuntimeAddress(dest));
__ blr(rscratch1); __ blr(rscratch1);
__ maybe_isb();
} }
} }
@ -1857,7 +1859,7 @@ nmethod* SharedRuntime::generate_native_wrapper(MacroAssembler* masm,
__ verify_sve_vector_length(); __ verify_sve_vector_length();
} }
// check for safepoint operation in progress and/or pending suspend requests // Check for safepoint operation in progress and/or pending suspend requests.
{ {
// We need an acquire here to ensure that any subsequent load of the // We need an acquire here to ensure that any subsequent load of the
// global SafepointSynchronize::_state flag is ordered after this load // global SafepointSynchronize::_state flag is ordered after this load
@ -2081,7 +2083,7 @@ nmethod* SharedRuntime::generate_native_wrapper(MacroAssembler* masm,
#endif #endif
__ lea(rscratch1, RuntimeAddress(CAST_FROM_FN_PTR(address, JavaThread::check_special_condition_for_native_trans))); __ lea(rscratch1, RuntimeAddress(CAST_FROM_FN_PTR(address, JavaThread::check_special_condition_for_native_trans)));
__ blr(rscratch1); __ blr(rscratch1);
__ maybe_isb();
// Restore any method result value // Restore any method result value
restore_native_result(masm, ret_type, stack_slots); restore_native_result(masm, ret_type, stack_slots);
@ -2787,7 +2789,6 @@ SafepointBlob* SharedRuntime::generate_handler_blob(address call_ptr, int poll_t
__ reset_last_Java_frame(false); __ reset_last_Java_frame(false);
__ maybe_isb();
__ membar(Assembler::LoadLoad | Assembler::LoadStore); __ membar(Assembler::LoadLoad | Assembler::LoadStore);
if (UseSVE > 0 && save_vectors) { if (UseSVE > 0 && save_vectors) {
@ -2894,8 +2895,6 @@ RuntimeStub* SharedRuntime::generate_resolve_blob(address destination, const cha
oop_maps->add_gc_map( __ offset() - start, map); oop_maps->add_gc_map( __ offset() - start, map);
__ maybe_isb();
// r0 contains the address we are going to jump to assuming no exception got installed // r0 contains the address we are going to jump to assuming no exception got installed
// clear last_Java_sp // clear last_Java_sp
@ -3017,7 +3016,8 @@ void OptoRuntime::generate_exception_blob() {
__ mov(c_rarg0, rthread); __ mov(c_rarg0, rthread);
__ lea(rscratch1, RuntimeAddress(CAST_FROM_FN_PTR(address, OptoRuntime::handle_exception_C))); __ lea(rscratch1, RuntimeAddress(CAST_FROM_FN_PTR(address, OptoRuntime::handle_exception_C)));
__ blr(rscratch1); __ blr(rscratch1);
__ maybe_isb(); // handle_exception_C is a special VM call which does not require an explicit
// instruction sync afterwards.
// Set an oopmap for the call site. This oopmap will only be used if we // Set an oopmap for the call site. This oopmap will only be used if we
// are unwinding the stack. Hence, all locations will be dead. // are unwinding the stack. Hence, all locations will be dead.

View file

@ -5629,7 +5629,6 @@ class StubGenerator: public StubCodeGenerator {
oop_maps->add_gc_map(the_pc - start, map); oop_maps->add_gc_map(the_pc - start, map);
__ reset_last_Java_frame(true); __ reset_last_Java_frame(true);
__ maybe_isb();
if (UseSVE > 0) { if (UseSVE > 0) {
// Reinitialize the ptrue predicate register, in case the external runtime // Reinitialize the ptrue predicate register, in case the external runtime

View file

@ -1357,7 +1357,6 @@ address TemplateInterpreterGenerator::generate_native_entry(bool synchronized) {
// Call the native method. // Call the native method.
__ blr(r10); __ blr(r10);
__ bind(native_return); __ bind(native_return);
__ maybe_isb();
__ get_method(rmethod); __ get_method(rmethod);
// result potentially in r0 or v0 // result potentially in r0 or v0
@ -1410,7 +1409,6 @@ address TemplateInterpreterGenerator::generate_native_entry(bool synchronized) {
__ mov(c_rarg0, rthread); __ mov(c_rarg0, rthread);
__ mov(rscratch2, CAST_FROM_FN_PTR(address, JavaThread::check_special_condition_for_native_trans)); __ mov(rscratch2, CAST_FROM_FN_PTR(address, JavaThread::check_special_condition_for_native_trans));
__ blr(rscratch2); __ blr(rscratch2);
__ maybe_isb();
__ get_method(rmethod); __ get_method(rmethod);
__ reinit_heapbase(); __ reinit_heapbase();
__ bind(Continue); __ bind(Continue);

View file

@ -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.
* *
@ -73,7 +73,7 @@ inline void OrderAccess::storeload() { inlasm_sync(); }
inline void OrderAccess::acquire() { inlasm_lwsync(); } inline void OrderAccess::acquire() { inlasm_lwsync(); }
inline void OrderAccess::release() { inlasm_lwsync(); } inline void OrderAccess::release() { inlasm_lwsync(); }
inline void OrderAccess::fence() { inlasm_sync(); } inline void OrderAccess::fence() { inlasm_sync(); }
inline void OrderAccess::cross_modify_fence() inline void OrderAccess::cross_modify_fence_impl()
{ inlasm_isync(); } { inlasm_isync(); }
#undef inlasm_sync #undef inlasm_sync

View file

@ -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
@ -59,7 +59,7 @@ inline void OrderAccess::fence() {
compiler_barrier(); compiler_barrier();
} }
inline void OrderAccess::cross_modify_fence() { inline void OrderAccess::cross_modify_fence_impl() {
int idx = 0; int idx = 0;
__asm__ volatile ("cpuid " : "+a" (idx) : : "ebx", "ecx", "edx", "memory"); __asm__ volatile ("cpuid " : "+a" (idx) : : "ebx", "ecx", "edx", "memory");
} }

View file

@ -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.
* Copyright 2007, 2008, 2009 Red Hat, Inc. * Copyright 2007, 2008, 2009 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.
* *
@ -77,6 +77,6 @@ inline void OrderAccess::storeload() { FULL_MEM_BARRIER; }
inline void OrderAccess::acquire() { LIGHT_MEM_BARRIER; } inline void OrderAccess::acquire() { LIGHT_MEM_BARRIER; }
inline void OrderAccess::release() { LIGHT_MEM_BARRIER; } inline void OrderAccess::release() { LIGHT_MEM_BARRIER; }
inline void OrderAccess::fence() { FULL_MEM_BARRIER; } inline void OrderAccess::fence() { FULL_MEM_BARRIER; }
inline void OrderAccess::cross_modify_fence() { } inline void OrderAccess::cross_modify_fence_impl() { }
#endif // OS_CPU_BSD_ZERO_ORDERACCESS_BSD_ZERO_HPP #endif // OS_CPU_BSD_ZERO_ORDERACCESS_BSD_ZERO_HPP

View file

@ -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.
* 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.
* *
@ -53,6 +53,8 @@ inline void OrderAccess::fence() {
FULL_MEM_BARRIER; FULL_MEM_BARRIER;
} }
inline void OrderAccess::cross_modify_fence() { } inline void OrderAccess::cross_modify_fence_impl() {
asm volatile("isb" : : : "memory");
}
#endif // OS_CPU_LINUX_AARCH64_ORDERACCESS_LINUX_AARCH64_HPP #endif // OS_CPU_LINUX_AARCH64_ORDERACCESS_LINUX_AARCH64_HPP

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2008, 2019, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2008, 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
@ -101,6 +101,6 @@ inline void OrderAccess::storestore() { dmb_st(); }
inline void OrderAccess::storeload() { dmb_sy(); } inline void OrderAccess::storeload() { dmb_sy(); }
inline void OrderAccess::release() { dmb_sy(); } inline void OrderAccess::release() { dmb_sy(); }
inline void OrderAccess::fence() { dmb_sy(); } inline void OrderAccess::fence() { dmb_sy(); }
inline void OrderAccess::cross_modify_fence() { } inline void OrderAccess::cross_modify_fence_impl() { }
#endif // OS_CPU_LINUX_ARM_ORDERACCESS_LINUX_ARM_HPP #endif // OS_CPU_LINUX_ARM_ORDERACCESS_LINUX_ARM_HPP

View file

@ -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, 2014 SAP SE. All rights reserved. * Copyright (c) 2012, 2014 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.
* *
@ -77,7 +77,7 @@ inline void OrderAccess::storeload() { inlasm_sync(); }
inline void OrderAccess::acquire() { inlasm_lwsync(); } inline void OrderAccess::acquire() { inlasm_lwsync(); }
inline void OrderAccess::release() { inlasm_lwsync(); } inline void OrderAccess::release() { inlasm_lwsync(); }
inline void OrderAccess::fence() { inlasm_sync(); } inline void OrderAccess::fence() { inlasm_sync(); }
inline void OrderAccess::cross_modify_fence() inline void OrderAccess::cross_modify_fence_impl()
{ inlasm_isync(); } { inlasm_isync(); }
#undef inlasm_sync #undef inlasm_sync

View file

@ -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.
* *
@ -74,7 +74,7 @@ inline void OrderAccess::storeload() { inlasm_zarch_sync(); }
inline void OrderAccess::acquire() { inlasm_zarch_acquire(); } inline void OrderAccess::acquire() { inlasm_zarch_acquire(); }
inline void OrderAccess::release() { inlasm_zarch_release(); } inline void OrderAccess::release() { inlasm_zarch_release(); }
inline void OrderAccess::fence() { inlasm_zarch_sync(); } inline void OrderAccess::fence() { inlasm_zarch_sync(); }
inline void OrderAccess::cross_modify_fence() { inlasm_zarch_sync(); } inline void OrderAccess::cross_modify_fence_impl() { inlasm_zarch_sync(); }
#undef inlasm_compiler_barrier #undef inlasm_compiler_barrier
#undef inlasm_zarch_sync #undef inlasm_zarch_sync

View file

@ -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
@ -55,7 +55,7 @@ inline void OrderAccess::fence() {
compiler_barrier(); compiler_barrier();
} }
inline void OrderAccess::cross_modify_fence() { inline void OrderAccess::cross_modify_fence_impl() {
int idx = 0; int idx = 0;
#ifdef AMD64 #ifdef AMD64
__asm__ volatile ("cpuid " : "+a" (idx) : : "ebx", "ecx", "edx", "memory"); __asm__ volatile ("cpuid " : "+a" (idx) : : "ebx", "ecx", "edx", "memory");

View file

@ -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.
* Copyright 2007, 2008, 2009 Red Hat, Inc. * Copyright 2007, 2008, 2009 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.
* *
@ -78,6 +78,6 @@ inline void OrderAccess::acquire() { LIGHT_MEM_BARRIER; }
inline void OrderAccess::release() { LIGHT_MEM_BARRIER; } inline void OrderAccess::release() { LIGHT_MEM_BARRIER; }
inline void OrderAccess::fence() { FULL_MEM_BARRIER; } inline void OrderAccess::fence() { FULL_MEM_BARRIER; }
inline void OrderAccess::cross_modify_fence() { } inline void OrderAccess::cross_modify_fence_impl() { }
#endif // OS_CPU_LINUX_ZERO_ORDERACCESS_LINUX_ZERO_HPP #endif // OS_CPU_LINUX_ZERO_ORDERACCESS_LINUX_ZERO_HPP

View file

@ -28,7 +28,7 @@
// Included in orderAccess.hpp header file. // Included in orderAccess.hpp header file.
#include <atomic> #include <atomic>
using std::atomic_thread_fence; using std::atomic_thread_fence;
#include <intrin.h> #include <arm64intr.h>
#include "vm_version_aarch64.hpp" #include "vm_version_aarch64.hpp"
#include "runtime/vm_version.hpp" #include "runtime/vm_version.hpp"
@ -55,6 +55,8 @@ inline void OrderAccess::fence() {
FULL_MEM_BARRIER; FULL_MEM_BARRIER;
} }
inline void OrderAccess::cross_modify_fence() { } inline void OrderAccess::cross_modify_fence_impl() {
__isb(_ARM64_BARRIER_SY);
}
#endif // OS_CPU_WINDOWS_AARCH64_ORDERACCESS_WINDOWS_AARCH64_HPP #endif // OS_CPU_WINDOWS_AARCH64_ORDERACCESS_WINDOWS_AARCH64_HPP

View file

@ -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
@ -58,7 +58,7 @@ inline void OrderAccess::fence() {
compiler_barrier(); compiler_barrier();
} }
inline void OrderAccess::cross_modify_fence() { inline void OrderAccess::cross_modify_fence_impl() {
int regs[4]; int regs[4];
__cpuid(regs, 0); __cpuid(regs, 0);
} }

View file

@ -2490,7 +2490,12 @@ const intx ObjectAlignmentInBytes = 8;
"Allow allocating fields in empty slots of super-classes") \ "Allow allocating fields in empty slots of super-classes") \
\ \
product(bool, DeoptimizeNMethodBarriersALot, false, DIAGNOSTIC, \ product(bool, DeoptimizeNMethodBarriersALot, false, DIAGNOSTIC, \
"Make nmethod barriers deoptimise a lot.") "Make nmethod barriers deoptimise a lot.") \
\
develop(bool, VerifyCrossModifyFence, \
false AARCH64_ONLY(DEBUG_ONLY(||true)), \
"Mark all threads after a safepoint, and clear on a modify " \
"fence. Add cleanliness checks.") \
// end of RUNTIME_FLAGS // end of RUNTIME_FLAGS

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2003, 2010, 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
@ -25,7 +25,10 @@
#include "precompiled.hpp" #include "precompiled.hpp"
#include "runtime/orderAccess.hpp" #include "runtime/orderAccess.hpp"
#include "runtime/stubRoutines.hpp" #include "runtime/stubRoutines.hpp"
#ifndef PRODUCT
#include "runtime/thread.hpp" #include "runtime/thread.hpp"
#endif
void OrderAccess::StubRoutines_fence() { void OrderAccess::StubRoutines_fence() {
// Use a stub if it exists. It may not exist during bootstrap so do // Use a stub if it exists. It may not exist during bootstrap so do
@ -38,3 +41,11 @@ void OrderAccess::StubRoutines_fence() {
} }
assert(Threads::number_of_threads() == 0, "for bootstrap only"); assert(Threads::number_of_threads() == 0, "for bootstrap only");
} }
#ifndef PRODUCT
void OrderAccess::cross_modify_fence_verify() {
if (VerifyCrossModifyFence) {
JavaThread::current()->set_requires_cross_modify_fence(false);
}
}
#endif

View file

@ -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
@ -112,7 +112,7 @@
// may be more conservative in implementations. We advise using the bound // may be more conservative in implementations. We advise using the bound
// variants whenever possible. // variants whenever possible.
// //
// Finally, we define a "fence" operation, as a bidirectional barrier. // We define a "fence" operation, as a bidirectional barrier.
// It guarantees that any memory access preceding the fence is not // It guarantees that any memory access preceding the fence is not
// reordered w.r.t. any memory accesses subsequent to the fence in program // reordered w.r.t. any memory accesses subsequent to the fence in program
// order. This may be used to prevent sequences of loads from floating up // order. This may be used to prevent sequences of loads from floating up
@ -229,6 +229,10 @@
// order*. And that their destructors do a release and unlock, in *that* // order*. And that their destructors do a release and unlock, in *that*
// order. If their implementations change such that these assumptions // order. If their implementations change such that these assumptions
// are violated, a whole lot of code will break. // are violated, a whole lot of code will break.
//
// Finally, we define an "instruction_fence" operation, which ensures that all
// instructions that come after the fence in program order are fetched
// from the cache or memory after the fence has completed.
class OrderAccess : public AllStatic { class OrderAccess : public AllStatic {
public: public:
@ -242,7 +246,10 @@ class OrderAccess : public AllStatic {
static void release(); static void release();
static void fence(); static void fence();
static void cross_modify_fence(); static void cross_modify_fence() {
cross_modify_fence_impl();
cross_modify_fence_verify();
}
// Processors which are not multi-copy-atomic require a full fence // Processors which are not multi-copy-atomic require a full fence
// to enforce a globally consistent order of Independent Reads of // to enforce a globally consistent order of Independent Reads of
@ -259,6 +266,10 @@ private:
// routine if it exists, It should only be used by platforms that // routine if it exists, It should only be used by platforms that
// don't have another way to do the inline assembly. // don't have another way to do the inline assembly.
static void StubRoutines_fence(); static void StubRoutines_fence();
static void cross_modify_fence_impl();
static void cross_modify_fence_verify() PRODUCT_RETURN;
}; };
#include OS_CPU_HEADER(orderAccess) #include OS_CPU_HEADER(orderAccess)

View file

@ -381,6 +381,14 @@ void SafepointSynchronize::begin() {
assert(_waiting_to_block == 0, "No thread should be running"); assert(_waiting_to_block == 0, "No thread should be running");
#ifndef PRODUCT #ifndef PRODUCT
// Mark all threads
if (VerifyCrossModifyFence) {
JavaThreadIteratorWithHandle jtiwh;
for (; JavaThread *cur = jtiwh.next(); ) {
cur->set_requires_cross_modify_fence(true);
}
}
if (safepoint_limit_time != 0) { if (safepoint_limit_time != 0) {
jlong current_time = os::javaTimeNanos(); jlong current_time = os::javaTimeNanos();
if (safepoint_limit_time < current_time) { if (safepoint_limit_time < current_time) {

View file

@ -1580,6 +1580,9 @@ JavaThread::JavaThread() :
ThreadSafepointState::create(this); ThreadSafepointState::create(this);
SafepointMechanism::initialize_header(this); SafepointMechanism::initialize_header(this);
set_requires_cross_modify_fence(false);
pd_initialize(); pd_initialize();
assert(deferred_card_mark().is_empty(), "Default MemRegion ctor"); assert(deferred_card_mark().is_empty(), "Default MemRegion ctor");
} }
@ -4646,3 +4649,9 @@ void Threads::verify() {
VMThread* thread = VMThread::vm_thread(); VMThread* thread = VMThread::vm_thread();
if (thread != NULL) thread->verify(); if (thread != NULL) thread->verify();
} }
#ifndef PRODUCT
void JavaThread::verify_cross_modify_fence_failure(JavaThread *thread) {
report_vm_error(__FILE__, __LINE__, "Cross modify fence failure", "%p", thread);
}
#endif

View file

@ -1093,6 +1093,7 @@ class JavaThread: public Thread {
private: private:
ThreadSafepointState* _safepoint_state; // Holds information about a thread during a safepoint ThreadSafepointState* _safepoint_state; // Holds information about a thread during a safepoint
address _saved_exception_pc; // Saved pc of instruction where last implicit exception happened address _saved_exception_pc; // Saved pc of instruction where last implicit exception happened
NOT_PRODUCT(bool _requires_cross_modify_fence;) // State used by VerifyCrossModifyFence
// JavaThread termination support // JavaThread termination support
enum TerminatedTypes { enum TerminatedTypes {
@ -1324,6 +1325,8 @@ class JavaThread: public Thread {
SafepointMechanism::ThreadData* poll_data() { return &_poll_data; } SafepointMechanism::ThreadData* poll_data() { return &_poll_data; }
void set_requires_cross_modify_fence(bool val) PRODUCT_RETURN NOT_PRODUCT({ _requires_cross_modify_fence = val; })
private: private:
// Support for thread handshake operations // Support for thread handshake operations
HandshakeState _handshake; HandshakeState _handshake;
@ -1599,6 +1602,7 @@ class JavaThread: public Thread {
return byte_offset_of(JavaThread, _should_post_on_exceptions_flag); return byte_offset_of(JavaThread, _should_post_on_exceptions_flag);
} }
static ByteSize doing_unsafe_access_offset() { return byte_offset_of(JavaThread, _doing_unsafe_access); } static ByteSize doing_unsafe_access_offset() { return byte_offset_of(JavaThread, _doing_unsafe_access); }
NOT_PRODUCT(static ByteSize requires_cross_modify_fence_offset() { return byte_offset_of(JavaThread, _requires_cross_modify_fence); })
// Returns the jni environment for this thread // Returns the jni environment for this thread
JNIEnv* jni_environment() { return &_jni_environment; } JNIEnv* jni_environment() { return &_jni_environment; }
@ -1888,6 +1892,8 @@ public:
bool is_interrupted(bool clear_interrupted); bool is_interrupted(bool clear_interrupted);
static OopStorage* thread_oop_storage(); static OopStorage* thread_oop_storage();
static void verify_cross_modify_fence_failure(JavaThread *thread) PRODUCT_RETURN;
}; };
// Inline implementation of JavaThread::current // Inline implementation of JavaThread::current