src/hotspot/cpu/x86/gc/shenandoah/shenandoahBarrierSetAssembler_x86.cpp
changeset 58819 ef8be51fff48
parent 58788 6a147ac7a68f
child 58946 83810b7d12e7
equal deleted inserted replaced
58817:7f27d70a2424 58819:ef8be51fff48
   245   if(tosca_live) __ pop(rax);
   245   if(tosca_live) __ pop(rax);
   246 
   246 
   247   __ bind(done);
   247   __ bind(done);
   248 }
   248 }
   249 
   249 
   250 void ShenandoahBarrierSetAssembler::load_reference_barrier_not_null(MacroAssembler* masm, Register dst) {
   250 void ShenandoahBarrierSetAssembler::load_reference_barrier_not_null(MacroAssembler* masm, Register dst, Address src) {
   251   assert(ShenandoahLoadRefBarrier, "Should be enabled");
   251   assert(ShenandoahLoadRefBarrier, "Should be enabled");
   252 
   252 
   253   Label done;
   253   Label done;
   254 
   254 
   255 #ifdef _LP64
   255 #ifdef _LP64
   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 
   939   __ bind(slow_path);
   969   __ bind(slow_path);
   940 
   970 
   941   __ push(rcx);
   971   __ push(rcx);
   942   __ push(rdx);
   972   __ push(rdx);
   943   __ push(rdi);
   973   __ push(rdi);
   944   __ push(rsi);
       
   945 #ifdef _LP64
   974 #ifdef _LP64
   946   __ push(r8);
   975   __ push(r8);
   947   __ push(r9);
   976   __ push(r9);
   948   __ push(r10);
   977   __ push(r10);
   949   __ push(r11);
   978   __ push(r11);
   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);
   968   __ pop(r11);
  1001   __ pop(r11);
   969   __ pop(r10);
  1002   __ pop(r10);
   970   __ pop(r9);
  1003   __ pop(r9);
   971   __ pop(r8);
  1004   __ pop(r8);
   972 #endif
  1005 #endif
   973   __ pop(rsi);
       
   974   __ pop(rdi);
  1006   __ pop(rdi);
   975   __ pop(rdx);
  1007   __ pop(rdx);
   976   __ pop(rcx);
  1008   __ pop(rcx);
   977 
  1009 
   978   __ pop(tmp2);
  1010   __ pop(tmp2);