< prev index next >

src/hotspot/cpu/x86/stubGenerator_x86_64_arraycopy.cpp

Print this page

2354   // 32        30    24            16              8     2                 0
2355   //
2356   //   array_tag: typeArray = 0x3, objArray = 0x2, non-array = 0x0
2357   //
2358 
2359   const int lh_offset = in_bytes(Klass::layout_helper_offset());
2360 
2361   // Handle objArrays completely differently...
2362   const jint objArray_lh = Klass::array_layout_helper(T_OBJECT);
2363   __ cmpl(Address(r10_src_klass, lh_offset), objArray_lh);
2364   __ jcc(Assembler::equal, L_objArray);
2365 
2366   //  if (src->klass() != dst->klass()) return -1;
2367   __ load_klass(rax, dst, rklass_tmp);
2368   __ cmpq(r10_src_klass, rax);
2369   __ jcc(Assembler::notEqual, L_failed);
2370 
2371   const Register rax_lh = rax;  // layout helper
2372   __ movl(rax_lh, Address(r10_src_klass, lh_offset));
2373 








2374   //  if (!src->is_Array()) return -1;
2375   __ cmpl(rax_lh, Klass::_lh_neutral_value);
2376   __ jcc(Assembler::greaterEqual, L_failed);
2377 
2378   // At this point, it is known to be a typeArray (array_tag 0x3).
2379 #ifdef ASSERT
2380   {
2381     BLOCK_COMMENT("assert primitive array {");
2382     Label L;
2383     __ cmpl(rax_lh, (Klass::_lh_array_tag_type_value << Klass::_lh_array_tag_shift));
2384     __ jcc(Assembler::greaterEqual, L);


2385     __ stop("must be a primitive array");
2386     __ bind(L);
2387     BLOCK_COMMENT("} assert primitive array done");
2388   }
2389 #endif
2390 
2391   arraycopy_range_checks(src, src_pos, dst, dst_pos, r11_length,
2392                          r10, L_failed);
2393 
2394   // TypeArrayKlass
2395   //
2396   // src_addr = (src + array_header_in_bytes()) + (src_pos << log2elemsize);
2397   // dst_addr = (dst + array_header_in_bytes()) + (dst_pos << log2elemsize);
2398   //
2399 
2400   const Register r10_offset = r10;    // array offset
2401   const Register rax_elsize = rax_lh; // element size
2402 
2403   __ movl(r10_offset, rax_lh);
2404   __ shrl(r10_offset, Klass::_lh_header_size_shift);

2472 
2473   // Identically typed arrays can be copied without element-wise checks.
2474   arraycopy_range_checks(src, src_pos, dst, dst_pos, r11_length,
2475                          r10, L_failed);
2476 
2477   __ lea(from, Address(src, src_pos, TIMES_OOP,
2478                arrayOopDesc::base_offset_in_bytes(T_OBJECT))); // src_addr
2479   __ lea(to,   Address(dst, dst_pos, TIMES_OOP,
2480                arrayOopDesc::base_offset_in_bytes(T_OBJECT))); // dst_addr
2481   __ movl2ptr(count, r11_length); // length
2482 __ BIND(L_plain_copy);
2483 #ifdef _WIN64
2484   __ pop(rklass_tmp); // Restore callee-save rdi
2485 #endif
2486   __ jump(RuntimeAddress(oop_copy_entry));
2487 
2488 __ BIND(L_checkcast_copy);
2489   // live at this point:  r10_src_klass, r11_length, rax (dst_klass)
2490   {
2491     // Before looking at dst.length, make sure dst is also an objArray.

2492     __ cmpl(Address(rax, lh_offset), objArray_lh);
2493     __ jcc(Assembler::notEqual, L_failed);
2494 













2495     // It is safe to examine both src.length and dst.length.
2496     arraycopy_range_checks(src, src_pos, dst, dst_pos, r11_length,
2497                            rax, L_failed);
2498 
2499     const Register r11_dst_klass = r11;
2500     __ load_klass(r11_dst_klass, dst, rklass_tmp); // reload
2501 
2502     // Marshal the base address arguments now, freeing registers.
2503     __ lea(from, Address(src, src_pos, TIMES_OOP,
2504                  arrayOopDesc::base_offset_in_bytes(T_OBJECT)));
2505     __ lea(to,   Address(dst, dst_pos, TIMES_OOP,
2506                  arrayOopDesc::base_offset_in_bytes(T_OBJECT)));
2507     __ movl(count, length);           // length (reloaded)
2508     Register sco_temp = c_rarg3;      // this register is free now
2509     assert_different_registers(from, to, count, sco_temp,
2510                                r11_dst_klass, r10_src_klass);
2511     assert_clean_int(count, sco_temp);
2512 
2513     // Generate the type check.
2514     const int sco_offset = in_bytes(Klass::super_check_offset_offset());

2354   // 32        30    24            16              8     2                 0
2355   //
2356   //   array_tag: typeArray = 0x3, objArray = 0x2, non-array = 0x0
2357   //
2358 
2359   const int lh_offset = in_bytes(Klass::layout_helper_offset());
2360 
2361   // Handle objArrays completely differently...
2362   const jint objArray_lh = Klass::array_layout_helper(T_OBJECT);
2363   __ cmpl(Address(r10_src_klass, lh_offset), objArray_lh);
2364   __ jcc(Assembler::equal, L_objArray);
2365 
2366   //  if (src->klass() != dst->klass()) return -1;
2367   __ load_klass(rax, dst, rklass_tmp);
2368   __ cmpq(r10_src_klass, rax);
2369   __ jcc(Assembler::notEqual, L_failed);
2370 
2371   const Register rax_lh = rax;  // layout helper
2372   __ movl(rax_lh, Address(r10_src_klass, lh_offset));
2373 
2374   // Check for flat inline type array -> return -1
2375   __ testl(rax_lh, Klass::_lh_array_tag_flat_value_bit_inplace);
2376   __ jcc(Assembler::notZero, L_failed);
2377 
2378   // Check for null-free (non-flat) inline type array -> handle as object array
2379   __ testl(rax_lh, Klass::_lh_null_free_array_bit_inplace);
2380   __ jcc(Assembler::notZero, L_objArray);
2381 
2382   //  if (!src->is_Array()) return -1;
2383   __ cmpl(rax_lh, Klass::_lh_neutral_value);
2384   __ jcc(Assembler::greaterEqual, L_failed);
2385 
2386   // At this point, it is known to be a typeArray (array_tag 0x3).
2387 #ifdef ASSERT
2388   {
2389     BLOCK_COMMENT("assert primitive array {");
2390     Label L;
2391     __ movl(rklass_tmp, rax_lh);
2392     __ sarl(rklass_tmp, Klass::_lh_array_tag_shift);
2393     __ cmpl(rklass_tmp, Klass::_lh_array_tag_type_value);
2394     __ jcc(Assembler::equal, L);
2395     __ stop("must be a primitive array");
2396     __ bind(L);
2397     BLOCK_COMMENT("} assert primitive array done");
2398   }
2399 #endif
2400 
2401   arraycopy_range_checks(src, src_pos, dst, dst_pos, r11_length,
2402                          r10, L_failed);
2403 
2404   // TypeArrayKlass
2405   //
2406   // src_addr = (src + array_header_in_bytes()) + (src_pos << log2elemsize);
2407   // dst_addr = (dst + array_header_in_bytes()) + (dst_pos << log2elemsize);
2408   //
2409 
2410   const Register r10_offset = r10;    // array offset
2411   const Register rax_elsize = rax_lh; // element size
2412 
2413   __ movl(r10_offset, rax_lh);
2414   __ shrl(r10_offset, Klass::_lh_header_size_shift);

2482 
2483   // Identically typed arrays can be copied without element-wise checks.
2484   arraycopy_range_checks(src, src_pos, dst, dst_pos, r11_length,
2485                          r10, L_failed);
2486 
2487   __ lea(from, Address(src, src_pos, TIMES_OOP,
2488                arrayOopDesc::base_offset_in_bytes(T_OBJECT))); // src_addr
2489   __ lea(to,   Address(dst, dst_pos, TIMES_OOP,
2490                arrayOopDesc::base_offset_in_bytes(T_OBJECT))); // dst_addr
2491   __ movl2ptr(count, r11_length); // length
2492 __ BIND(L_plain_copy);
2493 #ifdef _WIN64
2494   __ pop(rklass_tmp); // Restore callee-save rdi
2495 #endif
2496   __ jump(RuntimeAddress(oop_copy_entry));
2497 
2498 __ BIND(L_checkcast_copy);
2499   // live at this point:  r10_src_klass, r11_length, rax (dst_klass)
2500   {
2501     // Before looking at dst.length, make sure dst is also an objArray.
2502     // This check also fails for flat/null-free arrays which are not supported.
2503     __ cmpl(Address(rax, lh_offset), objArray_lh);
2504     __ jcc(Assembler::notEqual, L_failed);
2505 
2506 #ifdef ASSERT
2507     {
2508       BLOCK_COMMENT("assert not null-free array {");
2509       Label L;
2510       __ movl(rklass_tmp, Address(rax, lh_offset));
2511       __ testl(rklass_tmp, Klass::_lh_null_free_array_bit_inplace);
2512       __ jcc(Assembler::zero, L);
2513       __ stop("unexpected null-free array");
2514       __ bind(L);
2515       BLOCK_COMMENT("} assert not null-free array");
2516     }
2517 #endif
2518 
2519     // It is safe to examine both src.length and dst.length.
2520     arraycopy_range_checks(src, src_pos, dst, dst_pos, r11_length,
2521                            rax, L_failed);
2522 
2523     const Register r11_dst_klass = r11;
2524     __ load_klass(r11_dst_klass, dst, rklass_tmp); // reload
2525 
2526     // Marshal the base address arguments now, freeing registers.
2527     __ lea(from, Address(src, src_pos, TIMES_OOP,
2528                  arrayOopDesc::base_offset_in_bytes(T_OBJECT)));
2529     __ lea(to,   Address(dst, dst_pos, TIMES_OOP,
2530                  arrayOopDesc::base_offset_in_bytes(T_OBJECT)));
2531     __ movl(count, length);           // length (reloaded)
2532     Register sco_temp = c_rarg3;      // this register is free now
2533     assert_different_registers(from, to, count, sco_temp,
2534                                r11_dst_klass, r10_src_klass);
2535     assert_clean_int(count, sco_temp);
2536 
2537     // Generate the type check.
2538     const int sco_offset = in_bytes(Klass::super_check_offset_offset());
< prev index next >