< prev index next >
src/cpu/x86/vm/c1_LIRAssembler_x86.cpp
Print this page
@@ -37,11 +37,14 @@
#include "memory/cardTableModRefBS.hpp"
#include "nativeInst_x86.hpp"
#include "oops/objArrayKlass.hpp"
#include "runtime/sharedRuntime.hpp"
#include "vmreg_x86.inline.hpp"
-
+#include "utilities/macros.hpp"
+#if INCLUDE_ALL_GCS
+#include "shenandoahBarrierSetAssembler_x86.hpp"
+#endif
// These masks are used to provide 128-bit aligned bitmasks to the XMM
// instructions, to allow sign-masking or sign-bit flipping. They allow
// fast versions of NegF/NegD and AbsF/AbsD.
@@ -1996,25 +1999,48 @@
assert(newval != addr, "new value and addr must be in different registers");
if ( op->code() == lir_cas_obj) {
#ifdef _LP64
if (UseCompressedOops) {
- __ encode_heap_oop(cmpval);
- __ mov(rscratch1, newval);
- __ encode_heap_oop(rscratch1);
- if (os::is_MP()) {
- __ lock();
+#if INCLUDE_ALL_GCS
+ if (UseShenandoahGC && ShenandoahCASBarrier) {
+ Register tmp1 = op->tmp1()->as_register();
+ Register tmp2 = op->tmp2()->as_register();
+ Register res = op->result_opr()->as_register();
+ __ encode_heap_oop(cmpval);
+ __ mov(rscratch1, newval);
+ __ encode_heap_oop(rscratch1);
+ ShenandoahBarrierSetAssembler::bsasm()->cmpxchg_oop(_masm, res, Address(addr, 0), cmpval, rscratch1, false, tmp1, tmp2);
+ } else
+#endif
+ {
+ __ encode_heap_oop(cmpval);
+ __ mov(rscratch1, newval);
+ __ encode_heap_oop(rscratch1);
+ if (os::is_MP()) {
+ __ lock();
+ }
+ // cmpval (rax) is implicitly used by this instruction
+ __ cmpxchgl(rscratch1, Address(addr, 0));
}
- // cmpval (rax) is implicitly used by this instruction
- __ cmpxchgl(rscratch1, Address(addr, 0));
} else
#endif
{
- if (os::is_MP()) {
- __ lock();
- }
- __ cmpxchgptr(newval, Address(addr, 0));
+#if INCLUDE_ALL_GCS
+ if (UseShenandoahGC && ShenandoahCASBarrier) {
+ Register tmp1 = op->tmp1()->as_register();
+ Register tmp2 = op->tmp2()->as_register();
+ Register res = op->result_opr()->as_register();
+ ShenandoahBarrierSetAssembler::bsasm()->cmpxchg_oop(_masm, res, Address(addr, 0), cmpval, newval, false, tmp1, tmp2);
+ } else
+#endif
+ {
+ if (os::is_MP()) {
+ __ lock();
+ }
+ __ cmpxchgptr(newval, Address(addr, 0));
+ }
}
} else {
assert(op->code() == lir_cas_int, "lir_cas_int expected");
if (os::is_MP()) {
__ lock();
@@ -3883,15 +3909,31 @@
ShouldNotReachHere();
}
}
-void LIR_Assembler::leal(LIR_Opr addr, LIR_Opr dest) {
- assert(addr->is_address() && dest->is_register(), "check");
- Register reg;
- reg = dest->as_pointer_register();
- __ lea(reg, as_Address(addr->as_address_ptr()));
+void LIR_Assembler::leal(LIR_Opr src, LIR_Opr dest, LIR_PatchCode patch_code, CodeEmitInfo* info) {
+ assert(src->is_address(), "must be an address");
+ assert(dest->is_register(), "must be a register");
+
+ if (!UseShenandoahGC) {
+ Register reg = dest->as_pointer_register();
+ __ lea(reg, as_Address(src->as_address_ptr()));
+ } else {
+ PatchingStub* patch = NULL;
+ if (patch_code != lir_patch_none) {
+ patch = new PatchingStub(_masm, PatchingStub::access_field_id);
+ }
+
+ Register reg = dest->as_pointer_register();
+ LIR_Address* addr = src->as_address_ptr();
+ __ lea(reg, as_Address(addr));
+
+ if (patch != NULL) {
+ patching_epilog(patch, patch_code, addr->base()->as_register(), info);
+ }
+ }
}
void LIR_Assembler::rt_call(LIR_Opr result, address dest, const LIR_OprList* args, LIR_Opr tmp, CodeEmitInfo* info) {
< prev index next >