Mercurial > hg > release > icedtea7-forest-2.2 > hotspot
changeset 3474:b86d003a0ed6
7158807: Revise stack management with volatile call sites
Summary: Add missing stack banging into method handle assebly code and throw a StackOverflowError.
Reviewed-by: jrose, twisti
author | kvn |
---|---|
date | Mon, 18 Jun 2012 09:50:43 -0700 |
parents | 90113e624cb5 |
children | 043ccbc6b82c |
files | src/cpu/sparc/vm/methodHandles_sparc.cpp src/cpu/x86/vm/methodHandles_x86.cpp |
diffstat | 2 files changed, 66 insertions(+), 3 deletions(-) [+] |
line wrap: on
line diff
--- a/src/cpu/sparc/vm/methodHandles_sparc.cpp Fri Jun 08 12:49:52 2012 -0400 +++ b/src/cpu/sparc/vm/methodHandles_sparc.cpp Mon Jun 18 09:50:43 2012 -0700 @@ -698,6 +698,17 @@ if (arg_slots.is_constant() && arg_slots.as_constant() == 0) return; + // We have to insert at least one word, so bang the stack. + if (UseStackBanging) { + // Save G3_method_handle since bang_stack_with_offset uses it as a temp register + __ mov(G3_method_handle, temp_reg); + int frame_size = (arg_slots.is_constant() ? -1 * arg_slots.as_constant() * wordSize : 0); + if (frame_size <= 0) + frame_size = 256 * Interpreter::stackElementSize; // conservative + __ generate_stack_overflow_check(frame_size); + __ mov(temp_reg, G3_method_handle); + } + assert_different_registers(argslot_reg, temp_reg, temp2_reg, temp3_reg, (!arg_slots.is_register() ? Gargs : arg_slots.as_register())); @@ -1702,6 +1713,14 @@ "copied argument(s) must fall within current frame"); } + if (UseStackBanging) { + // Save G3_method_handle since bang_stack_with_offset uses it as a temp register + __ mov(G3_method_handle, O3_scratch); + // Bang the stack before pushing args. + int frame_size = 256 * Interpreter::stackElementSize; // conservative + __ generate_stack_overflow_check(frame_size + sizeof(RicochetFrame)); + __ mov(O3_scratch, G3_method_handle); + } // insert location is always the bottom of the argument list: __ neg(O1_stack_move); push_arg_slots(_masm, O0_argslot, O1_stack_move, O2_scratch, O3_scratch); @@ -2118,6 +2137,18 @@ // The return handler will further cut back the stack when it takes // down the RF. Perhaps there is a way to streamline this further. + if (UseStackBanging) { + // Save G3_method_handle since bang_stack_with_offset uses it as a temp register + __ mov(G3_method_handle, O4_scratch); + // Bang the stack before recursive call. + // Even if slots == 0, we are inside a RicochetFrame. + int frame_size = collect_count.is_constant() ? collect_count.as_constant() * wordSize : -1; + if (frame_size < 0) { + frame_size = 256 * Interpreter::stackElementSize; // conservative + } + __ generate_stack_overflow_check(frame_size + sizeof(RicochetFrame)); + __ mov(O4_scratch, G3_method_handle); + } // State during recursive call: // ... keep1 | dest | dest=42 | keep3 | RF... | collect | bounce_pc | __ jump_to_method_handle_entry(G3_method_handle, O1_scratch);
--- a/src/cpu/x86/vm/methodHandles_x86.cpp Fri Jun 08 12:49:52 2012 -0400 +++ b/src/cpu/x86/vm/methodHandles_x86.cpp Mon Jun 18 09:50:43 2012 -0700 @@ -691,6 +691,14 @@ if (VerifyMethodHandles) verify_stack_move(_masm, arg_slots, -1); + // We have to insert at least one word, so bang the stack. + if (UseStackBanging) { + int frame_size = (arg_slots.is_constant() ? -1 * arg_slots.as_constant() * wordSize : 0); + if (frame_size <= 0) + frame_size = 256 * Interpreter::stackElementSize; // conservative + __ generate_stack_overflow_check(frame_size); + } + // Make space on the stack for the inserted argument(s). // Then pull down everything shallower than rax_argslot. // The stacked return address gets pulled down with everything else. @@ -1769,6 +1777,11 @@ "copied argument(s) must fall within current frame"); } + if (UseStackBanging) { + // Bang the stack before pushing args. + int frame_size = 256 * Interpreter::stackElementSize; // conservative + __ generate_stack_overflow_check(frame_size + sizeof(RicochetFrame)); + } // insert location is always the bottom of the argument list: Address insert_location = __ argument_address(constant(0)); int pre_arg_words = insert_location.disp() / wordSize; // return PC is pushed @@ -2206,6 +2219,15 @@ // The return handler will further cut back the stack when it takes // down the RF. Perhaps there is a way to streamline this further. + if (UseStackBanging) { + // Bang the stack before recursive call. + // Even if slots == 0, we are inside a RicochetFrame. + int frame_size = collect_count.is_constant() ? collect_count.as_constant() * wordSize : -1; + if (frame_size < 0) { + frame_size = 256 * Interpreter::stackElementSize; // conservative + } + __ generate_stack_overflow_check(frame_size + sizeof(RicochetFrame)); + } // State during recursive call: // ... keep1 | dest | dest=42 | keep3 | RF... | collect | bounce_pc | __ jump_to_method_handle_entry(rcx_recv, rdx_temp); @@ -2366,10 +2388,15 @@ // case in a 32-bit version of the VM) we have to save 'rsi' // on the stack because later on (at 'L_array_is_empty') 'rsi' // will be overwritten. - { if (rsi_temp == saved_last_sp) __ push(saved_last_sp); } + if (rsi_temp == saved_last_sp) { + __ push(saved_last_sp); + // Need to re-push return PC to keep it on stack top. + __ lea(saved_last_sp, ExternalAddress(SharedRuntime::ricochet_blob()->bounce_addr()).addr()); + __ push(saved_last_sp); + } // Also prepare a handy macro which restores 'rsi' if required. #define UNPUSH_RSI \ - { if (rsi_temp == saved_last_sp) __ pop(saved_last_sp); } + { if (rsi_temp == saved_last_sp) { __ pop(saved_last_sp); __ pop(saved_last_sp); } } __ jmp(L_array_is_empty); __ bind(L_skip); @@ -2382,7 +2409,12 @@ // called in the case of a null pointer exception will not be // confused by the extra value on the stack (it expects the // return pointer on top of the stack) - { if (rsi_temp == saved_last_sp) __ push(saved_last_sp); } + if (rsi_temp == saved_last_sp) { + __ push(saved_last_sp); + // Need to re-push return PC to keep it on stack top. + __ lea(saved_last_sp, ExternalAddress(SharedRuntime::ricochet_blob()->bounce_addr()).addr()); + __ push(saved_last_sp); + } // Check the array type. Register rbx_klass = rbx_temp;