Skip to content

Commit 29db1dc

Browse files
committedNov 4, 2020
8255886: Shenandoah: Resolve cset address truncation and register clash in interpreter LRB
Reviewed-by: shade
1 parent 26e7ef7 commit 29db1dc

File tree

1 file changed

+35
-15
lines changed

1 file changed

+35
-15
lines changed
 

‎src/hotspot/cpu/x86/gc/shenandoah/shenandoahBarrierSetAssembler_x86.cpp

+35-15
Original file line numberDiff line numberDiff line change
@@ -291,25 +291,34 @@ void ShenandoahBarrierSetAssembler::load_reference_barrier(MacroAssembler* masm,
291291
__ testb(gc_state, ShenandoahHeap::HAS_FORWARDED);
292292
__ jcc(Assembler::zero, heap_stable);
293293

294-
Register tmp1 = noreg;
294+
Register tmp1 = noreg, tmp2 = noreg;
295295
if (kind == ShenandoahBarrierSet::AccessKind::NORMAL) {
296296
// Test for object in cset
297-
// Allocate tmp-reg.
297+
// Allocate temporary registers
298298
for (int i = 0; i < 8; i++) {
299299
Register r = as_Register(i);
300300
if (r != rsp && r != rbp && r != dst && r != src.base() && r != src.index()) {
301-
tmp1 = r;
302-
break;
301+
if (tmp1 == noreg) {
302+
tmp1 = r;
303+
} else {
304+
tmp2 = r;
305+
break;
306+
}
303307
}
304308
}
309+
assert(tmp1 != noreg, "tmp1 allocated");
310+
assert(tmp2 != noreg, "tmp2 allocated");
311+
assert_different_registers(tmp1, tmp2, src.base(), src.index());
312+
assert_different_registers(tmp1, tmp2, dst);
313+
305314
__ push(tmp1);
306-
assert_different_registers(tmp1, src.base(), src.index());
307-
assert_different_registers(tmp1, dst);
315+
__ push(tmp2);
308316

309317
// Optimized cset-test
310318
__ movptr(tmp1, dst);
311319
__ shrptr(tmp1, ShenandoahHeapRegion::region_size_bytes_shift_jint());
312-
__ movbool(tmp1, Address(tmp1, (intptr_t) ShenandoahHeap::in_cset_fast_test_addr(), Address::times_1));
320+
__ movptr(tmp2, (intptr_t) ShenandoahHeap::in_cset_fast_test_addr());
321+
__ movbool(tmp1, Address(tmp1, tmp2, Address::times_1));
313322
__ testbool(tmp1);
314323
__ jcc(Assembler::zero, not_cset);
315324
}
@@ -333,28 +342,38 @@ void ShenandoahBarrierSetAssembler::load_reference_barrier(MacroAssembler* masm,
333342
#endif
334343
assert(slot == 0, "must use all slots");
335344

336-
Register tmp2 = (dst == rsi) ? rdx : rsi;
337-
assert_different_registers(dst, tmp2);
338-
__ lea(tmp2, src);
345+
// Shuffle registers such that dst is in c_rarg0 and addr in c_rarg1.
346+
#ifdef _LP64
347+
Register arg0 = c_rarg0, arg1 = c_rarg1;
348+
#else
349+
Register arg0 = rdi, arg1 = rsi;
350+
#endif
351+
if (dst == arg1) {
352+
__ lea(arg0, src);
353+
__ xchgptr(arg1, arg0);
354+
} else {
355+
__ lea(arg1, src);
356+
__ movptr(arg0, dst);
357+
}
339358

340359
save_xmm_registers(masm);
341360
switch (kind) {
342361
case ShenandoahBarrierSet::AccessKind::NORMAL:
343362
if (UseCompressedOops) {
344-
__ super_call_VM_leaf(CAST_FROM_FN_PTR(address, ShenandoahRuntime::load_reference_barrier_narrow), dst, tmp2);
363+
__ call_VM_leaf(CAST_FROM_FN_PTR(address, ShenandoahRuntime::load_reference_barrier_narrow), arg0, arg1);
345364
} else {
346-
__ super_call_VM_leaf(CAST_FROM_FN_PTR(address, ShenandoahRuntime::load_reference_barrier), dst, tmp2);
365+
__ call_VM_leaf(CAST_FROM_FN_PTR(address, ShenandoahRuntime::load_reference_barrier), arg0, arg1);
347366
}
348367
break;
349368
case ShenandoahBarrierSet::AccessKind::WEAK:
350369
if (UseCompressedOops) {
351-
__ super_call_VM_leaf(CAST_FROM_FN_PTR(address, ShenandoahRuntime::load_reference_barrier_weak_narrow), dst, tmp2);
370+
__ super_call_VM_leaf(CAST_FROM_FN_PTR(address, ShenandoahRuntime::load_reference_barrier_weak_narrow), arg0, arg1);
352371
} else {
353-
__ super_call_VM_leaf(CAST_FROM_FN_PTR(address, ShenandoahRuntime::load_reference_barrier_weak), dst, tmp2);
372+
__ super_call_VM_leaf(CAST_FROM_FN_PTR(address, ShenandoahRuntime::load_reference_barrier_weak), arg0, arg1);
354373
}
355374
break;
356375
case ShenandoahBarrierSet::AccessKind::NATIVE:
357-
__ super_call_VM_leaf(CAST_FROM_FN_PTR(address, ShenandoahRuntime::load_reference_barrier_weak), dst, tmp2);
376+
__ call_VM_leaf(CAST_FROM_FN_PTR(address, ShenandoahRuntime::load_reference_barrier_weak), arg0, arg1);
358377
break;
359378
default:
360379
ShouldNotReachHere();
@@ -383,6 +402,7 @@ void ShenandoahBarrierSetAssembler::load_reference_barrier(MacroAssembler* masm,
383402
__ bind(not_cset);
384403

385404
if (kind == ShenandoahBarrierSet::AccessKind::NORMAL) {
405+
__ pop(tmp2);
386406
__ pop(tmp1);
387407
}
388408

0 commit comments

Comments
 (0)
Please sign in to comment.