mirror of
https://github.com/openjdk/jdk.git
synced 2026-05-05 03:05:47 +00:00
8351157: Clean up x86 GC barriers after 32-bit x86 removal
Reviewed-by: kbarrett, wkemper, tschatzl
This commit is contained in:
parent
c447a10225
commit
73c8c755ea
@ -147,7 +147,7 @@ void C1_MacroAssembler::unlock_object(Register hdr, Register obj, Register disp_
|
||||
// Defines obj, preserves var_size_in_bytes
|
||||
void C1_MacroAssembler::try_allocate(Register obj, Register var_size_in_bytes, int con_size_in_bytes, Register t1, Register t2, Label& slow_case) {
|
||||
if (UseTLAB) {
|
||||
tlab_allocate(noreg, obj, var_size_in_bytes, con_size_in_bytes, t1, t2, slow_case);
|
||||
tlab_allocate(obj, var_size_in_bytes, con_size_in_bytes, t1, t2, slow_case);
|
||||
} else {
|
||||
jmp(slow_case);
|
||||
}
|
||||
|
||||
@ -49,11 +49,7 @@ void G1BarrierSetAssembler::gen_write_ref_array_pre_barrier(MacroAssembler* masm
|
||||
bool dest_uninitialized = (decorators & IS_DEST_UNINITIALIZED) != 0;
|
||||
|
||||
if (!dest_uninitialized) {
|
||||
Register thread = NOT_LP64(rax) LP64_ONLY(r15_thread);
|
||||
#ifndef _LP64
|
||||
__ push(thread);
|
||||
__ get_thread(thread);
|
||||
#endif
|
||||
Register thread = r15_thread;
|
||||
|
||||
Label filtered;
|
||||
Address in_progress(thread, in_bytes(G1ThreadLocalData::satb_mark_queue_active_offset()));
|
||||
@ -65,12 +61,9 @@ void G1BarrierSetAssembler::gen_write_ref_array_pre_barrier(MacroAssembler* masm
|
||||
__ cmpb(in_progress, 0);
|
||||
}
|
||||
|
||||
NOT_LP64(__ pop(thread);)
|
||||
|
||||
__ jcc(Assembler::equal, filtered);
|
||||
|
||||
__ push_call_clobbered_registers(false /* save_fpu */);
|
||||
#ifdef _LP64
|
||||
if (count == c_rarg0) {
|
||||
if (addr == c_rarg1) {
|
||||
// exactly backwards!!
|
||||
@ -88,10 +81,6 @@ void G1BarrierSetAssembler::gen_write_ref_array_pre_barrier(MacroAssembler* masm
|
||||
} else {
|
||||
__ call_VM_leaf(CAST_FROM_FN_PTR(address, G1BarrierSetRuntime::write_ref_array_pre_oop_entry), 2);
|
||||
}
|
||||
#else
|
||||
__ call_VM_leaf(CAST_FROM_FN_PTR(address, G1BarrierSetRuntime::write_ref_array_pre_oop_entry),
|
||||
addr, count);
|
||||
#endif
|
||||
__ pop_call_clobbered_registers(false /* save_fpu */);
|
||||
|
||||
__ bind(filtered);
|
||||
@ -101,7 +90,6 @@ void G1BarrierSetAssembler::gen_write_ref_array_pre_barrier(MacroAssembler* masm
|
||||
void G1BarrierSetAssembler::gen_write_ref_array_post_barrier(MacroAssembler* masm, DecoratorSet decorators,
|
||||
Register addr, Register count, Register tmp) {
|
||||
__ push_call_clobbered_registers(false /* save_fpu */);
|
||||
#ifdef _LP64
|
||||
if (c_rarg0 == count) { // On win64 c_rarg0 == rcx
|
||||
assert_different_registers(c_rarg1, addr);
|
||||
__ mov(c_rarg1, count);
|
||||
@ -112,53 +100,26 @@ void G1BarrierSetAssembler::gen_write_ref_array_post_barrier(MacroAssembler* mas
|
||||
__ mov(c_rarg1, count);
|
||||
}
|
||||
__ call_VM_leaf(CAST_FROM_FN_PTR(address, G1BarrierSetRuntime::write_ref_array_post_entry), 2);
|
||||
#else
|
||||
__ call_VM_leaf(CAST_FROM_FN_PTR(address, G1BarrierSetRuntime::write_ref_array_post_entry),
|
||||
addr, count);
|
||||
#endif
|
||||
__ pop_call_clobbered_registers(false /* save_fpu */);
|
||||
|
||||
}
|
||||
|
||||
void G1BarrierSetAssembler::load_at(MacroAssembler* masm, DecoratorSet decorators, BasicType type,
|
||||
Register dst, Address src, Register tmp1, Register tmp_thread) {
|
||||
Register dst, Address src, Register tmp1) {
|
||||
bool on_oop = is_reference_type(type);
|
||||
bool on_weak = (decorators & ON_WEAK_OOP_REF) != 0;
|
||||
bool on_phantom = (decorators & ON_PHANTOM_OOP_REF) != 0;
|
||||
bool on_reference = on_weak || on_phantom;
|
||||
ModRefBarrierSetAssembler::load_at(masm, decorators, type, dst, src, tmp1, tmp_thread);
|
||||
ModRefBarrierSetAssembler::load_at(masm, decorators, type, dst, src, tmp1);
|
||||
if (on_oop && on_reference) {
|
||||
Register thread = NOT_LP64(tmp_thread) LP64_ONLY(r15_thread);
|
||||
|
||||
#ifndef _LP64
|
||||
// Work around the x86_32 bug that only manifests with Loom for some reason.
|
||||
// MacroAssembler::resolve_weak_handle calls this barrier with tmp_thread == noreg.
|
||||
if (thread == noreg) {
|
||||
if (dst != rcx && tmp1 != rcx) {
|
||||
thread = rcx;
|
||||
} else if (dst != rdx && tmp1 != rdx) {
|
||||
thread = rdx;
|
||||
} else if (dst != rdi && tmp1 != rdi) {
|
||||
thread = rdi;
|
||||
}
|
||||
}
|
||||
assert_different_registers(dst, tmp1, thread);
|
||||
__ push(thread);
|
||||
__ get_thread(thread);
|
||||
#endif
|
||||
|
||||
// Generate the G1 pre-barrier code to log the value of
|
||||
// the referent field in an SATB buffer.
|
||||
g1_write_barrier_pre(masm /* masm */,
|
||||
noreg /* obj */,
|
||||
dst /* pre_val */,
|
||||
thread /* thread */,
|
||||
tmp1 /* tmp */,
|
||||
true /* tosca_live */,
|
||||
true /* expand_call */);
|
||||
|
||||
#ifndef _LP64
|
||||
__ pop(thread);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
@ -199,7 +160,7 @@ static void generate_pre_barrier_slow_path(MacroAssembler* masm,
|
||||
Label& runtime) {
|
||||
// Do we need to load the previous value?
|
||||
if (obj != noreg) {
|
||||
__ load_heap_oop(pre_val, Address(obj, 0), noreg, noreg, AS_RAW);
|
||||
__ load_heap_oop(pre_val, Address(obj, 0), noreg, AS_RAW);
|
||||
}
|
||||
// Is the previous value null?
|
||||
__ cmpptr(pre_val, NULL_WORD);
|
||||
@ -215,7 +176,6 @@ static void generate_pre_barrier_slow_path(MacroAssembler* masm,
|
||||
void G1BarrierSetAssembler::g1_write_barrier_pre(MacroAssembler* masm,
|
||||
Register obj,
|
||||
Register pre_val,
|
||||
Register thread,
|
||||
Register tmp,
|
||||
bool tosca_live,
|
||||
bool expand_call) {
|
||||
@ -223,9 +183,7 @@ void G1BarrierSetAssembler::g1_write_barrier_pre(MacroAssembler* masm,
|
||||
// directly to skip generating the check by
|
||||
// InterpreterMacroAssembler::call_VM_leaf_base that checks _last_sp.
|
||||
|
||||
#ifdef _LP64
|
||||
assert(thread == r15_thread, "must be");
|
||||
#endif // _LP64
|
||||
const Register thread = r15_thread;
|
||||
|
||||
Label done;
|
||||
Label runtime;
|
||||
@ -260,18 +218,13 @@ void G1BarrierSetAssembler::g1_write_barrier_pre(MacroAssembler* masm,
|
||||
// expand_call should be passed true.
|
||||
|
||||
if (expand_call) {
|
||||
LP64_ONLY( assert(pre_val != c_rarg1, "smashed arg"); )
|
||||
#ifdef _LP64
|
||||
assert(pre_val != c_rarg1, "smashed arg");
|
||||
if (c_rarg1 != thread) {
|
||||
__ mov(c_rarg1, thread);
|
||||
}
|
||||
if (c_rarg0 != pre_val) {
|
||||
__ mov(c_rarg0, pre_val);
|
||||
}
|
||||
#else
|
||||
__ push(thread);
|
||||
__ push(pre_val);
|
||||
#endif
|
||||
__ MacroAssembler::call_VM_leaf_base(CAST_FROM_FN_PTR(address, G1BarrierSetRuntime::write_ref_field_pre_entry), 2);
|
||||
} else {
|
||||
__ call_VM_leaf(CAST_FROM_FN_PTR(address, G1BarrierSetRuntime::write_ref_field_pre_entry), pre_val, thread);
|
||||
@ -333,12 +286,9 @@ static void generate_post_barrier_slow_path(MacroAssembler* masm,
|
||||
void G1BarrierSetAssembler::g1_write_barrier_post(MacroAssembler* masm,
|
||||
Register store_addr,
|
||||
Register new_val,
|
||||
Register thread,
|
||||
Register tmp,
|
||||
Register tmp2) {
|
||||
#ifdef _LP64
|
||||
assert(thread == r15_thread, "must be");
|
||||
#endif // _LP64
|
||||
const Register thread = r15_thread;
|
||||
|
||||
Label done;
|
||||
Label runtime;
|
||||
@ -350,7 +300,7 @@ void G1BarrierSetAssembler::g1_write_barrier_post(MacroAssembler* masm,
|
||||
|
||||
__ bind(runtime);
|
||||
// save the live input values
|
||||
RegSet saved = RegSet::of(store_addr NOT_LP64(COMMA thread));
|
||||
RegSet saved = RegSet::of(store_addr);
|
||||
__ push_set(saved);
|
||||
__ call_VM_leaf(CAST_FROM_FN_PTR(address, G1BarrierSetRuntime::write_ref_field_post_entry), tmp, thread);
|
||||
__ pop_set(saved);
|
||||
@ -361,7 +311,6 @@ void G1BarrierSetAssembler::g1_write_barrier_post(MacroAssembler* masm,
|
||||
#if defined(COMPILER2)
|
||||
|
||||
static void generate_c2_barrier_runtime_call(MacroAssembler* masm, G1BarrierStubC2* stub, const Register arg, const address runtime_path) {
|
||||
#ifdef _LP64
|
||||
SaveLiveRegisters save_registers(masm, stub);
|
||||
if (c_rarg0 != arg) {
|
||||
__ mov(c_rarg0, arg);
|
||||
@ -373,20 +322,15 @@ static void generate_c2_barrier_runtime_call(MacroAssembler* masm, G1BarrierStub
|
||||
// call. If it did not contain any live value, it is free to be used. In
|
||||
// either case, it is safe to use it here as a call scratch register.
|
||||
__ call(RuntimeAddress(runtime_path), rax);
|
||||
#else
|
||||
Unimplemented();
|
||||
#endif // _LP64
|
||||
}
|
||||
|
||||
void G1BarrierSetAssembler::g1_write_barrier_pre_c2(MacroAssembler* masm,
|
||||
Register obj,
|
||||
Register pre_val,
|
||||
Register thread,
|
||||
Register tmp,
|
||||
G1PreBarrierStubC2* stub) {
|
||||
#ifdef _LP64
|
||||
assert(thread == r15_thread, "must be");
|
||||
#endif // _LP64
|
||||
const Register thread = r15_thread;
|
||||
|
||||
assert(pre_val != noreg, "check this code");
|
||||
if (obj != noreg) {
|
||||
assert_different_registers(obj, pre_val, tmp);
|
||||
@ -422,14 +366,10 @@ void G1BarrierSetAssembler::generate_c2_pre_barrier_stub(MacroAssembler* masm,
|
||||
void G1BarrierSetAssembler::g1_write_barrier_post_c2(MacroAssembler* masm,
|
||||
Register store_addr,
|
||||
Register new_val,
|
||||
Register thread,
|
||||
Register tmp,
|
||||
Register tmp2,
|
||||
G1PostBarrierStubC2* stub) {
|
||||
#ifdef _LP64
|
||||
assert(thread == r15_thread, "must be");
|
||||
#endif // _LP64
|
||||
|
||||
const Register thread = r15_thread;
|
||||
stub->initialize_registers(thread, tmp, tmp2);
|
||||
|
||||
bool new_val_may_be_null = (stub->barrier_data() & G1C2BarrierPostNotNull) == 0;
|
||||
@ -467,7 +407,6 @@ void G1BarrierSetAssembler::oop_store_at(MacroAssembler* masm, DecoratorSet deco
|
||||
bool needs_pre_barrier = as_normal;
|
||||
bool needs_post_barrier = val != noreg && in_heap;
|
||||
|
||||
Register rthread = LP64_ONLY(r15_thread) NOT_LP64(rcx);
|
||||
// flatten object address if needed
|
||||
// We do it regardless of precise because we need the registers
|
||||
if (dst.index() == noreg && dst.disp() == 0) {
|
||||
@ -478,18 +417,10 @@ void G1BarrierSetAssembler::oop_store_at(MacroAssembler* masm, DecoratorSet deco
|
||||
__ lea(tmp1, dst);
|
||||
}
|
||||
|
||||
#ifndef _LP64
|
||||
InterpreterMacroAssembler *imasm = static_cast<InterpreterMacroAssembler*>(masm);
|
||||
#endif
|
||||
|
||||
NOT_LP64(__ get_thread(rcx));
|
||||
NOT_LP64(imasm->save_bcp());
|
||||
|
||||
if (needs_pre_barrier) {
|
||||
g1_write_barrier_pre(masm /*masm*/,
|
||||
tmp1 /* obj */,
|
||||
tmp2 /* pre_val */,
|
||||
rthread /* thread */,
|
||||
tmp3 /* tmp */,
|
||||
val != noreg /* tosca_live */,
|
||||
false /* expand_call */);
|
||||
@ -510,12 +441,10 @@ void G1BarrierSetAssembler::oop_store_at(MacroAssembler* masm, DecoratorSet deco
|
||||
g1_write_barrier_post(masm /*masm*/,
|
||||
tmp1 /* store_adr */,
|
||||
new_val /* new_val */,
|
||||
rthread /* thread */,
|
||||
tmp3 /* tmp */,
|
||||
tmp2 /* tmp2 */);
|
||||
}
|
||||
}
|
||||
NOT_LP64(imasm->restore_bcp());
|
||||
}
|
||||
|
||||
#ifdef COMPILER1
|
||||
@ -575,11 +504,9 @@ void G1BarrierSetAssembler::generate_c1_pre_barrier_runtime_stub(StubAssembler*
|
||||
__ push(rdx);
|
||||
|
||||
const Register pre_val = rax;
|
||||
const Register thread = NOT_LP64(rax) LP64_ONLY(r15_thread);
|
||||
const Register thread = r15_thread;
|
||||
const Register tmp = rdx;
|
||||
|
||||
NOT_LP64(__ get_thread(thread);)
|
||||
|
||||
Address queue_active(thread, in_bytes(G1ThreadLocalData::satb_mark_queue_active_offset()));
|
||||
Address queue_index(thread, in_bytes(G1ThreadLocalData::satb_mark_queue_index_offset()));
|
||||
Address buffer(thread, in_bytes(G1ThreadLocalData::satb_mark_queue_buffer_offset()));
|
||||
@ -641,7 +568,7 @@ void G1BarrierSetAssembler::generate_c1_post_barrier_runtime_stub(StubAssembler*
|
||||
// At this point we know new_value is non-null and the new_value crosses regions.
|
||||
// Must check to see if card is already dirty
|
||||
|
||||
const Register thread = NOT_LP64(rax) LP64_ONLY(r15_thread);
|
||||
const Register thread = r15_thread;
|
||||
|
||||
Address queue_index(thread, in_bytes(G1ThreadLocalData::dirty_card_queue_index_offset()));
|
||||
Address buffer(thread, in_bytes(G1ThreadLocalData::dirty_card_queue_buffer_offset()));
|
||||
@ -659,8 +586,6 @@ void G1BarrierSetAssembler::generate_c1_post_barrier_runtime_stub(StubAssembler*
|
||||
__ movptr(cardtable, (intptr_t)ct->card_table()->byte_map_base());
|
||||
__ addptr(card_addr, cardtable);
|
||||
|
||||
NOT_LP64(__ get_thread(thread);)
|
||||
|
||||
__ cmpb(Address(card_addr, 0), G1CardTable::g1_young_card_val());
|
||||
__ jcc(Assembler::equal, done);
|
||||
|
||||
|
||||
@ -44,7 +44,6 @@ class G1BarrierSetAssembler: public ModRefBarrierSetAssembler {
|
||||
void g1_write_barrier_pre(MacroAssembler* masm,
|
||||
Register obj,
|
||||
Register pre_val,
|
||||
Register thread,
|
||||
Register tmp,
|
||||
bool tosca_live,
|
||||
bool expand_call);
|
||||
@ -52,7 +51,6 @@ class G1BarrierSetAssembler: public ModRefBarrierSetAssembler {
|
||||
void g1_write_barrier_post(MacroAssembler* masm,
|
||||
Register store_addr,
|
||||
Register new_val,
|
||||
Register thread,
|
||||
Register tmp,
|
||||
Register tmp2);
|
||||
|
||||
@ -67,13 +65,12 @@ class G1BarrierSetAssembler: public ModRefBarrierSetAssembler {
|
||||
void generate_c1_post_barrier_runtime_stub(StubAssembler* sasm);
|
||||
|
||||
virtual void load_at(MacroAssembler* masm, DecoratorSet decorators, BasicType type,
|
||||
Register dst, Address src, Register tmp1, Register tmp_thread);
|
||||
Register dst, Address src, Register tmp1);
|
||||
|
||||
#ifdef COMPILER2
|
||||
void g1_write_barrier_pre_c2(MacroAssembler* masm,
|
||||
Register obj,
|
||||
Register pre_val,
|
||||
Register thread,
|
||||
Register tmp,
|
||||
G1PreBarrierStubC2* c2_stub);
|
||||
void generate_c2_pre_barrier_stub(MacroAssembler* masm,
|
||||
@ -81,7 +78,6 @@ class G1BarrierSetAssembler: public ModRefBarrierSetAssembler {
|
||||
void g1_write_barrier_post_c2(MacroAssembler* masm,
|
||||
Register store_addr,
|
||||
Register new_val,
|
||||
Register thread,
|
||||
Register tmp,
|
||||
Register tmp2,
|
||||
G1PostBarrierStubC2* c2_stub);
|
||||
|
||||
@ -52,7 +52,7 @@ static void write_barrier_pre(MacroAssembler* masm,
|
||||
for (RegSetIterator<Register> reg = no_preserve.begin(); *reg != noreg; ++reg) {
|
||||
stub->dont_preserve(*reg);
|
||||
}
|
||||
g1_asm->g1_write_barrier_pre_c2(masm, obj, pre_val, r15_thread, tmp, stub);
|
||||
g1_asm->g1_write_barrier_pre_c2(masm, obj, pre_val, tmp, stub);
|
||||
}
|
||||
|
||||
static void write_barrier_post(MacroAssembler* masm,
|
||||
@ -67,7 +67,7 @@ static void write_barrier_post(MacroAssembler* masm,
|
||||
Assembler::InlineSkippedInstructionsCounter skip_counter(masm);
|
||||
G1BarrierSetAssembler* g1_asm = static_cast<G1BarrierSetAssembler*>(BarrierSet::barrier_set()->barrier_set_assembler());
|
||||
G1PostBarrierStubC2* const stub = G1PostBarrierStubC2::create(node);
|
||||
g1_asm->g1_write_barrier_post_c2(masm, store_addr, new_val, r15_thread, tmp1, tmp2, stub);
|
||||
g1_asm->g1_write_barrier_post_c2(masm, store_addr, new_val, tmp1, tmp2, stub);
|
||||
}
|
||||
|
||||
%}
|
||||
|
||||
@ -40,7 +40,7 @@
|
||||
#define __ masm->
|
||||
|
||||
void BarrierSetAssembler::load_at(MacroAssembler* masm, DecoratorSet decorators, BasicType type,
|
||||
Register dst, Address src, Register tmp1, Register tmp_thread) {
|
||||
Register dst, Address src, Register tmp1) {
|
||||
bool in_heap = (decorators & IN_HEAP) != 0;
|
||||
bool in_native = (decorators & IN_NATIVE) != 0;
|
||||
bool is_not_null = (decorators & IS_NOT_NULL) != 0;
|
||||
@ -50,7 +50,6 @@ void BarrierSetAssembler::load_at(MacroAssembler* masm, DecoratorSet decorators,
|
||||
case T_OBJECT:
|
||||
case T_ARRAY: {
|
||||
if (in_heap) {
|
||||
#ifdef _LP64
|
||||
if (UseCompressedOops) {
|
||||
__ movl(dst, src);
|
||||
if (is_not_null) {
|
||||
@ -58,9 +57,7 @@ void BarrierSetAssembler::load_at(MacroAssembler* masm, DecoratorSet decorators,
|
||||
} else {
|
||||
__ decode_heap_oop(dst);
|
||||
}
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
} else {
|
||||
__ movptr(dst, src);
|
||||
}
|
||||
} else {
|
||||
@ -85,20 +82,7 @@ void BarrierSetAssembler::load_at(MacroAssembler* masm, DecoratorSet decorators,
|
||||
break;
|
||||
case T_LONG:
|
||||
assert(dst == noreg, "only to ltos");
|
||||
#ifdef _LP64
|
||||
__ movq(rax, src);
|
||||
#else
|
||||
if (atomic) {
|
||||
__ fild_d(src); // Must load atomically
|
||||
__ subptr(rsp,2*wordSize); // Make space for store
|
||||
__ fistp_d(Address(rsp,0));
|
||||
__ pop(rax);
|
||||
__ pop(rdx);
|
||||
} else {
|
||||
__ movl(rax, src);
|
||||
__ movl(rdx, src.plus_disp(wordSize));
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
default: Unimplemented();
|
||||
}
|
||||
@ -117,17 +101,12 @@ void BarrierSetAssembler::store_at(MacroAssembler* masm, DecoratorSet decorators
|
||||
if (in_heap) {
|
||||
if (val == noreg) {
|
||||
assert(!is_not_null, "inconsistent access");
|
||||
#ifdef _LP64
|
||||
if (UseCompressedOops) {
|
||||
__ movl(dst, NULL_WORD);
|
||||
} else {
|
||||
__ movslq(dst, NULL_WORD);
|
||||
}
|
||||
#else
|
||||
__ movl(dst, NULL_WORD);
|
||||
#endif
|
||||
} else {
|
||||
#ifdef _LP64
|
||||
if (UseCompressedOops) {
|
||||
assert(!dst.uses(val), "not enough registers");
|
||||
if (is_not_null) {
|
||||
@ -136,9 +115,7 @@ void BarrierSetAssembler::store_at(MacroAssembler* masm, DecoratorSet decorators
|
||||
__ encode_heap_oop(val);
|
||||
}
|
||||
__ movl(dst, val);
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
} else {
|
||||
__ movptr(dst, val);
|
||||
}
|
||||
}
|
||||
@ -167,20 +144,7 @@ void BarrierSetAssembler::store_at(MacroAssembler* masm, DecoratorSet decorators
|
||||
break;
|
||||
case T_LONG:
|
||||
assert(val == noreg, "only tos");
|
||||
#ifdef _LP64
|
||||
__ movq(dst, rax);
|
||||
#else
|
||||
if (atomic) {
|
||||
__ push(rdx);
|
||||
__ push(rax); // Must update atomically with FIST
|
||||
__ fild_d(Address(rsp,0)); // So load into FPU register
|
||||
__ fistp_d(dst); // and put into memory atomically
|
||||
__ addptr(rsp, 2*wordSize);
|
||||
} else {
|
||||
__ movptr(dst, rax);
|
||||
__ movptr(dst.plus_disp(wordSize), rdx);
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
case T_FLOAT:
|
||||
assert(val == noreg, "only tos");
|
||||
@ -216,20 +180,14 @@ void BarrierSetAssembler::copy_load_at(MacroAssembler* masm,
|
||||
__ movl(dst, src);
|
||||
break;
|
||||
case 8:
|
||||
#ifdef _LP64
|
||||
__ movq(dst, src);
|
||||
#else
|
||||
fatal("No support for 8 bytes copy");
|
||||
#endif
|
||||
break;
|
||||
default:
|
||||
fatal("Unexpected size");
|
||||
}
|
||||
#ifdef _LP64
|
||||
if ((decorators & ARRAYCOPY_CHECKCAST) != 0 && UseCompressedOops) {
|
||||
__ decode_heap_oop(dst);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void BarrierSetAssembler::copy_store_at(MacroAssembler* masm,
|
||||
@ -239,11 +197,9 @@ void BarrierSetAssembler::copy_store_at(MacroAssembler* masm,
|
||||
Address dst,
|
||||
Register src,
|
||||
Register tmp) {
|
||||
#ifdef _LP64
|
||||
if ((decorators & ARRAYCOPY_CHECKCAST) != 0 && UseCompressedOops) {
|
||||
__ encode_heap_oop(src);
|
||||
}
|
||||
#endif
|
||||
assert(bytes <= 8, "can only deal with non-vector registers");
|
||||
switch (bytes) {
|
||||
case 1:
|
||||
@ -256,11 +212,7 @@ void BarrierSetAssembler::copy_store_at(MacroAssembler* masm,
|
||||
__ movl(dst, src);
|
||||
break;
|
||||
case 8:
|
||||
#ifdef _LP64
|
||||
__ movq(dst, src);
|
||||
#else
|
||||
fatal("No support for 8 bytes copy");
|
||||
#endif
|
||||
break;
|
||||
default:
|
||||
fatal("Unexpected size");
|
||||
@ -311,7 +263,7 @@ void BarrierSetAssembler::try_resolve_jobject_in_native(MacroAssembler* masm, Re
|
||||
}
|
||||
|
||||
void BarrierSetAssembler::tlab_allocate(MacroAssembler* masm,
|
||||
Register thread, Register obj,
|
||||
Register obj,
|
||||
Register var_size_in_bytes,
|
||||
int con_size_in_bytes,
|
||||
Register t1,
|
||||
@ -320,15 +272,8 @@ void BarrierSetAssembler::tlab_allocate(MacroAssembler* masm,
|
||||
assert_different_registers(obj, t1, t2);
|
||||
assert_different_registers(obj, var_size_in_bytes, t1);
|
||||
Register end = t2;
|
||||
if (!thread->is_valid()) {
|
||||
#ifdef _LP64
|
||||
thread = r15_thread;
|
||||
#else
|
||||
assert(t1->is_valid(), "need temp reg");
|
||||
thread = t1;
|
||||
__ get_thread(thread);
|
||||
#endif
|
||||
}
|
||||
|
||||
const Register thread = r15_thread;
|
||||
|
||||
__ verify_tlab();
|
||||
|
||||
@ -351,7 +296,6 @@ void BarrierSetAssembler::tlab_allocate(MacroAssembler* masm,
|
||||
__ verify_tlab();
|
||||
}
|
||||
|
||||
#ifdef _LP64
|
||||
void BarrierSetAssembler::nmethod_entry_barrier(MacroAssembler* masm, Label* slow_path, Label* continuation) {
|
||||
BarrierSetNMethod* bs_nm = BarrierSet::barrier_set()->barrier_set_nmethod();
|
||||
Register thread = r15_thread;
|
||||
@ -375,35 +319,14 @@ void BarrierSetAssembler::nmethod_entry_barrier(MacroAssembler* masm, Label* slo
|
||||
__ bind(done);
|
||||
}
|
||||
}
|
||||
#else
|
||||
void BarrierSetAssembler::nmethod_entry_barrier(MacroAssembler* masm, Label*, Label*) {
|
||||
BarrierSetNMethod* bs_nm = BarrierSet::barrier_set()->barrier_set_nmethod();
|
||||
Label continuation;
|
||||
|
||||
Register tmp = rdi;
|
||||
__ push(tmp);
|
||||
__ movptr(tmp, (intptr_t)bs_nm->disarmed_guard_value_address());
|
||||
Address disarmed_addr(tmp, 0);
|
||||
__ align(4);
|
||||
__ cmpl_imm32(disarmed_addr, 0);
|
||||
__ pop(tmp);
|
||||
__ jcc(Assembler::equal, continuation);
|
||||
__ call(RuntimeAddress(StubRoutines::method_entry_barrier()));
|
||||
__ bind(continuation);
|
||||
}
|
||||
#endif
|
||||
|
||||
void BarrierSetAssembler::c2i_entry_barrier(MacroAssembler* masm) {
|
||||
Label bad_call;
|
||||
__ cmpptr(rbx, 0); // rbx contains the incoming method for c2i adapters.
|
||||
__ jcc(Assembler::equal, bad_call);
|
||||
|
||||
Register tmp1 = LP64_ONLY( rscratch1 ) NOT_LP64( rax );
|
||||
Register tmp2 = LP64_ONLY( rscratch2 ) NOT_LP64( rcx );
|
||||
#ifndef _LP64
|
||||
__ push(tmp1);
|
||||
__ push(tmp2);
|
||||
#endif // !_LP64
|
||||
Register tmp1 = rscratch1;
|
||||
Register tmp2 = rscratch2;
|
||||
|
||||
// Pointer chase to the method holder to find out if the method is concurrently unloading.
|
||||
Label method_live;
|
||||
@ -419,19 +342,9 @@ void BarrierSetAssembler::c2i_entry_barrier(MacroAssembler* masm) {
|
||||
__ cmpptr(tmp1, 0);
|
||||
__ jcc(Assembler::notEqual, method_live);
|
||||
|
||||
#ifndef _LP64
|
||||
__ pop(tmp2);
|
||||
__ pop(tmp1);
|
||||
#endif
|
||||
|
||||
__ bind(bad_call);
|
||||
__ jump(RuntimeAddress(SharedRuntime::get_handle_wrong_method_stub()));
|
||||
__ bind(method_live);
|
||||
|
||||
#ifndef _LP64
|
||||
__ pop(tmp2);
|
||||
__ pop(tmp1);
|
||||
#endif
|
||||
}
|
||||
|
||||
void BarrierSetAssembler::check_oop(MacroAssembler* masm, Register obj, Register tmp1, Register tmp2, Label& error) {
|
||||
@ -451,8 +364,6 @@ void BarrierSetAssembler::check_oop(MacroAssembler* masm, Register obj, Register
|
||||
|
||||
#ifdef COMPILER2
|
||||
|
||||
#ifdef _LP64
|
||||
|
||||
OptoReg::Name BarrierSetAssembler::refine_register(const Node* node, OptoReg::Name opto_reg) {
|
||||
if (!OptoReg::is_reg(opto_reg)) {
|
||||
return OptoReg::Bad;
|
||||
@ -728,12 +639,4 @@ SaveLiveRegisters::~SaveLiveRegisters() {
|
||||
}
|
||||
}
|
||||
|
||||
#else // !_LP64
|
||||
|
||||
OptoReg::Name BarrierSetAssembler::refine_register(const Node* node, OptoReg::Name opto_reg) {
|
||||
Unimplemented(); // This must be implemented to support late barrier expansion.
|
||||
}
|
||||
|
||||
#endif // _LP64
|
||||
|
||||
#endif // COMPILER2
|
||||
|
||||
@ -44,7 +44,7 @@ public:
|
||||
Register src, Register dst, Register count) {}
|
||||
|
||||
virtual void load_at(MacroAssembler* masm, DecoratorSet decorators, BasicType type,
|
||||
Register dst, Address src, Register tmp1, Register tmp_thread);
|
||||
Register dst, Address src, Register tmp1);
|
||||
virtual void store_at(MacroAssembler* masm, DecoratorSet decorators, BasicType type,
|
||||
Address dst, Register val, Register tmp1, Register tmp2, Register tmp3);
|
||||
|
||||
@ -93,7 +93,7 @@ public:
|
||||
Register obj, Register tmp, Label& slowpath);
|
||||
|
||||
virtual void tlab_allocate(MacroAssembler* masm,
|
||||
Register thread, Register obj,
|
||||
Register obj,
|
||||
Register var_size_in_bytes,
|
||||
int con_size_in_bytes,
|
||||
Register t1, Register t2,
|
||||
@ -114,8 +114,6 @@ public:
|
||||
|
||||
#ifdef COMPILER2
|
||||
|
||||
#ifdef _LP64
|
||||
|
||||
// This class saves and restores the registers that need to be preserved across
|
||||
// the runtime call represented by a given C2 barrier stub. Use as follows:
|
||||
// {
|
||||
@ -160,8 +158,6 @@ public:
|
||||
~SaveLiveRegisters();
|
||||
};
|
||||
|
||||
#endif // _LP64
|
||||
|
||||
#endif // COMPILER2
|
||||
|
||||
#endif // CPU_X86_GC_SHARED_BARRIERSETASSEMBLER_X86_HPP
|
||||
|
||||
@ -39,7 +39,6 @@
|
||||
|
||||
class NativeNMethodCmpBarrier: public NativeInstruction {
|
||||
public:
|
||||
#ifdef _LP64
|
||||
enum Intel_specific_constants {
|
||||
instruction_code = 0x81,
|
||||
instruction_size = 8,
|
||||
@ -47,14 +46,6 @@ public:
|
||||
instruction_rex_prefix = Assembler::REX | Assembler::REX_B,
|
||||
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 immediate_address() const { return addr_at(imm_offset); }
|
||||
@ -70,7 +61,6 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
#ifdef _LP64
|
||||
bool NativeNMethodCmpBarrier::check_barrier(err_msg& msg) const {
|
||||
// Only require 4 byte alignment
|
||||
if (((uintptr_t) instruction_address()) & 0x3) {
|
||||
@ -97,29 +87,6 @@ bool NativeNMethodCmpBarrier::check_barrier(err_msg& msg) const {
|
||||
}
|
||||
return true;
|
||||
}
|
||||
#else
|
||||
bool NativeNMethodCmpBarrier::check_barrier(err_msg& msg) const {
|
||||
if (((uintptr_t) instruction_address()) & 0x3) {
|
||||
msg.print("Addr: " INTPTR_FORMAT " not properly aligned", p2i(instruction_address()));
|
||||
return false;
|
||||
}
|
||||
|
||||
int inst = ubyte_at(0);
|
||||
if (inst != instruction_code) {
|
||||
msg.print("Addr: " INTPTR_FORMAT " Code: 0x%x", p2i(instruction_address()),
|
||||
inst);
|
||||
return false;
|
||||
}
|
||||
|
||||
int modrm = ubyte_at(1);
|
||||
if (modrm != instruction_modrm) {
|
||||
msg.print("Addr: " INTPTR_FORMAT " mod/rm: 0x%x", p2i(instruction_address()),
|
||||
modrm);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
#endif // _LP64
|
||||
|
||||
void BarrierSetNMethod::deoptimize(nmethod* nm, address* return_address_ptr) {
|
||||
/*
|
||||
@ -169,15 +136,11 @@ void BarrierSetNMethod::deoptimize(nmethod* nm, address* return_address_ptr) {
|
||||
// not find the expected native instruction at this offset, which needs updating.
|
||||
// Note that this offset is invariant of PreserveFramePointer.
|
||||
static int entry_barrier_offset(nmethod* nm) {
|
||||
#ifdef _LP64
|
||||
if (nm->is_compiled_by_c2()) {
|
||||
return -14;
|
||||
} else {
|
||||
return -15;
|
||||
}
|
||||
#else
|
||||
return -18;
|
||||
#endif
|
||||
}
|
||||
|
||||
static NativeNMethodCmpBarrier* native_nmethod_barrier(nmethod* nm) {
|
||||
|
||||
@ -57,7 +57,6 @@ void CardTableBarrierSetAssembler::gen_write_ref_array_post_barrier(MacroAssembl
|
||||
__ jcc(Assembler::zero, L_done); // zero count - nothing to do
|
||||
|
||||
|
||||
#ifdef _LP64
|
||||
__ leaq(end, Address(addr, count, TIMES_OOP, 0)); // end == addr+count*oop_size
|
||||
__ subptr(end, BytesPerHeapOop); // end - 1 to make inclusive
|
||||
__ shrptr(addr, CardTable::card_shift());
|
||||
@ -70,17 +69,6 @@ __ BIND(L_loop);
|
||||
__ movb(Address(addr, count, Address::times_1), 0);
|
||||
__ decrement(count);
|
||||
__ jcc(Assembler::greaterEqual, L_loop);
|
||||
#else
|
||||
__ lea(end, Address(addr, count, Address::times_ptr, -wordSize));
|
||||
__ shrptr(addr, CardTable::card_shift());
|
||||
__ shrptr(end, CardTable::card_shift());
|
||||
__ subptr(end, addr); // end --> count
|
||||
__ BIND(L_loop);
|
||||
Address cardtable(addr, count, Address::times_1, disp);
|
||||
__ movb(cardtable, 0);
|
||||
__ decrement(count);
|
||||
__ jcc(Assembler::greaterEqual, L_loop);
|
||||
#endif
|
||||
|
||||
__ BIND(L_done);
|
||||
}
|
||||
|
||||
@ -31,10 +31,9 @@ void ModRefBarrierSetAssembler::arraycopy_prologue(MacroAssembler* masm, Decorat
|
||||
Register src, Register dst, Register count) {
|
||||
bool checkcast = (decorators & ARRAYCOPY_CHECKCAST) != 0;
|
||||
bool disjoint = (decorators & ARRAYCOPY_DISJOINT) != 0;
|
||||
bool obj_int = type == T_OBJECT LP64_ONLY(&& UseCompressedOops);
|
||||
bool obj_int = (type == T_OBJECT) && UseCompressedOops;
|
||||
|
||||
if (is_reference_type(type)) {
|
||||
#ifdef _LP64
|
||||
if (!checkcast) {
|
||||
if (!obj_int) {
|
||||
// Save count for barrier
|
||||
@ -44,11 +43,6 @@ void ModRefBarrierSetAssembler::arraycopy_prologue(MacroAssembler* masm, Decorat
|
||||
__ movq(r11, dst);
|
||||
}
|
||||
}
|
||||
#else
|
||||
if (disjoint) {
|
||||
__ mov(rdx, dst); // save 'to'
|
||||
}
|
||||
#endif
|
||||
gen_write_ref_array_pre_barrier(masm, decorators, dst, count);
|
||||
}
|
||||
}
|
||||
@ -57,11 +51,10 @@ void ModRefBarrierSetAssembler::arraycopy_epilogue(MacroAssembler* masm, Decorat
|
||||
Register src, Register dst, Register count) {
|
||||
bool checkcast = (decorators & ARRAYCOPY_CHECKCAST) != 0;
|
||||
bool disjoint = (decorators & ARRAYCOPY_DISJOINT) != 0;
|
||||
bool obj_int = type == T_OBJECT LP64_ONLY(&& UseCompressedOops);
|
||||
bool obj_int = (type == T_OBJECT) && UseCompressedOops;
|
||||
Register tmp = rax;
|
||||
|
||||
if (is_reference_type(type)) {
|
||||
#ifdef _LP64
|
||||
if (!checkcast) {
|
||||
if (!obj_int) {
|
||||
// Save count for barrier
|
||||
@ -73,11 +66,6 @@ void ModRefBarrierSetAssembler::arraycopy_epilogue(MacroAssembler* masm, Decorat
|
||||
} else {
|
||||
tmp = rscratch1;
|
||||
}
|
||||
#else
|
||||
if (disjoint) {
|
||||
__ mov(dst, rdx); // restore 'to'
|
||||
}
|
||||
#endif
|
||||
gen_write_ref_array_post_barrier(masm, decorators, dst, count, tmp);
|
||||
}
|
||||
}
|
||||
|
||||
@ -33,7 +33,6 @@
|
||||
#define __ masm->masm()->
|
||||
|
||||
void LIR_OpShenandoahCompareAndSwap::emit_code(LIR_Assembler* masm) {
|
||||
NOT_LP64(assert(_addr->is_single_cpu(), "must be single");)
|
||||
Register addr = _addr->is_single_cpu() ? _addr->as_register() : _addr->as_register_lo();
|
||||
Register newval = _new_value->as_register();
|
||||
Register cmpval = _cmp_value->as_register();
|
||||
@ -46,14 +45,12 @@ void LIR_OpShenandoahCompareAndSwap::emit_code(LIR_Assembler* masm) {
|
||||
assert(cmpval != addr, "cmp and addr must be in different registers");
|
||||
assert(newval != addr, "new value and addr must be in different registers");
|
||||
|
||||
#ifdef _LP64
|
||||
if (UseCompressedOops) {
|
||||
__ encode_heap_oop(cmpval);
|
||||
__ mov(rscratch1, newval);
|
||||
__ encode_heap_oop(rscratch1);
|
||||
newval = rscratch1;
|
||||
}
|
||||
#endif
|
||||
|
||||
ShenandoahBarrierSet::assembler()->cmpxchg_oop(masm->masm(), result, Address(addr, 0), cmpval, newval, false, tmp1, tmp2);
|
||||
}
|
||||
@ -105,7 +102,7 @@ LIR_Opr ShenandoahBarrierSetC1::atomic_xchg_at_resolved(LIRAccess& access, LIRIt
|
||||
// Because we want a 2-arg form of xchg and xadd
|
||||
__ move(value_opr, result);
|
||||
|
||||
assert(type == T_INT || is_reference_type(type) LP64_ONLY( || type == T_LONG ), "unexpected type");
|
||||
assert(type == T_INT || is_reference_type(type) || type == T_LONG, "unexpected type");
|
||||
__ xchg(access.resolved_addr(), result, result, LIR_OprFact::illegalOpr);
|
||||
|
||||
if (access.is_oop()) {
|
||||
|
||||
@ -51,10 +51,10 @@ static void save_machine_state(MacroAssembler* masm, bool handle_gpr, bool handl
|
||||
|
||||
if (handle_fp) {
|
||||
// Some paths can be reached from the c2i adapter with live fp arguments in registers.
|
||||
LP64_ONLY(assert(Argument::n_float_register_parameters_j == 8, "8 fp registers to save at java call"));
|
||||
assert(Argument::n_float_register_parameters_j == 8, "8 fp registers to save at java call");
|
||||
|
||||
if (UseSSE >= 2) {
|
||||
const int xmm_size = wordSize * LP64_ONLY(2) NOT_LP64(4);
|
||||
const int xmm_size = wordSize * 2;
|
||||
__ subptr(rsp, xmm_size * 8);
|
||||
__ movdbl(Address(rsp, xmm_size * 0), xmm0);
|
||||
__ movdbl(Address(rsp, xmm_size * 1), xmm1);
|
||||
@ -65,7 +65,7 @@ static void save_machine_state(MacroAssembler* masm, bool handle_gpr, bool handl
|
||||
__ movdbl(Address(rsp, xmm_size * 6), xmm6);
|
||||
__ movdbl(Address(rsp, xmm_size * 7), xmm7);
|
||||
} else if (UseSSE >= 1) {
|
||||
const int xmm_size = wordSize * LP64_ONLY(1) NOT_LP64(2);
|
||||
const int xmm_size = wordSize * 1;
|
||||
__ subptr(rsp, xmm_size * 8);
|
||||
__ movflt(Address(rsp, xmm_size * 0), xmm0);
|
||||
__ movflt(Address(rsp, xmm_size * 1), xmm1);
|
||||
@ -84,7 +84,7 @@ static void save_machine_state(MacroAssembler* masm, bool handle_gpr, bool handl
|
||||
static void restore_machine_state(MacroAssembler* masm, bool handle_gpr, bool handle_fp) {
|
||||
if (handle_fp) {
|
||||
if (UseSSE >= 2) {
|
||||
const int xmm_size = wordSize * LP64_ONLY(2) NOT_LP64(4);
|
||||
const int xmm_size = wordSize * 2;
|
||||
__ movdbl(xmm0, Address(rsp, xmm_size * 0));
|
||||
__ movdbl(xmm1, Address(rsp, xmm_size * 1));
|
||||
__ movdbl(xmm2, Address(rsp, xmm_size * 2));
|
||||
@ -95,7 +95,7 @@ static void restore_machine_state(MacroAssembler* masm, bool handle_gpr, bool ha
|
||||
__ movdbl(xmm7, Address(rsp, xmm_size * 7));
|
||||
__ addptr(rsp, xmm_size * 8);
|
||||
} else if (UseSSE >= 1) {
|
||||
const int xmm_size = wordSize * LP64_ONLY(1) NOT_LP64(2);
|
||||
const int xmm_size = wordSize * 1;
|
||||
__ movflt(xmm0, Address(rsp, xmm_size * 0));
|
||||
__ movflt(xmm1, Address(rsp, xmm_size * 1));
|
||||
__ movflt(xmm2, Address(rsp, xmm_size * 2));
|
||||
@ -124,11 +124,10 @@ void ShenandoahBarrierSetAssembler::arraycopy_prologue(MacroAssembler* masm, Dec
|
||||
if (ShenandoahCardBarrier) {
|
||||
bool checkcast = (decorators & ARRAYCOPY_CHECKCAST) != 0;
|
||||
bool disjoint = (decorators & ARRAYCOPY_DISJOINT) != 0;
|
||||
bool obj_int = type == T_OBJECT LP64_ONLY(&& UseCompressedOops);
|
||||
bool obj_int = (type == T_OBJECT) && UseCompressedOops;
|
||||
|
||||
// We need to save the original element count because the array copy stub
|
||||
// will destroy the value and we need it for the card marking barrier.
|
||||
#ifdef _LP64
|
||||
if (!checkcast) {
|
||||
if (!obj_int) {
|
||||
// Save count for barrier
|
||||
@ -138,30 +137,10 @@ void ShenandoahBarrierSetAssembler::arraycopy_prologue(MacroAssembler* masm, Dec
|
||||
__ movq(r11, dst);
|
||||
}
|
||||
}
|
||||
#else
|
||||
if (disjoint) {
|
||||
__ mov(rdx, dst); // save 'to'
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
if ((ShenandoahSATBBarrier && !dest_uninitialized) || ShenandoahLoadRefBarrier) {
|
||||
#ifdef _LP64
|
||||
Register thread = r15_thread;
|
||||
#else
|
||||
Register thread = rax;
|
||||
if (thread == src || thread == dst || thread == count) {
|
||||
thread = rbx;
|
||||
}
|
||||
if (thread == src || thread == dst || thread == count) {
|
||||
thread = rcx;
|
||||
}
|
||||
if (thread == src || thread == dst || thread == count) {
|
||||
thread = rdx;
|
||||
}
|
||||
__ push(thread);
|
||||
__ get_thread(thread);
|
||||
#endif
|
||||
assert_different_registers(src, dst, count, thread);
|
||||
|
||||
Label L_done;
|
||||
@ -182,16 +161,13 @@ void ShenandoahBarrierSetAssembler::arraycopy_prologue(MacroAssembler* masm, Dec
|
||||
|
||||
save_machine_state(masm, /* handle_gpr = */ true, /* handle_fp = */ false);
|
||||
|
||||
#ifdef _LP64
|
||||
assert(src == rdi, "expected");
|
||||
assert(dst == rsi, "expected");
|
||||
assert(count == rdx, "expected");
|
||||
if (UseCompressedOops) {
|
||||
__ call_VM_leaf(CAST_FROM_FN_PTR(address, ShenandoahRuntime::arraycopy_barrier_narrow_oop),
|
||||
src, dst, count);
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
} else {
|
||||
__ call_VM_leaf(CAST_FROM_FN_PTR(address, ShenandoahRuntime::arraycopy_barrier_oop),
|
||||
src, dst, count);
|
||||
}
|
||||
@ -199,7 +175,6 @@ void ShenandoahBarrierSetAssembler::arraycopy_prologue(MacroAssembler* masm, Dec
|
||||
restore_machine_state(masm, /* handle_gpr = */ true, /* handle_fp = */ false);
|
||||
|
||||
__ bind(L_done);
|
||||
NOT_LP64(__ pop(thread);)
|
||||
}
|
||||
}
|
||||
|
||||
@ -211,10 +186,9 @@ void ShenandoahBarrierSetAssembler::arraycopy_epilogue(MacroAssembler* masm, Dec
|
||||
if (ShenandoahCardBarrier && is_reference_type(type)) {
|
||||
bool checkcast = (decorators & ARRAYCOPY_CHECKCAST) != 0;
|
||||
bool disjoint = (decorators & ARRAYCOPY_DISJOINT) != 0;
|
||||
bool obj_int = type == T_OBJECT LP64_ONLY(&& UseCompressedOops);
|
||||
bool obj_int = (type == T_OBJECT) && UseCompressedOops;
|
||||
Register tmp = rax;
|
||||
|
||||
#ifdef _LP64
|
||||
if (!checkcast) {
|
||||
if (!obj_int) {
|
||||
// Save count for barrier
|
||||
@ -226,11 +200,6 @@ void ShenandoahBarrierSetAssembler::arraycopy_epilogue(MacroAssembler* masm, Dec
|
||||
} else {
|
||||
tmp = rscratch1;
|
||||
}
|
||||
#else
|
||||
if (disjoint) {
|
||||
__ mov(dst, rdx); // restore 'to'
|
||||
}
|
||||
#endif
|
||||
gen_write_ref_array_post_barrier(masm, decorators, dst, count, tmp);
|
||||
}
|
||||
}
|
||||
@ -238,20 +207,18 @@ void ShenandoahBarrierSetAssembler::arraycopy_epilogue(MacroAssembler* masm, Dec
|
||||
void ShenandoahBarrierSetAssembler::shenandoah_write_barrier_pre(MacroAssembler* masm,
|
||||
Register obj,
|
||||
Register pre_val,
|
||||
Register thread,
|
||||
Register tmp,
|
||||
bool tosca_live,
|
||||
bool expand_call) {
|
||||
|
||||
if (ShenandoahSATBBarrier) {
|
||||
satb_write_barrier_pre(masm, obj, pre_val, thread, tmp, tosca_live, expand_call);
|
||||
satb_write_barrier_pre(masm, obj, pre_val, tmp, tosca_live, expand_call);
|
||||
}
|
||||
}
|
||||
|
||||
void ShenandoahBarrierSetAssembler::satb_write_barrier_pre(MacroAssembler* masm,
|
||||
Register obj,
|
||||
Register pre_val,
|
||||
Register thread,
|
||||
Register tmp,
|
||||
bool tosca_live,
|
||||
bool expand_call) {
|
||||
@ -259,9 +226,7 @@ void ShenandoahBarrierSetAssembler::satb_write_barrier_pre(MacroAssembler* masm,
|
||||
// directly to skip generating the check by
|
||||
// InterpreterMacroAssembler::call_VM_leaf_base that checks _last_sp.
|
||||
|
||||
#ifdef _LP64
|
||||
assert(thread == r15_thread, "must be");
|
||||
#endif // _LP64
|
||||
const Register thread = r15_thread;
|
||||
|
||||
Label done;
|
||||
Label runtime;
|
||||
@ -282,7 +247,7 @@ void ShenandoahBarrierSetAssembler::satb_write_barrier_pre(MacroAssembler* masm,
|
||||
|
||||
// Do we need to load the previous value?
|
||||
if (obj != noreg) {
|
||||
__ load_heap_oop(pre_val, Address(obj, 0), noreg, noreg, AS_RAW);
|
||||
__ load_heap_oop(pre_val, Address(obj, 0), noreg, AS_RAW);
|
||||
}
|
||||
|
||||
// Is the previous value null?
|
||||
@ -327,9 +292,6 @@ void ShenandoahBarrierSetAssembler::satb_write_barrier_pre(MacroAssembler* masm,
|
||||
// So when we do not have have a full interpreter frame on the stack
|
||||
// expand_call should be passed true.
|
||||
|
||||
NOT_LP64( __ push(thread); )
|
||||
|
||||
#ifdef _LP64
|
||||
// We move pre_val into c_rarg0 early, in order to avoid smashing it, should
|
||||
// pre_val be c_rarg1 (where the call prologue would copy thread argument).
|
||||
// Note: this should not accidentally smash thread, because thread is always r15.
|
||||
@ -337,26 +299,18 @@ void ShenandoahBarrierSetAssembler::satb_write_barrier_pre(MacroAssembler* masm,
|
||||
if (c_rarg0 != pre_val) {
|
||||
__ mov(c_rarg0, pre_val);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (expand_call) {
|
||||
LP64_ONLY( assert(pre_val != c_rarg1, "smashed arg"); )
|
||||
#ifdef _LP64
|
||||
assert(pre_val != c_rarg1, "smashed arg");
|
||||
if (c_rarg1 != thread) {
|
||||
__ mov(c_rarg1, thread);
|
||||
}
|
||||
// Already moved pre_val into c_rarg0 above
|
||||
#else
|
||||
__ push(thread);
|
||||
__ push(pre_val);
|
||||
#endif
|
||||
__ MacroAssembler::call_VM_leaf_base(CAST_FROM_FN_PTR(address, ShenandoahRuntime::write_ref_field_pre), 2);
|
||||
} else {
|
||||
__ call_VM_leaf(CAST_FROM_FN_PTR(address, ShenandoahRuntime::write_ref_field_pre), LP64_ONLY(c_rarg0) NOT_LP64(pre_val), thread);
|
||||
__ call_VM_leaf(CAST_FROM_FN_PTR(address, ShenandoahRuntime::write_ref_field_pre), c_rarg0, thread);
|
||||
}
|
||||
|
||||
NOT_LP64( __ pop(thread); )
|
||||
|
||||
// save the live input values
|
||||
if (pre_val != rax)
|
||||
__ pop(pre_val);
|
||||
@ -383,16 +337,7 @@ void ShenandoahBarrierSetAssembler::load_reference_barrier(MacroAssembler* masm,
|
||||
__ block_comment("load_reference_barrier { ");
|
||||
|
||||
// Check if GC is active
|
||||
#ifdef _LP64
|
||||
Register thread = r15_thread;
|
||||
#else
|
||||
Register thread = rcx;
|
||||
if (thread == dst) {
|
||||
thread = rbx;
|
||||
}
|
||||
__ push(thread);
|
||||
__ get_thread(thread);
|
||||
#endif
|
||||
|
||||
Address gc_state(thread, in_bytes(ShenandoahThreadLocalData::gc_state_offset()));
|
||||
int flags = ShenandoahHeap::HAS_FORWARDED;
|
||||
@ -438,7 +383,7 @@ void ShenandoahBarrierSetAssembler::load_reference_barrier(MacroAssembler* masm,
|
||||
|
||||
// The rest is saved with the optimized path
|
||||
|
||||
uint num_saved_regs = 4 + (dst != rax ? 1 : 0) LP64_ONLY(+4);
|
||||
uint num_saved_regs = 4 + (dst != rax ? 1 : 0) + 4;
|
||||
__ subptr(rsp, num_saved_regs * wordSize);
|
||||
uint slot = num_saved_regs;
|
||||
if (dst != rax) {
|
||||
@ -448,21 +393,15 @@ void ShenandoahBarrierSetAssembler::load_reference_barrier(MacroAssembler* masm,
|
||||
__ movptr(Address(rsp, (--slot) * wordSize), rdx);
|
||||
__ movptr(Address(rsp, (--slot) * wordSize), rdi);
|
||||
__ movptr(Address(rsp, (--slot) * wordSize), rsi);
|
||||
#ifdef _LP64
|
||||
__ movptr(Address(rsp, (--slot) * wordSize), r8);
|
||||
__ movptr(Address(rsp, (--slot) * wordSize), r9);
|
||||
__ movptr(Address(rsp, (--slot) * wordSize), r10);
|
||||
__ movptr(Address(rsp, (--slot) * wordSize), r11);
|
||||
// r12-r15 are callee saved in all calling conventions
|
||||
#endif
|
||||
assert(slot == 0, "must use all slots");
|
||||
|
||||
// Shuffle registers such that dst is in c_rarg0 and addr in c_rarg1.
|
||||
#ifdef _LP64
|
||||
Register arg0 = c_rarg0, arg1 = c_rarg1;
|
||||
#else
|
||||
Register arg0 = rdi, arg1 = rsi;
|
||||
#endif
|
||||
if (dst == arg1) {
|
||||
__ lea(arg0, src);
|
||||
__ xchgptr(arg1, arg0);
|
||||
@ -489,12 +428,10 @@ void ShenandoahBarrierSetAssembler::load_reference_barrier(MacroAssembler* masm,
|
||||
__ super_call_VM_leaf(CAST_FROM_FN_PTR(address, ShenandoahRuntime::load_reference_barrier_phantom), arg0, arg1);
|
||||
}
|
||||
|
||||
#ifdef _LP64
|
||||
__ movptr(r11, Address(rsp, (slot++) * wordSize));
|
||||
__ movptr(r10, Address(rsp, (slot++) * wordSize));
|
||||
__ movptr(r9, Address(rsp, (slot++) * wordSize));
|
||||
__ movptr(r8, Address(rsp, (slot++) * wordSize));
|
||||
#endif
|
||||
__ movptr(rsi, Address(rsp, (slot++) * wordSize));
|
||||
__ movptr(rdi, Address(rsp, (slot++) * wordSize));
|
||||
__ movptr(rdx, Address(rsp, (slot++) * wordSize));
|
||||
@ -520,10 +457,6 @@ void ShenandoahBarrierSetAssembler::load_reference_barrier(MacroAssembler* masm,
|
||||
__ bind(heap_stable);
|
||||
|
||||
__ block_comment("} load_reference_barrier");
|
||||
|
||||
#ifndef _LP64
|
||||
__ pop(thread);
|
||||
#endif
|
||||
}
|
||||
|
||||
//
|
||||
@ -540,10 +473,10 @@ void ShenandoahBarrierSetAssembler::load_reference_barrier(MacroAssembler* masm,
|
||||
// tmp1 (if it is valid)
|
||||
//
|
||||
void ShenandoahBarrierSetAssembler::load_at(MacroAssembler* masm, DecoratorSet decorators, BasicType type,
|
||||
Register dst, Address src, Register tmp1, Register tmp_thread) {
|
||||
Register dst, Address src, Register tmp1) {
|
||||
// 1: non-reference load, no additional barrier is needed
|
||||
if (!is_reference_type(type)) {
|
||||
BarrierSetAssembler::load_at(masm, decorators, type, dst, src, tmp1, tmp_thread);
|
||||
BarrierSetAssembler::load_at(masm, decorators, type, dst, src, tmp1);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -567,7 +500,7 @@ void ShenandoahBarrierSetAssembler::load_at(MacroAssembler* masm, DecoratorSet d
|
||||
assert_different_registers(dst, src.base(), src.index());
|
||||
}
|
||||
|
||||
BarrierSetAssembler::load_at(masm, decorators, type, dst, src, tmp1, tmp_thread);
|
||||
BarrierSetAssembler::load_at(masm, decorators, type, dst, src, tmp1);
|
||||
|
||||
load_reference_barrier(masm, dst, src, decorators);
|
||||
|
||||
@ -582,25 +515,19 @@ void ShenandoahBarrierSetAssembler::load_at(MacroAssembler* masm, DecoratorSet d
|
||||
dst = result_dst;
|
||||
}
|
||||
} else {
|
||||
BarrierSetAssembler::load_at(masm, decorators, type, dst, src, tmp1, tmp_thread);
|
||||
BarrierSetAssembler::load_at(masm, decorators, type, dst, src, tmp1);
|
||||
}
|
||||
|
||||
// 3: apply keep-alive barrier if needed
|
||||
if (ShenandoahBarrierSet::need_keep_alive_barrier(decorators, type)) {
|
||||
save_machine_state(masm, /* handle_gpr = */ true, /* handle_fp = */ true);
|
||||
|
||||
Register thread = NOT_LP64(tmp_thread) LP64_ONLY(r15_thread);
|
||||
assert_different_registers(dst, tmp1, tmp_thread);
|
||||
if (!thread->is_valid()) {
|
||||
thread = rdx;
|
||||
}
|
||||
NOT_LP64(__ get_thread(thread));
|
||||
assert_different_registers(dst, tmp1, r15_thread);
|
||||
// Generate the SATB pre-barrier code to log the value of
|
||||
// the referent field in an SATB buffer.
|
||||
shenandoah_write_barrier_pre(masm /* masm */,
|
||||
noreg /* obj */,
|
||||
dst /* pre_val */,
|
||||
thread /* thread */,
|
||||
tmp1 /* tmp */,
|
||||
true /* tosca_live */,
|
||||
true /* expand_call */);
|
||||
@ -618,23 +545,8 @@ void ShenandoahBarrierSetAssembler::store_check(MacroAssembler* masm, Register o
|
||||
|
||||
// We'll use this register as the TLS base address and also later on
|
||||
// to hold the byte_map_base.
|
||||
Register thread = LP64_ONLY(r15_thread) NOT_LP64(rcx);
|
||||
Register tmp = LP64_ONLY(rscratch1) NOT_LP64(rdx);
|
||||
|
||||
#ifndef _LP64
|
||||
// The next two ifs are just to get temporary registers to use for TLS and card table base.
|
||||
if (thread == obj) {
|
||||
thread = rdx;
|
||||
tmp = rsi;
|
||||
}
|
||||
if (tmp == obj) {
|
||||
tmp = rsi;
|
||||
}
|
||||
|
||||
__ push(thread);
|
||||
__ push(tmp);
|
||||
__ get_thread(thread);
|
||||
#endif
|
||||
Register thread = r15_thread;
|
||||
Register tmp = rscratch1;
|
||||
|
||||
Address curr_ct_holder_addr(thread, in_bytes(ShenandoahThreadLocalData::card_table_offset()));
|
||||
__ movptr(tmp, curr_ct_holder_addr);
|
||||
@ -650,11 +562,6 @@ void ShenandoahBarrierSetAssembler::store_check(MacroAssembler* masm, Register o
|
||||
} else {
|
||||
__ movb(card_addr, dirty);
|
||||
}
|
||||
|
||||
#ifndef _LP64
|
||||
__ pop(tmp);
|
||||
__ pop(thread);
|
||||
#endif
|
||||
}
|
||||
|
||||
void ShenandoahBarrierSetAssembler::store_at(MacroAssembler* masm, DecoratorSet decorators, BasicType type,
|
||||
@ -666,7 +573,6 @@ void ShenandoahBarrierSetAssembler::store_at(MacroAssembler* masm, DecoratorSet
|
||||
if (on_oop && in_heap) {
|
||||
bool needs_pre_barrier = as_normal;
|
||||
|
||||
Register rthread = LP64_ONLY(r15_thread) NOT_LP64(rcx);
|
||||
// flatten object address if needed
|
||||
// We do it regardless of precise because we need the registers
|
||||
if (dst.index() == noreg && dst.disp() == 0) {
|
||||
@ -677,19 +583,12 @@ void ShenandoahBarrierSetAssembler::store_at(MacroAssembler* masm, DecoratorSet
|
||||
__ lea(tmp1, dst);
|
||||
}
|
||||
|
||||
assert_different_registers(val, tmp1, tmp2, tmp3, rthread);
|
||||
|
||||
#ifndef _LP64
|
||||
__ get_thread(rthread);
|
||||
InterpreterMacroAssembler *imasm = static_cast<InterpreterMacroAssembler*>(masm);
|
||||
imasm->save_bcp();
|
||||
#endif
|
||||
assert_different_registers(val, tmp1, tmp2, tmp3, r15_thread);
|
||||
|
||||
if (needs_pre_barrier) {
|
||||
shenandoah_write_barrier_pre(masm /*masm*/,
|
||||
tmp1 /* obj */,
|
||||
tmp2 /* pre_val */,
|
||||
rthread /* thread */,
|
||||
tmp3 /* tmp */,
|
||||
val != noreg /* tosca_live */,
|
||||
false /* expand_call */);
|
||||
@ -701,7 +600,6 @@ void ShenandoahBarrierSetAssembler::store_at(MacroAssembler* masm, DecoratorSet
|
||||
store_check(masm, tmp1);
|
||||
}
|
||||
}
|
||||
NOT_LP64(imasm->restore_bcp());
|
||||
} else {
|
||||
BarrierSetAssembler::store_at(masm, decorators, type, dst, val, tmp1, tmp2, tmp3);
|
||||
}
|
||||
@ -736,12 +634,9 @@ void ShenandoahBarrierSetAssembler::cmpxchg_oop(MacroAssembler* masm,
|
||||
Label L_success, L_failure;
|
||||
|
||||
// Remember oldval for retry logic below
|
||||
#ifdef _LP64
|
||||
if (UseCompressedOops) {
|
||||
__ movl(tmp1, oldval);
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
} else {
|
||||
__ movptr(tmp1, oldval);
|
||||
}
|
||||
|
||||
@ -749,13 +644,10 @@ void ShenandoahBarrierSetAssembler::cmpxchg_oop(MacroAssembler* masm,
|
||||
//
|
||||
// Try to CAS with given arguments. If successful, then we are done.
|
||||
|
||||
#ifdef _LP64
|
||||
if (UseCompressedOops) {
|
||||
__ lock();
|
||||
__ cmpxchgl(newval, addr);
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
} else {
|
||||
__ lock();
|
||||
__ cmpxchgptr(newval, addr);
|
||||
}
|
||||
@ -776,23 +668,15 @@ void ShenandoahBarrierSetAssembler::cmpxchg_oop(MacroAssembler* masm,
|
||||
__ jcc(Assembler::zero, L_failure);
|
||||
|
||||
// Filter: when heap is stable, the failure is definitely legitimate
|
||||
#ifdef _LP64
|
||||
const Register thread = r15_thread;
|
||||
#else
|
||||
const Register thread = tmp2;
|
||||
__ get_thread(thread);
|
||||
#endif
|
||||
Address gc_state(thread, in_bytes(ShenandoahThreadLocalData::gc_state_offset()));
|
||||
__ testb(gc_state, ShenandoahHeap::HAS_FORWARDED);
|
||||
__ jcc(Assembler::zero, L_failure);
|
||||
|
||||
#ifdef _LP64
|
||||
if (UseCompressedOops) {
|
||||
__ movl(tmp2, oldval);
|
||||
__ decode_heap_oop(tmp2);
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
} else {
|
||||
__ movptr(tmp2, oldval);
|
||||
}
|
||||
|
||||
@ -807,11 +691,9 @@ void ShenandoahBarrierSetAssembler::cmpxchg_oop(MacroAssembler* masm,
|
||||
__ shrptr(tmp2, 2);
|
||||
__ shlptr(tmp2, 2);
|
||||
|
||||
#ifdef _LP64
|
||||
if (UseCompressedOops) {
|
||||
__ decode_heap_oop(tmp1); // decode for comparison
|
||||
}
|
||||
#endif
|
||||
|
||||
// Now we have the forwarded offender in tmp2.
|
||||
// Compare and if they don't match, we have legitimate failure
|
||||
@ -827,19 +709,14 @@ void ShenandoahBarrierSetAssembler::cmpxchg_oop(MacroAssembler* masm,
|
||||
// with to-space ptr store. We still have to do the retry, because the GC might
|
||||
// have updated the reference for us.
|
||||
|
||||
#ifdef _LP64
|
||||
if (UseCompressedOops) {
|
||||
__ encode_heap_oop(tmp2); // previously decoded at step 2.
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef _LP64
|
||||
if (UseCompressedOops) {
|
||||
__ lock();
|
||||
__ cmpxchgl(tmp2, addr);
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
} else {
|
||||
__ lock();
|
||||
__ cmpxchgptr(tmp2, addr);
|
||||
}
|
||||
@ -851,22 +728,16 @@ void ShenandoahBarrierSetAssembler::cmpxchg_oop(MacroAssembler* masm,
|
||||
// from-space ptr into memory anymore. Make sure oldval is restored, after being
|
||||
// garbled during retries.
|
||||
//
|
||||
#ifdef _LP64
|
||||
if (UseCompressedOops) {
|
||||
__ movl(oldval, tmp2);
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
} else {
|
||||
__ movptr(oldval, tmp2);
|
||||
}
|
||||
|
||||
#ifdef _LP64
|
||||
if (UseCompressedOops) {
|
||||
__ lock();
|
||||
__ cmpxchgl(newval, addr);
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
} else {
|
||||
__ lock();
|
||||
__ cmpxchgptr(newval, addr);
|
||||
}
|
||||
@ -918,7 +789,6 @@ void ShenandoahBarrierSetAssembler::gen_write_ref_array_post_barrier(MacroAssemb
|
||||
__ testl(count, count);
|
||||
__ jccb(Assembler::zero, L_done);
|
||||
|
||||
#ifdef _LP64
|
||||
const Register thread = r15_thread;
|
||||
Address curr_ct_holder_addr(thread, in_bytes(ShenandoahThreadLocalData::card_table_offset()));
|
||||
__ movptr(tmp, curr_ct_holder_addr);
|
||||
@ -935,26 +805,6 @@ void ShenandoahBarrierSetAssembler::gen_write_ref_array_post_barrier(MacroAssemb
|
||||
__ movb(Address(addr, count, Address::times_1), 0);
|
||||
__ decrement(count);
|
||||
__ jccb(Assembler::greaterEqual, L_loop);
|
||||
#else
|
||||
const Register thread = tmp;
|
||||
__ get_thread(thread);
|
||||
|
||||
Address curr_ct_holder_addr(thread, in_bytes(ShenandoahThreadLocalData::byte_map_base_offset()));
|
||||
__ movptr(tmp, curr_ct_holder_addr);
|
||||
|
||||
__ lea(end, Address(addr, count, Address::times_ptr, -wordSize));
|
||||
__ shrptr(addr, CardTable::card_shift());
|
||||
__ shrptr(end, CardTable::card_shift());
|
||||
__ subptr(end, addr); // end --> count
|
||||
|
||||
__ addptr(addr, tmp);
|
||||
|
||||
__ BIND(L_loop);
|
||||
Address cardtable(addr, count, Address::times_1, 0);
|
||||
__ movb(cardtable, 0);
|
||||
__ decrement(count);
|
||||
__ jccb(Assembler::greaterEqual, L_loop);
|
||||
#endif
|
||||
|
||||
__ BIND(L_done);
|
||||
}
|
||||
@ -1019,15 +869,8 @@ void ShenandoahBarrierSetAssembler::gen_load_reference_barrier_stub(LIR_Assemble
|
||||
__ mov(tmp1, res);
|
||||
__ shrptr(tmp1, ShenandoahHeapRegion::region_size_bytes_shift_jint());
|
||||
__ movptr(tmp2, (intptr_t) ShenandoahHeap::in_cset_fast_test_addr());
|
||||
#ifdef _LP64
|
||||
__ movbool(tmp2, Address(tmp2, tmp1, Address::times_1));
|
||||
__ testbool(tmp2);
|
||||
#else
|
||||
// On x86_32, C1 register allocator can give us the register without 8-bit support.
|
||||
// Do the full-register access and test to avoid compilation failures.
|
||||
__ movptr(tmp2, Address(tmp2, tmp1, Address::times_1));
|
||||
__ testptr(tmp2, 0xFF);
|
||||
#endif
|
||||
__ jcc(Assembler::zero, *stub->continuation());
|
||||
}
|
||||
|
||||
@ -1061,11 +904,9 @@ void ShenandoahBarrierSetAssembler::generate_c1_pre_barrier_runtime_stub(StubAss
|
||||
__ push(rdx);
|
||||
|
||||
const Register pre_val = rax;
|
||||
const Register thread = NOT_LP64(rax) LP64_ONLY(r15_thread);
|
||||
const Register thread = r15_thread;
|
||||
const Register tmp = rdx;
|
||||
|
||||
NOT_LP64(__ get_thread(thread);)
|
||||
|
||||
Address queue_index(thread, in_bytes(ShenandoahThreadLocalData::satb_mark_queue_index_offset()));
|
||||
Address buffer(thread, in_bytes(ShenandoahThreadLocalData::satb_mark_queue_buffer_offset()));
|
||||
|
||||
@ -1120,7 +961,6 @@ void ShenandoahBarrierSetAssembler::generate_c1_load_reference_barrier_runtime_s
|
||||
bool is_phantom = ShenandoahBarrierSet::is_phantom_access(decorators);
|
||||
bool is_native = ShenandoahBarrierSet::is_native_access(decorators);
|
||||
|
||||
#ifdef _LP64
|
||||
__ load_parameter(0, c_rarg0);
|
||||
__ load_parameter(1, c_rarg1);
|
||||
if (is_strong) {
|
||||
@ -1145,18 +985,6 @@ void ShenandoahBarrierSetAssembler::generate_c1_load_reference_barrier_runtime_s
|
||||
assert(is_native, "phantom must only be called off-heap");
|
||||
__ call_VM_leaf(CAST_FROM_FN_PTR(address, ShenandoahRuntime::load_reference_barrier_phantom), c_rarg0, c_rarg1);
|
||||
}
|
||||
#else
|
||||
__ load_parameter(0, rax);
|
||||
__ load_parameter(1, rbx);
|
||||
if (is_strong) {
|
||||
__ call_VM_leaf(CAST_FROM_FN_PTR(address, ShenandoahRuntime::load_reference_barrier_strong), rax, rbx);
|
||||
} else if (is_weak) {
|
||||
__ call_VM_leaf(CAST_FROM_FN_PTR(address, ShenandoahRuntime::load_reference_barrier_weak), rax, rbx);
|
||||
} else {
|
||||
assert(is_phantom, "only remaining strength");
|
||||
__ call_VM_leaf(CAST_FROM_FN_PTR(address, ShenandoahRuntime::load_reference_barrier_phantom), rax, rbx);
|
||||
}
|
||||
#endif
|
||||
|
||||
__ restore_live_registers_except_rax(true);
|
||||
|
||||
|
||||
@ -44,7 +44,6 @@ private:
|
||||
void satb_write_barrier_pre(MacroAssembler* masm,
|
||||
Register obj,
|
||||
Register pre_val,
|
||||
Register thread,
|
||||
Register tmp,
|
||||
bool tosca_live,
|
||||
bool expand_call);
|
||||
@ -52,7 +51,6 @@ private:
|
||||
void shenandoah_write_barrier_pre(MacroAssembler* masm,
|
||||
Register obj,
|
||||
Register pre_val,
|
||||
Register thread,
|
||||
Register tmp,
|
||||
bool tosca_live,
|
||||
bool expand_call);
|
||||
@ -81,7 +79,7 @@ public:
|
||||
virtual void arraycopy_epilogue(MacroAssembler* masm, DecoratorSet decorators, BasicType type,
|
||||
Register src, Register dst, Register count);
|
||||
virtual void load_at(MacroAssembler* masm, DecoratorSet decorators, BasicType type,
|
||||
Register dst, Address src, Register tmp1, Register tmp_thread);
|
||||
Register dst, Address src, Register tmp1);
|
||||
virtual void store_at(MacroAssembler* masm, DecoratorSet decorators, BasicType type,
|
||||
Address dst, Register val, Register tmp1, Register tmp2, Register tmp3);
|
||||
virtual void try_resolve_jobject_in_native(MacroAssembler* masm, Register jni_env,
|
||||
|
||||
@ -220,11 +220,10 @@ void ZBarrierSetAssembler::load_at(MacroAssembler* masm,
|
||||
BasicType type,
|
||||
Register dst,
|
||||
Address src,
|
||||
Register tmp1,
|
||||
Register tmp_thread) {
|
||||
Register tmp1) {
|
||||
if (!ZBarrierSet::barrier_needed(decorators, type)) {
|
||||
// Barrier not needed
|
||||
BarrierSetAssembler::load_at(masm, decorators, type, dst, src, tmp1, tmp_thread);
|
||||
BarrierSetAssembler::load_at(masm, decorators, type, dst, src, tmp1);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@ -73,8 +73,7 @@ public:
|
||||
BasicType type,
|
||||
Register dst,
|
||||
Address src,
|
||||
Register tmp1,
|
||||
Register tmp_thread);
|
||||
Register tmp1);
|
||||
|
||||
virtual void store_at(MacroAssembler* masm,
|
||||
DecoratorSet decorators,
|
||||
|
||||
@ -4064,7 +4064,7 @@ void MacroAssembler::resolve_jobject(Register value,
|
||||
jcc(Assembler::notZero, tagged);
|
||||
|
||||
// Resolve local handle
|
||||
access_load_at(T_OBJECT, IN_NATIVE | AS_RAW, value, Address(value, 0), tmp, thread);
|
||||
access_load_at(T_OBJECT, IN_NATIVE | AS_RAW, value, Address(value, 0), tmp);
|
||||
verify_oop(value);
|
||||
jmp(done);
|
||||
|
||||
@ -4073,14 +4073,14 @@ void MacroAssembler::resolve_jobject(Register value,
|
||||
jcc(Assembler::notZero, weak_tagged);
|
||||
|
||||
// Resolve global handle
|
||||
access_load_at(T_OBJECT, IN_NATIVE, value, Address(value, -JNIHandles::TypeTag::global), tmp, thread);
|
||||
access_load_at(T_OBJECT, IN_NATIVE, value, Address(value, -JNIHandles::TypeTag::global), tmp);
|
||||
verify_oop(value);
|
||||
jmp(done);
|
||||
|
||||
bind(weak_tagged);
|
||||
// Resolve jweak.
|
||||
access_load_at(T_OBJECT, IN_NATIVE | ON_PHANTOM_OOP_REF,
|
||||
value, Address(value, -JNIHandles::TypeTag::weak_global), tmp, thread);
|
||||
value, Address(value, -JNIHandles::TypeTag::weak_global), tmp);
|
||||
verify_oop(value);
|
||||
|
||||
bind(done);
|
||||
@ -4106,7 +4106,7 @@ void MacroAssembler::resolve_global_jobject(Register value,
|
||||
#endif
|
||||
|
||||
// Resolve global handle
|
||||
access_load_at(T_OBJECT, IN_NATIVE, value, Address(value, -JNIHandles::TypeTag::global), tmp, thread);
|
||||
access_load_at(T_OBJECT, IN_NATIVE, value, Address(value, -JNIHandles::TypeTag::global), tmp);
|
||||
verify_oop(value);
|
||||
|
||||
bind(done);
|
||||
@ -4144,14 +4144,14 @@ void MacroAssembler::testptr(Register dst, Register src) {
|
||||
}
|
||||
|
||||
// Defines obj, preserves var_size_in_bytes, okay for t2 == var_size_in_bytes.
|
||||
void MacroAssembler::tlab_allocate(Register thread, Register obj,
|
||||
void MacroAssembler::tlab_allocate(Register obj,
|
||||
Register var_size_in_bytes,
|
||||
int con_size_in_bytes,
|
||||
Register t1,
|
||||
Register t2,
|
||||
Label& slow_case) {
|
||||
BarrierSetAssembler* bs = BarrierSet::barrier_set()->barrier_set_assembler();
|
||||
bs->tlab_allocate(this, thread, obj, var_size_in_bytes, con_size_in_bytes, t1, t2, slow_case);
|
||||
bs->tlab_allocate(this, obj, var_size_in_bytes, con_size_in_bytes, t1, t2, slow_case);
|
||||
}
|
||||
|
||||
RegSet MacroAssembler::call_clobbered_gp_registers() {
|
||||
@ -5979,7 +5979,7 @@ void MacroAssembler::resolve_oop_handle(Register result, Register tmp) {
|
||||
// Only IN_HEAP loads require a thread_tmp register
|
||||
// OopHandle::resolve is an indirection like jobject.
|
||||
access_load_at(T_OBJECT, IN_NATIVE,
|
||||
result, Address(result, 0), tmp, /*tmp_thread*/noreg);
|
||||
result, Address(result, 0), tmp);
|
||||
}
|
||||
|
||||
// ((WeakHandle)result).resolve();
|
||||
@ -5995,7 +5995,7 @@ void MacroAssembler::resolve_weak_handle(Register rresult, Register rtmp) {
|
||||
// Only IN_HEAP loads require a thread_tmp register
|
||||
// WeakHandle::resolve is an indirection like jweak.
|
||||
access_load_at(T_OBJECT, IN_NATIVE | ON_PHANTOM_OOP_REF,
|
||||
rresult, Address(rresult, 0), rtmp, /*tmp_thread*/noreg);
|
||||
rresult, Address(rresult, 0), rtmp);
|
||||
bind(resolved);
|
||||
}
|
||||
|
||||
@ -6092,14 +6092,14 @@ void MacroAssembler::cmp_klasses_from_objects(Register obj1, Register obj2, Regi
|
||||
}
|
||||
|
||||
void MacroAssembler::access_load_at(BasicType type, DecoratorSet decorators, Register dst, Address src,
|
||||
Register tmp1, Register thread_tmp) {
|
||||
Register tmp1) {
|
||||
BarrierSetAssembler* bs = BarrierSet::barrier_set()->barrier_set_assembler();
|
||||
decorators = AccessInternal::decorator_fixup(decorators, type);
|
||||
bool as_raw = (decorators & AS_RAW) != 0;
|
||||
if (as_raw) {
|
||||
bs->BarrierSetAssembler::load_at(this, decorators, type, dst, src, tmp1, thread_tmp);
|
||||
bs->BarrierSetAssembler::load_at(this, decorators, type, dst, src, tmp1);
|
||||
} else {
|
||||
bs->load_at(this, decorators, type, dst, src, tmp1, thread_tmp);
|
||||
bs->load_at(this, decorators, type, dst, src, tmp1);
|
||||
}
|
||||
}
|
||||
|
||||
@ -6115,15 +6115,13 @@ void MacroAssembler::access_store_at(BasicType type, DecoratorSet decorators, Ad
|
||||
}
|
||||
}
|
||||
|
||||
void MacroAssembler::load_heap_oop(Register dst, Address src, Register tmp1,
|
||||
Register thread_tmp, DecoratorSet decorators) {
|
||||
access_load_at(T_OBJECT, IN_HEAP | decorators, dst, src, tmp1, thread_tmp);
|
||||
void MacroAssembler::load_heap_oop(Register dst, Address src, Register tmp1, DecoratorSet decorators) {
|
||||
access_load_at(T_OBJECT, IN_HEAP | decorators, dst, src, tmp1);
|
||||
}
|
||||
|
||||
// Doesn't do verification, generates fixed size code
|
||||
void MacroAssembler::load_heap_oop_not_null(Register dst, Address src, Register tmp1,
|
||||
Register thread_tmp, DecoratorSet decorators) {
|
||||
access_load_at(T_OBJECT, IN_HEAP | IS_NOT_NULL | decorators, dst, src, tmp1, thread_tmp);
|
||||
void MacroAssembler::load_heap_oop_not_null(Register dst, Address src, Register tmp1, DecoratorSet decorators) {
|
||||
access_load_at(T_OBJECT, IN_HEAP | IS_NOT_NULL | decorators, dst, src, tmp1);
|
||||
}
|
||||
|
||||
void MacroAssembler::store_heap_oop(Address dst, Register val, Register tmp1,
|
||||
|
||||
@ -371,14 +371,12 @@ class MacroAssembler: public Assembler {
|
||||
void cmp_klasses_from_objects(Register obj1, Register obj2, Register tmp1, Register tmp2);
|
||||
|
||||
void access_load_at(BasicType type, DecoratorSet decorators, Register dst, Address src,
|
||||
Register tmp1, Register thread_tmp);
|
||||
Register tmp1);
|
||||
void access_store_at(BasicType type, DecoratorSet decorators, Address dst, Register val,
|
||||
Register tmp1, Register tmp2, Register tmp3);
|
||||
|
||||
void load_heap_oop(Register dst, Address src, Register tmp1 = noreg,
|
||||
Register thread_tmp = noreg, DecoratorSet decorators = 0);
|
||||
void load_heap_oop_not_null(Register dst, Address src, Register tmp1 = noreg,
|
||||
Register thread_tmp = noreg, DecoratorSet decorators = 0);
|
||||
void load_heap_oop(Register dst, Address src, Register tmp1 = noreg, DecoratorSet decorators = 0);
|
||||
void load_heap_oop_not_null(Register dst, Address src, Register tmp1 = noreg, DecoratorSet decorators = 0);
|
||||
void store_heap_oop(Address dst, Register val, Register tmp1 = noreg,
|
||||
Register tmp2 = noreg, Register tmp3 = noreg, DecoratorSet decorators = 0);
|
||||
|
||||
@ -588,7 +586,6 @@ public:
|
||||
|
||||
// allocation
|
||||
void tlab_allocate(
|
||||
Register thread, // Current thread
|
||||
Register obj, // result: pointer to object after successful allocation
|
||||
Register var_size_in_bytes, // object size in bytes if unknown at compile time; invalid otherwise
|
||||
int con_size_in_bytes, // object size in bytes if known at compile time
|
||||
|
||||
@ -182,7 +182,7 @@ void MethodHandles::jump_to_lambda_form(MacroAssembler* _masm,
|
||||
__ verify_oop(method_temp);
|
||||
__ access_load_at(T_ADDRESS, IN_HEAP, method_temp,
|
||||
Address(method_temp, NONZERO(java_lang_invoke_ResolvedMethodName::vmtarget_offset())),
|
||||
noreg, noreg);
|
||||
noreg);
|
||||
|
||||
if (VerifyMethodHandles && !for_compiler_entry) {
|
||||
// make sure recv is already on stack
|
||||
@ -212,7 +212,7 @@ void MethodHandles::jump_to_native_invoker(MacroAssembler* _masm, Register nep_r
|
||||
__ verify_oop(nep_reg);
|
||||
__ access_load_at(T_ADDRESS, IN_HEAP, temp_target,
|
||||
Address(nep_reg, NONZERO(jdk_internal_foreign_abi_NativeEntryPoint::downcall_stub_address_offset_in_bytes())),
|
||||
noreg, noreg);
|
||||
noreg);
|
||||
|
||||
__ jmp(temp_target);
|
||||
BLOCK_COMMENT("} jump_to_native_invoker");
|
||||
@ -420,7 +420,7 @@ void MethodHandles::generate_method_handle_dispatch(MacroAssembler* _masm,
|
||||
verify_ref_kind(_masm, JVM_REF_invokeSpecial, member_reg, temp3);
|
||||
}
|
||||
__ load_heap_oop(rbx_method, member_vmtarget);
|
||||
__ access_load_at(T_ADDRESS, IN_HEAP, rbx_method, vmtarget_method, noreg, noreg);
|
||||
__ access_load_at(T_ADDRESS, IN_HEAP, rbx_method, vmtarget_method, noreg);
|
||||
break;
|
||||
|
||||
case vmIntrinsics::_linkToStatic:
|
||||
@ -428,7 +428,7 @@ void MethodHandles::generate_method_handle_dispatch(MacroAssembler* _masm,
|
||||
verify_ref_kind(_masm, JVM_REF_invokeStatic, member_reg, temp3);
|
||||
}
|
||||
__ load_heap_oop(rbx_method, member_vmtarget);
|
||||
__ access_load_at(T_ADDRESS, IN_HEAP, rbx_method, vmtarget_method, noreg, noreg);
|
||||
__ access_load_at(T_ADDRESS, IN_HEAP, rbx_method, vmtarget_method, noreg);
|
||||
break;
|
||||
|
||||
case vmIntrinsics::_linkToVirtual:
|
||||
@ -442,7 +442,7 @@ void MethodHandles::generate_method_handle_dispatch(MacroAssembler* _masm,
|
||||
|
||||
// pick out the vtable index from the MemberName, and then we can discard it:
|
||||
Register temp2_index = temp2;
|
||||
__ access_load_at(T_ADDRESS, IN_HEAP, temp2_index, member_vmindex, noreg, noreg);
|
||||
__ access_load_at(T_ADDRESS, IN_HEAP, temp2_index, member_vmindex, noreg);
|
||||
|
||||
if (VerifyMethodHandles) {
|
||||
Label L_index_ok;
|
||||
@ -474,7 +474,7 @@ void MethodHandles::generate_method_handle_dispatch(MacroAssembler* _masm,
|
||||
__ verify_klass_ptr(temp3_intf);
|
||||
|
||||
Register rbx_index = rbx_method;
|
||||
__ access_load_at(T_ADDRESS, IN_HEAP, rbx_index, member_vmindex, noreg, noreg);
|
||||
__ access_load_at(T_ADDRESS, IN_HEAP, rbx_index, member_vmindex, noreg);
|
||||
if (VerifyMethodHandles) {
|
||||
Label L;
|
||||
__ cmpl(rbx_index, 0);
|
||||
|
||||
@ -3981,7 +3981,7 @@ address StubGenerator::generate_upcall_stub_load_target() {
|
||||
__ load_heap_oop(rbx, Address(rbx, java_lang_invoke_MemberName::method_offset()), rscratch1);
|
||||
__ access_load_at(T_ADDRESS, IN_HEAP, rbx,
|
||||
Address(rbx, java_lang_invoke_ResolvedMethodName::vmtarget_offset()),
|
||||
noreg, noreg);
|
||||
noreg);
|
||||
__ movptr(Address(r15_thread, JavaThread::callee_target_offset()), rbx); // just in case callee is deoptimized
|
||||
|
||||
__ ret(0);
|
||||
|
||||
@ -654,7 +654,7 @@ address TemplateInterpreterGenerator::generate_Reference_get_entry(void) {
|
||||
|
||||
// Load the value of the referent field.
|
||||
const Address field_address(rax, referent_offset);
|
||||
__ load_heap_oop(rax, field_address, /*tmp1*/ rbx, /*tmp_thread*/ rdx, ON_WEAK_OOP_REF);
|
||||
__ load_heap_oop(rax, field_address, /*tmp1*/ rbx, ON_WEAK_OOP_REF);
|
||||
|
||||
// _areturn
|
||||
__ pop(rdi); // get return address
|
||||
|
||||
@ -151,7 +151,7 @@ static void do_oop_load(InterpreterMacroAssembler* _masm,
|
||||
Address src,
|
||||
Register dst,
|
||||
DecoratorSet decorators = 0) {
|
||||
__ load_heap_oop(dst, src, rdx, rbx, decorators);
|
||||
__ load_heap_oop(dst, src, rdx, decorators);
|
||||
}
|
||||
|
||||
Address TemplateTable::at_bcp(int offset) {
|
||||
@ -740,7 +740,7 @@ void TemplateTable::iaload() {
|
||||
__ access_load_at(T_INT, IN_HEAP | IS_ARRAY, rax,
|
||||
Address(rdx, rax, Address::times_4,
|
||||
arrayOopDesc::base_offset_in_bytes(T_INT)),
|
||||
noreg, noreg);
|
||||
noreg);
|
||||
}
|
||||
|
||||
void TemplateTable::laload() {
|
||||
@ -752,7 +752,7 @@ void TemplateTable::laload() {
|
||||
__ access_load_at(T_LONG, IN_HEAP | IS_ARRAY, noreg /* ltos */,
|
||||
Address(rdx, rbx, Address::times_8,
|
||||
arrayOopDesc::base_offset_in_bytes(T_LONG)),
|
||||
noreg, noreg);
|
||||
noreg);
|
||||
}
|
||||
|
||||
|
||||
@ -766,7 +766,7 @@ void TemplateTable::faload() {
|
||||
Address(rdx, rax,
|
||||
Address::times_4,
|
||||
arrayOopDesc::base_offset_in_bytes(T_FLOAT)),
|
||||
noreg, noreg);
|
||||
noreg);
|
||||
}
|
||||
|
||||
void TemplateTable::daload() {
|
||||
@ -778,7 +778,7 @@ void TemplateTable::daload() {
|
||||
Address(rdx, rax,
|
||||
Address::times_8,
|
||||
arrayOopDesc::base_offset_in_bytes(T_DOUBLE)),
|
||||
noreg, noreg);
|
||||
noreg);
|
||||
}
|
||||
|
||||
void TemplateTable::aaload() {
|
||||
@ -801,7 +801,7 @@ void TemplateTable::baload() {
|
||||
index_check(rdx, rax); // kills rbx
|
||||
__ access_load_at(T_BYTE, IN_HEAP | IS_ARRAY, rax,
|
||||
Address(rdx, rax, Address::times_1, arrayOopDesc::base_offset_in_bytes(T_BYTE)),
|
||||
noreg, noreg);
|
||||
noreg);
|
||||
}
|
||||
|
||||
void TemplateTable::caload() {
|
||||
@ -811,7 +811,7 @@ void TemplateTable::caload() {
|
||||
index_check(rdx, rax); // kills rbx
|
||||
__ access_load_at(T_CHAR, IN_HEAP | IS_ARRAY, rax,
|
||||
Address(rdx, rax, Address::times_2, arrayOopDesc::base_offset_in_bytes(T_CHAR)),
|
||||
noreg, noreg);
|
||||
noreg);
|
||||
}
|
||||
|
||||
// iload followed by caload frequent pair
|
||||
@ -826,7 +826,7 @@ void TemplateTable::fast_icaload() {
|
||||
index_check(rdx, rax); // kills rbx
|
||||
__ access_load_at(T_CHAR, IN_HEAP | IS_ARRAY, rax,
|
||||
Address(rdx, rax, Address::times_2, arrayOopDesc::base_offset_in_bytes(T_CHAR)),
|
||||
noreg, noreg);
|
||||
noreg);
|
||||
}
|
||||
|
||||
|
||||
@ -837,7 +837,7 @@ void TemplateTable::saload() {
|
||||
index_check(rdx, rax); // kills rbx
|
||||
__ access_load_at(T_SHORT, IN_HEAP | IS_ARRAY, rax,
|
||||
Address(rdx, rax, Address::times_2, arrayOopDesc::base_offset_in_bytes(T_SHORT)),
|
||||
noreg, noreg);
|
||||
noreg);
|
||||
}
|
||||
|
||||
void TemplateTable::iload(int n) {
|
||||
@ -2566,7 +2566,7 @@ void TemplateTable::getfield_or_static(int byte_no, bool is_static, RewriteContr
|
||||
__ jcc(Assembler::notZero, notByte);
|
||||
|
||||
// btos
|
||||
__ access_load_at(T_BYTE, IN_HEAP, rax, field, noreg, noreg);
|
||||
__ access_load_at(T_BYTE, IN_HEAP, rax, field, noreg);
|
||||
__ push(btos);
|
||||
// Rewrite bytecode to be faster
|
||||
if (!is_static && rc == may_rewrite) {
|
||||
@ -2579,7 +2579,7 @@ void TemplateTable::getfield_or_static(int byte_no, bool is_static, RewriteContr
|
||||
__ jcc(Assembler::notEqual, notBool);
|
||||
|
||||
// ztos (same code as btos)
|
||||
__ access_load_at(T_BOOLEAN, IN_HEAP, rax, field, noreg, noreg);
|
||||
__ access_load_at(T_BOOLEAN, IN_HEAP, rax, field, noreg);
|
||||
__ push(ztos);
|
||||
// Rewrite bytecode to be faster
|
||||
if (!is_static && rc == may_rewrite) {
|
||||
@ -2603,7 +2603,7 @@ void TemplateTable::getfield_or_static(int byte_no, bool is_static, RewriteContr
|
||||
__ cmpl(tos_state, itos);
|
||||
__ jcc(Assembler::notEqual, notInt);
|
||||
// itos
|
||||
__ access_load_at(T_INT, IN_HEAP, rax, field, noreg, noreg);
|
||||
__ access_load_at(T_INT, IN_HEAP, rax, field, noreg);
|
||||
__ push(itos);
|
||||
// Rewrite bytecode to be faster
|
||||
if (!is_static && rc == may_rewrite) {
|
||||
@ -2615,7 +2615,7 @@ void TemplateTable::getfield_or_static(int byte_no, bool is_static, RewriteContr
|
||||
__ cmpl(tos_state, ctos);
|
||||
__ jcc(Assembler::notEqual, notChar);
|
||||
// ctos
|
||||
__ access_load_at(T_CHAR, IN_HEAP, rax, field, noreg, noreg);
|
||||
__ access_load_at(T_CHAR, IN_HEAP, rax, field, noreg);
|
||||
__ push(ctos);
|
||||
// Rewrite bytecode to be faster
|
||||
if (!is_static && rc == may_rewrite) {
|
||||
@ -2627,7 +2627,7 @@ void TemplateTable::getfield_or_static(int byte_no, bool is_static, RewriteContr
|
||||
__ cmpl(tos_state, stos);
|
||||
__ jcc(Assembler::notEqual, notShort);
|
||||
// stos
|
||||
__ access_load_at(T_SHORT, IN_HEAP, rax, field, noreg, noreg);
|
||||
__ access_load_at(T_SHORT, IN_HEAP, rax, field, noreg);
|
||||
__ push(stos);
|
||||
// Rewrite bytecode to be faster
|
||||
if (!is_static && rc == may_rewrite) {
|
||||
@ -2641,7 +2641,7 @@ void TemplateTable::getfield_or_static(int byte_no, bool is_static, RewriteContr
|
||||
// ltos
|
||||
// Generate code as if volatile (x86_32). There just aren't enough registers to
|
||||
// save that information and this code is faster than the test.
|
||||
__ access_load_at(T_LONG, IN_HEAP | MO_RELAXED, noreg /* ltos */, field, noreg, noreg);
|
||||
__ access_load_at(T_LONG, IN_HEAP | MO_RELAXED, noreg /* ltos */, field, noreg);
|
||||
__ push(ltos);
|
||||
// Rewrite bytecode to be faster
|
||||
if (!is_static && rc == may_rewrite) patch_bytecode(Bytecodes::_fast_lgetfield, bc, rbx);
|
||||
@ -2652,7 +2652,7 @@ void TemplateTable::getfield_or_static(int byte_no, bool is_static, RewriteContr
|
||||
__ jcc(Assembler::notEqual, notFloat);
|
||||
// ftos
|
||||
|
||||
__ access_load_at(T_FLOAT, IN_HEAP, noreg /* ftos */, field, noreg, noreg);
|
||||
__ access_load_at(T_FLOAT, IN_HEAP, noreg /* ftos */, field, noreg);
|
||||
__ push(ftos);
|
||||
// Rewrite bytecode to be faster
|
||||
if (!is_static && rc == may_rewrite) {
|
||||
@ -2668,7 +2668,7 @@ void TemplateTable::getfield_or_static(int byte_no, bool is_static, RewriteContr
|
||||
#endif
|
||||
// dtos
|
||||
// MO_RELAXED: for the case of volatile field, in fact it adds no extra work for the underlying implementation
|
||||
__ access_load_at(T_DOUBLE, IN_HEAP | MO_RELAXED, noreg /* dtos */, field, noreg, noreg);
|
||||
__ access_load_at(T_DOUBLE, IN_HEAP | MO_RELAXED, noreg /* dtos */, field, noreg);
|
||||
__ push(dtos);
|
||||
// Rewrite bytecode to be faster
|
||||
if (!is_static && rc == may_rewrite) {
|
||||
@ -3131,25 +3131,25 @@ void TemplateTable::fast_accessfield(TosState state) {
|
||||
__ verify_oop(rax);
|
||||
break;
|
||||
case Bytecodes::_fast_lgetfield:
|
||||
__ access_load_at(T_LONG, IN_HEAP, noreg /* ltos */, field, noreg, noreg);
|
||||
__ access_load_at(T_LONG, IN_HEAP, noreg /* ltos */, field, noreg);
|
||||
break;
|
||||
case Bytecodes::_fast_igetfield:
|
||||
__ access_load_at(T_INT, IN_HEAP, rax, field, noreg, noreg);
|
||||
__ access_load_at(T_INT, IN_HEAP, rax, field, noreg);
|
||||
break;
|
||||
case Bytecodes::_fast_bgetfield:
|
||||
__ access_load_at(T_BYTE, IN_HEAP, rax, field, noreg, noreg);
|
||||
__ access_load_at(T_BYTE, IN_HEAP, rax, field, noreg);
|
||||
break;
|
||||
case Bytecodes::_fast_sgetfield:
|
||||
__ access_load_at(T_SHORT, IN_HEAP, rax, field, noreg, noreg);
|
||||
__ access_load_at(T_SHORT, IN_HEAP, rax, field, noreg);
|
||||
break;
|
||||
case Bytecodes::_fast_cgetfield:
|
||||
__ access_load_at(T_CHAR, IN_HEAP, rax, field, noreg, noreg);
|
||||
__ access_load_at(T_CHAR, IN_HEAP, rax, field, noreg);
|
||||
break;
|
||||
case Bytecodes::_fast_fgetfield:
|
||||
__ access_load_at(T_FLOAT, IN_HEAP, noreg /* ftos */, field, noreg, noreg);
|
||||
__ access_load_at(T_FLOAT, IN_HEAP, noreg /* ftos */, field, noreg);
|
||||
break;
|
||||
case Bytecodes::_fast_dgetfield:
|
||||
__ access_load_at(T_DOUBLE, IN_HEAP, noreg /* dtos */, field, noreg, noreg);
|
||||
__ access_load_at(T_DOUBLE, IN_HEAP, noreg /* dtos */, field, noreg);
|
||||
break;
|
||||
default:
|
||||
ShouldNotReachHere();
|
||||
@ -3178,14 +3178,14 @@ void TemplateTable::fast_xaccess(TosState state) {
|
||||
const Address field = Address(rax, rbx, Address::times_1, 0*wordSize);
|
||||
switch (state) {
|
||||
case itos:
|
||||
__ access_load_at(T_INT, IN_HEAP, rax, field, noreg, noreg);
|
||||
__ access_load_at(T_INT, IN_HEAP, rax, field, noreg);
|
||||
break;
|
||||
case atos:
|
||||
do_oop_load(_masm, field, rax);
|
||||
__ verify_oop(rax);
|
||||
break;
|
||||
case ftos:
|
||||
__ access_load_at(T_FLOAT, IN_HEAP, noreg /* ftos */, field, noreg, noreg);
|
||||
__ access_load_at(T_FLOAT, IN_HEAP, noreg /* ftos */, field, noreg);
|
||||
break;
|
||||
default:
|
||||
ShouldNotReachHere();
|
||||
@ -3588,7 +3588,7 @@ void TemplateTable::_new() {
|
||||
// Go to slow path.
|
||||
|
||||
if (UseTLAB) {
|
||||
__ tlab_allocate(r15_thread, rax, rdx, 0, rcx, rbx, slow_case);
|
||||
__ tlab_allocate(rax, rdx, 0, rcx, rbx, slow_case);
|
||||
if (ZeroTLAB) {
|
||||
// the fields have been already cleared
|
||||
__ jmp(initialize_header);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user