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