src/cpu/mips/vm/runtime_mips_64.cpp

Tue, 04 Sep 2018 21:25:12 +0800

author
aoqi
date
Tue, 04 Sep 2018 21:25:12 +0800
changeset 9228
617b86d17edb
parent 9171
c67c94f5b85d
child 9251
1ccc5a3b3671
permissions
-rw-r--r--

#7517 mRegP match a0_RegP

aoqi@1 1 /*
aoqi@1 2 * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
aoqi@1 3 * Copyright (c) 2015, 2016, Loongson Technology. All rights reserved.
aoqi@1 4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
aoqi@1 5 *
aoqi@1 6 * This code is free software; you can redistribute it and/or modify it
aoqi@1 7 * under the terms of the GNU General Public License version 2 only, as
aoqi@1 8 * published by the Free Software Foundation.
aoqi@1 9 *
aoqi@1 10 * This code is distributed in the hope that it will be useful, but WITHOUT
aoqi@1 11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
aoqi@1 12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
aoqi@1 13 * version 2 for more details (a copy is included in the LICENSE file that
aoqi@1 14 * accompanied this code).
aoqi@1 15 *
aoqi@1 16 * You should have received a copy of the GNU General Public License version
aoqi@1 17 * 2 along with this work; if not, write to the Free Software Foundation,
aoqi@1 18 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
aoqi@1 19 *
aoqi@1 20 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
aoqi@1 21 * or visit www.oracle.com if you need additional information or have any
aoqi@1 22 * questions.
aoqi@1 23 *
aoqi@1 24 */
aoqi@1 25
aoqi@1 26 #include "precompiled.hpp"
aoqi@1 27 #ifdef COMPILER2
aoqi@1 28 #include "asm/macroAssembler.hpp"
aoqi@1 29 #include "asm/macroAssembler.inline.hpp"
aoqi@1 30 #include "classfile/systemDictionary.hpp"
aoqi@1 31 #include "code/vmreg.hpp"
aoqi@1 32 #include "interpreter/interpreter.hpp"
aoqi@1 33 #include "opto/runtime.hpp"
aoqi@1 34 #include "runtime/interfaceSupport.hpp"
aoqi@1 35 #include "runtime/sharedRuntime.hpp"
aoqi@1 36 #include "runtime/stubRoutines.hpp"
aoqi@1 37 #include "runtime/vframeArray.hpp"
aoqi@1 38 #include "utilities/globalDefinitions.hpp"
aoqi@1 39 #include "vmreg_mips.inline.hpp"
aoqi@1 40 #endif
aoqi@1 41
aoqi@1 42 #define __ masm->
aoqi@1 43
aoqi@1 44 //-------------- generate_exception_blob -----------
aoqi@1 45 // creates _exception_blob.
aoqi@1 46 // The exception blob is jumped to from a compiled method.
aoqi@1 47 // (see emit_exception_handler in sparc.ad file)
aoqi@6880 48 //
aoqi@1 49 // Given an exception pc at a call we call into the runtime for the
aoqi@1 50 // handler in this method. This handler might merely restore state
aoqi@1 51 // (i.e. callee save registers) unwind the frame and jump to the
aoqi@1 52 // exception handler for the nmethod if there is no Java level handler
aoqi@1 53 // for the nmethod.
aoqi@1 54 //
aoqi@1 55 // This code is entered with a jump, and left with a jump.
aoqi@6880 56 //
aoqi@1 57 // Arguments:
aoqi@1 58 // V0: exception oop
aoqi@1 59 // V1: exception pc
aoqi@1 60 //
aoqi@1 61 // Results:
aoqi@1 62 // A0: exception oop
aoqi@1 63 // A1: exception pc in caller or ???
aoqi@1 64 // jumps to: exception handler of caller
aoqi@6880 65 //
aoqi@1 66 // Note: the exception pc MUST be at a call (precise debug information)
aoqi@1 67 //
aoqi@9228 68 // [stubGenerator_mips.cpp] generate_forward_exception()
aoqi@9228 69 // |- V0, V1 are created
aoqi@9228 70 // |- T9 <= SharedRuntime::exception_handler_for_return_address
aoqi@9228 71 // `- jr T9
aoqi@9228 72 // `- the caller's exception_handler
aoqi@9228 73 // `- jr OptoRuntime::exception_blob
aoqi@9228 74 // `- here
aoqi@1 75 //
aoqi@1 76 void OptoRuntime::generate_exception_blob() {
aoqi@1 77 // Capture info about frame layout
aoqi@1 78 enum layout {
aoqi@1 79 fp_off,
aoqi@1 80 return_off, // slot for return address
aoqi@1 81 framesize
aoqi@1 82 };
aoqi@1 83
aoqi@1 84 // allocate space for the code
aoqi@1 85 ResourceMark rm;
aoqi@1 86 // setup code generation tools
aoqi@1 87 CodeBuffer buffer("exception_blob", 5120, 5120);
aoqi@1 88 MacroAssembler* masm = new MacroAssembler(&buffer);
aoqi@1 89
aoqi@1 90
aoqi@1 91 address start = __ pc();
aoqi@1 92
aoqi@1 93 __ daddiu(SP, SP, -1 * framesize * wordSize); // Prolog!
aoqi@1 94
aoqi@9228 95 // this frame will be treated as the original caller method.
aoqi@9228 96 // So, the return pc should be filled with the original exception pc.
aoqi@9228 97 // ref: X86's implementation
aoqi@6880 98 __ sd(V1, SP, return_off *wordSize); // return address
aoqi@6880 99 __ sd(FP, SP, fp_off *wordSize); // EBP
aoqi@1 100
aoqi@6880 101 // Save callee saved registers. None for UseSSE=0,
aoqi@1 102 // floats-only for UseSSE=1, and doubles for UseSSE=2.
aoqi@1 103
aoqi@1 104 __ daddiu(FP, SP, fp_off * wordSize);
aoqi@1 105
aoqi@1 106 // Store exception in Thread object. We cannot pass any arguments to the
aoqi@1 107 // handle_exception call, since we do not want to make any assumption
aoqi@1 108 // about the size of the frame where the exception happened in.
aoqi@1 109 Register thread = TREG;
aoqi@1 110
aoqi@1 111 #ifndef OPT_THREAD
aoqi@1 112 __ get_thread(thread);
aoqi@1 113 #endif
aoqi@1 114
aoqi@1 115 __ sd(V0, Address(thread, JavaThread::exception_oop_offset()));
aoqi@1 116 __ sd(V1, Address(thread, JavaThread::exception_pc_offset()));
aoqi@1 117
aoqi@1 118 // This call does all the hard work. It checks if an exception handler
aoqi@1 119 // exists in the method.
aoqi@1 120 // If so, it returns the handler address.
aoqi@1 121 // If not, it prepares for stack-unwinding, restoring the callee-save
aoqi@1 122 // registers of the frame being removed.
aoqi@1 123 __ set_last_Java_frame(thread, NOREG, NOREG, NULL);
aoqi@1 124
aoqi@1 125 __ move(AT, -(StackAlignmentInBytes));
aoqi@1 126 __ andr(SP, SP, AT); // Fix stack alignment as required by ABI
aoqi@1 127
aoqi@1 128 __ relocate(relocInfo::internal_pc_type);
aoqi@1 129
aoqi@1 130 {
fujie@373 131 long save_pc = (long)__ pc() + 48;
fujie@368 132 __ patchable_set48(AT, save_pc);
aoqi@1 133 }
aoqi@1 134 __ sd(AT, thread, in_bytes(JavaThread::last_Java_pc_offset()));
aoqi@1 135
aoqi@1 136 __ move(A0, thread);
fujie@373 137 __ patchable_set48(T9, (long)OptoRuntime::handle_exception_C);
aoqi@1 138 __ jalr(T9);
aoqi@1 139 __ delayed()->nop();
aoqi@1 140
aoqi@1 141 // Set an oopmap for the call site
aoqi@1 142 OopMapSet *oop_maps = new OopMapSet();
aoqi@1 143 OopMap* map = new OopMap( framesize, 0 );
aoqi@1 144
aoqi@1 145 oop_maps->add_gc_map( __ offset(), map);
aoqi@1 146
aoqi@1 147 #ifndef OPT_THREAD
aoqi@1 148 __ get_thread(thread);
aoqi@1 149 #endif
fujie@9171 150 __ reset_last_Java_frame(thread, true);
aoqi@1 151
aoqi@1 152 // Pop self-frame.
aoqi@1 153 __ leave(); // Epilog!
aoqi@1 154
aoqi@8865 155 // V0: exception handler
aoqi@1 156
aoqi@8865 157 // We have a handler in V0, (could be deopt blob)
aoqi@1 158 __ move(T9, V0);
aoqi@1 159
aoqi@1 160 #ifndef OPT_THREAD
aoqi@1 161 __ get_thread(thread);
aoqi@1 162 #endif
aoqi@1 163 // Get the exception
aoqi@1 164 __ ld(A0, Address(thread, JavaThread::exception_oop_offset()));
aoqi@1 165 // Get the exception pc in case we are deoptimized
aoqi@1 166 __ ld(A1, Address(thread, JavaThread::exception_pc_offset()));
aoqi@1 167 #ifdef ASSERT
aoqi@1 168 __ sd(R0, Address(thread, JavaThread::exception_handler_pc_offset()));
aoqi@1 169 __ sd(R0, Address(thread, JavaThread::exception_pc_offset()));
aoqi@1 170 #endif
aoqi@1 171 // Clear the exception oop so GC no longer processes it as a root.
aoqi@1 172 __ sd(R0, Address(thread, JavaThread::exception_oop_offset()));
aoqi@1 173
aoqi@9228 174 // Fix seg fault when running:
aoqi@9228 175 // Eclipse + Plugin + Debug As
aoqi@9228 176 // This is the only condition where C2 calls SharedRuntime::generate_deopt_blob()
aoqi@9228 177 //
aoqi@9228 178 // Ref: http://10.2.5.21:8000/projects/java/wiki/Jgj-log-2014-5-12_
aoqi@9228 179 //
aoqi@1 180 __ move(V0, A0);
aoqi@1 181 __ move(V1, A1);
aoqi@1 182
aoqi@1 183 // rax,: exception oop
aoqi@1 184 // rcx: exception handler
aoqi@1 185 // rdx: exception pc
aoqi@1 186 __ jr(T9);
aoqi@1 187 __ delayed()->nop();
aoqi@1 188
aoqi@1 189 // make sure all code is generated
aoqi@1 190 masm->flush();
aoqi@1 191
aoqi@1 192 _exception_blob = ExceptionBlob::create(&buffer, oop_maps, framesize);
aoqi@1 193 }

mercurial