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); |
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); |