26 #include "c1/c1_MacroAssembler.hpp" |
26 #include "c1/c1_MacroAssembler.hpp" |
27 #include "gc/shenandoah/shenandoahBarrierSet.hpp" |
27 #include "gc/shenandoah/shenandoahBarrierSet.hpp" |
28 #include "gc/shenandoah/shenandoahBarrierSetAssembler.hpp" |
28 #include "gc/shenandoah/shenandoahBarrierSetAssembler.hpp" |
29 #include "gc/shenandoah/c1/shenandoahBarrierSetC1.hpp" |
29 #include "gc/shenandoah/c1/shenandoahBarrierSetC1.hpp" |
30 |
30 |
|
31 #define __ masm->masm()-> |
|
32 |
31 void LIR_OpShenandoahCompareAndSwap::emit_code(LIR_Assembler* masm) { |
33 void LIR_OpShenandoahCompareAndSwap::emit_code(LIR_Assembler* masm) { |
32 Register addr = _addr->as_register_lo(); |
34 Register addr = _addr->as_register_lo(); |
33 Register newval = _new_value->as_register(); |
35 Register newval = _new_value->as_register(); |
34 Register cmpval = _cmp_value->as_register(); |
36 Register cmpval = _cmp_value->as_register(); |
35 Register tmp1 = _tmp1->as_register(); |
37 Register tmp1 = _tmp1->as_register(); |
36 Register tmp2 = _tmp2->as_register(); |
38 Register tmp2 = _tmp2->as_register(); |
|
39 Register result = result_opr()->as_register(); |
37 assert(cmpval == rax, "wrong register"); |
40 assert(cmpval == rax, "wrong register"); |
38 assert(newval != NULL, "new val must be register"); |
41 assert(newval != NULL, "new val must be register"); |
39 assert(cmpval != newval, "cmp and new values must be in different registers"); |
42 assert(cmpval != newval, "cmp and new values must be in different registers"); |
40 assert(cmpval != addr, "cmp and addr must be in different registers"); |
43 assert(cmpval != addr, "cmp and addr must be in different registers"); |
41 assert(newval != addr, "new value and addr must be in different registers"); |
44 assert(newval != addr, "new value and addr must be in different registers"); |
42 ShenandoahBarrierSet::assembler()->cmpxchg_oop(masm->masm(), NULL, Address(addr, 0), cmpval, newval, true, true, tmp1, tmp2); |
45 |
|
46 // Apply storeval barrier to newval. |
|
47 ShenandoahBarrierSet::assembler()->storeval_barrier(masm->masm(), newval, tmp1); |
|
48 |
|
49 if (UseCompressedOops) { |
|
50 __ encode_heap_oop(cmpval); |
|
51 __ mov(rscratch1, newval); |
|
52 __ encode_heap_oop(rscratch1); |
|
53 newval = rscratch1; |
|
54 } |
|
55 |
|
56 ShenandoahBarrierSet::assembler()->cmpxchg_oop(masm->masm(), result, Address(addr, 0), cmpval, newval, false, tmp1, tmp2); |
43 } |
57 } |
|
58 |
|
59 #undef __ |
44 |
60 |
45 #ifdef ASSERT |
61 #ifdef ASSERT |
46 #define __ gen->lir(__FILE__, __LINE__)-> |
62 #define __ gen->lir(__FILE__, __LINE__)-> |
47 #else |
63 #else |
48 #define __ gen->lir()-> |
64 #define __ gen->lir()-> |
61 new_value.load_item(); |
77 new_value.load_item(); |
62 |
78 |
63 LIR_Opr t1 = gen->new_register(T_OBJECT); |
79 LIR_Opr t1 = gen->new_register(T_OBJECT); |
64 LIR_Opr t2 = gen->new_register(T_OBJECT); |
80 LIR_Opr t2 = gen->new_register(T_OBJECT); |
65 LIR_Opr addr = access.resolved_addr()->as_address_ptr()->base(); |
81 LIR_Opr addr = access.resolved_addr()->as_address_ptr()->base(); |
|
82 LIR_Opr result = gen->new_register(T_INT); |
66 |
83 |
67 __ append(new LIR_OpShenandoahCompareAndSwap(addr, cmp_value.result(), new_value.result(), t1, t2, LIR_OprFact::illegalOpr)); |
84 __ append(new LIR_OpShenandoahCompareAndSwap(addr, cmp_value.result(), new_value.result(), t1, t2, result)); |
68 |
|
69 LIR_Opr result = gen->new_register(T_INT); |
|
70 __ cmove(lir_cond_equal, LIR_OprFact::intConst(1), LIR_OprFact::intConst(0), |
|
71 result, T_INT); |
|
72 return result; |
85 return result; |
73 } |
86 } |
74 } |
87 } |
75 return BarrierSetC1::atomic_cmpxchg_at_resolved(access, cmp_value, new_value); |
88 return BarrierSetC1::atomic_cmpxchg_at_resolved(access, cmp_value, new_value); |
76 } |
89 } |