src/cpu/ppc/vm/runtime_ppc.cpp

Thu, 06 Mar 2014 10:55:28 -0800

author
goetz
date
Thu, 06 Mar 2014 10:55:28 -0800
changeset 6511
31e80afe3fed
parent 6495
67fa91961822
child 6876
710a3c8b516e
permissions
-rw-r--r--

8035647: PPC64: Support for elf v2 abi.
Summary: ELFv2 ABI used by the little endian PowerPC64 on Linux.
Reviewed-by: kvn
Contributed-by: asmundak@google.com

goetz@6495 1 /*
goetz@6495 2 * Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved.
goetz@6495 3 * Copyright 2012, 2013 SAP AG. All rights reserved.
goetz@6495 4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
goetz@6495 5 *
goetz@6495 6 * This code is free software; you can redistribute it and/or modify it
goetz@6495 7 * under the terms of the GNU General Public License version 2 only, as
goetz@6495 8 * published by the Free Software Foundation.
goetz@6495 9 *
goetz@6495 10 * This code is distributed in the hope that it will be useful, but WITHOUT
goetz@6495 11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
goetz@6495 12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
goetz@6495 13 * version 2 for more details (a copy is included in the LICENSE file that
goetz@6495 14 * accompanied this code).
goetz@6495 15 *
goetz@6495 16 * You should have received a copy of the GNU General Public License version
goetz@6495 17 * 2 along with this work; if not, write to the Free Software Foundation,
goetz@6495 18 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
goetz@6495 19 *
goetz@6495 20 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
goetz@6495 21 * or visit www.oracle.com if you need additional information or have any
goetz@6495 22 * questions.
goetz@6495 23 *
goetz@6495 24 */
goetz@6495 25
goetz@6495 26 #include "precompiled.hpp"
goetz@6495 27 #ifdef COMPILER2
goetz@6495 28 #include "asm/assembler.inline.hpp"
goetz@6495 29 #include "asm/macroAssembler.inline.hpp"
goetz@6495 30 #include "classfile/systemDictionary.hpp"
goetz@6495 31 #include "code/vmreg.hpp"
goetz@6495 32 #include "interpreter/interpreter.hpp"
goetz@6495 33 #include "nativeInst_ppc.hpp"
goetz@6495 34 #include "opto/runtime.hpp"
goetz@6495 35 #include "runtime/interfaceSupport.hpp"
goetz@6495 36 #include "runtime/sharedRuntime.hpp"
goetz@6495 37 #include "runtime/stubRoutines.hpp"
goetz@6495 38 #include "runtime/vframeArray.hpp"
goetz@6495 39 #include "utilities/globalDefinitions.hpp"
goetz@6495 40 #include "vmreg_ppc.inline.hpp"
goetz@6495 41 #endif
goetz@6495 42
goetz@6495 43 #define __ masm->
goetz@6495 44
goetz@6495 45
goetz@6495 46 #ifdef COMPILER2
goetz@6495 47
goetz@6495 48 // SP adjustment (must use unextended SP) for method handle call sites
goetz@6495 49 // during exception handling.
goetz@6495 50 static intptr_t adjust_SP_for_methodhandle_callsite(JavaThread *thread) {
goetz@6495 51 RegisterMap map(thread, false);
goetz@6495 52 // The frame constructor will do the correction for us (see frame::adjust_unextended_SP).
goetz@6495 53 frame mh_caller_frame = thread->last_frame().sender(&map);
goetz@6495 54 assert(mh_caller_frame.is_compiled_frame(), "Only may reach here for compiled MH call sites");
goetz@6495 55 return (intptr_t) mh_caller_frame.unextended_sp();
goetz@6495 56 }
goetz@6495 57
goetz@6495 58 //------------------------------generate_exception_blob---------------------------
goetz@6495 59 // Creates exception blob at the end.
goetz@6495 60 // Using exception blob, this code is jumped from a compiled method.
goetz@6495 61 //
goetz@6495 62 // Given an exception pc at a call we call into the runtime for the
goetz@6495 63 // handler in this method. This handler might merely restore state
goetz@6495 64 // (i.e. callee save registers) unwind the frame and jump to the
goetz@6495 65 // exception handler for the nmethod if there is no Java level handler
goetz@6495 66 // for the nmethod.
goetz@6495 67 //
goetz@6495 68 // This code is entered with a jmp.
goetz@6495 69 //
goetz@6495 70 // Arguments:
goetz@6495 71 // R3_ARG1: exception oop
goetz@6495 72 // R4_ARG2: exception pc
goetz@6495 73 //
goetz@6495 74 // Results:
goetz@6495 75 // R3_ARG1: exception oop
goetz@6495 76 // R4_ARG2: exception pc in caller
goetz@6495 77 // destination: exception handler of caller
goetz@6495 78 //
goetz@6495 79 // Note: the exception pc MUST be at a call (precise debug information)
goetz@6495 80 //
goetz@6495 81 void OptoRuntime::generate_exception_blob() {
goetz@6495 82 // Allocate space for the code.
goetz@6495 83 ResourceMark rm;
goetz@6495 84 // Setup code generation tools.
goetz@6495 85 CodeBuffer buffer("exception_blob", 2048, 1024);
goetz@6495 86 InterpreterMacroAssembler* masm = new InterpreterMacroAssembler(&buffer);
goetz@6495 87
goetz@6495 88 address start = __ pc();
goetz@6495 89
goetz@6511 90 int frame_size_in_bytes = frame::abi_reg_args_size;
goetz@6495 91 OopMap* map = new OopMap(frame_size_in_bytes / sizeof(jint), 0);
goetz@6495 92
goetz@6495 93 // Exception pc is 'return address' for stack walker.
goetz@6495 94 __ std(R4_ARG2/*exception pc*/, _abi(lr), R1_SP);
goetz@6495 95
goetz@6495 96 // Store the exception in the Thread object.
goetz@6495 97 __ std(R3_ARG1/*exception oop*/, in_bytes(JavaThread::exception_oop_offset()), R16_thread);
goetz@6495 98 __ std(R4_ARG2/*exception pc*/, in_bytes(JavaThread::exception_pc_offset()), R16_thread);
goetz@6495 99
goetz@6495 100 // Save callee-saved registers.
goetz@6495 101 // Push a C frame for the exception blob. It is needed for the C call later on.
goetz@6511 102 __ push_frame_reg_args(0, R11_scratch1);
goetz@6495 103
goetz@6495 104 // This call does all the hard work. It checks if an exception handler
goetz@6495 105 // exists in the method.
goetz@6495 106 // If so, it returns the handler address.
goetz@6495 107 // If not, it prepares for stack-unwinding, restoring the callee-save
goetz@6495 108 // registers of the frame being removed.
goetz@6495 109 __ set_last_Java_frame(/*sp=*/R1_SP, noreg);
goetz@6495 110
goetz@6495 111 __ mr(R3_ARG1, R16_thread);
goetz@6511 112 #if defined(ABI_ELFv2)
goetz@6511 113 __ call_c((address) OptoRuntime::handle_exception_C, relocInfo::none);
goetz@6511 114 #else
goetz@6495 115 __ call_c(CAST_FROM_FN_PTR(FunctionDescriptor*, OptoRuntime::handle_exception_C),
goetz@6495 116 relocInfo::none);
goetz@6511 117 #endif
goetz@6495 118 address calls_return_pc = __ last_calls_return_pc();
goetz@6495 119 # ifdef ASSERT
goetz@6495 120 __ cmpdi(CCR0, R3_RET, 0);
goetz@6495 121 __ asm_assert_ne("handle_exception_C must not return NULL", 0x601);
goetz@6495 122 # endif
goetz@6495 123
goetz@6495 124 // Set an oopmap for the call site. This oopmap will only be used if we
goetz@6495 125 // are unwinding the stack. Hence, all locations will be dead.
goetz@6495 126 // Callee-saved registers will be the same as the frame above (i.e.,
goetz@6495 127 // handle_exception_stub), since they were restored when we got the
goetz@6495 128 // exception.
goetz@6495 129 OopMapSet* oop_maps = new OopMapSet();
goetz@6495 130 oop_maps->add_gc_map(calls_return_pc - start, map);
goetz@6495 131
goetz@6495 132 // Get unextended_sp for method handle call sites.
goetz@6495 133 Label mh_callsite, mh_done; // Use a 2nd c call if it's a method handle call site.
goetz@6495 134 __ lwa(R4_ARG2, in_bytes(JavaThread::is_method_handle_return_offset()), R16_thread);
goetz@6495 135 __ cmpwi(CCR0, R4_ARG2, 0);
goetz@6495 136 __ bne(CCR0, mh_callsite);
goetz@6495 137
goetz@6495 138 __ mtctr(R3_RET); // Move address of exception handler to SR_CTR.
goetz@6495 139 __ reset_last_Java_frame();
goetz@6495 140 __ pop_frame();
goetz@6495 141
goetz@6495 142 __ bind(mh_done);
goetz@6495 143 // We have a handler in register SR_CTR (could be deopt blob).
goetz@6495 144
goetz@6495 145 // Get the exception oop.
goetz@6495 146 __ ld(R3_ARG1, in_bytes(JavaThread::exception_oop_offset()), R16_thread);
goetz@6495 147
goetz@6495 148 // Get the exception pc in case we are deoptimized.
goetz@6495 149 __ ld(R4_ARG2, in_bytes(JavaThread::exception_pc_offset()), R16_thread);
goetz@6495 150
goetz@6495 151 // Reset thread values.
goetz@6495 152 __ li(R0, 0);
goetz@6495 153 #ifdef ASSERT
goetz@6495 154 __ std(R0, in_bytes(JavaThread::exception_handler_pc_offset()), R16_thread);
goetz@6495 155 __ std(R0, in_bytes(JavaThread::exception_pc_offset()), R16_thread);
goetz@6495 156 #endif
goetz@6495 157 // Clear the exception oop so GC no longer processes it as a root.
goetz@6495 158 __ std(R0, in_bytes(JavaThread::exception_oop_offset()), R16_thread);
goetz@6495 159
goetz@6495 160 // Move exception pc into SR_LR.
goetz@6495 161 __ mtlr(R4_ARG2);
goetz@6495 162 __ bctr();
goetz@6495 163
goetz@6495 164
goetz@6495 165 // Same as above, but also set sp to unextended_sp.
goetz@6495 166 __ bind(mh_callsite);
goetz@6495 167 __ mr(R31, R3_RET); // Save branch address.
goetz@6495 168 __ mr(R3_ARG1, R16_thread);
goetz@6511 169 #if defined(ABI_ELFv2)
goetz@6511 170 __ call_c((address) adjust_SP_for_methodhandle_callsite, relocInfo::none);
goetz@6511 171 #else
goetz@6495 172 __ call_c(CAST_FROM_FN_PTR(FunctionDescriptor*, adjust_SP_for_methodhandle_callsite), relocInfo::none);
goetz@6511 173 #endif
goetz@6495 174 // Returns unextended_sp in R3_RET.
goetz@6495 175
goetz@6495 176 __ mtctr(R31); // Move address of exception handler to SR_CTR.
goetz@6495 177 __ reset_last_Java_frame();
goetz@6495 178
goetz@6495 179 __ mr(R1_SP, R3_RET); // Set sp to unextended_sp.
goetz@6495 180 __ b(mh_done);
goetz@6495 181
goetz@6495 182
goetz@6495 183 // Make sure all code is generated.
goetz@6495 184 masm->flush();
goetz@6495 185
goetz@6495 186 // Set exception blob.
goetz@6495 187 _exception_blob = ExceptionBlob::create(&buffer, oop_maps,
goetz@6495 188 frame_size_in_bytes/wordSize);
goetz@6495 189 }
goetz@6495 190
goetz@6495 191 #endif // COMPILER2

mercurial