Mercurial > hg > truffle
comparison src/cpu/x86/vm/c1_LIRAssembler_x86.cpp @ 3739:28263a73ebfb
7047491: C1: registers saved incorrectly when calling checkcast_arraycopy stub
Summary: Save and restore the argument registers around the call to checkcast_arraycopy
Reviewed-by: never, roland
author | iveresov |
---|---|
date | Thu, 26 May 2011 13:15:01 -0700 |
parents | ccf072cdba91 |
children | c124e2e7463e |
comparison
equal
deleted
inserted
replaced
3738:c7c81f18c834 | 3739:28263a73ebfb |
---|---|
3111 // For the moment until C1 gets the new register allocator I just force all the | 3111 // For the moment until C1 gets the new register allocator I just force all the |
3112 // args to the right place (except the register args) and then on the back side | 3112 // args to the right place (except the register args) and then on the back side |
3113 // reload the register args properly if we go slow path. Yuck | 3113 // reload the register args properly if we go slow path. Yuck |
3114 | 3114 |
3115 // These are proper for the calling convention | 3115 // These are proper for the calling convention |
3116 | |
3117 store_parameter(length, 2); | 3116 store_parameter(length, 2); |
3118 store_parameter(dst_pos, 1); | 3117 store_parameter(dst_pos, 1); |
3119 store_parameter(dst, 0); | 3118 store_parameter(dst, 0); |
3120 | 3119 |
3121 // these are just temporary placements until we need to reload | 3120 // these are just temporary placements until we need to reload |
3349 jint objArray_lh = Klass::array_layout_helper(T_OBJECT); | 3348 jint objArray_lh = Klass::array_layout_helper(T_OBJECT); |
3350 __ cmpl(klass_lh_addr, objArray_lh); | 3349 __ cmpl(klass_lh_addr, objArray_lh); |
3351 __ jcc(Assembler::notEqual, *stub->entry()); | 3350 __ jcc(Assembler::notEqual, *stub->entry()); |
3352 } | 3351 } |
3353 | 3352 |
3353 // Spill because stubs can use any register they like and it's | |
3354 // easier to restore just those that we care about. | |
3355 store_parameter(dst, 0); | |
3356 store_parameter(dst_pos, 1); | |
3357 store_parameter(length, 2); | |
3358 store_parameter(src_pos, 3); | |
3359 store_parameter(src, 4); | |
3360 | |
3354 #ifndef _LP64 | 3361 #ifndef _LP64 |
3355 // save caller save registers | |
3356 store_parameter(rax, 2); | |
3357 store_parameter(rcx, 1); | |
3358 store_parameter(rdx, 0); | |
3359 | |
3360 __ movptr(tmp, dst_klass_addr); | 3362 __ movptr(tmp, dst_klass_addr); |
3361 __ movptr(tmp, Address(tmp, objArrayKlass::element_klass_offset_in_bytes() + sizeof(oopDesc))); | 3363 __ movptr(tmp, Address(tmp, objArrayKlass::element_klass_offset_in_bytes() + sizeof(oopDesc))); |
3362 __ push(tmp); | 3364 __ push(tmp); |
3363 __ movl(tmp, Address(tmp, Klass::super_check_offset_offset_in_bytes() + sizeof(oopDesc))); | 3365 __ movl(tmp, Address(tmp, Klass::super_check_offset_offset_in_bytes() + sizeof(oopDesc))); |
3364 __ push(tmp); | 3366 __ push(tmp); |
3369 __ push(tmp); | 3371 __ push(tmp); |
3370 | 3372 |
3371 __ call_VM_leaf(copyfunc_addr, 5); | 3373 __ call_VM_leaf(copyfunc_addr, 5); |
3372 #else | 3374 #else |
3373 __ movl2ptr(length, length); //higher 32bits must be null | 3375 __ movl2ptr(length, length); //higher 32bits must be null |
3374 | |
3375 // save caller save registers: copy them to callee save registers | |
3376 __ mov(rbx, rdx); | |
3377 __ mov(r13, r8); | |
3378 __ mov(r14, r9); | |
3379 #ifndef _WIN64 | |
3380 store_parameter(rsi, 1); | |
3381 store_parameter(rcx, 0); | |
3382 // on WIN64 other incoming parameters are in rdi and rsi saved | |
3383 // across the call | |
3384 #endif | |
3385 | 3376 |
3386 __ lea(c_rarg0, Address(src, src_pos, scale, arrayOopDesc::base_offset_in_bytes(basic_type))); | 3377 __ lea(c_rarg0, Address(src, src_pos, scale, arrayOopDesc::base_offset_in_bytes(basic_type))); |
3387 assert_different_registers(c_rarg0, dst, dst_pos, length); | 3378 assert_different_registers(c_rarg0, dst, dst_pos, length); |
3388 __ lea(c_rarg1, Address(dst, dst_pos, scale, arrayOopDesc::base_offset_in_bytes(basic_type))); | 3379 __ lea(c_rarg1, Address(dst, dst_pos, scale, arrayOopDesc::base_offset_in_bytes(basic_type))); |
3389 assert_different_registers(c_rarg1, dst, length); | 3380 assert_different_registers(c_rarg1, dst, length); |
3430 | 3421 |
3431 __ mov(tmp, rax); | 3422 __ mov(tmp, rax); |
3432 | 3423 |
3433 __ xorl(tmp, -1); | 3424 __ xorl(tmp, -1); |
3434 | 3425 |
3435 #ifndef _LP64 | 3426 // Restore previously spilled arguments |
3436 // restore caller save registers | 3427 __ movptr (dst, Address(rsp, 0*BytesPerWord)); |
3437 assert_different_registers(tmp, rdx, rcx, rax); // result of stub will be lost | 3428 __ movptr (dst_pos, Address(rsp, 1*BytesPerWord)); |
3438 __ movptr(rdx, Address(rsp, 0*BytesPerWord)); | 3429 __ movptr (length, Address(rsp, 2*BytesPerWord)); |
3439 __ movptr(rcx, Address(rsp, 1*BytesPerWord)); | 3430 __ movptr (src_pos, Address(rsp, 3*BytesPerWord)); |
3440 __ movptr(rax, Address(rsp, 2*BytesPerWord)); | 3431 __ movptr (src, Address(rsp, 4*BytesPerWord)); |
3441 #else | 3432 |
3442 // restore caller save registers | |
3443 __ mov(rdx, rbx); | |
3444 __ mov(r8, r13); | |
3445 __ mov(r9, r14); | |
3446 #ifndef _WIN64 | |
3447 assert_different_registers(tmp, rdx, r8, r9, rcx, rsi); // result of stub will be lost | |
3448 __ movptr(rcx, Address(rsp, 0*BytesPerWord)); | |
3449 __ movptr(rsi, Address(rsp, 1*BytesPerWord)); | |
3450 #else | |
3451 assert_different_registers(tmp, rdx, r8, r9); // result of stub will be lost | |
3452 #endif | |
3453 #endif | |
3454 | 3433 |
3455 __ subl(length, tmp); | 3434 __ subl(length, tmp); |
3456 __ addl(src_pos, tmp); | 3435 __ addl(src_pos, tmp); |
3457 __ addl(dst_pos, tmp); | 3436 __ addl(dst_pos, tmp); |
3458 } | 3437 } |