8351157: Clean up x86 GC barriers after 32-bit x86 removal

Reviewed-by: kbarrett, wkemper, tschatzl
This commit is contained in:
Aleksey Shipilev 2025-04-10 07:54:00 +00:00
parent c447a10225
commit 73c8c755ea
20 changed files with 117 additions and 542 deletions

View File

@ -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);
}

View File

@ -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);

View File

@ -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);

View File

@ -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);
}
%}

View File

@ -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

View File

@ -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

View File

@ -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) {

View File

@ -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);
}

View File

@ -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);
}
}

View File

@ -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()) {

View File

@ -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);

View File

@ -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,

View File

@ -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;
}

View File

@ -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,

View File

@ -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,

View File

@ -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

View File

@ -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);

View File

@ -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);

View File

@ -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

View File

@ -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);