260 thread = rbx; |
260 thread = rbx; |
261 } |
261 } |
262 __ push(thread); |
262 __ push(thread); |
263 __ get_thread(thread); |
263 __ get_thread(thread); |
264 #endif |
264 #endif |
265 assert_different_registers(dst, thread); |
|
266 |
265 |
267 Address gc_state(thread, in_bytes(ShenandoahThreadLocalData::gc_state_offset())); |
266 Address gc_state(thread, in_bytes(ShenandoahThreadLocalData::gc_state_offset())); |
268 __ testb(gc_state, ShenandoahHeap::HAS_FORWARDED); |
267 __ testb(gc_state, ShenandoahHeap::HAS_FORWARDED); |
269 __ jccb(Assembler::zero, done); |
268 __ jccb(Assembler::zero, done); |
270 |
269 |
271 if (dst != rax) { |
270 // Use rsi for src address |
272 __ xchgptr(dst, rax); // Move obj into rax and save rax into obj. |
271 const Register src_addr = rsi; |
273 } |
272 // Setup address parameter first, if it does not clobber oop in dst |
274 |
273 bool need_addr_setup = (src_addr != dst); |
275 __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, ShenandoahBarrierSetAssembler::shenandoah_lrb()))); |
274 |
276 |
275 if (need_addr_setup) { |
277 if (dst != rax) { |
276 __ push(src_addr); |
278 __ xchgptr(rax, dst); // Swap back obj with rax. |
277 __ lea(src_addr, src); |
279 } |
278 |
|
279 if (dst != rax) { |
|
280 // Move obj into rax and save rax |
|
281 __ push(rax); |
|
282 __ movptr(rax, dst); |
|
283 } |
|
284 } else { |
|
285 // dst == rsi |
|
286 __ push(rax); |
|
287 __ movptr(rax, dst); |
|
288 |
|
289 // we can clobber it, since it is outgoing register |
|
290 __ lea(src_addr, src); |
|
291 } |
|
292 |
|
293 __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, ShenandoahBarrierSetAssembler::shenandoah_lrb()))); |
|
294 |
|
295 if (need_addr_setup) { |
|
296 if (dst != rax) { |
|
297 __ movptr(dst, rax); |
|
298 __ pop(rax); |
|
299 } |
|
300 __ pop(src_addr); |
|
301 } else { |
|
302 __ movptr(dst, rax); |
|
303 __ pop(rax); |
|
304 } |
280 |
305 |
281 __ bind(done); |
306 __ bind(done); |
282 |
307 |
283 #ifndef _LP64 |
308 #ifndef _LP64 |
284 __ pop(thread); |
309 __ pop(thread); |
285 #endif |
310 #endif |
286 } |
311 } |
287 |
312 |
288 void ShenandoahBarrierSetAssembler::load_reference_barrier_native(MacroAssembler* masm, Register dst, Address src) { |
313 void ShenandoahBarrierSetAssembler::load_reference_barrier_native(MacroAssembler* masm, Register dst, Address src) { |
289 if (!ShenandoahLoadRefBarrier) { |
314 if (!ShenandoahLoadRefBarrier) { |
408 //__ pop_callee_saved_registers(); |
433 //__ pop_callee_saved_registers(); |
409 __ popa(); |
434 __ popa(); |
410 } |
435 } |
411 } |
436 } |
412 |
437 |
413 void ShenandoahBarrierSetAssembler::load_reference_barrier(MacroAssembler* masm, Register dst) { |
438 void ShenandoahBarrierSetAssembler::load_reference_barrier(MacroAssembler* masm, Register dst, Address src) { |
414 if (ShenandoahLoadRefBarrier) { |
439 if (ShenandoahLoadRefBarrier) { |
415 Label done; |
440 Label done; |
416 __ testptr(dst, dst); |
441 __ testptr(dst, dst); |
417 __ jcc(Assembler::zero, done); |
442 __ jcc(Assembler::zero, done); |
418 load_reference_barrier_not_null(masm, dst); |
443 load_reference_barrier_not_null(masm, dst, src); |
419 __ bind(done); |
444 __ bind(done); |
420 } |
445 } |
421 } |
446 } |
422 |
447 |
423 void ShenandoahBarrierSetAssembler::load_at(MacroAssembler* masm, DecoratorSet decorators, BasicType type, |
448 void ShenandoahBarrierSetAssembler::load_at(MacroAssembler* masm, DecoratorSet decorators, BasicType type, |
452 |
477 |
453 if (on_oop) { |
478 if (on_oop) { |
454 if (not_in_heap && !is_traversal_mode) { |
479 if (not_in_heap && !is_traversal_mode) { |
455 load_reference_barrier_native(masm, dst, src); |
480 load_reference_barrier_native(masm, dst, src); |
456 } else { |
481 } else { |
457 load_reference_barrier(masm, dst); |
482 load_reference_barrier(masm, dst, src); |
458 } |
483 } |
459 |
484 |
460 if (dst != result_dst) { |
485 if (dst != result_dst) { |
461 __ movptr(result_dst, dst); |
486 __ movptr(result_dst, dst); |
462 |
487 |
862 |
887 |
863 #ifdef _LP64 |
888 #ifdef _LP64 |
864 __ load_parameter(0, c_rarg0); |
889 __ load_parameter(0, c_rarg0); |
865 __ load_parameter(1, c_rarg1); |
890 __ load_parameter(1, c_rarg1); |
866 if (UseCompressedOops) { |
891 if (UseCompressedOops) { |
867 __ call_VM_leaf(CAST_FROM_FN_PTR(address, ShenandoahRuntime::load_reference_barrier_fixup_narrow), c_rarg0, c_rarg1); |
892 __ call_VM_leaf(CAST_FROM_FN_PTR(address, ShenandoahRuntime::load_reference_barrier_narrow), c_rarg0, c_rarg1); |
868 } else { |
893 } else { |
869 __ call_VM_leaf(CAST_FROM_FN_PTR(address, ShenandoahRuntime::load_reference_barrier_fixup), c_rarg0, c_rarg1); |
894 __ call_VM_leaf(CAST_FROM_FN_PTR(address, ShenandoahRuntime::load_reference_barrier), c_rarg0, c_rarg1); |
870 } |
895 } |
871 #else |
896 #else |
872 __ load_parameter(0, rax); |
897 __ load_parameter(0, rax); |
873 __ load_parameter(1, rbx); |
898 __ load_parameter(1, rbx); |
874 __ call_VM_leaf(CAST_FROM_FN_PTR(address, ShenandoahRuntime::load_reference_barrier_fixup), rax, rbx); |
899 __ call_VM_leaf(CAST_FROM_FN_PTR(address, ShenandoahRuntime::load_reference_barrier), rax, rbx); |
875 #endif |
900 #endif |
876 |
901 |
877 __ restore_live_registers_except_rax(true); |
902 __ restore_live_registers_except_rax(true); |
878 |
903 |
879 __ epilogue(); |
904 __ epilogue(); |
888 return _shenandoah_lrb; |
913 return _shenandoah_lrb; |
889 } |
914 } |
890 |
915 |
891 #define __ cgen->assembler()-> |
916 #define __ cgen->assembler()-> |
892 |
917 |
|
918 /* |
|
919 * Incoming parameters: |
|
920 * rax: oop |
|
921 * rsi: load address |
|
922 */ |
893 address ShenandoahBarrierSetAssembler::generate_shenandoah_lrb(StubCodeGenerator* cgen) { |
923 address ShenandoahBarrierSetAssembler::generate_shenandoah_lrb(StubCodeGenerator* cgen) { |
894 __ align(CodeEntryAlignment); |
924 __ align(CodeEntryAlignment); |
895 StubCodeMark mark(cgen, "StubRoutines", "shenandoah_lrb"); |
925 StubCodeMark mark(cgen, "StubRoutines", "shenandoah_lrb"); |
896 address start = __ pc(); |
926 address start = __ pc(); |
897 |
927 |
954 #endif |
983 #endif |
955 __ push(rbp); |
984 __ push(rbp); |
956 __ movptr(rbp, rsp); |
985 __ movptr(rbp, rsp); |
957 __ andptr(rsp, -StackAlignmentInBytes); |
986 __ andptr(rsp, -StackAlignmentInBytes); |
958 __ push_FPU_state(); |
987 __ push_FPU_state(); |
959 __ call_VM_leaf(CAST_FROM_FN_PTR(address, ShenandoahRuntime::load_reference_barrier), rax); |
988 if (UseCompressedOops) { |
|
989 __ call_VM_leaf(CAST_FROM_FN_PTR(address, ShenandoahRuntime::load_reference_barrier_narrow), rax, rsi); |
|
990 } else { |
|
991 __ call_VM_leaf(CAST_FROM_FN_PTR(address, ShenandoahRuntime::load_reference_barrier), rax, rsi); |
|
992 } |
960 __ pop_FPU_state(); |
993 __ pop_FPU_state(); |
961 __ movptr(rsp, rbp); |
994 __ movptr(rsp, rbp); |
962 __ pop(rbp); |
995 __ pop(rbp); |
963 #ifdef _LP64 |
996 #ifdef _LP64 |
964 __ pop(r15); |
997 __ pop(r15); |