src/cpu/x86/vm/stubGenerator_x86_32.cpp
Index Unified diffs Context diffs Sdiffs Patch New Old Previous File Next File 7118863 Sdiff src/cpu/x86/vm

src/cpu/x86/vm/stubGenerator_x86_32.cpp

Print this page




1357   // The sub_klass must be one of {rbx, rdx, rsi}.
1358   // The temp is killed.
1359   void generate_type_check(Register sub_klass,
1360                            Address& super_check_offset_addr,
1361                            Address& super_klass_addr,
1362                            Register temp,
1363                            Label* L_success, Label* L_failure) {
1364     BLOCK_COMMENT("type_check:");
1365 
1366     Label L_fallthrough;
1367 #define LOCAL_JCC(assembler_con, label_ptr)                             \
1368     if (label_ptr != NULL)  __ jcc(assembler_con, *(label_ptr));        \
1369     else                    __ jcc(assembler_con, L_fallthrough) /*omit semi*/
1370 
1371     // The following is a strange variation of the fast path which requires
1372     // one less register, because needed values are on the argument stack.
1373     // __ check_klass_subtype_fast_path(sub_klass, *super_klass*, temp,
1374     //                                  L_success, L_failure, NULL);
1375     assert_different_registers(sub_klass, temp);
1376 
1377     int sc_offset = (klassOopDesc::header_size() * HeapWordSize +
1378                      Klass::secondary_super_cache_offset_in_bytes());
1379 
1380     // if the pointers are equal, we are done (e.g., String[] elements)
1381     __ cmpptr(sub_klass, super_klass_addr);
1382     LOCAL_JCC(Assembler::equal, L_success);
1383 
1384     // check the supertype display:
1385     __ movl2ptr(temp, super_check_offset_addr);
1386     Address super_check_addr(sub_klass, temp, Address::times_1, 0);
1387     __ movptr(temp, super_check_addr); // load displayed supertype
1388     __ cmpptr(temp, super_klass_addr); // test the super type
1389     LOCAL_JCC(Assembler::equal, L_success);
1390 
1391     // if it was a primary super, we can just fail immediately
1392     __ cmpl(super_check_offset_addr, sc_offset);
1393     LOCAL_JCC(Assembler::notEqual, L_failure);
1394 
1395     // The repne_scan instruction uses fixed registers, which will get spilled.
1396     // We happen to know this works best when super_klass is in rax.
1397     Register super_klass = temp;
1398     __ movptr(super_klass, super_klass_addr);


1770     { Label L1, L2;
1771       __ testptr(rcx_src_klass, rcx_src_klass);
1772       __ jccb(Assembler::notZero, L2);   // it is broken if klass is NULL
1773       __ bind(L1);
1774       __ stop("broken null klass");
1775       __ bind(L2);
1776       __ cmpptr(dst_klass_addr, (int32_t)NULL_WORD);
1777       __ jccb(Assembler::equal, L1);      // this would be broken also
1778       BLOCK_COMMENT("assert done");
1779     }
1780 #endif //ASSERT
1781 
1782     // Load layout helper (32-bits)
1783     //
1784     //  |array_tag|     | header_size | element_type |     |log2_element_size|
1785     // 32        30    24            16              8     2                 0
1786     //
1787     //   array_tag: typeArray = 0x3, objArray = 0x2, non-array = 0x0
1788     //
1789 
1790     int lh_offset = klassOopDesc::header_size() * HeapWordSize +
1791                     Klass::layout_helper_offset_in_bytes();
1792     Address src_klass_lh_addr(rcx_src_klass, lh_offset);
1793 
1794     // Handle objArrays completely differently...
1795     jint objArray_lh = Klass::array_layout_helper(T_OBJECT);
1796     __ cmpl(src_klass_lh_addr, objArray_lh);
1797     __ jcc(Assembler::equal, L_objArray);
1798 
1799     //  if (src->klass() != dst->klass()) return -1;
1800     __ cmpptr(rcx_src_klass, dst_klass_addr);
1801     __ jccb(Assembler::notEqual, L_failed_0);
1802 
1803     const Register rcx_lh = rcx;  // layout helper
1804     assert(rcx_lh == rcx_src_klass, "known alias");
1805     __ movl(rcx_lh, src_klass_lh_addr);
1806 
1807     //  if (!src->is_Array()) return -1;
1808     __ cmpl(rcx_lh, Klass::_lh_neutral_value);
1809     __ jcc(Assembler::greaterEqual, L_failed_0); // signed cmp
1810 
1811     // At this point, it is known to be a typeArray (array_tag 0x3).


1897     assert_different_registers(src, src_pos, dst, dst_pos, rcx_src_klass);
1898     arraycopy_range_checks(src, src_pos, dst, dst_pos, LENGTH, L_failed);
1899 
1900   __ BIND(L_plain_copy);
1901     __ movl2ptr(count, LENGTH); // elements count
1902     __ movl2ptr(src_pos, SRC_POS);  // reload src_pos
1903     __ lea(from, Address(src, src_pos, Address::times_ptr,
1904                  arrayOopDesc::base_offset_in_bytes(T_OBJECT))); // src_addr
1905     __ movl2ptr(dst_pos, DST_POS);  // reload dst_pos
1906     __ lea(to,   Address(dst, dst_pos, Address::times_ptr,
1907                  arrayOopDesc::base_offset_in_bytes(T_OBJECT))); // dst_addr
1908     __ movptr(FROM,  from);   // src_addr
1909     __ movptr(TO,    to);     // dst_addr
1910     __ movl(COUNT, count);  // count
1911     __ jump(RuntimeAddress(entry_oop_arraycopy));
1912 
1913   __ BIND(L_checkcast_copy);
1914     // live at this point:  rcx_src_klass, dst[_pos], src[_pos]
1915     {
1916       // Handy offsets:
1917       int  ek_offset = (klassOopDesc::header_size() * HeapWordSize +
1918                         objArrayKlass::element_klass_offset_in_bytes());
1919       int sco_offset = (klassOopDesc::header_size() * HeapWordSize +
1920                         Klass::super_check_offset_offset_in_bytes());
1921 
1922       Register rsi_dst_klass = rsi;
1923       Register rdi_temp      = rdi;
1924       assert(rsi_dst_klass == src_pos, "expected alias w/ src_pos");
1925       assert(rdi_temp      == dst_pos, "expected alias w/ dst_pos");
1926       Address dst_klass_lh_addr(rsi_dst_klass, lh_offset);
1927 
1928       // Before looking at dst.length, make sure dst is also an objArray.
1929       __ movptr(rsi_dst_klass, dst_klass_addr);
1930       __ cmpl(dst_klass_lh_addr, objArray_lh);
1931       __ jccb(Assembler::notEqual, L_failed);
1932 
1933       // It is safe to examine both src.length and dst.length.
1934       __ movl2ptr(src_pos, SRC_POS);        // reload rsi
1935       arraycopy_range_checks(src, src_pos, dst, dst_pos, LENGTH, L_failed);
1936       // (Now src_pos and dst_pos are killed, but not src and dst.)
1937 
1938       // We'll need this temp (don't forget to pop it after the type check).
1939       __ push(rbx);
1940       Register rbx_src_klass = rbx;




1357   // The sub_klass must be one of {rbx, rdx, rsi}.
1358   // The temp is killed.
1359   void generate_type_check(Register sub_klass,
1360                            Address& super_check_offset_addr,
1361                            Address& super_klass_addr,
1362                            Register temp,
1363                            Label* L_success, Label* L_failure) {
1364     BLOCK_COMMENT("type_check:");
1365 
1366     Label L_fallthrough;
1367 #define LOCAL_JCC(assembler_con, label_ptr)                             \
1368     if (label_ptr != NULL)  __ jcc(assembler_con, *(label_ptr));        \
1369     else                    __ jcc(assembler_con, L_fallthrough) /*omit semi*/
1370 
1371     // The following is a strange variation of the fast path which requires
1372     // one less register, because needed values are on the argument stack.
1373     // __ check_klass_subtype_fast_path(sub_klass, *super_klass*, temp,
1374     //                                  L_success, L_failure, NULL);
1375     assert_different_registers(sub_klass, temp);
1376 
1377     int sc_offset = Klass::secondary_super_cache_offset_in_bytes();

1378 
1379     // if the pointers are equal, we are done (e.g., String[] elements)
1380     __ cmpptr(sub_klass, super_klass_addr);
1381     LOCAL_JCC(Assembler::equal, L_success);
1382 
1383     // check the supertype display:
1384     __ movl2ptr(temp, super_check_offset_addr);
1385     Address super_check_addr(sub_klass, temp, Address::times_1, 0);
1386     __ movptr(temp, super_check_addr); // load displayed supertype
1387     __ cmpptr(temp, super_klass_addr); // test the super type
1388     LOCAL_JCC(Assembler::equal, L_success);
1389 
1390     // if it was a primary super, we can just fail immediately
1391     __ cmpl(super_check_offset_addr, sc_offset);
1392     LOCAL_JCC(Assembler::notEqual, L_failure);
1393 
1394     // The repne_scan instruction uses fixed registers, which will get spilled.
1395     // We happen to know this works best when super_klass is in rax.
1396     Register super_klass = temp;
1397     __ movptr(super_klass, super_klass_addr);


1769     { Label L1, L2;
1770       __ testptr(rcx_src_klass, rcx_src_klass);
1771       __ jccb(Assembler::notZero, L2);   // it is broken if klass is NULL
1772       __ bind(L1);
1773       __ stop("broken null klass");
1774       __ bind(L2);
1775       __ cmpptr(dst_klass_addr, (int32_t)NULL_WORD);
1776       __ jccb(Assembler::equal, L1);      // this would be broken also
1777       BLOCK_COMMENT("assert done");
1778     }
1779 #endif //ASSERT
1780 
1781     // Load layout helper (32-bits)
1782     //
1783     //  |array_tag|     | header_size | element_type |     |log2_element_size|
1784     // 32        30    24            16              8     2                 0
1785     //
1786     //   array_tag: typeArray = 0x3, objArray = 0x2, non-array = 0x0
1787     //
1788 
1789     int lh_offset = Klass::layout_helper_offset_in_bytes();

1790     Address src_klass_lh_addr(rcx_src_klass, lh_offset);
1791 
1792     // Handle objArrays completely differently...
1793     jint objArray_lh = Klass::array_layout_helper(T_OBJECT);
1794     __ cmpl(src_klass_lh_addr, objArray_lh);
1795     __ jcc(Assembler::equal, L_objArray);
1796 
1797     //  if (src->klass() != dst->klass()) return -1;
1798     __ cmpptr(rcx_src_klass, dst_klass_addr);
1799     __ jccb(Assembler::notEqual, L_failed_0);
1800 
1801     const Register rcx_lh = rcx;  // layout helper
1802     assert(rcx_lh == rcx_src_klass, "known alias");
1803     __ movl(rcx_lh, src_klass_lh_addr);
1804 
1805     //  if (!src->is_Array()) return -1;
1806     __ cmpl(rcx_lh, Klass::_lh_neutral_value);
1807     __ jcc(Assembler::greaterEqual, L_failed_0); // signed cmp
1808 
1809     // At this point, it is known to be a typeArray (array_tag 0x3).


1895     assert_different_registers(src, src_pos, dst, dst_pos, rcx_src_klass);
1896     arraycopy_range_checks(src, src_pos, dst, dst_pos, LENGTH, L_failed);
1897 
1898   __ BIND(L_plain_copy);
1899     __ movl2ptr(count, LENGTH); // elements count
1900     __ movl2ptr(src_pos, SRC_POS);  // reload src_pos
1901     __ lea(from, Address(src, src_pos, Address::times_ptr,
1902                  arrayOopDesc::base_offset_in_bytes(T_OBJECT))); // src_addr
1903     __ movl2ptr(dst_pos, DST_POS);  // reload dst_pos
1904     __ lea(to,   Address(dst, dst_pos, Address::times_ptr,
1905                  arrayOopDesc::base_offset_in_bytes(T_OBJECT))); // dst_addr
1906     __ movptr(FROM,  from);   // src_addr
1907     __ movptr(TO,    to);     // dst_addr
1908     __ movl(COUNT, count);  // count
1909     __ jump(RuntimeAddress(entry_oop_arraycopy));
1910 
1911   __ BIND(L_checkcast_copy);
1912     // live at this point:  rcx_src_klass, dst[_pos], src[_pos]
1913     {
1914       // Handy offsets:
1915       int  ek_offset = objArrayKlass::element_klass_offset_in_bytes();
1916       int sco_offset = Klass::super_check_offset_offset_in_bytes();


1917 
1918       Register rsi_dst_klass = rsi;
1919       Register rdi_temp      = rdi;
1920       assert(rsi_dst_klass == src_pos, "expected alias w/ src_pos");
1921       assert(rdi_temp      == dst_pos, "expected alias w/ dst_pos");
1922       Address dst_klass_lh_addr(rsi_dst_klass, lh_offset);
1923 
1924       // Before looking at dst.length, make sure dst is also an objArray.
1925       __ movptr(rsi_dst_klass, dst_klass_addr);
1926       __ cmpl(dst_klass_lh_addr, objArray_lh);
1927       __ jccb(Assembler::notEqual, L_failed);
1928 
1929       // It is safe to examine both src.length and dst.length.
1930       __ movl2ptr(src_pos, SRC_POS);        // reload rsi
1931       arraycopy_range_checks(src, src_pos, dst, dst_pos, LENGTH, L_failed);
1932       // (Now src_pos and dst_pos are killed, but not src and dst.)
1933 
1934       // We'll need this temp (don't forget to pop it after the type check).
1935       __ push(rbx);
1936       Register rbx_src_klass = rbx;


src/cpu/x86/vm/stubGenerator_x86_32.cpp
Index Unified diffs Context diffs Sdiffs Patch New Old Previous File Next File