# HG changeset patch # User coleenp # Date 1291063416 18000 # Node ID 0fc262af204ff29ed9c6638c01585360b188ba2c # Parent f95d63e2154a34660fd7b6774174a7c2dc5d9282 6780143: hs203t003 hits SIGSEGV/EXCEPTION_ACCESS_VIOLATION with -XX:+UseCompressedOops Summary: Using r12 as temporary register around call_VM trashes heapbase becausecall_VM doesn't always return immediately to following code (eg forward_exception, popframe and early return support). Reviewed-by: never, kvn diff -r f95d63e2154a -r 0fc262af204f src/cpu/x86/vm/assembler_x86.cpp --- a/src/cpu/x86/vm/assembler_x86.cpp Tue Nov 23 13:22:55 2010 -0800 +++ b/src/cpu/x86/vm/assembler_x86.cpp Mon Nov 29 15:43:36 2010 -0500 @@ -5538,17 +5538,14 @@ } void MacroAssembler::warn(const char* msg) { - push(r12); - movq(r12, rsp); + push(rsp); andq(rsp, -16); // align stack as required by push_CPU_state and call push_CPU_state(); // keeps alignment at 16 bytes lea(c_rarg0, ExternalAddress((address) msg)); call_VM_leaf(CAST_FROM_FN_PTR(address, warning), c_rarg0); pop_CPU_state(); - - movq(rsp, r12); - pop(r12); + pop(rsp); } #ifndef PRODUCT @@ -5860,6 +5857,10 @@ // debugging support assert(number_of_arguments >= 0 , "cannot have negative number of arguments"); LP64_ONLY(assert(java_thread == r15_thread, "unexpected register")); +#ifdef ASSERT + LP64_ONLY(if (UseCompressedOops) verify_heapbase("call_VM_base");) +#endif // ASSERT + assert(java_thread != oop_result , "cannot use the same register for java_thread & oop_result"); assert(java_thread != last_java_sp, "cannot use the same register for java_thread & last_java_sp"); diff -r f95d63e2154a -r 0fc262af204f src/cpu/x86/vm/interp_masm_x86_64.cpp --- a/src/cpu/x86/vm/interp_masm_x86_64.cpp Tue Nov 23 13:22:55 2010 -0800 +++ b/src/cpu/x86/vm/interp_masm_x86_64.cpp Mon Nov 29 15:43:36 2010 -0500 @@ -449,10 +449,9 @@ // JVMTI events, such as single-stepping, are implemented partly by avoiding running // compiled code in threads for which the event is enabled. Check here for // interp_only_mode if these events CAN be enabled. - get_thread(temp); // interp_only is an int, on little endian it is sufficient to test the byte only - // Is a cmpl faster (ce - cmpb(Address(temp, JavaThread::interp_only_mode_offset()), 0); + // Is a cmpl faster? + cmpb(Address(r15_thread, JavaThread::interp_only_mode_offset()), 0); jcc(Assembler::zero, run_compiled_code); jmp(Address(method, methodOopDesc::interpreter_entry_offset())); bind(run_compiled_code); diff -r f95d63e2154a -r 0fc262af204f src/cpu/x86/vm/templateInterpreter_x86_64.cpp --- a/src/cpu/x86/vm/templateInterpreter_x86_64.cpp Tue Nov 23 13:22:55 2010 -0800 +++ b/src/cpu/x86/vm/templateInterpreter_x86_64.cpp Mon Nov 29 15:43:36 2010 -0500 @@ -1069,7 +1069,7 @@ // runtime call by hand. // __ mov(c_rarg0, r15_thread); - __ mov(r12, rsp); // remember sp + __ mov(r12, rsp); // remember sp (can only use r12 if not using call_VM) __ subptr(rsp, frame::arg_reg_save_area_bytes); // windows __ andptr(rsp, -16); // align stack as required by ABI __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, JavaThread::check_special_condition_for_native_trans))); @@ -1116,7 +1116,7 @@ __ jcc(Assembler::notEqual, no_reguard); __ pusha(); // XXX only save smashed registers - __ mov(r12, rsp); // remember sp + __ mov(r12, rsp); // remember sp (can only use r12 if not using call_VM) __ subptr(rsp, frame::arg_reg_save_area_bytes); // windows __ andptr(rsp, -16); // align stack as required by ABI __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, SharedRuntime::reguard_yellow_pages))); @@ -1907,7 +1907,7 @@ assert(Interpreter::trace_code(t->tos_in()) != NULL, "entry must have been generated"); - __ mov(r12, rsp); // remember sp + __ mov(r12, rsp); // remember sp (can only use r12 if not using call_VM) __ andptr(rsp, -16); // align stack as required by ABI __ call(RuntimeAddress(Interpreter::trace_code(t->tos_in()))); __ mov(rsp, r12); // restore sp diff -r f95d63e2154a -r 0fc262af204f src/cpu/x86/vm/templateTable_x86_64.cpp --- a/src/cpu/x86/vm/templateTable_x86_64.cpp Tue Nov 23 13:22:55 2010 -0800 +++ b/src/cpu/x86/vm/templateTable_x86_64.cpp Mon Nov 29 15:43:36 2010 -0500 @@ -2762,7 +2762,7 @@ // access constant pool cache entry __ get_cache_entry_pointer_at_bcp(c_rarg2, rcx, 1); __ verify_oop(rax); - __ mov(r12, rax); // save object pointer before call_VM() clobbers it + __ push_ptr(rax); // save object pointer before call_VM() clobbers it __ mov(c_rarg1, rax); // c_rarg1: object pointer copied above // c_rarg2: cache entry pointer @@ -2770,8 +2770,7 @@ CAST_FROM_FN_PTR(address, InterpreterRuntime::post_field_access), c_rarg1, c_rarg2); - __ mov(rax, r12); // restore object pointer - __ reinit_heapbase(); + __ pop_ptr(rax); // restore object pointer __ bind(L1); } @@ -3365,10 +3364,7 @@ JVM_CONSTANT_Class); __ jcc(Assembler::equal, quicked); __ push(atos); // save receiver for result, and for GC - __ mov(r12, rcx); // save rcx XXX call_VM(rax, CAST_FROM_FN_PTR(address, InterpreterRuntime::quicken_io_cc)); - __ movq(rcx, r12); // restore rcx XXX - __ reinit_heapbase(); __ pop_ptr(rdx); // restore receiver __ jmpb(resolved); @@ -3422,11 +3418,9 @@ __ jcc(Assembler::equal, quicked); __ push(atos); // save receiver for result, and for GC - __ mov(r12, rcx); // save rcx call_VM(rax, CAST_FROM_FN_PTR(address, InterpreterRuntime::quicken_io_cc)); - __ movq(rcx, r12); // restore rcx - __ reinit_heapbase(); __ pop_ptr(rdx); // restore receiver + __ verify_oop(rdx); __ load_klass(rdx, rdx); __ jmpb(resolved);