comparison src/cpu/x86/vm/templateTable_x86_32.cpp @ 5995:19e197e2a1af

7158988: jvm crashes while debugging on x86_32 and x86_64 Summary: Object pointer is pushed more than once on stack, where GC doesn't expect it. Reviewed-by: coleenp, kvn Contributed-by: axel.siebenborn@sap.com
author coleenp
date Thu, 05 Apr 2012 12:17:52 -0400
parents 22cee0ee8927
children 1d7922586cf6
comparison
equal deleted inserted replaced
5983:749b1464aa81 5995:19e197e2a1af
2649 void TemplateTable::jvmti_post_fast_field_mod() { 2649 void TemplateTable::jvmti_post_fast_field_mod() {
2650 if (JvmtiExport::can_post_field_modification()) { 2650 if (JvmtiExport::can_post_field_modification()) {
2651 // Check to see if a field modification watch has been set before we take 2651 // Check to see if a field modification watch has been set before we take
2652 // the time to call into the VM. 2652 // the time to call into the VM.
2653 Label L2; 2653 Label L2;
2654 __ mov32(rcx, ExternalAddress((address)JvmtiExport::get_field_modification_count_addr())); 2654 __ mov32(rcx, ExternalAddress((address)JvmtiExport::get_field_modification_count_addr()));
2655 __ testl(rcx,rcx); 2655 __ testl(rcx,rcx);
2656 __ jcc(Assembler::zero, L2); 2656 __ jcc(Assembler::zero, L2);
2657 __ pop_ptr(rbx); // copy the object pointer from tos 2657 __ pop_ptr(rbx); // copy the object pointer from tos
2658 __ verify_oop(rbx); 2658 __ verify_oop(rbx);
2659 __ push_ptr(rbx); // put the object pointer back on tos 2659 __ push_ptr(rbx); // put the object pointer back on tos
2660 __ subptr(rsp, sizeof(jvalue)); // add space for a jvalue object 2660
2661 __ mov(rcx, rsp); 2661 // Save tos values before call_VM() clobbers them. Since we have
2662 __ push_ptr(rbx); // save object pointer so we can steal rbx, 2662 // to do it for every data type, we use the saved values as the
2663 __ xorptr(rbx, rbx); 2663 // jvalue object.
2664 const Address lo_value(rcx, rbx, Address::times_1, 0*wordSize); 2664 switch (bytecode()) { // load values into the jvalue object
2665 const Address hi_value(rcx, rbx, Address::times_1, 1*wordSize); 2665 case Bytecodes::_fast_aputfield: __ push_ptr(rax); break;
2666 switch (bytecode()) { // load values into the jvalue object 2666 case Bytecodes::_fast_bputfield: // fall through
2667 case Bytecodes::_fast_bputfield: __ movb(lo_value, rax); break; 2667 case Bytecodes::_fast_sputfield: // fall through
2668 case Bytecodes::_fast_sputfield: __ movw(lo_value, rax); break; 2668 case Bytecodes::_fast_cputfield: // fall through
2669 case Bytecodes::_fast_cputfield: __ movw(lo_value, rax); break; 2669 case Bytecodes::_fast_iputfield: __ push_i(rax); break;
2670 case Bytecodes::_fast_iputfield: __ movl(lo_value, rax); break; 2670 case Bytecodes::_fast_dputfield: __ push_d(); break;
2671 case Bytecodes::_fast_lputfield: 2671 case Bytecodes::_fast_fputfield: __ push_f(); break;
2672 NOT_LP64(__ movptr(hi_value, rdx)); 2672 case Bytecodes::_fast_lputfield: __ push_l(rax); break;
2673 __ movptr(lo_value, rax); 2673
2674 break; 2674 default:
2675 2675 ShouldNotReachHere();
2676 // need to call fld_s() after fstp_s() to restore the value for below 2676 }
2677 case Bytecodes::_fast_fputfield: __ fstp_s(lo_value); __ fld_s(lo_value); break; 2677 __ mov(rcx, rsp); // points to jvalue on the stack
2678 2678 // access constant pool cache entry
2679 // need to call fld_d() after fstp_d() to restore the value for below 2679 __ get_cache_entry_pointer_at_bcp(rax, rdx, 1);
2680 case Bytecodes::_fast_dputfield: __ fstp_d(lo_value); __ fld_d(lo_value); break; 2680 __ verify_oop(rbx);
2681 2681 // rbx,: object pointer copied above
2682 // since rcx is not an object we don't call store_check() here 2682 // rax,: cache entry pointer
2683 case Bytecodes::_fast_aputfield: __ movptr(lo_value, rax); break; 2683 // rcx: jvalue object on the stack
2684 2684 __ call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::post_field_modification), rbx, rax, rcx);
2685 default: ShouldNotReachHere(); 2685
2686 } 2686 switch (bytecode()) { // restore tos values
2687 __ pop_ptr(rbx); // restore copy of object pointer 2687 case Bytecodes::_fast_aputfield: __ pop_ptr(rax); break;
2688 2688 case Bytecodes::_fast_bputfield: // fall through
2689 // Save rax, and sometimes rdx because call_VM() will clobber them, 2689 case Bytecodes::_fast_sputfield: // fall through
2690 // then use them for JVM/DI purposes 2690 case Bytecodes::_fast_cputfield: // fall through
2691 __ push(rax); 2691 case Bytecodes::_fast_iputfield: __ pop_i(rax); break;
2692 if (bytecode() == Bytecodes::_fast_lputfield) __ push(rdx); 2692 case Bytecodes::_fast_dputfield: __ pop_d(); break;
2693 // access constant pool cache entry 2693 case Bytecodes::_fast_fputfield: __ pop_f(); break;
2694 __ get_cache_entry_pointer_at_bcp(rax, rdx, 1); 2694 case Bytecodes::_fast_lputfield: __ pop_l(rax); break;
2695 __ verify_oop(rbx); 2695 }
2696 // rbx,: object pointer copied above 2696 __ bind(L2);
2697 // rax,: cache entry pointer
2698 // rcx: jvalue object on the stack
2699 __ call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::post_field_modification), rbx, rax, rcx);
2700 if (bytecode() == Bytecodes::_fast_lputfield) __ pop(rdx); // restore high value
2701 __ pop(rax); // restore lower value
2702 __ addptr(rsp, sizeof(jvalue)); // release jvalue object space
2703 __ bind(L2);
2704 } 2697 }
2705 } 2698 }
2706 2699
2707 void TemplateTable::fast_storefield(TosState state) { 2700 void TemplateTable::fast_storefield(TosState state) {
2708 transition(state, vtos); 2701 transition(state, vtos);