2244
2245 // allocate spill slots for r13, r14
2246 enum {
2247 saved_r13_offset,
2248 saved_r14_offset,
2249 saved_rbp_offset
2250 };
2251 __ subptr(rsp, saved_rbp_offset * wordSize);
2252 __ movptr(Address(rsp, saved_r13_offset * wordSize), r13);
2253 __ movptr(Address(rsp, saved_r14_offset * wordSize), r14);
2254
2255 // check that int operands are properly extended to size_t
2256 assert_clean_int(length, rax);
2257 assert_clean_int(ckoff, rax);
2258
2259 #ifdef ASSERT
2260 BLOCK_COMMENT("assert consistent ckoff/ckval");
2261 // The ckoff and ckval must be mutually consistent,
2262 // even though caller generates both.
2263 { Label L;
2264 int sco_offset = (klassOopDesc::header_size() * HeapWordSize +
2265 Klass::super_check_offset_offset_in_bytes());
2266 __ cmpl(ckoff, Address(ckval, sco_offset));
2267 __ jcc(Assembler::equal, L);
2268 __ stop("super_check_offset inconsistent");
2269 __ bind(L);
2270 }
2271 #endif //ASSERT
2272
2273 // Loop-invariant addresses. They are exclusive end pointers.
2274 Address end_from_addr(from, length, TIMES_OOP, 0);
2275 Address end_to_addr(to, length, TIMES_OOP, 0);
2276 // Loop-variant addresses. They assume post-incremented count < 0.
2277 Address from_element_addr(end_from, count, TIMES_OOP, 0);
2278 Address to_element_addr(end_to, count, TIMES_OOP, 0);
2279
2280 gen_write_ref_array_pre_barrier(to, count, dest_uninitialized);
2281
2282 // Copy from low to high addresses, indexed from the end of each array.
2283 __ lea(end_from, end_from_addr);
2284 __ lea(end_to, end_to_addr);
2285 __ movptr(r14_length, length); // save a copy of the length
2555 __ testptr(r10_src_klass, r10_src_klass);
2556 __ jcc(Assembler::notZero, L2); // it is broken if klass is NULL
2557 __ bind(L1);
2558 __ stop("broken null klass");
2559 __ bind(L2);
2560 __ load_klass(rax, dst);
2561 __ cmpq(rax, 0);
2562 __ jcc(Assembler::equal, L1); // this would be broken also
2563 BLOCK_COMMENT("} assert klasses not null done");
2564 }
2565 #endif
2566
2567 // Load layout helper (32-bits)
2568 //
2569 // |array_tag| | header_size | element_type | |log2_element_size|
2570 // 32 30 24 16 8 2 0
2571 //
2572 // array_tag: typeArray = 0x3, objArray = 0x2, non-array = 0x0
2573 //
2574
2575 const int lh_offset = klassOopDesc::header_size() * HeapWordSize +
2576 Klass::layout_helper_offset_in_bytes();
2577
2578 // Handle objArrays completely differently...
2579 const jint objArray_lh = Klass::array_layout_helper(T_OBJECT);
2580 __ cmpl(Address(r10_src_klass, lh_offset), objArray_lh);
2581 __ jcc(Assembler::equal, L_objArray);
2582
2583 // if (src->klass() != dst->klass()) return -1;
2584 __ load_klass(rax, dst);
2585 __ cmpq(r10_src_klass, rax);
2586 __ jcc(Assembler::notEqual, L_failed);
2587
2588 const Register rax_lh = rax; // layout helper
2589 __ movl(rax_lh, Address(r10_src_klass, lh_offset));
2590
2591 // if (!src->is_Array()) return -1;
2592 __ cmpl(rax_lh, Klass::_lh_neutral_value);
2593 __ jcc(Assembler::greaterEqual, L_failed);
2594
2595 // At this point, it is known to be a typeArray (array_tag 0x3).
2596 #ifdef ASSERT
2705
2706 // It is safe to examine both src.length and dst.length.
2707 arraycopy_range_checks(src, src_pos, dst, dst_pos, r11_length,
2708 rax, L_failed);
2709
2710 const Register r11_dst_klass = r11;
2711 __ load_klass(r11_dst_klass, dst); // reload
2712
2713 // Marshal the base address arguments now, freeing registers.
2714 __ lea(from, Address(src, src_pos, TIMES_OOP,
2715 arrayOopDesc::base_offset_in_bytes(T_OBJECT)));
2716 __ lea(to, Address(dst, dst_pos, TIMES_OOP,
2717 arrayOopDesc::base_offset_in_bytes(T_OBJECT)));
2718 __ movl(count, length); // length (reloaded)
2719 Register sco_temp = c_rarg3; // this register is free now
2720 assert_different_registers(from, to, count, sco_temp,
2721 r11_dst_klass, r10_src_klass);
2722 assert_clean_int(count, sco_temp);
2723
2724 // Generate the type check.
2725 const int sco_offset = (klassOopDesc::header_size() * HeapWordSize +
2726 Klass::super_check_offset_offset_in_bytes());
2727 __ movl(sco_temp, Address(r11_dst_klass, sco_offset));
2728 assert_clean_int(sco_temp, rax);
2729 generate_type_check(r10_src_klass, sco_temp, r11_dst_klass, L_plain_copy);
2730
2731 // Fetch destination element klass from the objArrayKlass header.
2732 int ek_offset = (klassOopDesc::header_size() * HeapWordSize +
2733 objArrayKlass::element_klass_offset_in_bytes());
2734 __ movptr(r11_dst_klass, Address(r11_dst_klass, ek_offset));
2735 __ movl( sco_temp, Address(r11_dst_klass, sco_offset));
2736 assert_clean_int(sco_temp, rax);
2737
2738 // the checkcast_copy loop needs two extra arguments:
2739 assert(c_rarg3 == sco_temp, "#3 already in place");
2740 // Set up arguments for checkcast_copy_entry.
2741 setup_arg_regs(4);
2742 __ movptr(r8, r11_dst_klass); // dst.klass.element_klass, r8 is c_rarg4 on Linux/Solaris
2743 __ jump(RuntimeAddress(checkcast_copy_entry));
2744 }
2745
2746 __ BIND(L_failed);
2747 __ xorptr(rax, rax);
2748 __ notptr(rax); // return -1
2749 __ leave(); // required for proper stackwalking of RuntimeStub frame
2750 __ ret(0);
2751
2752 return start;
2753 }
|
2244
2245 // allocate spill slots for r13, r14
2246 enum {
2247 saved_r13_offset,
2248 saved_r14_offset,
2249 saved_rbp_offset
2250 };
2251 __ subptr(rsp, saved_rbp_offset * wordSize);
2252 __ movptr(Address(rsp, saved_r13_offset * wordSize), r13);
2253 __ movptr(Address(rsp, saved_r14_offset * wordSize), r14);
2254
2255 // check that int operands are properly extended to size_t
2256 assert_clean_int(length, rax);
2257 assert_clean_int(ckoff, rax);
2258
2259 #ifdef ASSERT
2260 BLOCK_COMMENT("assert consistent ckoff/ckval");
2261 // The ckoff and ckval must be mutually consistent,
2262 // even though caller generates both.
2263 { Label L;
2264 int sco_offset = Klass::super_check_offset_offset_in_bytes();
2265 __ cmpl(ckoff, Address(ckval, sco_offset));
2266 __ jcc(Assembler::equal, L);
2267 __ stop("super_check_offset inconsistent");
2268 __ bind(L);
2269 }
2270 #endif //ASSERT
2271
2272 // Loop-invariant addresses. They are exclusive end pointers.
2273 Address end_from_addr(from, length, TIMES_OOP, 0);
2274 Address end_to_addr(to, length, TIMES_OOP, 0);
2275 // Loop-variant addresses. They assume post-incremented count < 0.
2276 Address from_element_addr(end_from, count, TIMES_OOP, 0);
2277 Address to_element_addr(end_to, count, TIMES_OOP, 0);
2278
2279 gen_write_ref_array_pre_barrier(to, count, dest_uninitialized);
2280
2281 // Copy from low to high addresses, indexed from the end of each array.
2282 __ lea(end_from, end_from_addr);
2283 __ lea(end_to, end_to_addr);
2284 __ movptr(r14_length, length); // save a copy of the length
2554 __ testptr(r10_src_klass, r10_src_klass);
2555 __ jcc(Assembler::notZero, L2); // it is broken if klass is NULL
2556 __ bind(L1);
2557 __ stop("broken null klass");
2558 __ bind(L2);
2559 __ load_klass(rax, dst);
2560 __ cmpq(rax, 0);
2561 __ jcc(Assembler::equal, L1); // this would be broken also
2562 BLOCK_COMMENT("} assert klasses not null done");
2563 }
2564 #endif
2565
2566 // Load layout helper (32-bits)
2567 //
2568 // |array_tag| | header_size | element_type | |log2_element_size|
2569 // 32 30 24 16 8 2 0
2570 //
2571 // array_tag: typeArray = 0x3, objArray = 0x2, non-array = 0x0
2572 //
2573
2574 const int lh_offset = Klass::layout_helper_offset_in_bytes();
2575
2576 // Handle objArrays completely differently...
2577 const jint objArray_lh = Klass::array_layout_helper(T_OBJECT);
2578 __ cmpl(Address(r10_src_klass, lh_offset), objArray_lh);
2579 __ jcc(Assembler::equal, L_objArray);
2580
2581 // if (src->klass() != dst->klass()) return -1;
2582 __ load_klass(rax, dst);
2583 __ cmpq(r10_src_klass, rax);
2584 __ jcc(Assembler::notEqual, L_failed);
2585
2586 const Register rax_lh = rax; // layout helper
2587 __ movl(rax_lh, Address(r10_src_klass, lh_offset));
2588
2589 // if (!src->is_Array()) return -1;
2590 __ cmpl(rax_lh, Klass::_lh_neutral_value);
2591 __ jcc(Assembler::greaterEqual, L_failed);
2592
2593 // At this point, it is known to be a typeArray (array_tag 0x3).
2594 #ifdef ASSERT
2703
2704 // It is safe to examine both src.length and dst.length.
2705 arraycopy_range_checks(src, src_pos, dst, dst_pos, r11_length,
2706 rax, L_failed);
2707
2708 const Register r11_dst_klass = r11;
2709 __ load_klass(r11_dst_klass, dst); // reload
2710
2711 // Marshal the base address arguments now, freeing registers.
2712 __ lea(from, Address(src, src_pos, TIMES_OOP,
2713 arrayOopDesc::base_offset_in_bytes(T_OBJECT)));
2714 __ lea(to, Address(dst, dst_pos, TIMES_OOP,
2715 arrayOopDesc::base_offset_in_bytes(T_OBJECT)));
2716 __ movl(count, length); // length (reloaded)
2717 Register sco_temp = c_rarg3; // this register is free now
2718 assert_different_registers(from, to, count, sco_temp,
2719 r11_dst_klass, r10_src_klass);
2720 assert_clean_int(count, sco_temp);
2721
2722 // Generate the type check.
2723 const int sco_offset = Klass::super_check_offset_offset_in_bytes();
2724 __ movl(sco_temp, Address(r11_dst_klass, sco_offset));
2725 assert_clean_int(sco_temp, rax);
2726 generate_type_check(r10_src_klass, sco_temp, r11_dst_klass, L_plain_copy);
2727
2728 // Fetch destination element klass from the objArrayKlass header.
2729 int ek_offset = objArrayKlass::element_klass_offset_in_bytes();
2730 __ movptr(r11_dst_klass, Address(r11_dst_klass, ek_offset));
2731 __ movl( sco_temp, Address(r11_dst_klass, sco_offset));
2732 assert_clean_int(sco_temp, rax);
2733
2734 // the checkcast_copy loop needs two extra arguments:
2735 assert(c_rarg3 == sco_temp, "#3 already in place");
2736 // Set up arguments for checkcast_copy_entry.
2737 setup_arg_regs(4);
2738 __ movptr(r8, r11_dst_klass); // dst.klass.element_klass, r8 is c_rarg4 on Linux/Solaris
2739 __ jump(RuntimeAddress(checkcast_copy_entry));
2740 }
2741
2742 __ BIND(L_failed);
2743 __ xorptr(rax, rax);
2744 __ notptr(rax); // return -1
2745 __ leave(); // required for proper stackwalking of RuntimeStub frame
2746 __ ret(0);
2747
2748 return start;
2749 }
|