8291302: ARM32: nmethod entry barriers support
Reviewed-by: eosterlund, rrich, mdoerr, aph
This commit is contained in:
parent
a9ce7726a7
commit
245f0cf4ac
@ -59,6 +59,9 @@ source_hpp %{
|
|||||||
// To keep related declarations/definitions/uses close together,
|
// To keep related declarations/definitions/uses close together,
|
||||||
// we switch between source %{ }% and source_hpp %{ }% freely as needed.
|
// we switch between source %{ }% and source_hpp %{ }% freely as needed.
|
||||||
|
|
||||||
|
#include "asm/macroAssembler.hpp"
|
||||||
|
#include "gc/shared/barrierSetAssembler.hpp"
|
||||||
|
|
||||||
// Does destination need to be loaded in a register then passed to a
|
// Does destination need to be loaded in a register then passed to a
|
||||||
// branch instruction?
|
// branch instruction?
|
||||||
extern bool maybe_far_call(const CallNode *n);
|
extern bool maybe_far_call(const CallNode *n);
|
||||||
@ -286,6 +289,17 @@ void MachPrologNode::format( PhaseRegAlloc *ra_, outputStream *st ) const {
|
|||||||
if (framesize != 0) {
|
if (framesize != 0) {
|
||||||
st->print ("SUB R_SP, R_SP, " SIZE_FORMAT,framesize);
|
st->print ("SUB R_SP, R_SP, " SIZE_FORMAT,framesize);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (C->stub_function() == NULL && BarrierSet::barrier_set()->barrier_set_nmethod() != NULL) {
|
||||||
|
st->print("ldr t0, [guard]\n\t");
|
||||||
|
st->print("ldr t1, [Rthread, #thread_disarmed_offset]\n\t");
|
||||||
|
st->print("cmp t0, t1\n\t");
|
||||||
|
st->print("beq skip\n\t");
|
||||||
|
st->print("blr #nmethod_entry_barrier_stub\n\t");
|
||||||
|
st->print("b skip\n\t");
|
||||||
|
st->print("guard: int\n\t");
|
||||||
|
st->print("skip:\n\t");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -318,6 +332,11 @@ void MachPrologNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const {
|
|||||||
__ sub_slow(SP, SP, framesize);
|
__ sub_slow(SP, SP, framesize);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (C->stub_function() == NULL) {
|
||||||
|
BarrierSetAssembler* bs = BarrierSet::barrier_set()->barrier_set_assembler();
|
||||||
|
bs->nmethod_entry_barrier(&_masm);
|
||||||
|
}
|
||||||
|
|
||||||
// offset from scratch buffer is not valid
|
// offset from scratch buffer is not valid
|
||||||
if (strcmp(cbuf.name(), "Compile::Fill_buffer") == 0) {
|
if (strcmp(cbuf.name(), "Compile::Fill_buffer") == 0) {
|
||||||
C->output()->set_frame_complete( __ offset() );
|
C->output()->set_frame_complete( __ offset() );
|
||||||
|
@ -25,6 +25,8 @@
|
|||||||
#include "precompiled.hpp"
|
#include "precompiled.hpp"
|
||||||
#include "c1/c1_MacroAssembler.hpp"
|
#include "c1/c1_MacroAssembler.hpp"
|
||||||
#include "c1/c1_Runtime1.hpp"
|
#include "c1/c1_Runtime1.hpp"
|
||||||
|
#include "gc/shared/barrierSet.hpp"
|
||||||
|
#include "gc/shared/barrierSetAssembler.hpp"
|
||||||
#include "gc/shared/collectedHeap.hpp"
|
#include "gc/shared/collectedHeap.hpp"
|
||||||
#include "gc/shared/tlab_globals.hpp"
|
#include "gc/shared/tlab_globals.hpp"
|
||||||
#include "interpreter/interpreter.hpp"
|
#include "interpreter/interpreter.hpp"
|
||||||
@ -62,6 +64,10 @@ void C1_MacroAssembler::build_frame(int frame_size_in_bytes, int bang_size_in_by
|
|||||||
// if this method contains a methodHandle call site
|
// if this method contains a methodHandle call site
|
||||||
raw_push(FP, LR);
|
raw_push(FP, LR);
|
||||||
sub_slow(SP, SP, frame_size_in_bytes);
|
sub_slow(SP, SP, frame_size_in_bytes);
|
||||||
|
|
||||||
|
// Insert nmethod entry barrier into frame.
|
||||||
|
BarrierSetAssembler* bs = BarrierSet::barrier_set()->barrier_set_assembler();
|
||||||
|
bs->nmethod_entry_barrier(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
void C1_MacroAssembler::remove_frame(int frame_size_in_bytes) {
|
void C1_MacroAssembler::remove_frame(int frame_size_in_bytes) {
|
||||||
|
@ -23,10 +23,13 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "precompiled.hpp"
|
#include "precompiled.hpp"
|
||||||
|
#include "gc/shared/barrierSet.hpp"
|
||||||
#include "gc/shared/barrierSetAssembler.hpp"
|
#include "gc/shared/barrierSetAssembler.hpp"
|
||||||
|
#include "gc/shared/barrierSetNMethod.hpp"
|
||||||
#include "gc/shared/collectedHeap.hpp"
|
#include "gc/shared/collectedHeap.hpp"
|
||||||
#include "memory/universe.hpp"
|
#include "memory/universe.hpp"
|
||||||
#include "runtime/javaThread.hpp"
|
#include "runtime/javaThread.hpp"
|
||||||
|
#include "runtime/stubRoutines.hpp"
|
||||||
|
|
||||||
#define __ masm->
|
#define __ masm->
|
||||||
|
|
||||||
@ -195,3 +198,47 @@ void BarrierSetAssembler::incr_allocated_bytes(MacroAssembler* masm, RegisterOrC
|
|||||||
// Unborrow the Rthread
|
// Unborrow the Rthread
|
||||||
__ sub(Rthread, Ralloc, in_bytes(JavaThread::allocated_bytes_offset()));
|
__ sub(Rthread, Ralloc, in_bytes(JavaThread::allocated_bytes_offset()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void BarrierSetAssembler::nmethod_entry_barrier(MacroAssembler* masm) {
|
||||||
|
|
||||||
|
BarrierSetNMethod* bs_nm = BarrierSet::barrier_set()->barrier_set_nmethod();
|
||||||
|
|
||||||
|
Register tmp0 = Rtemp;
|
||||||
|
Register tmp1 = R5; // must be callee-save register
|
||||||
|
|
||||||
|
if (bs_nm == NULL) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// The are no GCs that require memory barrier on arm32 now
|
||||||
|
#ifdef ASSERT
|
||||||
|
NMethodPatchingType patching_type = nmethod_patching_type();
|
||||||
|
assert(patching_type == NMethodPatchingType::stw_instruction_and_data_patch, "Unsupported patching type");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
Label skip, guard;
|
||||||
|
Address thread_disarmed_addr(Rthread, in_bytes(bs_nm->thread_disarmed_offset()));
|
||||||
|
|
||||||
|
__ block_comment("nmethod_barrier begin");
|
||||||
|
__ ldr_label(tmp0, guard);
|
||||||
|
|
||||||
|
// No memory barrier here
|
||||||
|
__ ldr(tmp1, thread_disarmed_addr);
|
||||||
|
__ cmp(tmp0, tmp1);
|
||||||
|
__ b(skip, eq);
|
||||||
|
|
||||||
|
__ mov_address(tmp0, StubRoutines::Arm::method_entry_barrier());
|
||||||
|
__ call(tmp0);
|
||||||
|
__ b(skip);
|
||||||
|
|
||||||
|
__ bind(guard);
|
||||||
|
|
||||||
|
// nmethod guard value. Skipped over in common case.
|
||||||
|
//
|
||||||
|
// Put a debug value to make any offsets skew
|
||||||
|
// clearly visible in coredump
|
||||||
|
__ emit_int32(0xDEADBEAF);
|
||||||
|
|
||||||
|
__ bind(skip);
|
||||||
|
__ block_comment("nmethod_barrier end");
|
||||||
|
}
|
||||||
|
@ -29,6 +29,10 @@
|
|||||||
#include "memory/allocation.hpp"
|
#include "memory/allocation.hpp"
|
||||||
#include "oops/access.hpp"
|
#include "oops/access.hpp"
|
||||||
|
|
||||||
|
enum class NMethodPatchingType {
|
||||||
|
stw_instruction_and_data_patch,
|
||||||
|
};
|
||||||
|
|
||||||
class BarrierSetAssembler: public CHeapObj<mtGC> {
|
class BarrierSetAssembler: public CHeapObj<mtGC> {
|
||||||
private:
|
private:
|
||||||
void incr_allocated_bytes(MacroAssembler* masm,
|
void incr_allocated_bytes(MacroAssembler* masm,
|
||||||
@ -56,6 +60,8 @@ public:
|
|||||||
);
|
);
|
||||||
|
|
||||||
virtual void barrier_stubs_init() {}
|
virtual void barrier_stubs_init() {}
|
||||||
|
virtual NMethodPatchingType nmethod_patching_type() { return NMethodPatchingType::stw_instruction_and_data_patch; }
|
||||||
|
virtual void nmethod_entry_barrier(MacroAssembler* masm);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // CPU_ARM_GC_SHARED_BARRIERSETASSEMBLER_ARM_HPP
|
#endif // CPU_ARM_GC_SHARED_BARRIERSETASSEMBLER_ARM_HPP
|
||||||
|
@ -23,18 +23,124 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "precompiled.hpp"
|
#include "precompiled.hpp"
|
||||||
|
#include "code/nativeInst.hpp"
|
||||||
|
#include "gc/shared/barrierSetAssembler.hpp"
|
||||||
#include "gc/shared/barrierSetNMethod.hpp"
|
#include "gc/shared/barrierSetNMethod.hpp"
|
||||||
|
#include "logging/log.hpp"
|
||||||
|
#include "memory/resourceArea.hpp"
|
||||||
|
#include "runtime/frame.inline.hpp"
|
||||||
|
#include "runtime/javaThread.hpp"
|
||||||
|
#include "runtime/sharedRuntime.hpp"
|
||||||
|
#include "runtime/registerMap.hpp"
|
||||||
|
#include "utilities/align.hpp"
|
||||||
#include "utilities/debug.hpp"
|
#include "utilities/debug.hpp"
|
||||||
|
|
||||||
|
// The constant below reflects the size of the barrier
|
||||||
|
// in barrierSetAssembler_arm.cpp
|
||||||
|
static const int entry_barrier_bytes = 9 * NativeInstruction::size();
|
||||||
|
|
||||||
|
class NativeNMethodBarrier: public NativeInstruction {
|
||||||
|
address instruction_address() const { return addr_at(0); }
|
||||||
|
|
||||||
|
int *guard_addr() const {
|
||||||
|
// Last instruction in a barrier
|
||||||
|
return reinterpret_cast<int*>(instruction_address() + entry_barrier_bytes - wordSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
int get_value() {
|
||||||
|
return Atomic::load_acquire(guard_addr());
|
||||||
|
}
|
||||||
|
|
||||||
|
void set_value(int value) {
|
||||||
|
Atomic::release_store(guard_addr(), value);
|
||||||
|
}
|
||||||
|
|
||||||
|
void verify() const;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Check the first instruction of the nmethod entry barrier
|
||||||
|
// to make sure that the offsets are not skewed.
|
||||||
|
void NativeNMethodBarrier::verify() const {
|
||||||
|
NativeInstruction *ni = (NativeInstruction *) instruction_address();
|
||||||
|
if (!ni->is_ldr()) {
|
||||||
|
uint32_t *addr = (uint32_t *) ni;
|
||||||
|
tty->print_cr("Addr: " INTPTR_FORMAT " Code: 0x%x", (intptr_t) addr, (uint32_t) *addr);
|
||||||
|
fatal("not an ldr instruction.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static NativeNMethodBarrier* native_nmethod_barrier(nmethod* nm) {
|
||||||
|
address barrier_address = nm->code_begin() + nm->frame_complete_offset() - entry_barrier_bytes;
|
||||||
|
NativeNMethodBarrier* barrier = reinterpret_cast<NativeNMethodBarrier*>(barrier_address);
|
||||||
|
debug_only(barrier->verify());
|
||||||
|
return barrier;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* We're called from an nmethod when we need to deoptimize it. We do
|
||||||
|
this by throwing away the nmethod's frame and jumping to the
|
||||||
|
ic_miss stub. This looks like there has been an IC miss at the
|
||||||
|
entry of the nmethod, so we resolve the call, which will fall back
|
||||||
|
to the interpreter if the nmethod has been unloaded. */
|
||||||
void BarrierSetNMethod::deoptimize(nmethod* nm, address* return_address_ptr) {
|
void BarrierSetNMethod::deoptimize(nmethod* nm, address* return_address_ptr) {
|
||||||
ShouldNotReachHere();
|
|
||||||
|
typedef struct {
|
||||||
|
intptr_t *sp; intptr_t *fp; address lr; address pc;
|
||||||
|
} frame_pointers_t;
|
||||||
|
|
||||||
|
frame_pointers_t *new_frame = (frame_pointers_t *)(return_address_ptr - 5);
|
||||||
|
|
||||||
|
JavaThread *thread = JavaThread::current();
|
||||||
|
RegisterMap reg_map(thread,
|
||||||
|
RegisterMap::UpdateMap::skip,
|
||||||
|
RegisterMap::ProcessFrames::include,
|
||||||
|
RegisterMap::WalkContinuation::skip);
|
||||||
|
frame frame = thread->last_frame();
|
||||||
|
|
||||||
|
assert(frame.is_compiled_frame() || frame.is_native_frame(), "must be");
|
||||||
|
assert(frame.cb() == nm, "must be");
|
||||||
|
frame = frame.sender(®_map);
|
||||||
|
|
||||||
|
LogTarget(Trace, nmethod, barrier) out;
|
||||||
|
if (out.is_enabled()) {
|
||||||
|
ResourceMark mark;
|
||||||
|
log_trace(nmethod, barrier)("deoptimize(nmethod: %s(%p), return_addr: %p, osr: %d, thread: %p(%s), making rsp: %p) -> %p",
|
||||||
|
nm->method()->name_and_sig_as_C_string(),
|
||||||
|
nm, *(address *) return_address_ptr, nm->is_osr_method(), thread,
|
||||||
|
thread->name(), frame.sp(), nm->verified_entry_point());
|
||||||
|
}
|
||||||
|
|
||||||
|
new_frame->sp = frame.sp();
|
||||||
|
new_frame->fp = frame.fp();
|
||||||
|
new_frame->lr = frame.pc();
|
||||||
|
new_frame->pc = SharedRuntime::get_handle_wrong_method_stub();
|
||||||
}
|
}
|
||||||
|
|
||||||
void BarrierSetNMethod::disarm(nmethod* nm) {
|
void BarrierSetNMethod::disarm(nmethod* nm) {
|
||||||
ShouldNotReachHere();
|
if (!supports_entry_barrier(nm)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Disarms the nmethod guard emitted by BarrierSetAssembler::nmethod_entry_barrier.
|
||||||
|
// Symmetric "LDR; DMB ISHLD" is in the nmethod barrier.
|
||||||
|
NativeNMethodBarrier* barrier = native_nmethod_barrier(nm);
|
||||||
|
barrier->set_value(disarmed_value());
|
||||||
|
}
|
||||||
|
|
||||||
|
void BarrierSetNMethod::arm(nmethod* nm, int arm_value) {
|
||||||
|
if (!supports_entry_barrier(nm)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
NativeNMethodBarrier* barrier = native_nmethod_barrier(nm);
|
||||||
|
barrier->set_value(arm_value);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool BarrierSetNMethod::is_armed(nmethod* nm) {
|
bool BarrierSetNMethod::is_armed(nmethod* nm) {
|
||||||
ShouldNotReachHere();
|
if (!supports_entry_barrier(nm)) {
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
NativeNMethodBarrier* barrier = native_nmethod_barrier(nm);
|
||||||
|
return barrier->get_value() != disarmed_value();
|
||||||
}
|
}
|
||||||
|
@ -587,9 +587,23 @@ public:
|
|||||||
AbstractAssembler::emit_address((address)L.data());
|
AbstractAssembler::emit_address((address)L.data());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ldr_label(Register rd, Label& L) {
|
||||||
|
ldr(rd, Address(PC, target(L) - pc() - 8));
|
||||||
|
}
|
||||||
|
|
||||||
void resolve_oop_handle(Register result);
|
void resolve_oop_handle(Register result);
|
||||||
void load_mirror(Register mirror, Register method, Register tmp);
|
void load_mirror(Register mirror, Register method, Register tmp);
|
||||||
|
|
||||||
|
void enter() {
|
||||||
|
raw_push(FP, LR);
|
||||||
|
mov(FP, SP);
|
||||||
|
}
|
||||||
|
|
||||||
|
void leave() {
|
||||||
|
mov(SP, FP);
|
||||||
|
raw_pop(FP, LR);
|
||||||
|
}
|
||||||
|
|
||||||
#define ARM_INSTR_1(common_mnemonic, arm32_mnemonic, arg_type) \
|
#define ARM_INSTR_1(common_mnemonic, arm32_mnemonic, arg_type) \
|
||||||
void common_mnemonic(arg_type arg) { \
|
void common_mnemonic(arg_type arg) { \
|
||||||
arm32_mnemonic(arg); \
|
arm32_mnemonic(arg); \
|
||||||
|
@ -77,9 +77,12 @@ class RawNativeInstruction {
|
|||||||
address instruction_address() const { return addr_at(0); }
|
address instruction_address() const { return addr_at(0); }
|
||||||
address next_raw_instruction_address() const { return addr_at(instruction_size); }
|
address next_raw_instruction_address() const { return addr_at(instruction_size); }
|
||||||
|
|
||||||
|
static int size() { return instruction_size; }
|
||||||
|
|
||||||
static RawNativeInstruction* at(address address) {
|
static RawNativeInstruction* at(address address) {
|
||||||
return (RawNativeInstruction*)address;
|
return (RawNativeInstruction*)address;
|
||||||
}
|
}
|
||||||
|
|
||||||
RawNativeInstruction* next_raw() const {
|
RawNativeInstruction* next_raw() const {
|
||||||
return at(next_raw_instruction_address());
|
return at(next_raw_instruction_address());
|
||||||
}
|
}
|
||||||
|
@ -28,6 +28,7 @@
|
|||||||
#include "code/icBuffer.hpp"
|
#include "code/icBuffer.hpp"
|
||||||
#include "code/vtableStubs.hpp"
|
#include "code/vtableStubs.hpp"
|
||||||
#include "compiler/oopMap.hpp"
|
#include "compiler/oopMap.hpp"
|
||||||
|
#include "gc/shared/barrierSetAssembler.hpp"
|
||||||
#include "interpreter/interpreter.hpp"
|
#include "interpreter/interpreter.hpp"
|
||||||
#include "logging/log.hpp"
|
#include "logging/log.hpp"
|
||||||
#include "memory/resourceArea.hpp"
|
#include "memory/resourceArea.hpp"
|
||||||
@ -873,6 +874,10 @@ nmethod* SharedRuntime::generate_native_wrapper(MacroAssembler* masm,
|
|||||||
__ mov(FP, SP);
|
__ mov(FP, SP);
|
||||||
__ sub_slow(SP, SP, stack_size - 2*wordSize);
|
__ sub_slow(SP, SP, stack_size - 2*wordSize);
|
||||||
|
|
||||||
|
BarrierSetAssembler* bs = BarrierSet::barrier_set()->barrier_set_assembler();
|
||||||
|
assert(bs != NULL, "Sanity");
|
||||||
|
bs->nmethod_entry_barrier(masm);
|
||||||
|
|
||||||
int frame_complete = __ pc() - start;
|
int frame_complete = __ pc() - start;
|
||||||
|
|
||||||
OopMapSet* oop_maps = new OopMapSet();
|
OopMapSet* oop_maps = new OopMapSet();
|
||||||
|
@ -27,6 +27,7 @@
|
|||||||
#include "compiler/oopMap.hpp"
|
#include "compiler/oopMap.hpp"
|
||||||
#include "gc/shared/barrierSet.hpp"
|
#include "gc/shared/barrierSet.hpp"
|
||||||
#include "gc/shared/barrierSetAssembler.hpp"
|
#include "gc/shared/barrierSetAssembler.hpp"
|
||||||
|
#include "gc/shared/barrierSetNMethod.hpp"
|
||||||
#include "interpreter/interpreter.hpp"
|
#include "interpreter/interpreter.hpp"
|
||||||
#include "memory/universe.hpp"
|
#include "memory/universe.hpp"
|
||||||
#include "nativeInst_arm.hpp"
|
#include "nativeInst_arm.hpp"
|
||||||
@ -2905,6 +2906,53 @@ class StubGenerator: public StubCodeGenerator {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
address generate_method_entry_barrier() {
|
||||||
|
__ align(CodeEntryAlignment);
|
||||||
|
StubCodeMark mark(this, "StubRoutines", "nmethod_entry_barrier");
|
||||||
|
|
||||||
|
Label deoptimize_label;
|
||||||
|
|
||||||
|
address start = __ pc();
|
||||||
|
|
||||||
|
// No need to save PC on Arm
|
||||||
|
__ set_last_Java_frame(SP, FP, false, Rtemp);
|
||||||
|
|
||||||
|
__ enter();
|
||||||
|
|
||||||
|
__ add(Rtemp, SP, wordSize); // Rtemp points to the saved lr
|
||||||
|
__ sub(SP, SP, 4 * wordSize); // four words for the returned {sp, fp, lr, pc}
|
||||||
|
|
||||||
|
const RegisterSet saved_regs = RegisterSet(R0, R10);
|
||||||
|
__ push(saved_regs);
|
||||||
|
__ fpush(FloatRegisterSet(D0, 16));
|
||||||
|
|
||||||
|
__ mov(c_rarg0, Rtemp);
|
||||||
|
__ call_VM_leaf(CAST_FROM_FN_PTR(address, BarrierSetNMethod::nmethod_stub_entry_barrier), c_rarg0);
|
||||||
|
|
||||||
|
__ reset_last_Java_frame(Rtemp);
|
||||||
|
|
||||||
|
__ mov(Rtemp, R0);
|
||||||
|
|
||||||
|
__ fpop(FloatRegisterSet(D0, 16));
|
||||||
|
__ pop(saved_regs);
|
||||||
|
|
||||||
|
__ cbnz(Rtemp, deoptimize_label);
|
||||||
|
|
||||||
|
__ leave();
|
||||||
|
__ bx(LR);
|
||||||
|
|
||||||
|
__ BIND(deoptimize_label);
|
||||||
|
|
||||||
|
__ ldr(Rtemp, Address(SP, 0));
|
||||||
|
__ ldr(FP, Address(SP, wordSize));
|
||||||
|
__ ldr(LR, Address(SP, wordSize * 2));
|
||||||
|
__ ldr(R5, Address(SP, wordSize * 3));
|
||||||
|
__ mov(SP, Rtemp);
|
||||||
|
__ bx(R5);
|
||||||
|
|
||||||
|
return start;
|
||||||
|
}
|
||||||
|
|
||||||
#define COMPILE_CRYPTO
|
#define COMPILE_CRYPTO
|
||||||
#include "stubRoutinesCrypto_arm.cpp"
|
#include "stubRoutinesCrypto_arm.cpp"
|
||||||
|
|
||||||
@ -3097,6 +3145,11 @@ class StubGenerator: public StubCodeGenerator {
|
|||||||
// arraycopy stubs used by compilers
|
// arraycopy stubs used by compilers
|
||||||
generate_arraycopy_stubs();
|
generate_arraycopy_stubs();
|
||||||
|
|
||||||
|
BarrierSetNMethod* bs_nm = BarrierSet::barrier_set()->barrier_set_nmethod();
|
||||||
|
if (bs_nm != NULL) {
|
||||||
|
StubRoutines::Arm::_method_entry_barrier = generate_method_entry_barrier();
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef COMPILE_CRYPTO
|
#ifdef COMPILE_CRYPTO
|
||||||
// generate AES intrinsics code
|
// generate AES intrinsics code
|
||||||
if (UseAESIntrinsics) {
|
if (UseAESIntrinsics) {
|
||||||
|
@ -33,3 +33,5 @@ address StubRoutines::Arm::_partial_subtype_check = NULL;
|
|||||||
|
|
||||||
address StubRoutines::_atomic_load_long_entry = NULL;
|
address StubRoutines::_atomic_load_long_entry = NULL;
|
||||||
address StubRoutines::_atomic_store_long_entry = NULL;
|
address StubRoutines::_atomic_store_long_entry = NULL;
|
||||||
|
|
||||||
|
address StubRoutines::Arm::_method_entry_barrier = NULL;
|
||||||
|
@ -42,11 +42,13 @@ class Arm {
|
|||||||
|
|
||||||
static address _idiv_irem_entry;
|
static address _idiv_irem_entry;
|
||||||
static address _partial_subtype_check;
|
static address _partial_subtype_check;
|
||||||
|
static address _method_entry_barrier;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
static address idiv_irem_entry() { return _idiv_irem_entry; }
|
static address idiv_irem_entry() { return _idiv_irem_entry; }
|
||||||
static address partial_subtype_check() { return _partial_subtype_check; }
|
static address partial_subtype_check() { return _partial_subtype_check; }
|
||||||
|
static address method_entry_barrier() { return _method_entry_barrier; }
|
||||||
};
|
};
|
||||||
|
|
||||||
static bool returns_to_call_stub(address return_pc) {
|
static bool returns_to_call_stub(address return_pc) {
|
||||||
|
@ -59,7 +59,7 @@ static BarrierSetNMethod* select_barrier_set_nmethod(BarrierSetNMethod* barrier_
|
|||||||
} else {
|
} else {
|
||||||
// The GC needs nmethod entry barriers to deal with continuations
|
// The GC needs nmethod entry barriers to deal with continuations
|
||||||
// and code cache unloading
|
// and code cache unloading
|
||||||
return NOT_ARM32(new BarrierSetNMethod()) ARM32_ONLY(nullptr);
|
return new BarrierSetNMethod();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user