Mercurial > hg > graal-jvmci-8
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); |