149 __ movptr(rbp, Address(rsp, 5 * wordSize));
150 // skip rsp
151 __ movptr(rbx, Address(rsp, 3 * wordSize));
152 __ movptr(rdx, Address(rsp, 2 * wordSize));
153 __ movptr(rcx, Address(rsp, 1 * wordSize));
154 if (dst != rax) {
155 __ movptr(dst, rax);
156 __ movptr(rax, Address(rsp, 0 * wordSize));
157 }
158 __ addptr(rsp, LP64_ONLY(16) NOT_LP64(8) * wordSize);
159
160 __ restore_vector_registers();
161 }
162 __ bind(done);
163
164 #ifndef _LP64
165 __ pop(thread);
166 #endif
167 }
168
169 void ShenandoahBarrierSetAssembler::load_reference_barrier(MacroAssembler* masm, Register dst) {
170 if (ShenandoahLoadRefBarrier) {
171 Label done;
172 __ testptr(dst, dst);
173 __ jcc(Assembler::zero, done);
174 load_reference_barrier_not_null(masm, dst);
175 __ bind(done);
176 }
177 }
178
179 // Special Shenandoah CAS implementation that handles false negatives
180 // due to concurrent evacuation.
181 void ShenandoahBarrierSetAssembler::cmpxchg_oop(MacroAssembler* masm,
182 Register res, Address addr, Register oldval, Register newval,
183 bool exchange, Register tmp1, Register tmp2) {
184 assert(ShenandoahCASBarrier, "Should only be used when CAS barrier is enabled");
185 assert(oldval == rax, "must be in rax for implicit use in cmpxchg");
186
187 Label retry, done;
188
|
149 __ movptr(rbp, Address(rsp, 5 * wordSize));
150 // skip rsp
151 __ movptr(rbx, Address(rsp, 3 * wordSize));
152 __ movptr(rdx, Address(rsp, 2 * wordSize));
153 __ movptr(rcx, Address(rsp, 1 * wordSize));
154 if (dst != rax) {
155 __ movptr(dst, rax);
156 __ movptr(rax, Address(rsp, 0 * wordSize));
157 }
158 __ addptr(rsp, LP64_ONLY(16) NOT_LP64(8) * wordSize);
159
160 __ restore_vector_registers();
161 }
162 __ bind(done);
163
164 #ifndef _LP64
165 __ pop(thread);
166 #endif
167 }
168
169 void ShenandoahBarrierSetAssembler::storeval_barrier(MacroAssembler* masm, Register dst, Register tmp) {
170 if (ShenandoahStoreValEnqueueBarrier) {
171 storeval_barrier_impl(masm, dst, tmp);
172 }
173 }
174
175 void ShenandoahBarrierSetAssembler::storeval_barrier_impl(MacroAssembler* masm, Register dst, Register tmp) {
176 assert(ShenandoahStoreValEnqueueBarrier, "should be enabled");
177
178 if (dst == noreg) return;
179
180 if (ShenandoahStoreValEnqueueBarrier) {
181 // The set of registers to be saved+restored is the same as in the write-barrier above.
182 // Those are the commonly used registers in the interpreter.
183 __ pusha();
184 // __ push_callee_saved_registers();
185 __ subptr(rsp, 2 * Interpreter::stackElementSize);
186 __ movdbl(Address(rsp, 0), xmm0);
187
188 #ifdef _LP64
189 Register thread = r15_thread;
190 #else
191 Register thread = rcx;
192 if (thread == dst || thread == tmp) {
193 thread = rdi;
194 }
195 if (thread == dst || thread == tmp) {
196 thread = rbx;
197 }
198 __ get_thread(thread);
199 #endif
200 assert_different_registers(dst, tmp, thread);
201
202 __ g1_write_barrier_pre(noreg, dst, thread, tmp, true, false);
203 __ movdbl(xmm0, Address(rsp, 0));
204 __ addptr(rsp, 2 * Interpreter::stackElementSize);
205 //__ pop_callee_saved_registers();
206 __ popa();
207 }
208 }
209
210 void ShenandoahBarrierSetAssembler::load_reference_barrier(MacroAssembler* masm, Register dst) {
211 if (ShenandoahLoadRefBarrier) {
212 Label done;
213 __ testptr(dst, dst);
214 __ jcc(Assembler::zero, done);
215 load_reference_barrier_not_null(masm, dst);
216 __ bind(done);
217 }
218 }
219
220 // Special Shenandoah CAS implementation that handles false negatives
221 // due to concurrent evacuation.
222 void ShenandoahBarrierSetAssembler::cmpxchg_oop(MacroAssembler* masm,
223 Register res, Address addr, Register oldval, Register newval,
224 bool exchange, Register tmp1, Register tmp2) {
225 assert(ShenandoahCASBarrier, "Should only be used when CAS barrier is enabled");
226 assert(oldval == rax, "must be in rax for implicit use in cmpxchg");
227
228 Label retry, done;
229
|