@@ -2939,7 +2939,7 @@ class StubGenerator: public StubCodeGenerator {
2939
2939
address long_copy_entry, address checkcast_copy_entry) {
2940
2940
2941
2941
Label L_failed, L_failed_0, L_objArray;
2942
- Label L_copy_bytes, L_copy_shorts, L_copy_ints, L_copy_longs;
2942
+ Label L_copy_shorts, L_copy_ints, L_copy_longs;
2943
2943
2944
2944
// Input registers
2945
2945
const Register src = c_rarg0; // source array oop
@@ -2950,7 +2950,7 @@ class StubGenerator: public StubCodeGenerator {
2950
2950
const Register length = c_rarg4;
2951
2951
const Register rklass_tmp = r9; // load_klass
2952
2952
#else
2953
- const Address length (rsp, 6 * wordSize); // elements count is on stack on Win64
2953
+ const Address length (rsp, 7 * wordSize); // elements count is on stack on Win64
2954
2954
const Register rklass_tmp = rdi; // load_klass
2955
2955
#endif
2956
2956
@@ -2972,6 +2972,10 @@ class StubGenerator: public StubCodeGenerator {
2972
2972
2973
2973
__ enter (); // required for proper stackwalking of RuntimeStub frame
2974
2974
2975
+ #ifdef _WIN64
2976
+ __ push (rklass_tmp); // rdi is callee-save on Windows
2977
+ #endif
2978
+
2975
2979
// bump this on entry, not on exit:
2976
2980
inc_counter_np (SharedRuntime::_generic_array_copy_ctr);
2977
2981
@@ -3102,6 +3106,10 @@ class StubGenerator: public StubCodeGenerator {
3102
3106
BLOCK_COMMENT (" choose copy loop based on element size" );
3103
3107
__ andl (rax_lh, Klass::_lh_log2_element_size_mask); // rax_lh -> rax_elsize
3104
3108
3109
+ #ifdef _WIN64
3110
+ __ pop (rklass_tmp); // Restore callee-save rdi
3111
+ #endif
3112
+
3105
3113
// next registers should be set before the jump to corresponding stub
3106
3114
const Register from = c_rarg0; // source array address
3107
3115
const Register to = c_rarg1; // destination array address
@@ -3110,7 +3118,6 @@ class StubGenerator: public StubCodeGenerator {
3110
3118
// 'from', 'to', 'count' registers should be set in such order
3111
3119
// since they are the same as 'src', 'src_pos', 'dst'.
3112
3120
3113
- __ BIND (L_copy_bytes);
3114
3121
__ cmpl (rax_elsize, 0 );
3115
3122
__ jccb (Assembler::notEqual, L_copy_shorts);
3116
3123
__ lea (from, Address (src, src_pos, Address::times_1, 0 ));// src_addr
@@ -3171,6 +3178,9 @@ class StubGenerator: public StubCodeGenerator {
3171
3178
arrayOopDesc::base_offset_in_bytes (T_OBJECT))); // dst_addr
3172
3179
__ movl2ptr (count, r11_length); // length
3173
3180
__ BIND (L_plain_copy);
3181
+ #ifdef _WIN64
3182
+ __ pop (rklass_tmp); // Restore callee-save rdi
3183
+ #endif
3174
3184
__ jump (RuntimeAddress (oop_copy_entry));
3175
3185
3176
3186
__ BIND (L_checkcast_copy);
@@ -3210,6 +3220,10 @@ class StubGenerator: public StubCodeGenerator {
3210
3220
__ movl ( sco_temp, Address (r11_dst_klass, sco_offset));
3211
3221
assert_clean_int (sco_temp, rax);
3212
3222
3223
+ #ifdef _WIN64
3224
+ __ pop (rklass_tmp); // Restore callee-save rdi
3225
+ #endif
3226
+
3213
3227
// the checkcast_copy loop needs two extra arguments:
3214
3228
assert (c_rarg3 == sco_temp, " #3 already in place" );
3215
3229
// Set up arguments for checkcast_copy_entry.
@@ -3219,6 +3233,9 @@ class StubGenerator: public StubCodeGenerator {
3219
3233
}
3220
3234
3221
3235
__ BIND (L_failed);
3236
+ #ifdef _WIN64
3237
+ __ pop (rklass_tmp); // Restore callee-save rdi
3238
+ #endif
3222
3239
__ xorptr (rax, rax);
3223
3240
__ notptr (rax); // return -1
3224
3241
__ leave (); // required for proper stackwalking of RuntimeStub frame
0 commit comments