< prev index next >

src/hotspot/cpu/x86/stubGenerator_x86_64.cpp

Print this page
rev 54706 : 8223244: Fix usage of ARRAYCOPY_DISJOINT decorator


2132     Label L_copy_bytes, L_copy_8_bytes, L_exit;
2133     const Register from        = rdi;  // source array address
2134     const Register to          = rsi;  // destination array address
2135     const Register qword_count = rdx;  // elements count
2136     const Register saved_count = rcx;
2137 
2138     __ enter(); // required for proper stackwalking of RuntimeStub frame
2139     assert_clean_int(c_rarg2, rax);    // Make sure 'count' is clean int.
2140 
2141     if (entry != NULL) {
2142       *entry = __ pc();
2143       // caller can pass a 64-bit byte count here (from Unsafe.copyMemory)
2144       BLOCK_COMMENT("Entry:");
2145     }
2146 
2147     array_overlap_test(nooverlap_target, Address::times_8);
2148     setup_arg_regs_using_thread(); // from => rdi, to => rsi, count => rdx
2149                                    // r9 is used to save r15_thread
2150     // 'from', 'to' and 'qword_count' are now valid
2151 
2152     DecoratorSet decorators = IN_HEAP | IS_ARRAY | ARRAYCOPY_DISJOINT;
2153     if (dest_uninitialized) {
2154       decorators |= IS_DEST_UNINITIALIZED;
2155     }
2156     if (aligned) {
2157       decorators |= ARRAYCOPY_ALIGNED;
2158     }
2159 
2160     BasicType type = is_oop ? T_OBJECT : T_LONG;
2161     BarrierSetAssembler *bs = BarrierSet::barrier_set()->barrier_set_assembler();
2162     bs->arraycopy_prologue(_masm, decorators, type, from, to, qword_count);
2163 
2164     __ jmp(L_copy_bytes);
2165 
2166     // Copy trailing qwords
2167   __ BIND(L_copy_8_bytes);
2168     __ movq(rax, Address(from, qword_count, Address::times_8, -8));
2169     __ movq(Address(to, qword_count, Address::times_8, -8), rax);
2170     __ decrement(qword_count);
2171     __ jcc(Assembler::notZero, L_copy_8_bytes);
2172 


2326 #ifdef ASSERT
2327     BLOCK_COMMENT("assert consistent ckoff/ckval");
2328     // The ckoff and ckval must be mutually consistent,
2329     // even though caller generates both.
2330     { Label L;
2331       int sco_offset = in_bytes(Klass::super_check_offset_offset());
2332       __ cmpl(ckoff, Address(ckval, sco_offset));
2333       __ jcc(Assembler::equal, L);
2334       __ stop("super_check_offset inconsistent");
2335       __ bind(L);
2336     }
2337 #endif //ASSERT
2338 
2339     // Loop-invariant addresses.  They are exclusive end pointers.
2340     Address end_from_addr(from, length, TIMES_OOP, 0);
2341     Address   end_to_addr(to,   length, TIMES_OOP, 0);
2342     // Loop-variant addresses.  They assume post-incremented count < 0.
2343     Address from_element_addr(end_from, count, TIMES_OOP, 0);
2344     Address   to_element_addr(end_to,   count, TIMES_OOP, 0);
2345 
2346     DecoratorSet decorators = IN_HEAP | IS_ARRAY | ARRAYCOPY_CHECKCAST;


2347     if (dest_uninitialized) {
2348       decorators |= IS_DEST_UNINITIALIZED;
2349     }
2350 
2351     BasicType type = T_OBJECT;
2352     BarrierSetAssembler *bs = BarrierSet::barrier_set()->barrier_set_assembler();
2353     bs->arraycopy_prologue(_masm, decorators, type, from, to, count);
2354 
2355     // Copy from low to high addresses, indexed from the end of each array.
2356     __ lea(end_from, end_from_addr);
2357     __ lea(end_to,   end_to_addr);
2358     __ movptr(r14_length, length);        // save a copy of the length
2359     assert(length == count, "");          // else fix next line:
2360     __ negptr(count);                     // negate and test the length
2361     __ jcc(Assembler::notZero, L_load_element);
2362 
2363     // Empty array:  Nothing to do.
2364     __ xorptr(rax, rax);                  // return 0 on (trivial) success
2365     __ jmp(L_done);
2366 




2132     Label L_copy_bytes, L_copy_8_bytes, L_exit;
2133     const Register from        = rdi;  // source array address
2134     const Register to          = rsi;  // destination array address
2135     const Register qword_count = rdx;  // elements count
2136     const Register saved_count = rcx;
2137 
2138     __ enter(); // required for proper stackwalking of RuntimeStub frame
2139     assert_clean_int(c_rarg2, rax);    // Make sure 'count' is clean int.
2140 
2141     if (entry != NULL) {
2142       *entry = __ pc();
2143       // caller can pass a 64-bit byte count here (from Unsafe.copyMemory)
2144       BLOCK_COMMENT("Entry:");
2145     }
2146 
2147     array_overlap_test(nooverlap_target, Address::times_8);
2148     setup_arg_regs_using_thread(); // from => rdi, to => rsi, count => rdx
2149                                    // r9 is used to save r15_thread
2150     // 'from', 'to' and 'qword_count' are now valid
2151 
2152     DecoratorSet decorators = IN_HEAP | IS_ARRAY;
2153     if (dest_uninitialized) {
2154       decorators |= IS_DEST_UNINITIALIZED;
2155     }
2156     if (aligned) {
2157       decorators |= ARRAYCOPY_ALIGNED;
2158     }
2159 
2160     BasicType type = is_oop ? T_OBJECT : T_LONG;
2161     BarrierSetAssembler *bs = BarrierSet::barrier_set()->barrier_set_assembler();
2162     bs->arraycopy_prologue(_masm, decorators, type, from, to, qword_count);
2163 
2164     __ jmp(L_copy_bytes);
2165 
2166     // Copy trailing qwords
2167   __ BIND(L_copy_8_bytes);
2168     __ movq(rax, Address(from, qword_count, Address::times_8, -8));
2169     __ movq(Address(to, qword_count, Address::times_8, -8), rax);
2170     __ decrement(qword_count);
2171     __ jcc(Assembler::notZero, L_copy_8_bytes);
2172 


2326 #ifdef ASSERT
2327     BLOCK_COMMENT("assert consistent ckoff/ckval");
2328     // The ckoff and ckval must be mutually consistent,
2329     // even though caller generates both.
2330     { Label L;
2331       int sco_offset = in_bytes(Klass::super_check_offset_offset());
2332       __ cmpl(ckoff, Address(ckval, sco_offset));
2333       __ jcc(Assembler::equal, L);
2334       __ stop("super_check_offset inconsistent");
2335       __ bind(L);
2336     }
2337 #endif //ASSERT
2338 
2339     // Loop-invariant addresses.  They are exclusive end pointers.
2340     Address end_from_addr(from, length, TIMES_OOP, 0);
2341     Address   end_to_addr(to,   length, TIMES_OOP, 0);
2342     // Loop-variant addresses.  They assume post-incremented count < 0.
2343     Address from_element_addr(end_from, count, TIMES_OOP, 0);
2344     Address   to_element_addr(end_to,   count, TIMES_OOP, 0);
2345 
2346     // Note: checkcast arraycopy is always disjoint. If it were not, then we wouldn't
2347     // need to checkcast.
2348     DecoratorSet decorators = IN_HEAP | IS_ARRAY | ARRAYCOPY_CHECKCAST | ARRAYCOPY_DISJOINT;
2349     if (dest_uninitialized) {
2350       decorators |= IS_DEST_UNINITIALIZED;
2351     }
2352 
2353     BasicType type = T_OBJECT;
2354     BarrierSetAssembler *bs = BarrierSet::barrier_set()->barrier_set_assembler();
2355     bs->arraycopy_prologue(_masm, decorators, type, from, to, count);
2356 
2357     // Copy from low to high addresses, indexed from the end of each array.
2358     __ lea(end_from, end_from_addr);
2359     __ lea(end_to,   end_to_addr);
2360     __ movptr(r14_length, length);        // save a copy of the length
2361     assert(length == count, "");          // else fix next line:
2362     __ negptr(count);                     // negate and test the length
2363     __ jcc(Assembler::notZero, L_load_element);
2364 
2365     // Empty array:  Nothing to do.
2366     __ xorptr(rax, rax);                  // return 0 on (trivial) success
2367     __ jmp(L_done);
2368 


< prev index next >