Mercurial > hg > truffle
comparison src/cpu/x86/vm/c1_LIRAssembler_x86.cpp @ 2002:ac637b7220d1
6985015: C1 needs to support compressed oops
Summary: This change implements compressed oops for C1 for x64 and sparc. The changes are mostly on the codegen level, with a few exceptions when we do access things outside of the heap that are uncompressed from the IR. Compressed oops are now also enabled with tiered.
Reviewed-by: twisti, kvn, never, phh
author | iveresov |
---|---|
date | Tue, 30 Nov 2010 23:23:40 -0800 |
parents | f95d63e2154a |
children | 5ddfcf4b079e |
comparison
equal
deleted
inserted
replaced
1972:f95d63e2154a | 2002:ac637b7220d1 |
---|---|
341 // inline cache check; done before the frame is built. | 341 // inline cache check; done before the frame is built. |
342 int LIR_Assembler::check_icache() { | 342 int LIR_Assembler::check_icache() { |
343 Register receiver = FrameMap::receiver_opr->as_register(); | 343 Register receiver = FrameMap::receiver_opr->as_register(); |
344 Register ic_klass = IC_Klass; | 344 Register ic_klass = IC_Klass; |
345 const int ic_cmp_size = LP64_ONLY(10) NOT_LP64(9); | 345 const int ic_cmp_size = LP64_ONLY(10) NOT_LP64(9); |
346 | 346 const bool do_post_padding = VerifyOops || UseCompressedOops; |
347 if (!VerifyOops) { | 347 if (!do_post_padding) { |
348 // insert some nops so that the verified entry point is aligned on CodeEntryAlignment | 348 // insert some nops so that the verified entry point is aligned on CodeEntryAlignment |
349 while ((__ offset() + ic_cmp_size) % CodeEntryAlignment != 0) { | 349 while ((__ offset() + ic_cmp_size) % CodeEntryAlignment != 0) { |
350 __ nop(); | 350 __ nop(); |
351 } | 351 } |
352 } | 352 } |
353 int offset = __ offset(); | 353 int offset = __ offset(); |
354 __ inline_cache_check(receiver, IC_Klass); | 354 __ inline_cache_check(receiver, IC_Klass); |
355 assert(__ offset() % CodeEntryAlignment == 0 || VerifyOops, "alignment must be correct"); | 355 assert(__ offset() % CodeEntryAlignment == 0 || do_post_padding, "alignment must be correct"); |
356 if (VerifyOops) { | 356 if (do_post_padding) { |
357 // force alignment after the cache check. | 357 // force alignment after the cache check. |
358 // It's been verified to be aligned if !VerifyOops | 358 // It's been verified to be aligned if !VerifyOops |
359 __ align(CodeEntryAlignment); | 359 __ align(CodeEntryAlignment); |
360 } | 360 } |
361 return offset; | 361 return offset; |
557 void LIR_Assembler::emit_string_compare(LIR_Opr arg0, LIR_Opr arg1, LIR_Opr dst, CodeEmitInfo* info) { | 557 void LIR_Assembler::emit_string_compare(LIR_Opr arg0, LIR_Opr arg1, LIR_Opr dst, CodeEmitInfo* info) { |
558 __ movptr (rbx, rcx); // receiver is in rcx | 558 __ movptr (rbx, rcx); // receiver is in rcx |
559 __ movptr (rax, arg1->as_register()); | 559 __ movptr (rax, arg1->as_register()); |
560 | 560 |
561 // Get addresses of first characters from both Strings | 561 // Get addresses of first characters from both Strings |
562 __ movptr (rsi, Address(rax, java_lang_String::value_offset_in_bytes())); | 562 __ load_heap_oop(rsi, Address(rax, java_lang_String::value_offset_in_bytes())); |
563 __ movptr (rcx, Address(rax, java_lang_String::offset_offset_in_bytes())); | 563 __ movptr (rcx, Address(rax, java_lang_String::offset_offset_in_bytes())); |
564 __ lea (rsi, Address(rsi, rcx, Address::times_2, arrayOopDesc::base_offset_in_bytes(T_CHAR))); | 564 __ lea (rsi, Address(rsi, rcx, Address::times_2, arrayOopDesc::base_offset_in_bytes(T_CHAR))); |
565 | 565 |
566 | 566 |
567 // rbx, may be NULL | 567 // rbx, may be NULL |
568 add_debug_info_for_null_check_here(info); | 568 add_debug_info_for_null_check_here(info); |
569 __ movptr (rdi, Address(rbx, java_lang_String::value_offset_in_bytes())); | 569 __ load_heap_oop(rdi, Address(rbx, java_lang_String::value_offset_in_bytes())); |
570 __ movptr (rcx, Address(rbx, java_lang_String::offset_offset_in_bytes())); | 570 __ movptr (rcx, Address(rbx, java_lang_String::offset_offset_in_bytes())); |
571 __ lea (rdi, Address(rdi, rcx, Address::times_2, arrayOopDesc::base_offset_in_bytes(T_CHAR))); | 571 __ lea (rdi, Address(rdi, rcx, Address::times_2, arrayOopDesc::base_offset_in_bytes(T_CHAR))); |
572 | 572 |
573 // compute minimum length (in rax) and difference of lengths (on top of stack) | 573 // compute minimum length (in rax) and difference of lengths (on top of stack) |
574 if (VM_Version::supports_cmov()) { | 574 if (VM_Version::supports_cmov()) { |
575 __ movl (rbx, Address(rbx, java_lang_String::count_offset_in_bytes())); | 575 __ movl (rbx, Address(rbx, java_lang_String::count_offset_in_bytes())); |
576 __ movl (rax, Address(rax, java_lang_String::count_offset_in_bytes())); | 576 __ movl (rax, Address(rax, java_lang_String::count_offset_in_bytes())); |
694 assert(src->is_constant(), "should not call otherwise"); | 694 assert(src->is_constant(), "should not call otherwise"); |
695 assert(dest->is_register(), "should not call otherwise"); | 695 assert(dest->is_register(), "should not call otherwise"); |
696 LIR_Const* c = src->as_constant_ptr(); | 696 LIR_Const* c = src->as_constant_ptr(); |
697 | 697 |
698 switch (c->type()) { | 698 switch (c->type()) { |
699 case T_INT: | 699 case T_INT: { |
700 assert(patch_code == lir_patch_none, "no patching handled here"); | |
701 __ movl(dest->as_register(), c->as_jint()); | |
702 break; | |
703 } | |
704 | |
700 case T_ADDRESS: { | 705 case T_ADDRESS: { |
701 assert(patch_code == lir_patch_none, "no patching handled here"); | 706 assert(patch_code == lir_patch_none, "no patching handled here"); |
702 __ movl(dest->as_register(), c->as_jint()); | 707 __ movptr(dest->as_register(), c->as_jint()); |
703 break; | 708 break; |
704 } | 709 } |
705 | 710 |
706 case T_LONG: { | 711 case T_LONG: { |
707 assert(patch_code == lir_patch_none, "no patching handled here"); | 712 assert(patch_code == lir_patch_none, "no patching handled here"); |
778 LIR_Const* c = src->as_constant_ptr(); | 783 LIR_Const* c = src->as_constant_ptr(); |
779 | 784 |
780 switch (c->type()) { | 785 switch (c->type()) { |
781 case T_INT: // fall through | 786 case T_INT: // fall through |
782 case T_FLOAT: | 787 case T_FLOAT: |
788 __ movl(frame_map()->address_for_slot(dest->single_stack_ix()), c->as_jint_bits()); | |
789 break; | |
790 | |
783 case T_ADDRESS: | 791 case T_ADDRESS: |
784 __ movl(frame_map()->address_for_slot(dest->single_stack_ix()), c->as_jint_bits()); | 792 __ movptr(frame_map()->address_for_slot(dest->single_stack_ix()), c->as_jint_bits()); |
785 break; | 793 break; |
786 | 794 |
787 case T_OBJECT: | 795 case T_OBJECT: |
788 __ movoop(frame_map()->address_for_slot(dest->single_stack_ix()), c->as_jobject()); | 796 __ movoop(frame_map()->address_for_slot(dest->single_stack_ix()), c->as_jobject()); |
789 break; | 797 break; |
804 default: | 812 default: |
805 ShouldNotReachHere(); | 813 ShouldNotReachHere(); |
806 } | 814 } |
807 } | 815 } |
808 | 816 |
809 void LIR_Assembler::const2mem(LIR_Opr src, LIR_Opr dest, BasicType type, CodeEmitInfo* info ) { | 817 void LIR_Assembler::const2mem(LIR_Opr src, LIR_Opr dest, BasicType type, CodeEmitInfo* info, bool wide) { |
810 assert(src->is_constant(), "should not call otherwise"); | 818 assert(src->is_constant(), "should not call otherwise"); |
811 assert(dest->is_address(), "should not call otherwise"); | 819 assert(dest->is_address(), "should not call otherwise"); |
812 LIR_Const* c = src->as_constant_ptr(); | 820 LIR_Const* c = src->as_constant_ptr(); |
813 LIR_Address* addr = dest->as_address_ptr(); | 821 LIR_Address* addr = dest->as_address_ptr(); |
814 | 822 |
815 int null_check_here = code_offset(); | 823 int null_check_here = code_offset(); |
816 switch (type) { | 824 switch (type) { |
817 case T_INT: // fall through | 825 case T_INT: // fall through |
818 case T_FLOAT: | 826 case T_FLOAT: |
827 __ movl(as_Address(addr), c->as_jint_bits()); | |
828 break; | |
829 | |
819 case T_ADDRESS: | 830 case T_ADDRESS: |
820 __ movl(as_Address(addr), c->as_jint_bits()); | 831 __ movptr(as_Address(addr), c->as_jint_bits()); |
821 break; | 832 break; |
822 | 833 |
823 case T_OBJECT: // fall through | 834 case T_OBJECT: // fall through |
824 case T_ARRAY: | 835 case T_ARRAY: |
825 if (c->as_jobject() == NULL) { | 836 if (c->as_jobject() == NULL) { |
826 __ movptr(as_Address(addr), NULL_WORD); | 837 if (UseCompressedOops && !wide) { |
838 __ movl(as_Address(addr), (int32_t)NULL_WORD); | |
839 } else { | |
840 __ movptr(as_Address(addr), NULL_WORD); | |
841 } | |
827 } else { | 842 } else { |
828 if (is_literal_address(addr)) { | 843 if (is_literal_address(addr)) { |
829 ShouldNotReachHere(); | 844 ShouldNotReachHere(); |
830 __ movoop(as_Address(addr, noreg), c->as_jobject()); | 845 __ movoop(as_Address(addr, noreg), c->as_jobject()); |
831 } else { | 846 } else { |
832 #ifdef _LP64 | 847 #ifdef _LP64 |
833 __ movoop(rscratch1, c->as_jobject()); | 848 __ movoop(rscratch1, c->as_jobject()); |
834 null_check_here = code_offset(); | 849 if (UseCompressedOops && !wide) { |
835 __ movptr(as_Address_lo(addr), rscratch1); | 850 __ encode_heap_oop(rscratch1); |
851 null_check_here = code_offset(); | |
852 __ movl(as_Address_lo(addr), rscratch1); | |
853 } else { | |
854 null_check_here = code_offset(); | |
855 __ movptr(as_Address_lo(addr), rscratch1); | |
856 } | |
836 #else | 857 #else |
837 __ movoop(as_Address(addr), c->as_jobject()); | 858 __ movoop(as_Address(addr), c->as_jobject()); |
838 #endif | 859 #endif |
839 } | 860 } |
840 } | 861 } |
1007 ShouldNotReachHere(); | 1028 ShouldNotReachHere(); |
1008 } | 1029 } |
1009 } | 1030 } |
1010 | 1031 |
1011 | 1032 |
1012 void LIR_Assembler::reg2mem(LIR_Opr src, LIR_Opr dest, BasicType type, LIR_PatchCode patch_code, CodeEmitInfo* info, bool pop_fpu_stack, bool /* unaligned */) { | 1033 void LIR_Assembler::reg2mem(LIR_Opr src, LIR_Opr dest, BasicType type, LIR_PatchCode patch_code, CodeEmitInfo* info, bool pop_fpu_stack, bool wide, bool /* unaligned */) { |
1013 LIR_Address* to_addr = dest->as_address_ptr(); | 1034 LIR_Address* to_addr = dest->as_address_ptr(); |
1014 PatchingStub* patch = NULL; | 1035 PatchingStub* patch = NULL; |
1036 Register compressed_src = rscratch1; | |
1015 | 1037 |
1016 if (type == T_ARRAY || type == T_OBJECT) { | 1038 if (type == T_ARRAY || type == T_OBJECT) { |
1017 __ verify_oop(src->as_register()); | 1039 __ verify_oop(src->as_register()); |
1018 } | 1040 #ifdef _LP64 |
1041 if (UseCompressedOops && !wide) { | |
1042 __ movptr(compressed_src, src->as_register()); | |
1043 __ encode_heap_oop(compressed_src); | |
1044 } | |
1045 #endif | |
1046 } | |
1047 | |
1019 if (patch_code != lir_patch_none) { | 1048 if (patch_code != lir_patch_none) { |
1020 patch = new PatchingStub(_masm, PatchingStub::access_field_id); | 1049 patch = new PatchingStub(_masm, PatchingStub::access_field_id); |
1021 Address toa = as_Address(to_addr); | 1050 Address toa = as_Address(to_addr); |
1022 assert(toa.disp() != 0, "must have"); | 1051 assert(toa.disp() != 0, "must have"); |
1023 } | 1052 } |
1024 if (info != NULL) { | 1053 |
1025 add_debug_info_for_null_check_here(info); | 1054 int null_check_here = code_offset(); |
1026 } | |
1027 | |
1028 switch (type) { | 1055 switch (type) { |
1029 case T_FLOAT: { | 1056 case T_FLOAT: { |
1030 if (src->is_single_xmm()) { | 1057 if (src->is_single_xmm()) { |
1031 __ movflt(as_Address(to_addr), src->as_xmm_float_reg()); | 1058 __ movflt(as_Address(to_addr), src->as_xmm_float_reg()); |
1032 } else { | 1059 } else { |
1048 else __ fst_d (as_Address(to_addr)); | 1075 else __ fst_d (as_Address(to_addr)); |
1049 } | 1076 } |
1050 break; | 1077 break; |
1051 } | 1078 } |
1052 | 1079 |
1053 case T_ADDRESS: // fall through | |
1054 case T_ARRAY: // fall through | 1080 case T_ARRAY: // fall through |
1055 case T_OBJECT: // fall through | 1081 case T_OBJECT: // fall through |
1056 #ifdef _LP64 | 1082 if (UseCompressedOops && !wide) { |
1083 __ movl(as_Address(to_addr), compressed_src); | |
1084 } else { | |
1085 __ movptr(as_Address(to_addr), src->as_register()); | |
1086 } | |
1087 break; | |
1088 case T_ADDRESS: | |
1057 __ movptr(as_Address(to_addr), src->as_register()); | 1089 __ movptr(as_Address(to_addr), src->as_register()); |
1058 break; | 1090 break; |
1059 #endif // _LP64 | |
1060 case T_INT: | 1091 case T_INT: |
1061 __ movl(as_Address(to_addr), src->as_register()); | 1092 __ movl(as_Address(to_addr), src->as_register()); |
1062 break; | 1093 break; |
1063 | 1094 |
1064 case T_LONG: { | 1095 case T_LONG: { |
1111 break; | 1142 break; |
1112 | 1143 |
1113 default: | 1144 default: |
1114 ShouldNotReachHere(); | 1145 ShouldNotReachHere(); |
1115 } | 1146 } |
1147 if (info != NULL) { | |
1148 add_debug_info_for_null_check(null_check_here, info); | |
1149 } | |
1116 | 1150 |
1117 if (patch_code != lir_patch_none) { | 1151 if (patch_code != lir_patch_none) { |
1118 patching_epilog(patch, patch_code, to_addr->base()->as_register(), info); | 1152 patching_epilog(patch, patch_code, to_addr->base()->as_register(), info); |
1119 } | 1153 } |
1120 } | 1154 } |
1194 ShouldNotReachHere(); | 1228 ShouldNotReachHere(); |
1195 } | 1229 } |
1196 } | 1230 } |
1197 | 1231 |
1198 | 1232 |
1199 void LIR_Assembler::mem2reg(LIR_Opr src, LIR_Opr dest, BasicType type, LIR_PatchCode patch_code, CodeEmitInfo* info, bool /* unaligned */) { | 1233 void LIR_Assembler::mem2reg(LIR_Opr src, LIR_Opr dest, BasicType type, LIR_PatchCode patch_code, CodeEmitInfo* info, bool wide, bool /* unaligned */) { |
1200 assert(src->is_address(), "should not call otherwise"); | 1234 assert(src->is_address(), "should not call otherwise"); |
1201 assert(dest->is_register(), "should not call otherwise"); | 1235 assert(dest->is_register(), "should not call otherwise"); |
1202 | 1236 |
1203 LIR_Address* addr = src->as_address_ptr(); | 1237 LIR_Address* addr = src->as_address_ptr(); |
1204 Address from_addr = as_Address(addr); | 1238 Address from_addr = as_Address(addr); |
1248 __ fld_d(from_addr); | 1282 __ fld_d(from_addr); |
1249 } | 1283 } |
1250 break; | 1284 break; |
1251 } | 1285 } |
1252 | 1286 |
1253 case T_ADDRESS: // fall through | |
1254 case T_OBJECT: // fall through | 1287 case T_OBJECT: // fall through |
1255 case T_ARRAY: // fall through | 1288 case T_ARRAY: // fall through |
1256 #ifdef _LP64 | 1289 if (UseCompressedOops && !wide) { |
1290 __ movl(dest->as_register(), from_addr); | |
1291 } else { | |
1292 __ movptr(dest->as_register(), from_addr); | |
1293 } | |
1294 break; | |
1295 | |
1296 case T_ADDRESS: | |
1257 __ movptr(dest->as_register(), from_addr); | 1297 __ movptr(dest->as_register(), from_addr); |
1258 break; | 1298 break; |
1259 #endif // _L64 | |
1260 case T_INT: | 1299 case T_INT: |
1261 __ movl(dest->as_register(), from_addr); | 1300 __ movl(dest->as_register(), from_addr); |
1262 break; | 1301 break; |
1263 | 1302 |
1264 case T_LONG: { | 1303 case T_LONG: { |
1349 if (patch != NULL) { | 1388 if (patch != NULL) { |
1350 patching_epilog(patch, patch_code, addr->base()->as_register(), info); | 1389 patching_epilog(patch, patch_code, addr->base()->as_register(), info); |
1351 } | 1390 } |
1352 | 1391 |
1353 if (type == T_ARRAY || type == T_OBJECT) { | 1392 if (type == T_ARRAY || type == T_OBJECT) { |
1393 #ifdef _LP64 | |
1394 if (UseCompressedOops && !wide) { | |
1395 __ decode_heap_oop(dest->as_register()); | |
1396 } | |
1397 #endif | |
1354 __ verify_oop(dest->as_register()); | 1398 __ verify_oop(dest->as_register()); |
1355 } | 1399 } |
1356 } | 1400 } |
1357 | 1401 |
1358 | 1402 |
1688 if (obj == k_RInfo) { | 1732 if (obj == k_RInfo) { |
1689 k_RInfo = dst; | 1733 k_RInfo = dst; |
1690 } else if (obj == klass_RInfo) { | 1734 } else if (obj == klass_RInfo) { |
1691 klass_RInfo = dst; | 1735 klass_RInfo = dst; |
1692 } | 1736 } |
1693 if (k->is_loaded()) { | 1737 if (k->is_loaded() && !UseCompressedOops) { |
1694 select_different_registers(obj, dst, k_RInfo, klass_RInfo); | 1738 select_different_registers(obj, dst, k_RInfo, klass_RInfo); |
1695 } else { | 1739 } else { |
1696 Rtmp1 = op->tmp3()->as_register(); | 1740 Rtmp1 = op->tmp3()->as_register(); |
1697 select_different_registers(obj, dst, k_RInfo, klass_RInfo, Rtmp1); | 1741 select_different_registers(obj, dst, k_RInfo, klass_RInfo, Rtmp1); |
1698 } | 1742 } |
1725 __ verify_oop(obj); | 1769 __ verify_oop(obj); |
1726 | 1770 |
1727 if (op->fast_check()) { | 1771 if (op->fast_check()) { |
1728 // get object class | 1772 // get object class |
1729 // not a safepoint as obj null check happens earlier | 1773 // not a safepoint as obj null check happens earlier |
1774 #ifdef _LP64 | |
1775 if (UseCompressedOops) { | |
1776 __ load_klass(Rtmp1, obj); | |
1777 __ cmpptr(k_RInfo, Rtmp1); | |
1778 } else { | |
1779 __ cmpptr(k_RInfo, Address(obj, oopDesc::klass_offset_in_bytes())); | |
1780 } | |
1781 #else | |
1730 if (k->is_loaded()) { | 1782 if (k->is_loaded()) { |
1731 #ifdef _LP64 | 1783 __ cmpoop(Address(obj, oopDesc::klass_offset_in_bytes()), k->constant_encoding()); |
1784 } else { | |
1732 __ cmpptr(k_RInfo, Address(obj, oopDesc::klass_offset_in_bytes())); | 1785 __ cmpptr(k_RInfo, Address(obj, oopDesc::klass_offset_in_bytes())); |
1733 #else | 1786 } |
1734 __ cmpoop(Address(obj, oopDesc::klass_offset_in_bytes()), k->constant_encoding()); | 1787 #endif |
1735 #endif // _LP64 | |
1736 } else { | |
1737 __ cmpptr(k_RInfo, Address(obj, oopDesc::klass_offset_in_bytes())); | |
1738 } | |
1739 __ jcc(Assembler::notEqual, *failure_target); | 1788 __ jcc(Assembler::notEqual, *failure_target); |
1740 // successful cast, fall through to profile or jump | 1789 // successful cast, fall through to profile or jump |
1741 } else { | 1790 } else { |
1742 // get object class | 1791 // get object class |
1743 // not a safepoint as obj null check happens earlier | 1792 // not a safepoint as obj null check happens earlier |
1744 __ movptr(klass_RInfo, Address(obj, oopDesc::klass_offset_in_bytes())); | 1793 __ load_klass(klass_RInfo, obj); |
1745 if (k->is_loaded()) { | 1794 if (k->is_loaded()) { |
1746 // See if we get an immediate positive hit | 1795 // See if we get an immediate positive hit |
1747 #ifdef _LP64 | 1796 #ifdef _LP64 |
1748 __ cmpptr(k_RInfo, Address(klass_RInfo, k->super_check_offset())); | 1797 __ cmpptr(k_RInfo, Address(klass_RInfo, k->super_check_offset())); |
1749 #else | 1798 #else |
1794 } | 1843 } |
1795 if (op->should_profile()) { | 1844 if (op->should_profile()) { |
1796 Register mdo = klass_RInfo, recv = k_RInfo; | 1845 Register mdo = klass_RInfo, recv = k_RInfo; |
1797 __ bind(profile_cast_success); | 1846 __ bind(profile_cast_success); |
1798 __ movoop(mdo, md->constant_encoding()); | 1847 __ movoop(mdo, md->constant_encoding()); |
1799 __ movptr(recv, Address(obj, oopDesc::klass_offset_in_bytes())); | 1848 __ load_klass(recv, obj); |
1800 Label update_done; | 1849 Label update_done; |
1801 type_profile_helper(mdo, md, data, recv, success); | 1850 type_profile_helper(mdo, md, data, recv, success); |
1802 __ jmp(*success); | 1851 __ jmp(*success); |
1803 | 1852 |
1804 __ bind(profile_cast_failure); | 1853 __ bind(profile_cast_failure); |
1858 } else { | 1907 } else { |
1859 __ jcc(Assembler::equal, done); | 1908 __ jcc(Assembler::equal, done); |
1860 } | 1909 } |
1861 | 1910 |
1862 add_debug_info_for_null_check_here(op->info_for_exception()); | 1911 add_debug_info_for_null_check_here(op->info_for_exception()); |
1863 __ movptr(k_RInfo, Address(array, oopDesc::klass_offset_in_bytes())); | 1912 __ load_klass(k_RInfo, array); |
1864 __ movptr(klass_RInfo, Address(value, oopDesc::klass_offset_in_bytes())); | 1913 __ load_klass(klass_RInfo, value); |
1865 | 1914 |
1866 // get instance klass | 1915 // get instance klass (it's already uncompressed) |
1867 __ movptr(k_RInfo, Address(k_RInfo, objArrayKlass::element_klass_offset_in_bytes() + sizeof(oopDesc))); | 1916 __ movptr(k_RInfo, Address(k_RInfo, objArrayKlass::element_klass_offset_in_bytes() + sizeof(oopDesc))); |
1868 // perform the fast part of the checking logic | 1917 // perform the fast part of the checking logic |
1869 __ check_klass_subtype_fast_path(klass_RInfo, k_RInfo, Rtmp1, success_target, failure_target, NULL); | 1918 __ check_klass_subtype_fast_path(klass_RInfo, k_RInfo, Rtmp1, success_target, failure_target, NULL); |
1870 // call out-of-line instance of __ check_klass_subtype_slow_path(...): | 1919 // call out-of-line instance of __ check_klass_subtype_slow_path(...): |
1871 __ push(klass_RInfo); | 1920 __ push(klass_RInfo); |
1880 | 1929 |
1881 if (op->should_profile()) { | 1930 if (op->should_profile()) { |
1882 Register mdo = klass_RInfo, recv = k_RInfo; | 1931 Register mdo = klass_RInfo, recv = k_RInfo; |
1883 __ bind(profile_cast_success); | 1932 __ bind(profile_cast_success); |
1884 __ movoop(mdo, md->constant_encoding()); | 1933 __ movoop(mdo, md->constant_encoding()); |
1885 __ movptr(recv, Address(value, oopDesc::klass_offset_in_bytes())); | 1934 __ load_klass(recv, value); |
1886 Label update_done; | 1935 Label update_done; |
1887 type_profile_helper(mdo, md, data, recv, &done); | 1936 type_profile_helper(mdo, md, data, recv, &done); |
1888 __ jmpb(done); | 1937 __ jmpb(done); |
1889 | 1938 |
1890 __ bind(profile_cast_failure); | 1939 __ bind(profile_cast_failure); |
1944 assert(cmpval == rax, "wrong register"); | 1993 assert(cmpval == rax, "wrong register"); |
1945 assert(newval != NULL, "new val must be register"); | 1994 assert(newval != NULL, "new val must be register"); |
1946 assert(cmpval != newval, "cmp and new values must be in different registers"); | 1995 assert(cmpval != newval, "cmp and new values must be in different registers"); |
1947 assert(cmpval != addr, "cmp and addr must be in different registers"); | 1996 assert(cmpval != addr, "cmp and addr must be in different registers"); |
1948 assert(newval != addr, "new value and addr must be in different registers"); | 1997 assert(newval != addr, "new value and addr must be in different registers"); |
1949 if (os::is_MP()) { | 1998 |
1950 __ lock(); | |
1951 } | |
1952 if ( op->code() == lir_cas_obj) { | 1999 if ( op->code() == lir_cas_obj) { |
1953 __ cmpxchgptr(newval, Address(addr, 0)); | 2000 #ifdef _LP64 |
1954 } else if (op->code() == lir_cas_int) { | 2001 if (UseCompressedOops) { |
2002 __ mov(rscratch1, cmpval); | |
2003 __ encode_heap_oop(cmpval); | |
2004 __ mov(rscratch2, newval); | |
2005 __ encode_heap_oop(rscratch2); | |
2006 if (os::is_MP()) { | |
2007 __ lock(); | |
2008 } | |
2009 __ cmpxchgl(rscratch2, Address(addr, 0)); | |
2010 __ mov(cmpval, rscratch1); | |
2011 } else | |
2012 #endif | |
2013 { | |
2014 if (os::is_MP()) { | |
2015 __ lock(); | |
2016 } | |
2017 __ cmpxchgptr(newval, Address(addr, 0)); | |
2018 } | |
2019 } else { | |
2020 assert(op->code() == lir_cas_int, "lir_cas_int expected"); | |
2021 if (os::is_MP()) { | |
2022 __ lock(); | |
2023 } | |
1955 __ cmpxchgl(newval, Address(addr, 0)); | 2024 __ cmpxchgl(newval, Address(addr, 0)); |
1956 } | 2025 } |
1957 #ifdef _LP64 | 2026 #ifdef _LP64 |
1958 } else if (op->code() == lir_cas_long) { | 2027 } else if (op->code() == lir_cas_long) { |
1959 Register addr = (op->addr()->is_single_cpu() ? op->addr()->as_register() : op->addr()->as_register_lo()); | 2028 Register addr = (op->addr()->is_single_cpu() ? op->addr()->as_register() : op->addr()->as_register_lo()); |
3191 __ cmpl(tmp, dst_length_addr); | 3260 __ cmpl(tmp, dst_length_addr); |
3192 __ jcc(Assembler::above, *stub->entry()); | 3261 __ jcc(Assembler::above, *stub->entry()); |
3193 } | 3262 } |
3194 | 3263 |
3195 if (flags & LIR_OpArrayCopy::type_check) { | 3264 if (flags & LIR_OpArrayCopy::type_check) { |
3196 __ movptr(tmp, src_klass_addr); | 3265 if (UseCompressedOops) { |
3197 __ cmpptr(tmp, dst_klass_addr); | 3266 __ movl(tmp, src_klass_addr); |
3267 __ cmpl(tmp, dst_klass_addr); | |
3268 } else { | |
3269 __ movptr(tmp, src_klass_addr); | |
3270 __ cmpptr(tmp, dst_klass_addr); | |
3271 } | |
3198 __ jcc(Assembler::notEqual, *stub->entry()); | 3272 __ jcc(Assembler::notEqual, *stub->entry()); |
3199 } | 3273 } |
3200 | 3274 |
3201 #ifdef ASSERT | 3275 #ifdef ASSERT |
3202 if (basic_type != T_OBJECT || !(flags & LIR_OpArrayCopy::type_check)) { | 3276 if (basic_type != T_OBJECT || !(flags & LIR_OpArrayCopy::type_check)) { |
3207 // dst type is exactly the expected type and the src type is a | 3281 // dst type is exactly the expected type and the src type is a |
3208 // subtype which we can't check or src is the same array as dst | 3282 // subtype which we can't check or src is the same array as dst |
3209 // but not necessarily exactly of type default_type. | 3283 // but not necessarily exactly of type default_type. |
3210 Label known_ok, halt; | 3284 Label known_ok, halt; |
3211 __ movoop(tmp, default_type->constant_encoding()); | 3285 __ movoop(tmp, default_type->constant_encoding()); |
3286 #ifdef _LP64 | |
3287 if (UseCompressedOops) { | |
3288 __ encode_heap_oop(tmp); | |
3289 } | |
3290 #endif | |
3291 | |
3212 if (basic_type != T_OBJECT) { | 3292 if (basic_type != T_OBJECT) { |
3213 __ cmpptr(tmp, dst_klass_addr); | 3293 |
3294 if (UseCompressedOops) __ cmpl(tmp, dst_klass_addr); | |
3295 else __ cmpptr(tmp, dst_klass_addr); | |
3214 __ jcc(Assembler::notEqual, halt); | 3296 __ jcc(Assembler::notEqual, halt); |
3215 __ cmpptr(tmp, src_klass_addr); | 3297 if (UseCompressedOops) __ cmpl(tmp, src_klass_addr); |
3298 else __ cmpptr(tmp, src_klass_addr); | |
3216 __ jcc(Assembler::equal, known_ok); | 3299 __ jcc(Assembler::equal, known_ok); |
3217 } else { | 3300 } else { |
3218 __ cmpptr(tmp, dst_klass_addr); | 3301 if (UseCompressedOops) __ cmpl(tmp, dst_klass_addr); |
3302 else __ cmpptr(tmp, dst_klass_addr); | |
3219 __ jcc(Assembler::equal, known_ok); | 3303 __ jcc(Assembler::equal, known_ok); |
3220 __ cmpptr(src, dst); | 3304 __ cmpptr(src, dst); |
3221 __ jcc(Assembler::equal, known_ok); | 3305 __ jcc(Assembler::equal, known_ok); |
3222 } | 3306 } |
3223 __ bind(halt); | 3307 __ bind(halt); |
3342 __ addptr(data_addr, DataLayout::counter_increment); | 3426 __ addptr(data_addr, DataLayout::counter_increment); |
3343 return; | 3427 return; |
3344 } | 3428 } |
3345 } | 3429 } |
3346 } else { | 3430 } else { |
3347 __ movptr(recv, Address(recv, oopDesc::klass_offset_in_bytes())); | 3431 __ load_klass(recv, recv); |
3348 Label update_done; | 3432 Label update_done; |
3349 type_profile_helper(mdo, md, data, recv, &update_done); | 3433 type_profile_helper(mdo, md, data, recv, &update_done); |
3350 // Receiver did not match any saved receiver and there is no empty row for it. | 3434 // Receiver did not match any saved receiver and there is no empty row for it. |
3351 // Increment total counter to indicate polymorphic case. | 3435 // Increment total counter to indicate polymorphic case. |
3352 __ addptr(counter_addr, DataLayout::counter_increment); | 3436 __ addptr(counter_addr, DataLayout::counter_increment); |