src/hotspot/cpu/x86/gc/shenandoah/shenandoahBarrierSetAssembler_x86.cpp
changeset 58693 3f35a9efd7de
parent 58407 b14643d898d3
child 58788 6a147ac7a68f
equal deleted inserted replaced
58692:04946947ca79 58693:3f35a9efd7de
   331 #ifndef _LP64
   331 #ifndef _LP64
   332   __ pop(thread);
   332   __ pop(thread);
   333 #endif
   333 #endif
   334 }
   334 }
   335 
   335 
   336 void ShenandoahBarrierSetAssembler::load_reference_barrier_native(MacroAssembler* masm, Register dst) {
   336 void ShenandoahBarrierSetAssembler::load_reference_barrier_native(MacroAssembler* masm, Register dst, Address src) {
   337   if (!ShenandoahLoadRefBarrier) {
   337   if (!ShenandoahLoadRefBarrier) {
   338     return;
   338     return;
   339   }
   339   }
   340 
   340 
   341   Label done;
   341   Label done;
   342   Label not_null;
   342   Label not_null;
   343   Label slow_path;
   343   Label slow_path;
       
   344   __ block_comment("load_reference_barrier_native { ");
   344 
   345 
   345   // null check
   346   // null check
   346   __ testptr(dst, dst);
   347   __ testptr(dst, dst);
   347   __ jcc(Assembler::notZero, not_null);
   348   __ jcc(Assembler::notZero, not_null);
   348   __ jmp(done);
   349   __ jmp(done);
   369   __ jccb(Assembler::notZero, slow_path);
   370   __ jccb(Assembler::notZero, slow_path);
   370   __ jmp(done);
   371   __ jmp(done);
   371   __ bind(slow_path);
   372   __ bind(slow_path);
   372 
   373 
   373   if (dst != rax) {
   374   if (dst != rax) {
   374     __ xchgptr(dst, rax); // Move obj into rax and save rax into obj.
   375     __ push(rax);
   375   }
   376   }
   376   __ push(rcx);
   377   __ push(rcx);
   377   __ push(rdx);
   378   __ push(rdx);
   378   __ push(rdi);
   379   __ push(rdi);
   379   __ push(rsi);
   380   __ push(rsi);
   386   __ push(r13);
   387   __ push(r13);
   387   __ push(r14);
   388   __ push(r14);
   388   __ push(r15);
   389   __ push(r15);
   389 #endif
   390 #endif
   390 
   391 
   391   __ movptr(rdi, rax);
   392   assert_different_registers(dst, rsi);
   392   __ call_VM_leaf(CAST_FROM_FN_PTR(address, ShenandoahRuntime::load_reference_barrier_native), rdi);
   393   __ lea(rsi, src);
       
   394   __ call_VM_leaf(CAST_FROM_FN_PTR(address, ShenandoahRuntime::load_reference_barrier_native), dst, rsi);
   393 
   395 
   394 #ifdef _LP64
   396 #ifdef _LP64
   395   __ pop(r15);
   397   __ pop(r15);
   396   __ pop(r14);
   398   __ pop(r14);
   397   __ pop(r13);
   399   __ pop(r13);
   405   __ pop(rdi);
   407   __ pop(rdi);
   406   __ pop(rdx);
   408   __ pop(rdx);
   407   __ pop(rcx);
   409   __ pop(rcx);
   408 
   410 
   409   if (dst != rax) {
   411   if (dst != rax) {
   410     __ xchgptr(rax, dst); // Swap back obj with rax.
   412     __ movptr(dst, rax);
       
   413     __ pop(rax);
   411   }
   414   }
   412 
   415 
   413   __ bind(done);
   416   __ bind(done);
       
   417   __ block_comment("load_reference_barrier_native { ");
   414 }
   418 }
   415 
   419 
   416 void ShenandoahBarrierSetAssembler::storeval_barrier(MacroAssembler* masm, Register dst, Register tmp) {
   420 void ShenandoahBarrierSetAssembler::storeval_barrier(MacroAssembler* masm, Register dst, Register tmp) {
   417   if (ShenandoahStoreValEnqueueBarrier) {
   421   if (ShenandoahStoreValEnqueueBarrier) {
   418     storeval_barrier_impl(masm, dst, tmp);
   422     storeval_barrier_impl(masm, dst, tmp);
   472   bool not_in_heap = (decorators & IN_NATIVE) != 0;
   476   bool not_in_heap = (decorators & IN_NATIVE) != 0;
   473   bool on_reference = on_weak || on_phantom;
   477   bool on_reference = on_weak || on_phantom;
   474   bool is_traversal_mode = ShenandoahHeap::heap()->is_traversal_mode();
   478   bool is_traversal_mode = ShenandoahHeap::heap()->is_traversal_mode();
   475   bool keep_alive = ((decorators & AS_NO_KEEPALIVE) == 0) || is_traversal_mode;
   479   bool keep_alive = ((decorators & AS_NO_KEEPALIVE) == 0) || is_traversal_mode;
   476 
   480 
       
   481   Register result_dst = dst;
       
   482   bool use_tmp1_for_dst = false;
       
   483 
       
   484   if (on_oop) {
       
   485     // We want to preserve src
       
   486     if (dst == src.base() || dst == src.index()) {
       
   487       // Use tmp1 for dst if possible, as it is not used in BarrierAssembler::load_at()
       
   488       if (tmp1->is_valid() && tmp1 != src.base() && tmp1 != src.index()) {
       
   489         dst = tmp1;
       
   490         use_tmp1_for_dst = true;
       
   491       } else {
       
   492         dst = rdi;
       
   493         __ push(dst);
       
   494       }
       
   495     }
       
   496     assert_different_registers(dst, src.base(), src.index());
       
   497   }
       
   498 
   477   BarrierSetAssembler::load_at(masm, decorators, type, dst, src, tmp1, tmp_thread);
   499   BarrierSetAssembler::load_at(masm, decorators, type, dst, src, tmp1, tmp_thread);
       
   500 
   478   if (on_oop) {
   501   if (on_oop) {
   479     if (not_in_heap && !is_traversal_mode) {
   502     if (not_in_heap && !is_traversal_mode) {
   480       load_reference_barrier_native(masm, dst);
   503       load_reference_barrier_native(masm, dst, src);
   481     } else {
   504     } else {
   482       load_reference_barrier(masm, dst);
   505       load_reference_barrier(masm, dst);
       
   506     }
       
   507 
       
   508     if (dst != result_dst) {
       
   509       __ movptr(result_dst, dst);
       
   510 
       
   511       if (!use_tmp1_for_dst) {
       
   512         __ pop(dst);
       
   513       }
       
   514 
       
   515       dst = result_dst;
   483     }
   516     }
   484 
   517 
   485     if (ShenandoahKeepAliveBarrier && on_reference && keep_alive) {
   518     if (ShenandoahKeepAliveBarrier && on_reference && keep_alive) {
   486       const Register thread = NOT_LP64(tmp_thread) LP64_ONLY(r15_thread);
   519       const Register thread = NOT_LP64(tmp_thread) LP64_ONLY(r15_thread);
   487       assert_different_registers(dst, tmp1, tmp_thread);
   520       assert_different_registers(dst, tmp1, tmp_thread);