src/cpu/mips/vm/runtime_mips_64.cpp

Thu, 24 May 2018 19:49:50 +0800

author
aoqi
date
Thu, 24 May 2018 19:49:50 +0800
changeset 8865
ffcdff41a92f
parent 6880
52ea28d233d2
child 9171
c67c94f5b85d
permissions
-rw-r--r--

some C1 fix
Contributed-by: chenhaoxuan, zhaixiang, aoqi

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@1 68 // 2012/9/14 Jin: [stubGenerator_mips.cpp] generate_forward_exception()
aoqi@1 69 // |- V0, V1 are created
aoqi@1 70 // |- T9 <= SharedRuntime::exception_handler_for_return_address
aoqi@1 71 // `- jr T9
aoqi@1 72 // `- the caller's exception_handler
aoqi@1 73 // `- jr OptoRuntime::exception_blob
aoqi@1 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@1 95 /* 2012/9.27 Jin: this frame will be treated as the original caller method.
aoqi@1 96 * So, the return pc should be filled with the original exception pc.
aoqi@1 97 * ref: X86's implementation
aoqi@1 98 */
aoqi@6880 99 __ sd(V1, SP, return_off *wordSize); // return address
aoqi@6880 100 __ sd(FP, SP, fp_off *wordSize); // EBP
aoqi@1 101
aoqi@6880 102 // Save callee saved registers. None for UseSSE=0,
aoqi@1 103 // floats-only for UseSSE=1, and doubles for UseSSE=2.
aoqi@1 104
aoqi@1 105 __ daddiu(FP, SP, fp_off * wordSize);
aoqi@1 106
aoqi@1 107 // Store exception in Thread object. We cannot pass any arguments to the
aoqi@1 108 // handle_exception call, since we do not want to make any assumption
aoqi@1 109 // about the size of the frame where the exception happened in.
aoqi@1 110 Register thread = TREG;
aoqi@1 111
aoqi@1 112 #ifndef OPT_THREAD
aoqi@1 113 __ get_thread(thread);
aoqi@1 114 #endif
aoqi@1 115
aoqi@1 116 __ sd(V0, Address(thread, JavaThread::exception_oop_offset()));
aoqi@1 117 __ sd(V1, Address(thread, JavaThread::exception_pc_offset()));
aoqi@1 118
aoqi@1 119 // This call does all the hard work. It checks if an exception handler
aoqi@1 120 // exists in the method.
aoqi@1 121 // If so, it returns the handler address.
aoqi@1 122 // If not, it prepares for stack-unwinding, restoring the callee-save
aoqi@1 123 // registers of the frame being removed.
aoqi@1 124 __ set_last_Java_frame(thread, NOREG, NOREG, NULL);
aoqi@1 125
aoqi@1 126 __ move(AT, -(StackAlignmentInBytes));
aoqi@1 127 __ andr(SP, SP, AT); // Fix stack alignment as required by ABI
aoqi@1 128
aoqi@1 129 __ relocate(relocInfo::internal_pc_type);
aoqi@1 130
aoqi@1 131 {
fujie@373 132 long save_pc = (long)__ pc() + 48;
fujie@368 133 __ patchable_set48(AT, save_pc);
aoqi@1 134 }
aoqi@1 135 __ sd(AT, thread, in_bytes(JavaThread::last_Java_pc_offset()));
aoqi@1 136
aoqi@1 137 __ move(A0, thread);
fujie@373 138 __ patchable_set48(T9, (long)OptoRuntime::handle_exception_C);
aoqi@1 139 __ jalr(T9);
aoqi@1 140 __ delayed()->nop();
aoqi@1 141
aoqi@1 142 // Set an oopmap for the call site
aoqi@1 143 OopMapSet *oop_maps = new OopMapSet();
aoqi@1 144 OopMap* map = new OopMap( framesize, 0 );
aoqi@1 145
aoqi@1 146 oop_maps->add_gc_map( __ offset(), map);
aoqi@1 147
aoqi@1 148 #ifndef OPT_THREAD
aoqi@1 149 __ get_thread(thread);
aoqi@1 150 #endif
aoqi@1 151 __ reset_last_Java_frame(thread, true, true);
aoqi@1 152
aoqi@1 153 // Pop self-frame.
aoqi@1 154 __ leave(); // Epilog!
aoqi@1 155
aoqi@8865 156 // V0: exception handler
aoqi@1 157
aoqi@8865 158 // We have a handler in V0, (could be deopt blob)
aoqi@1 159 __ move(T9, V0);
aoqi@1 160
aoqi@1 161 #ifndef OPT_THREAD
aoqi@1 162 __ get_thread(thread);
aoqi@1 163 #endif
aoqi@1 164 // Get the exception
aoqi@1 165 __ ld(A0, Address(thread, JavaThread::exception_oop_offset()));
aoqi@1 166 // Get the exception pc in case we are deoptimized
aoqi@1 167 __ ld(A1, Address(thread, JavaThread::exception_pc_offset()));
aoqi@1 168 #ifdef ASSERT
aoqi@1 169 __ sd(R0, Address(thread, JavaThread::exception_handler_pc_offset()));
aoqi@1 170 __ sd(R0, Address(thread, JavaThread::exception_pc_offset()));
aoqi@1 171 #endif
aoqi@1 172 // Clear the exception oop so GC no longer processes it as a root.
aoqi@1 173 __ sd(R0, Address(thread, JavaThread::exception_oop_offset()));
aoqi@1 174
aoqi@1 175 /* 2014/5/12 Jin: Fix seg fault when running:
aoqi@1 176 * Eclipse + Plugin + Debug As
aoqi@1 177 * This is the only condition where C2 calls SharedRuntime::generate_deopt_blob()
aoqi@1 178 *
aoqi@1 179 * Ref: http://10.2.5.21:8000/projects/java/wiki/Jgj-log-2014-5-12_
aoqi@1 180 */
aoqi@1 181 __ move(V0, A0);
aoqi@1 182 __ move(V1, A1);
aoqi@1 183
aoqi@1 184 // rax,: exception oop
aoqi@1 185 // rcx: exception handler
aoqi@1 186 // rdx: exception pc
aoqi@1 187 __ jr(T9);
aoqi@1 188 __ delayed()->nop();
aoqi@1 189
aoqi@1 190 // make sure all code is generated
aoqi@1 191 masm->flush();
aoqi@1 192
aoqi@1 193 _exception_blob = ExceptionBlob::create(&buffer, oop_maps, framesize);
aoqi@1 194 }

mercurial