23 */ |
23 */ |
24 |
24 |
25 #include "precompiled.hpp" |
25 #include "precompiled.hpp" |
26 #include "asm/macroAssembler.hpp" |
26 #include "asm/macroAssembler.hpp" |
27 #include "asm/macroAssembler.inline.hpp" |
27 #include "asm/macroAssembler.inline.hpp" |
28 #include "gc/shared/cardTable.hpp" |
28 #include "gc/shared/barrierSet.hpp" |
29 #include "gc/shared/cardTableBarrierSet.hpp" |
29 #include "gc/shared/barrierSetAssembler.hpp" |
30 #include "interpreter/interpreter.hpp" |
30 #include "interpreter/interpreter.hpp" |
31 #include "nativeInst_x86.hpp" |
31 #include "nativeInst_x86.hpp" |
32 #include "oops/instanceOop.hpp" |
32 #include "oops/instanceOop.hpp" |
33 #include "oops/method.hpp" |
33 #include "oops/method.hpp" |
34 #include "oops/objArrayKlass.hpp" |
34 #include "oops/objArrayKlass.hpp" |
664 BLOCK_COMMENT("call MacroAssembler::debug"); |
664 BLOCK_COMMENT("call MacroAssembler::debug"); |
665 __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, MacroAssembler::debug32))); |
665 __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, MacroAssembler::debug32))); |
666 __ popa(); |
666 __ popa(); |
667 __ ret(3 * wordSize); // pop arguments |
667 __ ret(3 * wordSize); // pop arguments |
668 return start; |
668 return start; |
669 } |
|
670 |
|
671 // |
|
672 // Generate pre-barrier for array stores |
|
673 // |
|
674 // Input: |
|
675 // start - starting address |
|
676 // count - element count |
|
677 void gen_write_ref_array_pre_barrier(Register start, Register count, bool uninitialized_target) { |
|
678 assert_different_registers(start, count); |
|
679 BarrierSet* bs = Universe::heap()->barrier_set(); |
|
680 switch (bs->kind()) { |
|
681 #if INCLUDE_ALL_GCS |
|
682 case BarrierSet::G1BarrierSet: |
|
683 // With G1, don't generate the call if we statically know that the target in uninitialized |
|
684 if (!uninitialized_target) { |
|
685 Register thread = rax; |
|
686 Label filtered; |
|
687 __ push(thread); |
|
688 __ get_thread(thread); |
|
689 Address in_progress(thread, in_bytes(JavaThread::satb_mark_queue_offset() + |
|
690 SATBMarkQueue::byte_offset_of_active())); |
|
691 // Is marking active? |
|
692 if (in_bytes(SATBMarkQueue::byte_width_of_active()) == 4) { |
|
693 __ cmpl(in_progress, 0); |
|
694 } else { |
|
695 assert(in_bytes(SATBMarkQueue::byte_width_of_active()) == 1, "Assumption"); |
|
696 __ cmpb(in_progress, 0); |
|
697 } |
|
698 __ pop(thread); |
|
699 __ jcc(Assembler::equal, filtered); |
|
700 |
|
701 __ pusha(); // push registers |
|
702 __ call_VM_leaf(CAST_FROM_FN_PTR(address, BarrierSet::static_write_ref_array_pre), |
|
703 start, count); |
|
704 __ popa(); |
|
705 |
|
706 __ bind(filtered); |
|
707 } |
|
708 break; |
|
709 #endif // INCLUDE_ALL_GCS |
|
710 case BarrierSet::CardTableBarrierSet: |
|
711 break; |
|
712 default : |
|
713 ShouldNotReachHere(); |
|
714 |
|
715 } |
|
716 } |
|
717 |
|
718 |
|
719 // |
|
720 // Generate a post-barrier for an array store |
|
721 // |
|
722 // start - starting address |
|
723 // count - element count |
|
724 // |
|
725 // The two input registers are overwritten. |
|
726 // |
|
727 void gen_write_ref_array_post_barrier(Register start, Register count) { |
|
728 BarrierSet* bs = Universe::heap()->barrier_set(); |
|
729 assert_different_registers(start, count); |
|
730 switch (bs->kind()) { |
|
731 #if INCLUDE_ALL_GCS |
|
732 case BarrierSet::G1BarrierSet: |
|
733 { |
|
734 __ pusha(); // push registers |
|
735 __ call_VM_leaf(CAST_FROM_FN_PTR(address, BarrierSet::static_write_ref_array_post), |
|
736 start, count); |
|
737 __ popa(); |
|
738 } |
|
739 break; |
|
740 #endif // INCLUDE_ALL_GCS |
|
741 |
|
742 case BarrierSet::CardTableBarrierSet: |
|
743 { |
|
744 CardTableBarrierSet* ctbs = barrier_set_cast<CardTableBarrierSet>(bs); |
|
745 CardTable* ct = ctbs->card_table(); |
|
746 assert(sizeof(*ct->byte_map_base()) == sizeof(jbyte), "adjust this code"); |
|
747 |
|
748 Label L_loop; |
|
749 const Register end = count; // elements count; end == start+count-1 |
|
750 assert_different_registers(start, end); |
|
751 |
|
752 __ lea(end, Address(start, count, Address::times_ptr, -wordSize)); |
|
753 __ shrptr(start, CardTable::card_shift); |
|
754 __ shrptr(end, CardTable::card_shift); |
|
755 __ subptr(end, start); // end --> count |
|
756 __ BIND(L_loop); |
|
757 intptr_t disp = (intptr_t) ct->byte_map_base(); |
|
758 Address cardtable(start, count, Address::times_1, disp); |
|
759 __ movb(cardtable, 0); |
|
760 __ decrement(count); |
|
761 __ jcc(Assembler::greaterEqual, L_loop); |
|
762 } |
|
763 break; |
|
764 case BarrierSet::ModRef: |
|
765 break; |
|
766 default : |
|
767 ShouldNotReachHere(); |
|
768 |
|
769 } |
|
770 } |
669 } |
771 |
670 |
772 |
671 |
773 // Copy 64 bytes chunks |
672 // Copy 64 bytes chunks |
774 // |
673 // |
934 } |
833 } |
935 |
834 |
936 if (t == T_OBJECT) { |
835 if (t == T_OBJECT) { |
937 __ testl(count, count); |
836 __ testl(count, count); |
938 __ jcc(Assembler::zero, L_0_count); |
837 __ jcc(Assembler::zero, L_0_count); |
939 gen_write_ref_array_pre_barrier(to, count, dest_uninitialized); |
838 } |
940 __ mov(saved_to, to); // save 'to' |
839 |
941 } |
840 DecoratorSet decorators = ARRAYCOPY_DISJOINT; |
|
841 if (dest_uninitialized) { |
|
842 decorators |= AS_DEST_NOT_INITIALIZED; |
|
843 } |
|
844 if (aligned) { |
|
845 decorators |= ARRAYCOPY_ALIGNED; |
|
846 } |
|
847 |
|
848 BarrierSetAssembler *bs = Universe::heap()->barrier_set()->barrier_set_assembler(); |
|
849 bs->arraycopy_prologue(_masm, decorators, t, from, to, count); |
942 |
850 |
943 __ subptr(to, from); // to --> to_from |
851 __ subptr(to, from); // to --> to_from |
944 __ cmpl(count, 2<<shift); // Short arrays (< 8 bytes) copy by element |
852 __ cmpl(count, 2<<shift); // Short arrays (< 8 bytes) copy by element |
945 __ jcc(Assembler::below, L_copy_4_bytes); // use unsigned cmp |
853 __ jcc(Assembler::below, L_copy_4_bytes); // use unsigned cmp |
946 if (!UseUnalignedLoadStores && !aligned && (t == T_BYTE || t == T_SHORT)) { |
854 if (!UseUnalignedLoadStores && !aligned && (t == T_BYTE || t == T_SHORT)) { |
1114 __ jump_cc(Assembler::aboveEqual, nooverlap); |
1022 __ jump_cc(Assembler::aboveEqual, nooverlap); |
1115 |
1023 |
1116 if (t == T_OBJECT) { |
1024 if (t == T_OBJECT) { |
1117 __ testl(count, count); |
1025 __ testl(count, count); |
1118 __ jcc(Assembler::zero, L_0_count); |
1026 __ jcc(Assembler::zero, L_0_count); |
1119 gen_write_ref_array_pre_barrier(dst, count, dest_uninitialized); |
1027 } |
1120 } |
1028 |
|
1029 DecoratorSet decorators = 0; |
|
1030 if (dest_uninitialized) { |
|
1031 decorators |= AS_DEST_NOT_INITIALIZED; |
|
1032 } |
|
1033 if (aligned) { |
|
1034 decorators |= ARRAYCOPY_ALIGNED; |
|
1035 } |
|
1036 |
|
1037 BarrierSetAssembler *bs = Universe::heap()->barrier_set()->barrier_set_assembler(); |
|
1038 bs->arraycopy_prologue(_masm, decorators, t, from, to, count); |
1121 |
1039 |
1122 // copy from high to low |
1040 // copy from high to low |
1123 __ cmpl(count, 2<<shift); // Short arrays (< 8 bytes) copy by element |
1041 __ cmpl(count, 2<<shift); // Short arrays (< 8 bytes) copy by element |
1124 __ jcc(Assembler::below, L_copy_4_bytes); // use unsigned cmp |
1042 __ jcc(Assembler::below, L_copy_4_bytes); // use unsigned cmp |
1125 if (t == T_BYTE || t == T_SHORT) { |
1043 if (t == T_BYTE || t == T_SHORT) { |
1461 // Loop-variant addresses. They assume post-incremented count < 0. |
1381 // Loop-variant addresses. They assume post-incremented count < 0. |
1462 Address from_element_addr(end_from, count, Address::times_ptr, 0); |
1382 Address from_element_addr(end_from, count, Address::times_ptr, 0); |
1463 Address to_element_addr(end_to, count, Address::times_ptr, 0); |
1383 Address to_element_addr(end_to, count, Address::times_ptr, 0); |
1464 Address elem_klass_addr(elem, oopDesc::klass_offset_in_bytes()); |
1384 Address elem_klass_addr(elem, oopDesc::klass_offset_in_bytes()); |
1465 |
1385 |
|
1386 DecoratorSet decorators = ARRAYCOPY_CHECKCAST; |
|
1387 if (dest_uninitialized) { |
|
1388 decorators |= AS_DEST_NOT_INITIALIZED; |
|
1389 } |
|
1390 |
|
1391 BasicType type = T_OBJECT; |
|
1392 BarrierSetAssembler *bs = Universe::heap()->barrier_set()->barrier_set_assembler(); |
|
1393 bs->arraycopy_prologue(_masm, decorators, type, from, to, count); |
|
1394 |
1466 // Copy from low to high addresses, indexed from the end of each array. |
1395 // Copy from low to high addresses, indexed from the end of each array. |
1467 gen_write_ref_array_pre_barrier(to, count, dest_uninitialized); |
|
1468 __ lea(end_from, end_from_addr); |
1396 __ lea(end_from, end_from_addr); |
1469 __ lea(end_to, end_to_addr); |
1397 __ lea(end_to, end_to_addr); |
1470 assert(length == count, ""); // else fix next line: |
1398 assert(length == count, ""); // else fix next line: |
1471 __ negptr(count); // negate and test the length |
1399 __ negptr(count); // negate and test the length |
1472 __ jccb(Assembler::notZero, L_load_element); |
1400 __ jccb(Assembler::notZero, L_load_element); |
1519 __ xorptr(rax, rax); // return 0 on success |
1447 __ xorptr(rax, rax); // return 0 on success |
1520 __ movl2ptr(count, length_arg); |
1448 __ movl2ptr(count, length_arg); |
1521 |
1449 |
1522 __ BIND(L_post_barrier); |
1450 __ BIND(L_post_barrier); |
1523 __ movptr(to, to_arg); // reload |
1451 __ movptr(to, to_arg); // reload |
1524 gen_write_ref_array_post_barrier(to, count); |
1452 bs->arraycopy_epilogue(_masm, decorators, type, from, to, count); |
1525 |
1453 |
1526 // Common exit point (success or failure). |
1454 // Common exit point (success or failure). |
1527 __ BIND(L_done); |
1455 __ BIND(L_done); |
1528 __ pop(rbx); |
1456 __ pop(rbx); |
1529 __ pop(rdi); |
1457 __ pop(rdi); |