8230765: Implement nmethod barrier for x86_32 platforms
Reviewed-by: rkennke, eosterlund
This commit is contained in:
parent
598ec40995
commit
7f3ef14d5b
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2018, 2019, 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
|
||||||
@ -327,24 +327,42 @@ void BarrierSetAssembler::incr_allocated_bytes(MacroAssembler* masm, Register th
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef _LP64
|
||||||
void BarrierSetAssembler::nmethod_entry_barrier(MacroAssembler* masm) {
|
void BarrierSetAssembler::nmethod_entry_barrier(MacroAssembler* masm) {
|
||||||
BarrierSetNMethod* bs_nm = BarrierSet::barrier_set()->barrier_set_nmethod();
|
BarrierSetNMethod* bs_nm = BarrierSet::barrier_set()->barrier_set_nmethod();
|
||||||
if (bs_nm == NULL) {
|
if (bs_nm == NULL) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
#ifndef _LP64
|
|
||||||
ShouldNotReachHere();
|
|
||||||
#else
|
|
||||||
Label continuation;
|
Label continuation;
|
||||||
Register thread = LP64_ONLY(r15_thread);
|
Register thread = r15_thread;
|
||||||
Address disarmed_addr(thread, in_bytes(bs_nm->thread_disarmed_offset()));
|
Address disarmed_addr(thread, in_bytes(bs_nm->thread_disarmed_offset()));
|
||||||
__ align(8);
|
__ align(8);
|
||||||
__ cmpl(disarmed_addr, 0);
|
__ cmpl(disarmed_addr, 0);
|
||||||
__ jcc(Assembler::equal, continuation);
|
__ jcc(Assembler::equal, continuation);
|
||||||
__ call(RuntimeAddress(StubRoutines::x86::method_entry_barrier()));
|
__ call(RuntimeAddress(StubRoutines::x86::method_entry_barrier()));
|
||||||
__ bind(continuation);
|
__ bind(continuation);
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
#else
|
||||||
|
void BarrierSetAssembler::nmethod_entry_barrier(MacroAssembler* masm) {
|
||||||
|
BarrierSetNMethod* bs_nm = BarrierSet::barrier_set()->barrier_set_nmethod();
|
||||||
|
if (bs_nm == NULL) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Label continuation;
|
||||||
|
|
||||||
|
Register tmp = rdi;
|
||||||
|
__ push(tmp);
|
||||||
|
__ movptr(tmp, (intptr_t)bs_nm->disarmed_value_address());
|
||||||
|
Address disarmed_addr(tmp, 0);
|
||||||
|
__ align(4);
|
||||||
|
__ cmpl(disarmed_addr, 0);
|
||||||
|
__ pop(tmp);
|
||||||
|
__ jcc(Assembler::equal, continuation);
|
||||||
|
__ call(RuntimeAddress(StubRoutines::x86::method_entry_barrier()));
|
||||||
|
__ bind(continuation);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
void BarrierSetAssembler::c2i_entry_barrier(MacroAssembler* masm) {
|
void BarrierSetAssembler::c2i_entry_barrier(MacroAssembler* masm) {
|
||||||
BarrierSetNMethod* bs = BarrierSet::barrier_set()->barrier_set_nmethod();
|
BarrierSetNMethod* bs = BarrierSet::barrier_set()->barrier_set_nmethod();
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2018, 2019, 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
|
||||||
@ -35,6 +35,7 @@
|
|||||||
|
|
||||||
class NativeNMethodCmpBarrier: public NativeInstruction {
|
class NativeNMethodCmpBarrier: public NativeInstruction {
|
||||||
public:
|
public:
|
||||||
|
#ifdef _LP64
|
||||||
enum Intel_specific_constants {
|
enum Intel_specific_constants {
|
||||||
instruction_code = 0x81,
|
instruction_code = 0x81,
|
||||||
instruction_size = 8,
|
instruction_size = 8,
|
||||||
@ -42,6 +43,14 @@ public:
|
|||||||
instruction_rex_prefix = Assembler::REX | Assembler::REX_B,
|
instruction_rex_prefix = Assembler::REX | Assembler::REX_B,
|
||||||
instruction_modrm = 0x7f // [r15 + offset]
|
instruction_modrm = 0x7f // [r15 + offset]
|
||||||
};
|
};
|
||||||
|
#else
|
||||||
|
enum Intel_specific_constants {
|
||||||
|
instruction_code = 0x81,
|
||||||
|
instruction_size = 7,
|
||||||
|
imm_offset = 2,
|
||||||
|
instruction_modrm = 0x3f // [rdi]
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
address instruction_address() const { return addr_at(0); }
|
address instruction_address() const { return addr_at(0); }
|
||||||
address immediate_address() const { return addr_at(imm_offset); }
|
address immediate_address() const { return addr_at(imm_offset); }
|
||||||
@ -51,6 +60,7 @@ public:
|
|||||||
void verify() const;
|
void verify() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#ifdef _LP64
|
||||||
void NativeNMethodCmpBarrier::verify() const {
|
void NativeNMethodCmpBarrier::verify() const {
|
||||||
if (((uintptr_t) instruction_address()) & 0x7) {
|
if (((uintptr_t) instruction_address()) & 0x7) {
|
||||||
fatal("Not properly aligned");
|
fatal("Not properly aligned");
|
||||||
@ -77,6 +87,27 @@ void NativeNMethodCmpBarrier::verify() const {
|
|||||||
fatal("not a cmp barrier");
|
fatal("not a cmp barrier");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#else
|
||||||
|
void NativeNMethodCmpBarrier::verify() const {
|
||||||
|
if (((uintptr_t) instruction_address()) & 0x3) {
|
||||||
|
fatal("Not properly aligned");
|
||||||
|
}
|
||||||
|
|
||||||
|
int inst = ubyte_at(0);
|
||||||
|
if (inst != instruction_code) {
|
||||||
|
tty->print_cr("Addr: " INTPTR_FORMAT " Code: 0x%x", p2i(instruction_address()),
|
||||||
|
inst);
|
||||||
|
fatal("not a cmp barrier");
|
||||||
|
}
|
||||||
|
|
||||||
|
int modrm = ubyte_at(1);
|
||||||
|
if (modrm != instruction_modrm) {
|
||||||
|
tty->print_cr("Addr: " INTPTR_FORMAT " mod/rm: 0x%x", p2i(instruction_address()),
|
||||||
|
modrm);
|
||||||
|
fatal("not a cmp barrier");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif // _LP64
|
||||||
|
|
||||||
void BarrierSetNMethod::deoptimize(nmethod* nm, address* return_address_ptr) {
|
void BarrierSetNMethod::deoptimize(nmethod* nm, address* return_address_ptr) {
|
||||||
/*
|
/*
|
||||||
@ -127,7 +158,7 @@ void BarrierSetNMethod::deoptimize(nmethod* nm, address* return_address_ptr) {
|
|||||||
// NativeNMethodCmpBarrier::verify() will immediately complain when it does
|
// NativeNMethodCmpBarrier::verify() will immediately complain when it does
|
||||||
// not find the expected native instruction at this offset, which needs updating.
|
// not find the expected native instruction at this offset, which needs updating.
|
||||||
// Note that this offset is invariant of PreserveFramePointer.
|
// Note that this offset is invariant of PreserveFramePointer.
|
||||||
static const int entry_barrier_offset = -19;
|
static const int entry_barrier_offset = LP64_ONLY(-19) NOT_LP64(-18);
|
||||||
|
|
||||||
static NativeNMethodCmpBarrier* native_nmethod_barrier(nmethod* nm) {
|
static NativeNMethodCmpBarrier* native_nmethod_barrier(nmethod* nm) {
|
||||||
address barrier_address = nm->code_begin() + nm->frame_complete_offset() + entry_barrier_offset;
|
address barrier_address = nm->code_begin() + nm->frame_complete_offset() + entry_barrier_offset;
|
||||||
|
@ -975,6 +975,9 @@ AdapterHandlerEntry* SharedRuntime::generate_i2c2i_adapters(MacroAssembler *masm
|
|||||||
|
|
||||||
address c2i_entry = __ pc();
|
address c2i_entry = __ pc();
|
||||||
|
|
||||||
|
BarrierSetAssembler* bs = BarrierSet::barrier_set()->barrier_set_assembler();
|
||||||
|
bs->c2i_entry_barrier(masm);
|
||||||
|
|
||||||
gen_c2i_adapter(masm, total_args_passed, comp_args_on_stack, sig_bt, regs, skip_fixup);
|
gen_c2i_adapter(masm, total_args_passed, comp_args_on_stack, sig_bt, regs, skip_fixup);
|
||||||
|
|
||||||
__ flush();
|
__ flush();
|
||||||
@ -1886,6 +1889,10 @@ nmethod* SharedRuntime::generate_native_wrapper(MacroAssembler* masm,
|
|||||||
// -2 because return address is already present and so is saved rbp
|
// -2 because return address is already present and so is saved rbp
|
||||||
__ subptr(rsp, stack_size - 2*wordSize);
|
__ subptr(rsp, stack_size - 2*wordSize);
|
||||||
|
|
||||||
|
|
||||||
|
BarrierSetAssembler* bs = BarrierSet::barrier_set()->barrier_set_assembler();
|
||||||
|
bs->nmethod_entry_barrier(masm);
|
||||||
|
|
||||||
// Frame is now completed as far as size and linkage.
|
// Frame is now completed as far as size and linkage.
|
||||||
int frame_complete = ((intptr_t)__ pc()) - start;
|
int frame_complete = ((intptr_t)__ pc()) - start;
|
||||||
|
|
||||||
@ -1921,12 +1928,12 @@ nmethod* SharedRuntime::generate_native_wrapper(MacroAssembler* masm,
|
|||||||
// if we load it once it is usable thru the entire wrapper
|
// if we load it once it is usable thru the entire wrapper
|
||||||
const Register thread = rdi;
|
const Register thread = rdi;
|
||||||
|
|
||||||
// We use rsi as the oop handle for the receiver/klass
|
// We use rsi as the oop handle for the receiver/klass
|
||||||
// It is callee save so it survives the call to native
|
// It is callee save so it survives the call to native
|
||||||
|
|
||||||
const Register oop_handle_reg = rsi;
|
const Register oop_handle_reg = rsi;
|
||||||
|
|
||||||
__ get_thread(thread);
|
__ get_thread(thread);
|
||||||
|
|
||||||
if (is_critical_native && !Universe::heap()->supports_object_pinning()) {
|
if (is_critical_native && !Universe::heap()->supports_object_pinning()) {
|
||||||
check_needs_gc_for_critical_native(masm, thread, stack_slots, total_c_args, total_in_args,
|
check_needs_gc_for_critical_native(masm, thread, stack_slots, total_c_args, total_in_args,
|
||||||
|
@ -27,6 +27,7 @@
|
|||||||
#include "asm/macroAssembler.inline.hpp"
|
#include "asm/macroAssembler.inline.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_x86.hpp"
|
#include "nativeInst_x86.hpp"
|
||||||
@ -3663,6 +3664,68 @@ class StubGenerator: public StubCodeGenerator {
|
|||||||
__ ret(0);
|
__ ret(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
address generate_method_entry_barrier() {
|
||||||
|
__ align(CodeEntryAlignment);
|
||||||
|
StubCodeMark mark(this, "StubRoutines", "nmethod_entry_barrier");
|
||||||
|
|
||||||
|
Label deoptimize_label;
|
||||||
|
|
||||||
|
address start = __ pc();
|
||||||
|
|
||||||
|
__ push(-1); // cookie, this is used for writing the new rsp when deoptimizing
|
||||||
|
|
||||||
|
BLOCK_COMMENT("Entry:");
|
||||||
|
__ enter(); // save rbp
|
||||||
|
|
||||||
|
// save rbx, because we want to use that value.
|
||||||
|
// We could do without it but then we depend on the number of slots used by pusha
|
||||||
|
__ push(rbx);
|
||||||
|
|
||||||
|
__ lea(rbx, Address(rsp, wordSize * 3)); // 1 for cookie, 1 for rbp, 1 for rbx - this should be the return address
|
||||||
|
|
||||||
|
__ pusha();
|
||||||
|
|
||||||
|
// xmm0 and xmm1 may be used for passing float/double arguments
|
||||||
|
const int xmm_size = wordSize * 2;
|
||||||
|
const int xmm_spill_size = xmm_size * 2;
|
||||||
|
__ subptr(rsp, xmm_spill_size);
|
||||||
|
__ movdqu(Address(rsp, xmm_size * 1), xmm1);
|
||||||
|
__ movdqu(Address(rsp, xmm_size * 0), xmm0);
|
||||||
|
|
||||||
|
__ call_VM_leaf(CAST_FROM_FN_PTR(address, static_cast<int (*)(address*)>(BarrierSetNMethod::nmethod_stub_entry_barrier)), rbx);
|
||||||
|
|
||||||
|
__ movdqu(xmm0, Address(rsp, xmm_size * 0));
|
||||||
|
__ movdqu(xmm1, Address(rsp, xmm_size * 1));
|
||||||
|
__ addptr(rsp, xmm_spill_size);
|
||||||
|
|
||||||
|
__ cmpl(rax, 1); // 1 means deoptimize
|
||||||
|
__ jcc(Assembler::equal, deoptimize_label);
|
||||||
|
|
||||||
|
__ popa();
|
||||||
|
__ pop(rbx);
|
||||||
|
|
||||||
|
__ leave();
|
||||||
|
|
||||||
|
__ addptr(rsp, 1 * wordSize); // cookie
|
||||||
|
__ ret(0);
|
||||||
|
|
||||||
|
__ BIND(deoptimize_label);
|
||||||
|
|
||||||
|
__ popa();
|
||||||
|
__ pop(rbx);
|
||||||
|
|
||||||
|
__ leave();
|
||||||
|
|
||||||
|
// this can be taken out, but is good for verification purposes. getting a SIGSEGV
|
||||||
|
// here while still having a correct stack is valuable
|
||||||
|
__ testptr(rsp, Address(rsp, 0));
|
||||||
|
|
||||||
|
__ movptr(rsp, Address(rsp, 0)); // new rsp was written in the barrier
|
||||||
|
__ jmp(Address(rsp, -1 * wordSize)); // jmp target should be callers verified_entry_point
|
||||||
|
|
||||||
|
return start;
|
||||||
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
// Information about frame layout at time of blocking runtime call.
|
// Information about frame layout at time of blocking runtime call.
|
||||||
// Note that we only have to preserve callee-saved registers since
|
// Note that we only have to preserve callee-saved registers since
|
||||||
@ -3959,6 +4022,11 @@ class StubGenerator: public StubCodeGenerator {
|
|||||||
StubRoutines::_safefetchN_entry = StubRoutines::_safefetch32_entry;
|
StubRoutines::_safefetchN_entry = StubRoutines::_safefetch32_entry;
|
||||||
StubRoutines::_safefetchN_fault_pc = StubRoutines::_safefetch32_fault_pc;
|
StubRoutines::_safefetchN_fault_pc = StubRoutines::_safefetch32_fault_pc;
|
||||||
StubRoutines::_safefetchN_continuation_pc = StubRoutines::_safefetch32_continuation_pc;
|
StubRoutines::_safefetchN_continuation_pc = StubRoutines::_safefetch32_continuation_pc;
|
||||||
|
|
||||||
|
BarrierSetNMethod* bs_nm = BarrierSet::barrier_set()->barrier_set_nmethod();
|
||||||
|
if (bs_nm != NULL) {
|
||||||
|
StubRoutines::x86::_method_entry_barrier = generate_method_entry_barrier();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -55,14 +55,8 @@ class x86 {
|
|||||||
static address _double_sign_mask;
|
static address _double_sign_mask;
|
||||||
static address _double_sign_flip;
|
static address _double_sign_flip;
|
||||||
|
|
||||||
static address _method_entry_barrier;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
static address method_entry_barrier() {
|
|
||||||
return _method_entry_barrier;
|
|
||||||
}
|
|
||||||
|
|
||||||
static address get_previous_fp_entry() {
|
static address get_previous_fp_entry() {
|
||||||
return _get_previous_fp_entry;
|
return _get_previous_fp_entry;
|
||||||
}
|
}
|
||||||
@ -121,6 +115,8 @@ class x86 {
|
|||||||
//shuffle mask for big-endian 128-bit integers
|
//shuffle mask for big-endian 128-bit integers
|
||||||
static address _counter_shuffle_mask_addr;
|
static address _counter_shuffle_mask_addr;
|
||||||
|
|
||||||
|
static address _method_entry_barrier;
|
||||||
|
|
||||||
// masks and table for CRC32
|
// masks and table for CRC32
|
||||||
static uint64_t _crc_by128_masks[];
|
static uint64_t _crc_by128_masks[];
|
||||||
static juint _crc_table[];
|
static juint _crc_table[];
|
||||||
@ -221,6 +217,7 @@ class x86 {
|
|||||||
static address upper_word_mask_addr() { return _upper_word_mask_addr; }
|
static address upper_word_mask_addr() { return _upper_word_mask_addr; }
|
||||||
static address shuffle_byte_flip_mask_addr() { return _shuffle_byte_flip_mask_addr; }
|
static address shuffle_byte_flip_mask_addr() { return _shuffle_byte_flip_mask_addr; }
|
||||||
static address k256_addr() { return _k256_adr; }
|
static address k256_addr() { return _k256_adr; }
|
||||||
|
static address method_entry_barrier() { return _method_entry_barrier; }
|
||||||
|
|
||||||
static address vector_short_to_byte_mask() {
|
static address vector_short_to_byte_mask() {
|
||||||
return _vector_short_to_byte_mask;
|
return _vector_short_to_byte_mask;
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 1997, 2019, 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
|
||||||
@ -32,3 +32,5 @@
|
|||||||
// a description of how to extend it, see the stubRoutines.hpp file.
|
// a description of how to extend it, see the stubRoutines.hpp file.
|
||||||
|
|
||||||
address StubRoutines::x86::_verify_fpu_cntrl_wrd_entry = NULL;
|
address StubRoutines::x86::_verify_fpu_cntrl_wrd_entry = NULL;
|
||||||
|
address StubRoutines::x86::_method_entry_barrier = NULL;
|
||||||
|
|
||||||
|
@ -32,9 +32,7 @@
|
|||||||
#include "utilities/debug.hpp"
|
#include "utilities/debug.hpp"
|
||||||
|
|
||||||
int BarrierSetNMethod::disarmed_value() const {
|
int BarrierSetNMethod::disarmed_value() const {
|
||||||
char* disarmed_addr = reinterpret_cast<char*>(Thread::current());
|
return *disarmed_value_address();
|
||||||
disarmed_addr += in_bytes(thread_disarmed_offset());
|
|
||||||
return *reinterpret_cast<int*>(disarmed_addr);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool BarrierSetNMethod::supports_entry_barrier(nmethod* nm) {
|
bool BarrierSetNMethod::supports_entry_barrier(nmethod* nm) {
|
||||||
|
@ -34,13 +34,14 @@ class nmethod;
|
|||||||
class BarrierSetNMethod: public CHeapObj<mtGC> {
|
class BarrierSetNMethod: public CHeapObj<mtGC> {
|
||||||
bool supports_entry_barrier(nmethod* nm);
|
bool supports_entry_barrier(nmethod* nm);
|
||||||
void deoptimize(nmethod* nm, address* return_addr_ptr);
|
void deoptimize(nmethod* nm, address* return_addr_ptr);
|
||||||
|
int disarmed_value() const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual int disarmed_value() const;
|
|
||||||
virtual bool nmethod_entry_barrier(nmethod* nm) = 0;
|
virtual bool nmethod_entry_barrier(nmethod* nm) = 0;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
virtual ByteSize thread_disarmed_offset() const = 0;
|
virtual ByteSize thread_disarmed_offset() const = 0;
|
||||||
|
virtual int* disarmed_value_address() const = 0;
|
||||||
|
|
||||||
static int nmethod_stub_entry_barrier(address* return_address_ptr);
|
static int nmethod_stub_entry_barrier(address* return_address_ptr);
|
||||||
bool nmethod_osr_entry_barrier(nmethod* nm);
|
bool nmethod_osr_entry_barrier(nmethod* nm);
|
||||||
|
@ -61,12 +61,10 @@ bool ZBarrierSetNMethod::nmethod_entry_barrier(nmethod* nm) {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
int ZBarrierSetNMethod::disarmed_value() const {
|
int* ZBarrierSetNMethod::disarmed_value_address() const {
|
||||||
// We override the default BarrierSetNMethod::disarmed_value() since
|
const uintptr_t mask_addr = reinterpret_cast<uintptr_t>(&ZAddressBadMask);
|
||||||
// this can be called by GC threads, which doesn't keep an up to date
|
const uintptr_t disarmed_addr = mask_addr + ZNMethodDisarmedOffset;
|
||||||
// address_bad_mask.
|
return reinterpret_cast<int*>(disarmed_addr);
|
||||||
const uintptr_t disarmed_addr = ((uintptr_t)&ZAddressBadMask) + ZNMethodDisarmedOffset;
|
|
||||||
return *((int*)disarmed_addr);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ByteSize ZBarrierSetNMethod::thread_disarmed_offset() const {
|
ByteSize ZBarrierSetNMethod::thread_disarmed_offset() const {
|
||||||
|
@ -31,11 +31,11 @@ class nmethod;
|
|||||||
|
|
||||||
class ZBarrierSetNMethod : public BarrierSetNMethod {
|
class ZBarrierSetNMethod : public BarrierSetNMethod {
|
||||||
protected:
|
protected:
|
||||||
virtual int disarmed_value() const;
|
|
||||||
virtual bool nmethod_entry_barrier(nmethod* nm);
|
virtual bool nmethod_entry_barrier(nmethod* nm);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
virtual ByteSize thread_disarmed_offset() const;
|
virtual ByteSize thread_disarmed_offset() const;
|
||||||
|
virtual int* disarmed_value_address() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // SHARE_GC_Z_ZBARRIERSETNMETHOD_HPP
|
#endif // SHARE_GC_Z_ZBARRIERSETNMETHOD_HPP
|
||||||
|
Loading…
x
Reference in New Issue
Block a user