src/cpu/x86/vm/sharedRuntime_x86_32.cpp
Index Unified diffs Context diffs Sdiffs Patch New Old Previous File Next File hotspot Sdiff src/cpu/x86/vm

src/cpu/x86/vm/sharedRuntime_x86_32.cpp

Print this page
rev 6132 : 8032410: compiler/uncommontrap/TestStackBangRbp.java times out on Solaris-Sparc V9
Summary: make compiled code bang the stack by the worst case size of the interpreter frame at deoptimization points.
Reviewed-by:
rev 6133 : [mq]: newstackbang-reviews


1786       __ jcc (Assembler::notZero, slowCase);
1787     }
1788 
1789     // get hash
1790     __ andptr(result, markOopDesc::hash_mask_in_place);
1791     // test if hashCode exists
1792     __ jcc  (Assembler::zero, slowCase);
1793     __ shrptr(result, markOopDesc::hash_shift);
1794     __ ret(0);
1795     __ bind (slowCase);
1796   }
1797 #endif // COMPILER1
1798 
1799   // The instruction at the verified entry point must be 5 bytes or longer
1800   // because it can be patched on the fly by make_non_entrant. The stack bang
1801   // instruction fits that requirement.
1802 
1803   // Generate stack overflow check
1804 
1805   if (UseStackBanging) {
1806     __ bang_stack_with_offset(StackShadowPages*os::vm_page_size());

1807   } else {
1808     // need a 5 byte instruction to allow MT safe patching to non-entrant
1809     __ fat_nop();
1810   }
1811 
1812   // Generate a new frame for the wrapper.
1813   __ enter();
1814   // -2 because return address is already present and so is saved rbp
1815   __ subptr(rsp, stack_size - 2*wordSize);
1816 
1817   // Frame is now completed as far as size and linkage.
1818   int frame_complete = ((intptr_t)__ pc()) - start;
1819 
1820   // Calculate the difference between rsp and rbp,. We need to know it
1821   // after the native call because on windows Java Natives will pop
1822   // the arguments and it is painful to do rsp relative addressing
1823   // in a platform independent way. So after the call we switch to
1824   // rbp, relative addressing.
1825 
1826   int fp_adjustment = stack_size - 2*wordSize;


2990   // Pop all the frames we must move/replace.
2991   //
2992   // Frame picture (youngest to oldest)
2993   // 1: self-frame (no frame link)
2994   // 2: deopting frame  (no frame link)
2995   // 3: caller of deopting frame (could be compiled/interpreted).
2996   //
2997   // Note: by leaving the return address of self-frame on the stack
2998   // and using the size of frame 2 to adjust the stack
2999   // when we are done the return to frame 3 will still be on the stack.
3000 
3001   // Pop deoptimized frame
3002   __ addptr(rsp, Address(rdi,Deoptimization::UnrollBlock::size_of_deoptimized_frame_offset_in_bytes()));
3003 
3004   // sp should be pointing at the return address to the caller (3)
3005 
3006   // Pick up the initial fp we should save
3007   // restore rbp before stack bang because if stack overflow is thrown it needs to be pushed (and preserved)
3008   __ movptr(rbp, Address(rdi, Deoptimization::UnrollBlock::initial_info_offset_in_bytes()));
3009 
3010   // Stack bang to make sure there's enough room for these interpreter frames.



3011   if (UseStackBanging) {
3012     __ movl(rbx, Address(rdi ,Deoptimization::UnrollBlock::total_frame_sizes_offset_in_bytes()));
3013     __ bang_stack_size(rbx, rcx);
3014   }

3015 
3016   // Load array of frame pcs into ECX
3017   __ movptr(rcx,Address(rdi,Deoptimization::UnrollBlock::frame_pcs_offset_in_bytes()));
3018 
3019   __ pop(rsi); // trash the old pc
3020 
3021   // Load array of frame sizes into ESI
3022   __ movptr(rsi,Address(rdi,Deoptimization::UnrollBlock::frame_sizes_offset_in_bytes()));
3023 
3024   Address counter(rdi, Deoptimization::UnrollBlock::counter_temp_offset_in_bytes());
3025 
3026   __ movl(rbx, Address(rdi, Deoptimization::UnrollBlock::number_of_frames_offset_in_bytes()));
3027   __ movl(counter, rbx);
3028 
3029   // Now adjust the caller's stack to make up for the extra locals
3030   // but record the original sp so that we can save it in the skeletal interpreter
3031   // frame and the stack walking of interpreter_sender will get the unextended sp
3032   // value and not the "real" sp value.
3033 
3034   Address sp_temp(rdi, Deoptimization::UnrollBlock::sender_sp_temp_offset_in_bytes());


3210   // Pop all the frames we must move/replace.
3211   //
3212   // Frame picture (youngest to oldest)
3213   // 1: self-frame (no frame link)
3214   // 2: deopting frame  (no frame link)
3215   // 3: caller of deopting frame (could be compiled/interpreted).
3216 
3217   // Pop self-frame.  We have no frame, and must rely only on EAX and ESP.
3218   __ addptr(rsp,(framesize-1)*wordSize);     // Epilog!
3219 
3220   // Pop deoptimized frame
3221   __ movl2ptr(rcx, Address(rdi,Deoptimization::UnrollBlock::size_of_deoptimized_frame_offset_in_bytes()));
3222   __ addptr(rsp, rcx);
3223 
3224   // sp should be pointing at the return address to the caller (3)
3225 
3226   // Pick up the initial fp we should save
3227   // restore rbp before stack bang because if stack overflow is thrown it needs to be pushed (and preserved)
3228   __ movptr(rbp, Address(rdi, Deoptimization::UnrollBlock::initial_info_offset_in_bytes()));
3229 
3230   // Stack bang to make sure there's enough room for these interpreter frames.



3231   if (UseStackBanging) {
3232     __ movl(rbx, Address(rdi ,Deoptimization::UnrollBlock::total_frame_sizes_offset_in_bytes()));
3233     __ bang_stack_size(rbx, rcx);
3234   }
3235 
3236 
3237   // Load array of frame pcs into ECX
3238   __ movl(rcx,Address(rdi,Deoptimization::UnrollBlock::frame_pcs_offset_in_bytes()));
3239 
3240   __ pop(rsi); // trash the pc
3241 
3242   // Load array of frame sizes into ESI
3243   __ movptr(rsi,Address(rdi,Deoptimization::UnrollBlock::frame_sizes_offset_in_bytes()));
3244 
3245   Address counter(rdi, Deoptimization::UnrollBlock::counter_temp_offset_in_bytes());
3246 
3247   __ movl(rbx, Address(rdi, Deoptimization::UnrollBlock::number_of_frames_offset_in_bytes()));
3248   __ movl(counter, rbx);
3249 
3250   // Now adjust the caller's stack to make up for the extra locals
3251   // but record the original sp so that we can save it in the skeletal interpreter
3252   // frame and the stack walking of interpreter_sender will get the unextended sp
3253   // value and not the "real" sp value.
3254 
3255   Address sp_temp(rdi, Deoptimization::UnrollBlock::sender_sp_temp_offset_in_bytes());




1786       __ jcc (Assembler::notZero, slowCase);
1787     }
1788 
1789     // get hash
1790     __ andptr(result, markOopDesc::hash_mask_in_place);
1791     // test if hashCode exists
1792     __ jcc  (Assembler::zero, slowCase);
1793     __ shrptr(result, markOopDesc::hash_shift);
1794     __ ret(0);
1795     __ bind (slowCase);
1796   }
1797 #endif // COMPILER1
1798 
1799   // The instruction at the verified entry point must be 5 bytes or longer
1800   // because it can be patched on the fly by make_non_entrant. The stack bang
1801   // instruction fits that requirement.
1802 
1803   // Generate stack overflow check
1804 
1805   if (UseStackBanging) {
1806     // See AbstractAssembler::generate_stack_overflow_check
1807     __ bang_stack_with_offset((StackShadowPages+1)*os::vm_page_size());
1808   } else {
1809     // need a 5 byte instruction to allow MT safe patching to non-entrant
1810     __ fat_nop();
1811   }
1812 
1813   // Generate a new frame for the wrapper.
1814   __ enter();
1815   // -2 because return address is already present and so is saved rbp
1816   __ subptr(rsp, stack_size - 2*wordSize);
1817 
1818   // Frame is now completed as far as size and linkage.
1819   int frame_complete = ((intptr_t)__ pc()) - start;
1820 
1821   // Calculate the difference between rsp and rbp,. We need to know it
1822   // after the native call because on windows Java Natives will pop
1823   // the arguments and it is painful to do rsp relative addressing
1824   // in a platform independent way. So after the call we switch to
1825   // rbp, relative addressing.
1826 
1827   int fp_adjustment = stack_size - 2*wordSize;


2991   // Pop all the frames we must move/replace.
2992   //
2993   // Frame picture (youngest to oldest)
2994   // 1: self-frame (no frame link)
2995   // 2: deopting frame  (no frame link)
2996   // 3: caller of deopting frame (could be compiled/interpreted).
2997   //
2998   // Note: by leaving the return address of self-frame on the stack
2999   // and using the size of frame 2 to adjust the stack
3000   // when we are done the return to frame 3 will still be on the stack.
3001 
3002   // Pop deoptimized frame
3003   __ addptr(rsp, Address(rdi,Deoptimization::UnrollBlock::size_of_deoptimized_frame_offset_in_bytes()));
3004 
3005   // sp should be pointing at the return address to the caller (3)
3006 
3007   // Pick up the initial fp we should save
3008   // restore rbp before stack bang because if stack overflow is thrown it needs to be pushed (and preserved)
3009   __ movptr(rbp, Address(rdi, Deoptimization::UnrollBlock::initial_info_offset_in_bytes()));
3010 
3011 #ifdef ASSERT
3012   // Compilers generate code that bang the stack by as much as the
3013   // interpreter would need. So this stack banging should never
3014   // trigger a fault. Verify that it does not on non product builds.
3015   if (UseStackBanging) {
3016     __ movl(rbx, Address(rdi ,Deoptimization::UnrollBlock::total_frame_sizes_offset_in_bytes()));
3017     __ bang_stack_size(rbx, rcx);
3018   }
3019 #endif
3020 
3021   // Load array of frame pcs into ECX
3022   __ movptr(rcx,Address(rdi,Deoptimization::UnrollBlock::frame_pcs_offset_in_bytes()));
3023 
3024   __ pop(rsi); // trash the old pc
3025 
3026   // Load array of frame sizes into ESI
3027   __ movptr(rsi,Address(rdi,Deoptimization::UnrollBlock::frame_sizes_offset_in_bytes()));
3028 
3029   Address counter(rdi, Deoptimization::UnrollBlock::counter_temp_offset_in_bytes());
3030 
3031   __ movl(rbx, Address(rdi, Deoptimization::UnrollBlock::number_of_frames_offset_in_bytes()));
3032   __ movl(counter, rbx);
3033 
3034   // Now adjust the caller's stack to make up for the extra locals
3035   // but record the original sp so that we can save it in the skeletal interpreter
3036   // frame and the stack walking of interpreter_sender will get the unextended sp
3037   // value and not the "real" sp value.
3038 
3039   Address sp_temp(rdi, Deoptimization::UnrollBlock::sender_sp_temp_offset_in_bytes());


3215   // Pop all the frames we must move/replace.
3216   //
3217   // Frame picture (youngest to oldest)
3218   // 1: self-frame (no frame link)
3219   // 2: deopting frame  (no frame link)
3220   // 3: caller of deopting frame (could be compiled/interpreted).
3221 
3222   // Pop self-frame.  We have no frame, and must rely only on EAX and ESP.
3223   __ addptr(rsp,(framesize-1)*wordSize);     // Epilog!
3224 
3225   // Pop deoptimized frame
3226   __ movl2ptr(rcx, Address(rdi,Deoptimization::UnrollBlock::size_of_deoptimized_frame_offset_in_bytes()));
3227   __ addptr(rsp, rcx);
3228 
3229   // sp should be pointing at the return address to the caller (3)
3230 
3231   // Pick up the initial fp we should save
3232   // restore rbp before stack bang because if stack overflow is thrown it needs to be pushed (and preserved)
3233   __ movptr(rbp, Address(rdi, Deoptimization::UnrollBlock::initial_info_offset_in_bytes()));
3234 
3235 #ifdef ASSERT
3236   // Compilers generate code that bang the stack by as much as the
3237   // interpreter would need. So this stack banging should never
3238   // trigger a fault. Verify that it does not on non product builds.
3239   if (UseStackBanging) {
3240     __ movl(rbx, Address(rdi ,Deoptimization::UnrollBlock::total_frame_sizes_offset_in_bytes()));
3241     __ bang_stack_size(rbx, rcx);
3242   }
3243 #endif
3244 
3245   // Load array of frame pcs into ECX
3246   __ movl(rcx,Address(rdi,Deoptimization::UnrollBlock::frame_pcs_offset_in_bytes()));
3247 
3248   __ pop(rsi); // trash the pc
3249 
3250   // Load array of frame sizes into ESI
3251   __ movptr(rsi,Address(rdi,Deoptimization::UnrollBlock::frame_sizes_offset_in_bytes()));
3252 
3253   Address counter(rdi, Deoptimization::UnrollBlock::counter_temp_offset_in_bytes());
3254 
3255   __ movl(rbx, Address(rdi, Deoptimization::UnrollBlock::number_of_frames_offset_in_bytes()));
3256   __ movl(counter, rbx);
3257 
3258   // Now adjust the caller's stack to make up for the extra locals
3259   // but record the original sp so that we can save it in the skeletal interpreter
3260   // frame and the stack walking of interpreter_sender will get the unextended sp
3261   // value and not the "real" sp value.
3262 
3263   Address sp_temp(rdi, Deoptimization::UnrollBlock::sender_sp_temp_offset_in_bytes());


src/cpu/x86/vm/sharedRuntime_x86_32.cpp
Index Unified diffs Context diffs Sdiffs Patch New Old Previous File Next File