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