Skip to content

Commit 31d9b7f

Browse files
committed
8254252: Generic arraycopy stub overwrites callee-save rdi register on 64-bit Windows
Reviewed-by: kvn, chagedorn
1 parent a098037 commit 31d9b7f

File tree

1 file changed

+20
-3
lines changed

1 file changed

+20
-3
lines changed

src/hotspot/cpu/x86/stubGenerator_x86_64.cpp

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2939,7 +2939,7 @@ class StubGenerator: public StubCodeGenerator {
29392939
address long_copy_entry, address checkcast_copy_entry) {
29402940

29412941
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;
29432943

29442944
// Input registers
29452945
const Register src = c_rarg0; // source array oop
@@ -2950,7 +2950,7 @@ class StubGenerator: public StubCodeGenerator {
29502950
const Register length = c_rarg4;
29512951
const Register rklass_tmp = r9; // load_klass
29522952
#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
29542954
const Register rklass_tmp = rdi; // load_klass
29552955
#endif
29562956

@@ -2972,6 +2972,10 @@ class StubGenerator: public StubCodeGenerator {
29722972

29732973
__ enter(); // required for proper stackwalking of RuntimeStub frame
29742974

2975+
#ifdef _WIN64
2976+
__ push(rklass_tmp); // rdi is callee-save on Windows
2977+
#endif
2978+
29752979
// bump this on entry, not on exit:
29762980
inc_counter_np(SharedRuntime::_generic_array_copy_ctr);
29772981

@@ -3102,6 +3106,10 @@ class StubGenerator: public StubCodeGenerator {
31023106
BLOCK_COMMENT("choose copy loop based on element size");
31033107
__ andl(rax_lh, Klass::_lh_log2_element_size_mask); // rax_lh -> rax_elsize
31043108

3109+
#ifdef _WIN64
3110+
__ pop(rklass_tmp); // Restore callee-save rdi
3111+
#endif
3112+
31053113
// next registers should be set before the jump to corresponding stub
31063114
const Register from = c_rarg0; // source array address
31073115
const Register to = c_rarg1; // destination array address
@@ -3110,7 +3118,6 @@ class StubGenerator: public StubCodeGenerator {
31103118
// 'from', 'to', 'count' registers should be set in such order
31113119
// since they are the same as 'src', 'src_pos', 'dst'.
31123120

3113-
__ BIND(L_copy_bytes);
31143121
__ cmpl(rax_elsize, 0);
31153122
__ jccb(Assembler::notEqual, L_copy_shorts);
31163123
__ lea(from, Address(src, src_pos, Address::times_1, 0));// src_addr
@@ -3171,6 +3178,9 @@ class StubGenerator: public StubCodeGenerator {
31713178
arrayOopDesc::base_offset_in_bytes(T_OBJECT))); // dst_addr
31723179
__ movl2ptr(count, r11_length); // length
31733180
__ BIND(L_plain_copy);
3181+
#ifdef _WIN64
3182+
__ pop(rklass_tmp); // Restore callee-save rdi
3183+
#endif
31743184
__ jump(RuntimeAddress(oop_copy_entry));
31753185

31763186
__ BIND(L_checkcast_copy);
@@ -3210,6 +3220,10 @@ class StubGenerator: public StubCodeGenerator {
32103220
__ movl( sco_temp, Address(r11_dst_klass, sco_offset));
32113221
assert_clean_int(sco_temp, rax);
32123222

3223+
#ifdef _WIN64
3224+
__ pop(rklass_tmp); // Restore callee-save rdi
3225+
#endif
3226+
32133227
// the checkcast_copy loop needs two extra arguments:
32143228
assert(c_rarg3 == sco_temp, "#3 already in place");
32153229
// Set up arguments for checkcast_copy_entry.
@@ -3219,6 +3233,9 @@ class StubGenerator: public StubCodeGenerator {
32193233
}
32203234

32213235
__ BIND(L_failed);
3236+
#ifdef _WIN64
3237+
__ pop(rklass_tmp); // Restore callee-save rdi
3238+
#endif
32223239
__ xorptr(rax, rax);
32233240
__ notptr(rax); // return -1
32243241
__ leave(); // required for proper stackwalking of RuntimeStub frame

0 commit comments

Comments
 (0)