src/cpu/x86/vm/stubGenerator_x86_64.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_64.cpp

Print this page




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   }


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