Mercurial > hg > truffle
annotate src/cpu/x86/vm/c1_Runtime1_x86.cpp @ 3096:8073f5ad1d87
IdealGraphVisualizer: Rename predecessors to "Nodes Above" and successors to "Nodes Below" and actions "Expand Predecessors" and "Expand Successors" to "Expand Above" and "Expand Below" to avoid ambiguity with the Graal concept of successors and predecessors
author | Peter Hofer <peter.hofer@jku.at> |
---|---|
date | Wed, 29 Jun 2011 18:27:14 +0200 |
parents | 75a99b4f1c98 |
children | 28ba2439034f |
rev | line source |
---|---|
0 | 1 /* |
2100
b1a2afa37ec4
7003271: Hotspot should track cumulative Java heap bytes allocated on a per-thread basis
phh
parents:
2002
diff
changeset
|
2 * Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved. |
0 | 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
4 * | |
5 * This code is free software; you can redistribute it and/or modify it | |
6 * under the terms of the GNU General Public License version 2 only, as | |
7 * published by the Free Software Foundation. | |
8 * | |
9 * This code is distributed in the hope that it will be useful, but WITHOUT | |
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
12 * version 2 for more details (a copy is included in the LICENSE file that | |
13 * accompanied this code). | |
14 * | |
15 * You should have received a copy of the GNU General Public License version | |
16 * 2 along with this work; if not, write to the Free Software Foundation, | |
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | |
18 * | |
1552
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1368
diff
changeset
|
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1368
diff
changeset
|
20 * or visit www.oracle.com if you need additional information or have any |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1368
diff
changeset
|
21 * questions. |
0 | 22 * |
23 */ | |
24 | |
1972 | 25 #include "precompiled.hpp" |
2415
09f96c3ff1ad
7032388: guarantee(VM_Version::supports_cmov()) failed: illegal instruction on i586 after 6919934
twisti
parents:
2321
diff
changeset
|
26 #include "asm/assembler.hpp" |
1972 | 27 #include "c1/c1_Defs.hpp" |
28 #include "c1/c1_MacroAssembler.hpp" | |
29 #include "c1/c1_Runtime1.hpp" | |
30 #include "interpreter/interpreter.hpp" | |
31 #include "nativeInst_x86.hpp" | |
32 #include "oops/compiledICHolderOop.hpp" | |
33 #include "oops/oop.inline.hpp" | |
34 #include "prims/jvmtiExport.hpp" | |
35 #include "register_x86.hpp" | |
36 #include "runtime/sharedRuntime.hpp" | |
37 #include "runtime/signature.hpp" | |
38 #include "runtime/vframeArray.hpp" | |
39 #include "vmreg_x86.inline.hpp" | |
0 | 40 |
2662
440ceca8e3d7
Add exception handlers only to Invoke and Throw instructions. Deoptimize if there is an exception in a HotSpot runtime call.
Thomas Wuerthinger <thomas@wuerthinger.net>
parents:
2608
diff
changeset
|
41 static void restore_live_registers(StubAssembler* sasm, bool restore_fpu_registers = true); |
0 | 42 |
43 // Implementation of StubAssembler | |
44 | |
45 int StubAssembler::call_RT(Register oop_result1, Register oop_result2, address entry, int args_size) { | |
46 // setup registers | |
304 | 47 const Register thread = NOT_LP64(rdi) LP64_ONLY(r15_thread); // is callee-saved register (Visual C++ calling conventions) |
0 | 48 assert(!(oop_result1->is_valid() || oop_result2->is_valid()) || oop_result1 != oop_result2, "registers must be different"); |
49 assert(oop_result1 != thread && oop_result2 != thread, "registers must be different"); | |
50 assert(args_size >= 0, "illegal args_size"); | |
51 | |
304 | 52 #ifdef _LP64 |
53 mov(c_rarg0, thread); | |
54 set_num_rt_args(0); // Nothing on stack | |
55 #else | |
0 | 56 set_num_rt_args(1 + args_size); |
57 | |
58 // push java thread (becomes first argument of C function) | |
59 get_thread(thread); | |
304 | 60 push(thread); |
61 #endif // _LP64 | |
0 | 62 |
63 set_last_Java_frame(thread, noreg, rbp, NULL); | |
304 | 64 |
0 | 65 // do the call |
66 call(RuntimeAddress(entry)); | |
67 int call_offset = offset(); | |
68 // verify callee-saved register | |
69 #ifdef ASSERT | |
70 guarantee(thread != rax, "change this code"); | |
304 | 71 push(rax); |
0 | 72 { Label L; |
73 get_thread(rax); | |
304 | 74 cmpptr(thread, rax); |
0 | 75 jcc(Assembler::equal, L); |
76 int3(); | |
77 stop("StubAssembler::call_RT: rdi not callee saved?"); | |
78 bind(L); | |
79 } | |
304 | 80 pop(rax); |
0 | 81 #endif |
82 reset_last_Java_frame(thread, true, false); | |
83 | |
84 // discard thread and arguments | |
304 | 85 NOT_LP64(addptr(rsp, num_rt_args()*BytesPerWord)); |
0 | 86 |
87 // check for pending exceptions | |
88 { Label L; | |
304 | 89 cmpptr(Address(thread, Thread::pending_exception_offset()), (int32_t)NULL_WORD); |
0 | 90 jcc(Assembler::equal, L); |
91 // exception pending => remove activation and forward to exception handler | |
304 | 92 movptr(rax, Address(thread, Thread::pending_exception_offset())); |
0 | 93 // make sure that the vm_results are cleared |
94 if (oop_result1->is_valid()) { | |
512
db4caa99ef11
6787106: Hotspot 32 bit build fails on platforms having different definitions for intptr_t & int32_t
xlu
parents:
380
diff
changeset
|
95 movptr(Address(thread, JavaThread::vm_result_offset()), NULL_WORD); |
0 | 96 } |
97 if (oop_result2->is_valid()) { | |
512
db4caa99ef11
6787106: Hotspot 32 bit build fails on platforms having different definitions for intptr_t & int32_t
xlu
parents:
380
diff
changeset
|
98 movptr(Address(thread, JavaThread::vm_result_2_offset()), NULL_WORD); |
0 | 99 } |
2662
440ceca8e3d7
Add exception handlers only to Invoke and Throw instructions. Deoptimize if there is an exception in a HotSpot runtime call.
Thomas Wuerthinger <thomas@wuerthinger.net>
parents:
2608
diff
changeset
|
100 // (tw) Deoptimize in case of an exception. |
440ceca8e3d7
Add exception handlers only to Invoke and Throw instructions. Deoptimize if there is an exception in a HotSpot runtime call.
Thomas Wuerthinger <thomas@wuerthinger.net>
parents:
2608
diff
changeset
|
101 restore_live_registers(this, false); |
440ceca8e3d7
Add exception handlers only to Invoke and Throw instructions. Deoptimize if there is an exception in a HotSpot runtime call.
Thomas Wuerthinger <thomas@wuerthinger.net>
parents:
2608
diff
changeset
|
102 movptr(Address(thread, Thread::pending_exception_offset()), NULL_WORD); |
440ceca8e3d7
Add exception handlers only to Invoke and Throw instructions. Deoptimize if there is an exception in a HotSpot runtime call.
Thomas Wuerthinger <thomas@wuerthinger.net>
parents:
2608
diff
changeset
|
103 leave(); |
440ceca8e3d7
Add exception handlers only to Invoke and Throw instructions. Deoptimize if there is an exception in a HotSpot runtime call.
Thomas Wuerthinger <thomas@wuerthinger.net>
parents:
2608
diff
changeset
|
104 jump(RuntimeAddress(SharedRuntime::deopt_blob()->uncommon_trap())); |
0 | 105 bind(L); |
106 } | |
107 // get oop results if there are any and reset the values in the thread | |
108 if (oop_result1->is_valid()) { | |
304 | 109 movptr(oop_result1, Address(thread, JavaThread::vm_result_offset())); |
512
db4caa99ef11
6787106: Hotspot 32 bit build fails on platforms having different definitions for intptr_t & int32_t
xlu
parents:
380
diff
changeset
|
110 movptr(Address(thread, JavaThread::vm_result_offset()), NULL_WORD); |
0 | 111 verify_oop(oop_result1); |
112 } | |
113 if (oop_result2->is_valid()) { | |
304 | 114 movptr(oop_result2, Address(thread, JavaThread::vm_result_2_offset())); |
512
db4caa99ef11
6787106: Hotspot 32 bit build fails on platforms having different definitions for intptr_t & int32_t
xlu
parents:
380
diff
changeset
|
115 movptr(Address(thread, JavaThread::vm_result_2_offset()), NULL_WORD); |
0 | 116 verify_oop(oop_result2); |
117 } | |
118 return call_offset; | |
119 } | |
120 | |
121 | |
122 int StubAssembler::call_RT(Register oop_result1, Register oop_result2, address entry, Register arg1) { | |
304 | 123 #ifdef _LP64 |
124 mov(c_rarg1, arg1); | |
125 #else | |
126 push(arg1); | |
127 #endif // _LP64 | |
0 | 128 return call_RT(oop_result1, oop_result2, entry, 1); |
129 } | |
130 | |
131 | |
132 int StubAssembler::call_RT(Register oop_result1, Register oop_result2, address entry, Register arg1, Register arg2) { | |
304 | 133 #ifdef _LP64 |
134 if (c_rarg1 == arg2) { | |
135 if (c_rarg2 == arg1) { | |
136 xchgq(arg1, arg2); | |
137 } else { | |
138 mov(c_rarg2, arg2); | |
139 mov(c_rarg1, arg1); | |
140 } | |
141 } else { | |
142 mov(c_rarg1, arg1); | |
143 mov(c_rarg2, arg2); | |
144 } | |
145 #else | |
146 push(arg2); | |
147 push(arg1); | |
148 #endif // _LP64 | |
0 | 149 return call_RT(oop_result1, oop_result2, entry, 2); |
150 } | |
151 | |
152 | |
153 int StubAssembler::call_RT(Register oop_result1, Register oop_result2, address entry, Register arg1, Register arg2, Register arg3) { | |
304 | 154 #ifdef _LP64 |
155 // if there is any conflict use the stack | |
156 if (arg1 == c_rarg2 || arg1 == c_rarg3 || | |
157 arg2 == c_rarg1 || arg1 == c_rarg3 || | |
158 arg3 == c_rarg1 || arg1 == c_rarg2) { | |
159 push(arg3); | |
160 push(arg2); | |
161 push(arg1); | |
162 pop(c_rarg1); | |
163 pop(c_rarg2); | |
164 pop(c_rarg3); | |
165 } else { | |
166 mov(c_rarg1, arg1); | |
167 mov(c_rarg2, arg2); | |
168 mov(c_rarg3, arg3); | |
169 } | |
170 #else | |
171 push(arg3); | |
172 push(arg2); | |
173 push(arg1); | |
174 #endif // _LP64 | |
0 | 175 return call_RT(oop_result1, oop_result2, entry, 3); |
176 } | |
177 | |
178 | |
179 // Implementation of StubFrame | |
180 | |
181 class StubFrame: public StackObj { | |
182 private: | |
183 StubAssembler* _sasm; | |
184 | |
185 public: | |
186 StubFrame(StubAssembler* sasm, const char* name, bool must_gc_arguments); | |
187 void load_argument(int offset_in_words, Register reg); | |
188 | |
189 ~StubFrame(); | |
190 }; | |
191 | |
192 | |
193 #define __ _sasm-> | |
194 | |
195 StubFrame::StubFrame(StubAssembler* sasm, const char* name, bool must_gc_arguments) { | |
196 _sasm = sasm; | |
197 __ set_info(name, must_gc_arguments); | |
198 __ enter(); | |
199 } | |
200 | |
201 // load parameters that were stored with LIR_Assembler::store_parameter | |
202 // Note: offsets for store_parameter and load_argument must match | |
203 void StubFrame::load_argument(int offset_in_words, Register reg) { | |
204 // rbp, + 0: link | |
205 // + 1: return address | |
206 // + 2: argument with offset 0 | |
207 // + 3: argument with offset 1 | |
208 // + 4: ... | |
209 | |
304 | 210 __ movptr(reg, Address(rbp, (offset_in_words + 2) * BytesPerWord)); |
0 | 211 } |
212 | |
213 | |
214 StubFrame::~StubFrame() { | |
215 __ leave(); | |
216 __ ret(0); | |
217 } | |
218 | |
219 #undef __ | |
220 | |
221 | |
222 // Implementation of Runtime1 | |
223 | |
224 #define __ sasm-> | |
225 | |
304 | 226 const int float_regs_as_doubles_size_in_slots = pd_nof_fpu_regs_frame_map * 2; |
227 const int xmm_regs_as_doubles_size_in_slots = FrameMap::nof_xmm_regs * 2; | |
0 | 228 |
229 // Stack layout for saving/restoring all the registers needed during a runtime | |
230 // call (this includes deoptimization) | |
231 // Note: note that users of this frame may well have arguments to some runtime | |
232 // while these values are on the stack. These positions neglect those arguments | |
233 // but the code in save_live_registers will take the argument count into | |
234 // account. | |
235 // | |
304 | 236 #ifdef _LP64 |
237 #define SLOT2(x) x, | |
238 #define SLOT_PER_WORD 2 | |
239 #else | |
240 #define SLOT2(x) | |
241 #define SLOT_PER_WORD 1 | |
242 #endif // _LP64 | |
243 | |
0 | 244 enum reg_save_layout { |
304 | 245 // 64bit needs to keep stack 16 byte aligned. So we add some alignment dummies to make that |
246 // happen and will assert if the stack size we create is misaligned | |
247 #ifdef _LP64 | |
248 align_dummy_0, align_dummy_1, | |
249 #endif // _LP64 | |
2321
1b4e6a5d98e0
7012914: JSR 292 MethodHandlesTest C1: frame::verify_return_pc(return_address) failed: must be a return pc
twisti
parents:
2168
diff
changeset
|
250 #ifdef _WIN64 |
1b4e6a5d98e0
7012914: JSR 292 MethodHandlesTest C1: frame::verify_return_pc(return_address) failed: must be a return pc
twisti
parents:
2168
diff
changeset
|
251 // Windows always allocates space for it's argument registers (see |
1b4e6a5d98e0
7012914: JSR 292 MethodHandlesTest C1: frame::verify_return_pc(return_address) failed: must be a return pc
twisti
parents:
2168
diff
changeset
|
252 // frame::arg_reg_save_area_bytes). |
1b4e6a5d98e0
7012914: JSR 292 MethodHandlesTest C1: frame::verify_return_pc(return_address) failed: must be a return pc
twisti
parents:
2168
diff
changeset
|
253 arg_reg_save_1, arg_reg_save_1H, // 0, 4 |
1b4e6a5d98e0
7012914: JSR 292 MethodHandlesTest C1: frame::verify_return_pc(return_address) failed: must be a return pc
twisti
parents:
2168
diff
changeset
|
254 arg_reg_save_2, arg_reg_save_2H, // 8, 12 |
1b4e6a5d98e0
7012914: JSR 292 MethodHandlesTest C1: frame::verify_return_pc(return_address) failed: must be a return pc
twisti
parents:
2168
diff
changeset
|
255 arg_reg_save_3, arg_reg_save_3H, // 16, 20 |
1b4e6a5d98e0
7012914: JSR 292 MethodHandlesTest C1: frame::verify_return_pc(return_address) failed: must be a return pc
twisti
parents:
2168
diff
changeset
|
256 arg_reg_save_4, arg_reg_save_4H, // 24, 28 |
1b4e6a5d98e0
7012914: JSR 292 MethodHandlesTest C1: frame::verify_return_pc(return_address) failed: must be a return pc
twisti
parents:
2168
diff
changeset
|
257 #endif // _WIN64 |
304 | 258 xmm_regs_as_doubles_off, // 32 |
259 float_regs_as_doubles_off = xmm_regs_as_doubles_off + xmm_regs_as_doubles_size_in_slots, // 160 | |
260 fpu_state_off = float_regs_as_doubles_off + float_regs_as_doubles_size_in_slots, // 224 | |
261 // fpu_state_end_off is exclusive | |
262 fpu_state_end_off = fpu_state_off + (FPUStateSizeInWords / SLOT_PER_WORD), // 352 | |
263 marker = fpu_state_end_off, SLOT2(markerH) // 352, 356 | |
264 extra_space_offset, // 360 | |
265 #ifdef _LP64 | |
266 r15_off = extra_space_offset, r15H_off, // 360, 364 | |
267 r14_off, r14H_off, // 368, 372 | |
268 r13_off, r13H_off, // 376, 380 | |
269 r12_off, r12H_off, // 384, 388 | |
270 r11_off, r11H_off, // 392, 396 | |
271 r10_off, r10H_off, // 400, 404 | |
272 r9_off, r9H_off, // 408, 412 | |
273 r8_off, r8H_off, // 416, 420 | |
274 rdi_off, rdiH_off, // 424, 428 | |
275 #else | |
0 | 276 rdi_off = extra_space_offset, |
304 | 277 #endif // _LP64 |
278 rsi_off, SLOT2(rsiH_off) // 432, 436 | |
279 rbp_off, SLOT2(rbpH_off) // 440, 444 | |
280 rsp_off, SLOT2(rspH_off) // 448, 452 | |
281 rbx_off, SLOT2(rbxH_off) // 456, 460 | |
282 rdx_off, SLOT2(rdxH_off) // 464, 468 | |
283 rcx_off, SLOT2(rcxH_off) // 472, 476 | |
284 rax_off, SLOT2(raxH_off) // 480, 484 | |
285 saved_rbp_off, SLOT2(saved_rbpH_off) // 488, 492 | |
286 return_off, SLOT2(returnH_off) // 496, 500 | |
2321
1b4e6a5d98e0
7012914: JSR 292 MethodHandlesTest C1: frame::verify_return_pc(return_address) failed: must be a return pc
twisti
parents:
2168
diff
changeset
|
287 reg_save_frame_size // As noted: neglects any parameters to runtime // 504 |
0 | 288 }; |
289 | |
290 | |
291 | |
292 // Save off registers which might be killed by calls into the runtime. | |
293 // Tries to smart of about FP registers. In particular we separate | |
294 // saving and describing the FPU registers for deoptimization since we | |
295 // have to save the FPU registers twice if we describe them and on P4 | |
296 // saving FPU registers which don't contain anything appears | |
297 // expensive. The deopt blob is the only thing which needs to | |
298 // describe FPU registers. In all other cases it should be sufficient | |
299 // to simply save their current value. | |
300 | |
301 static OopMap* generate_oop_map(StubAssembler* sasm, int num_rt_args, | |
302 bool save_fpu_registers = true) { | |
304 | 303 |
304 // In 64bit all the args are in regs so there are no additional stack slots | |
305 LP64_ONLY(num_rt_args = 0); | |
306 LP64_ONLY(assert((reg_save_frame_size * VMRegImpl::stack_slot_size) % 16 == 0, "must be 16 byte aligned");) | |
307 int frame_size_in_slots = reg_save_frame_size + num_rt_args; // args + thread | |
308 sasm->set_frame_size(frame_size_in_slots / VMRegImpl::slots_per_word ); | |
0 | 309 |
310 // record saved value locations in an OopMap | |
311 // locations are offsets from sp after runtime call; num_rt_args is number of arguments in call, including thread | |
304 | 312 OopMap* map = new OopMap(frame_size_in_slots, 0); |
0 | 313 map->set_callee_saved(VMRegImpl::stack2reg(rax_off + num_rt_args), rax->as_VMReg()); |
314 map->set_callee_saved(VMRegImpl::stack2reg(rcx_off + num_rt_args), rcx->as_VMReg()); | |
315 map->set_callee_saved(VMRegImpl::stack2reg(rdx_off + num_rt_args), rdx->as_VMReg()); | |
316 map->set_callee_saved(VMRegImpl::stack2reg(rbx_off + num_rt_args), rbx->as_VMReg()); | |
317 map->set_callee_saved(VMRegImpl::stack2reg(rsi_off + num_rt_args), rsi->as_VMReg()); | |
318 map->set_callee_saved(VMRegImpl::stack2reg(rdi_off + num_rt_args), rdi->as_VMReg()); | |
304 | 319 #ifdef _LP64 |
320 map->set_callee_saved(VMRegImpl::stack2reg(r8_off + num_rt_args), r8->as_VMReg()); | |
321 map->set_callee_saved(VMRegImpl::stack2reg(r9_off + num_rt_args), r9->as_VMReg()); | |
322 map->set_callee_saved(VMRegImpl::stack2reg(r10_off + num_rt_args), r10->as_VMReg()); | |
323 map->set_callee_saved(VMRegImpl::stack2reg(r11_off + num_rt_args), r11->as_VMReg()); | |
324 map->set_callee_saved(VMRegImpl::stack2reg(r12_off + num_rt_args), r12->as_VMReg()); | |
325 map->set_callee_saved(VMRegImpl::stack2reg(r13_off + num_rt_args), r13->as_VMReg()); | |
326 map->set_callee_saved(VMRegImpl::stack2reg(r14_off + num_rt_args), r14->as_VMReg()); | |
327 map->set_callee_saved(VMRegImpl::stack2reg(r15_off + num_rt_args), r15->as_VMReg()); | |
328 | |
329 // This is stupid but needed. | |
330 map->set_callee_saved(VMRegImpl::stack2reg(raxH_off + num_rt_args), rax->as_VMReg()->next()); | |
331 map->set_callee_saved(VMRegImpl::stack2reg(rcxH_off + num_rt_args), rcx->as_VMReg()->next()); | |
332 map->set_callee_saved(VMRegImpl::stack2reg(rdxH_off + num_rt_args), rdx->as_VMReg()->next()); | |
333 map->set_callee_saved(VMRegImpl::stack2reg(rbxH_off + num_rt_args), rbx->as_VMReg()->next()); | |
334 map->set_callee_saved(VMRegImpl::stack2reg(rsiH_off + num_rt_args), rsi->as_VMReg()->next()); | |
335 map->set_callee_saved(VMRegImpl::stack2reg(rdiH_off + num_rt_args), rdi->as_VMReg()->next()); | |
336 | |
337 map->set_callee_saved(VMRegImpl::stack2reg(r8H_off + num_rt_args), r8->as_VMReg()->next()); | |
338 map->set_callee_saved(VMRegImpl::stack2reg(r9H_off + num_rt_args), r9->as_VMReg()->next()); | |
339 map->set_callee_saved(VMRegImpl::stack2reg(r10H_off + num_rt_args), r10->as_VMReg()->next()); | |
340 map->set_callee_saved(VMRegImpl::stack2reg(r11H_off + num_rt_args), r11->as_VMReg()->next()); | |
341 map->set_callee_saved(VMRegImpl::stack2reg(r12H_off + num_rt_args), r12->as_VMReg()->next()); | |
342 map->set_callee_saved(VMRegImpl::stack2reg(r13H_off + num_rt_args), r13->as_VMReg()->next()); | |
343 map->set_callee_saved(VMRegImpl::stack2reg(r14H_off + num_rt_args), r14->as_VMReg()->next()); | |
344 map->set_callee_saved(VMRegImpl::stack2reg(r15H_off + num_rt_args), r15->as_VMReg()->next()); | |
345 #endif // _LP64 | |
0 | 346 |
347 if (save_fpu_registers) { | |
348 if (UseSSE < 2) { | |
349 int fpu_off = float_regs_as_doubles_off; | |
350 for (int n = 0; n < FrameMap::nof_fpu_regs; n++) { | |
351 VMReg fpu_name_0 = FrameMap::fpu_regname(n); | |
352 map->set_callee_saved(VMRegImpl::stack2reg(fpu_off + num_rt_args), fpu_name_0); | |
353 // %%% This is really a waste but we'll keep things as they were for now | |
354 if (true) { | |
355 map->set_callee_saved(VMRegImpl::stack2reg(fpu_off + 1 + num_rt_args), fpu_name_0->next()); | |
356 } | |
357 fpu_off += 2; | |
358 } | |
359 assert(fpu_off == fpu_state_off, "incorrect number of fpu stack slots"); | |
360 } | |
361 | |
362 if (UseSSE >= 2) { | |
363 int xmm_off = xmm_regs_as_doubles_off; | |
364 for (int n = 0; n < FrameMap::nof_xmm_regs; n++) { | |
365 VMReg xmm_name_0 = as_XMMRegister(n)->as_VMReg(); | |
366 map->set_callee_saved(VMRegImpl::stack2reg(xmm_off + num_rt_args), xmm_name_0); | |
367 // %%% This is really a waste but we'll keep things as they were for now | |
368 if (true) { | |
369 map->set_callee_saved(VMRegImpl::stack2reg(xmm_off + 1 + num_rt_args), xmm_name_0->next()); | |
370 } | |
371 xmm_off += 2; | |
372 } | |
373 assert(xmm_off == float_regs_as_doubles_off, "incorrect number of xmm registers"); | |
374 | |
375 } else if (UseSSE == 1) { | |
376 int xmm_off = xmm_regs_as_doubles_off; | |
377 for (int n = 0; n < FrameMap::nof_xmm_regs; n++) { | |
378 VMReg xmm_name_0 = as_XMMRegister(n)->as_VMReg(); | |
379 map->set_callee_saved(VMRegImpl::stack2reg(xmm_off + num_rt_args), xmm_name_0); | |
380 xmm_off += 2; | |
381 } | |
382 assert(xmm_off == float_regs_as_doubles_off, "incorrect number of xmm registers"); | |
383 } | |
384 } | |
385 | |
386 return map; | |
387 } | |
388 | |
389 static OopMap* save_live_registers(StubAssembler* sasm, int num_rt_args, | |
390 bool save_fpu_registers = true) { | |
391 __ block_comment("save_live_registers"); | |
392 | |
304 | 393 __ pusha(); // integer registers |
0 | 394 |
395 // assert(float_regs_as_doubles_off % 2 == 0, "misaligned offset"); | |
396 // assert(xmm_regs_as_doubles_off % 2 == 0, "misaligned offset"); | |
397 | |
304 | 398 __ subptr(rsp, extra_space_offset * VMRegImpl::stack_slot_size); |
0 | 399 |
400 #ifdef ASSERT | |
304 | 401 __ movptr(Address(rsp, marker * VMRegImpl::stack_slot_size), (int32_t)0xfeedbeef); |
0 | 402 #endif |
403 | |
404 if (save_fpu_registers) { | |
405 if (UseSSE < 2) { | |
406 // save FPU stack | |
304 | 407 __ fnsave(Address(rsp, fpu_state_off * VMRegImpl::stack_slot_size)); |
0 | 408 __ fwait(); |
409 | |
410 #ifdef ASSERT | |
411 Label ok; | |
304 | 412 __ cmpw(Address(rsp, fpu_state_off * VMRegImpl::stack_slot_size), StubRoutines::fpu_cntrl_wrd_std()); |
0 | 413 __ jccb(Assembler::equal, ok); |
414 __ stop("corrupted control word detected"); | |
415 __ bind(ok); | |
416 #endif | |
417 | |
418 // Reset the control word to guard against exceptions being unmasked | |
419 // since fstp_d can cause FPU stack underflow exceptions. Write it | |
420 // into the on stack copy and then reload that to make sure that the | |
421 // current and future values are correct. | |
304 | 422 __ movw(Address(rsp, fpu_state_off * VMRegImpl::stack_slot_size), StubRoutines::fpu_cntrl_wrd_std()); |
423 __ frstor(Address(rsp, fpu_state_off * VMRegImpl::stack_slot_size)); | |
0 | 424 |
425 // Save the FPU registers in de-opt-able form | |
304 | 426 __ fstp_d(Address(rsp, float_regs_as_doubles_off * VMRegImpl::stack_slot_size + 0)); |
427 __ fstp_d(Address(rsp, float_regs_as_doubles_off * VMRegImpl::stack_slot_size + 8)); | |
428 __ fstp_d(Address(rsp, float_regs_as_doubles_off * VMRegImpl::stack_slot_size + 16)); | |
429 __ fstp_d(Address(rsp, float_regs_as_doubles_off * VMRegImpl::stack_slot_size + 24)); | |
430 __ fstp_d(Address(rsp, float_regs_as_doubles_off * VMRegImpl::stack_slot_size + 32)); | |
431 __ fstp_d(Address(rsp, float_regs_as_doubles_off * VMRegImpl::stack_slot_size + 40)); | |
432 __ fstp_d(Address(rsp, float_regs_as_doubles_off * VMRegImpl::stack_slot_size + 48)); | |
433 __ fstp_d(Address(rsp, float_regs_as_doubles_off * VMRegImpl::stack_slot_size + 56)); | |
0 | 434 } |
435 | |
436 if (UseSSE >= 2) { | |
437 // save XMM registers | |
438 // XMM registers can contain float or double values, but this is not known here, | |
439 // so always save them as doubles. | |
440 // note that float values are _not_ converted automatically, so for float values | |
441 // the second word contains only garbage data. | |
304 | 442 __ movdbl(Address(rsp, xmm_regs_as_doubles_off * VMRegImpl::stack_slot_size + 0), xmm0); |
443 __ movdbl(Address(rsp, xmm_regs_as_doubles_off * VMRegImpl::stack_slot_size + 8), xmm1); | |
444 __ movdbl(Address(rsp, xmm_regs_as_doubles_off * VMRegImpl::stack_slot_size + 16), xmm2); | |
445 __ movdbl(Address(rsp, xmm_regs_as_doubles_off * VMRegImpl::stack_slot_size + 24), xmm3); | |
446 __ movdbl(Address(rsp, xmm_regs_as_doubles_off * VMRegImpl::stack_slot_size + 32), xmm4); | |
447 __ movdbl(Address(rsp, xmm_regs_as_doubles_off * VMRegImpl::stack_slot_size + 40), xmm5); | |
448 __ movdbl(Address(rsp, xmm_regs_as_doubles_off * VMRegImpl::stack_slot_size + 48), xmm6); | |
449 __ movdbl(Address(rsp, xmm_regs_as_doubles_off * VMRegImpl::stack_slot_size + 56), xmm7); | |
450 #ifdef _LP64 | |
451 __ movdbl(Address(rsp, xmm_regs_as_doubles_off * VMRegImpl::stack_slot_size + 64), xmm8); | |
452 __ movdbl(Address(rsp, xmm_regs_as_doubles_off * VMRegImpl::stack_slot_size + 72), xmm9); | |
453 __ movdbl(Address(rsp, xmm_regs_as_doubles_off * VMRegImpl::stack_slot_size + 80), xmm10); | |
454 __ movdbl(Address(rsp, xmm_regs_as_doubles_off * VMRegImpl::stack_slot_size + 88), xmm11); | |
455 __ movdbl(Address(rsp, xmm_regs_as_doubles_off * VMRegImpl::stack_slot_size + 96), xmm12); | |
456 __ movdbl(Address(rsp, xmm_regs_as_doubles_off * VMRegImpl::stack_slot_size + 104), xmm13); | |
457 __ movdbl(Address(rsp, xmm_regs_as_doubles_off * VMRegImpl::stack_slot_size + 112), xmm14); | |
458 __ movdbl(Address(rsp, xmm_regs_as_doubles_off * VMRegImpl::stack_slot_size + 120), xmm15); | |
459 #endif // _LP64 | |
0 | 460 } else if (UseSSE == 1) { |
461 // save XMM registers as float because double not supported without SSE2 | |
304 | 462 __ movflt(Address(rsp, xmm_regs_as_doubles_off * VMRegImpl::stack_slot_size + 0), xmm0); |
463 __ movflt(Address(rsp, xmm_regs_as_doubles_off * VMRegImpl::stack_slot_size + 8), xmm1); | |
464 __ movflt(Address(rsp, xmm_regs_as_doubles_off * VMRegImpl::stack_slot_size + 16), xmm2); | |
465 __ movflt(Address(rsp, xmm_regs_as_doubles_off * VMRegImpl::stack_slot_size + 24), xmm3); | |
466 __ movflt(Address(rsp, xmm_regs_as_doubles_off * VMRegImpl::stack_slot_size + 32), xmm4); | |
467 __ movflt(Address(rsp, xmm_regs_as_doubles_off * VMRegImpl::stack_slot_size + 40), xmm5); | |
468 __ movflt(Address(rsp, xmm_regs_as_doubles_off * VMRegImpl::stack_slot_size + 48), xmm6); | |
469 __ movflt(Address(rsp, xmm_regs_as_doubles_off * VMRegImpl::stack_slot_size + 56), xmm7); | |
0 | 470 } |
471 } | |
472 | |
473 // FPU stack must be empty now | |
474 __ verify_FPU(0, "save_live_registers"); | |
475 | |
476 return generate_oop_map(sasm, num_rt_args, save_fpu_registers); | |
477 } | |
478 | |
479 | |
480 static void restore_fpu(StubAssembler* sasm, bool restore_fpu_registers = true) { | |
481 if (restore_fpu_registers) { | |
482 if (UseSSE >= 2) { | |
483 // restore XMM registers | |
304 | 484 __ movdbl(xmm0, Address(rsp, xmm_regs_as_doubles_off * VMRegImpl::stack_slot_size + 0)); |
485 __ movdbl(xmm1, Address(rsp, xmm_regs_as_doubles_off * VMRegImpl::stack_slot_size + 8)); | |
486 __ movdbl(xmm2, Address(rsp, xmm_regs_as_doubles_off * VMRegImpl::stack_slot_size + 16)); | |
487 __ movdbl(xmm3, Address(rsp, xmm_regs_as_doubles_off * VMRegImpl::stack_slot_size + 24)); | |
488 __ movdbl(xmm4, Address(rsp, xmm_regs_as_doubles_off * VMRegImpl::stack_slot_size + 32)); | |
489 __ movdbl(xmm5, Address(rsp, xmm_regs_as_doubles_off * VMRegImpl::stack_slot_size + 40)); | |
490 __ movdbl(xmm6, Address(rsp, xmm_regs_as_doubles_off * VMRegImpl::stack_slot_size + 48)); | |
491 __ movdbl(xmm7, Address(rsp, xmm_regs_as_doubles_off * VMRegImpl::stack_slot_size + 56)); | |
492 #ifdef _LP64 | |
493 __ movdbl(xmm8, Address(rsp, xmm_regs_as_doubles_off * VMRegImpl::stack_slot_size + 64)); | |
494 __ movdbl(xmm9, Address(rsp, xmm_regs_as_doubles_off * VMRegImpl::stack_slot_size + 72)); | |
495 __ movdbl(xmm10, Address(rsp, xmm_regs_as_doubles_off * VMRegImpl::stack_slot_size + 80)); | |
496 __ movdbl(xmm11, Address(rsp, xmm_regs_as_doubles_off * VMRegImpl::stack_slot_size + 88)); | |
497 __ movdbl(xmm12, Address(rsp, xmm_regs_as_doubles_off * VMRegImpl::stack_slot_size + 96)); | |
498 __ movdbl(xmm13, Address(rsp, xmm_regs_as_doubles_off * VMRegImpl::stack_slot_size + 104)); | |
499 __ movdbl(xmm14, Address(rsp, xmm_regs_as_doubles_off * VMRegImpl::stack_slot_size + 112)); | |
500 __ movdbl(xmm15, Address(rsp, xmm_regs_as_doubles_off * VMRegImpl::stack_slot_size + 120)); | |
501 #endif // _LP64 | |
0 | 502 } else if (UseSSE == 1) { |
503 // restore XMM registers | |
304 | 504 __ movflt(xmm0, Address(rsp, xmm_regs_as_doubles_off * VMRegImpl::stack_slot_size + 0)); |
505 __ movflt(xmm1, Address(rsp, xmm_regs_as_doubles_off * VMRegImpl::stack_slot_size + 8)); | |
506 __ movflt(xmm2, Address(rsp, xmm_regs_as_doubles_off * VMRegImpl::stack_slot_size + 16)); | |
507 __ movflt(xmm3, Address(rsp, xmm_regs_as_doubles_off * VMRegImpl::stack_slot_size + 24)); | |
508 __ movflt(xmm4, Address(rsp, xmm_regs_as_doubles_off * VMRegImpl::stack_slot_size + 32)); | |
509 __ movflt(xmm5, Address(rsp, xmm_regs_as_doubles_off * VMRegImpl::stack_slot_size + 40)); | |
510 __ movflt(xmm6, Address(rsp, xmm_regs_as_doubles_off * VMRegImpl::stack_slot_size + 48)); | |
511 __ movflt(xmm7, Address(rsp, xmm_regs_as_doubles_off * VMRegImpl::stack_slot_size + 56)); | |
0 | 512 } |
513 | |
514 if (UseSSE < 2) { | |
304 | 515 __ frstor(Address(rsp, fpu_state_off * VMRegImpl::stack_slot_size)); |
0 | 516 } else { |
517 // check that FPU stack is really empty | |
518 __ verify_FPU(0, "restore_live_registers"); | |
519 } | |
520 | |
521 } else { | |
522 // check that FPU stack is really empty | |
523 __ verify_FPU(0, "restore_live_registers"); | |
524 } | |
525 | |
526 #ifdef ASSERT | |
527 { | |
528 Label ok; | |
304 | 529 __ cmpptr(Address(rsp, marker * VMRegImpl::stack_slot_size), (int32_t)0xfeedbeef); |
0 | 530 __ jcc(Assembler::equal, ok); |
531 __ stop("bad offsets in frame"); | |
532 __ bind(ok); | |
533 } | |
304 | 534 #endif // ASSERT |
0 | 535 |
304 | 536 __ addptr(rsp, extra_space_offset * VMRegImpl::stack_slot_size); |
0 | 537 } |
538 | |
539 | |
2662
440ceca8e3d7
Add exception handlers only to Invoke and Throw instructions. Deoptimize if there is an exception in a HotSpot runtime call.
Thomas Wuerthinger <thomas@wuerthinger.net>
parents:
2608
diff
changeset
|
540 static void restore_live_registers(StubAssembler* sasm, bool restore_fpu_registers/* = true*/) { |
0 | 541 __ block_comment("restore_live_registers"); |
542 | |
543 restore_fpu(sasm, restore_fpu_registers); | |
304 | 544 __ popa(); |
0 | 545 } |
546 | |
547 | |
548 static void restore_live_registers_except_rax(StubAssembler* sasm, bool restore_fpu_registers = true) { | |
549 __ block_comment("restore_live_registers_except_rax"); | |
550 | |
551 restore_fpu(sasm, restore_fpu_registers); | |
552 | |
304 | 553 #ifdef _LP64 |
554 __ movptr(r15, Address(rsp, 0)); | |
555 __ movptr(r14, Address(rsp, wordSize)); | |
556 __ movptr(r13, Address(rsp, 2 * wordSize)); | |
557 __ movptr(r12, Address(rsp, 3 * wordSize)); | |
558 __ movptr(r11, Address(rsp, 4 * wordSize)); | |
559 __ movptr(r10, Address(rsp, 5 * wordSize)); | |
560 __ movptr(r9, Address(rsp, 6 * wordSize)); | |
561 __ movptr(r8, Address(rsp, 7 * wordSize)); | |
562 __ movptr(rdi, Address(rsp, 8 * wordSize)); | |
563 __ movptr(rsi, Address(rsp, 9 * wordSize)); | |
564 __ movptr(rbp, Address(rsp, 10 * wordSize)); | |
565 // skip rsp | |
566 __ movptr(rbx, Address(rsp, 12 * wordSize)); | |
567 __ movptr(rdx, Address(rsp, 13 * wordSize)); | |
568 __ movptr(rcx, Address(rsp, 14 * wordSize)); | |
569 | |
570 __ addptr(rsp, 16 * wordSize); | |
571 #else | |
572 | |
573 __ pop(rdi); | |
574 __ pop(rsi); | |
575 __ pop(rbp); | |
576 __ pop(rbx); // skip this value | |
577 __ pop(rbx); | |
578 __ pop(rdx); | |
579 __ pop(rcx); | |
580 __ addptr(rsp, BytesPerWord); | |
581 #endif // _LP64 | |
0 | 582 } |
583 | |
584 | |
585 void Runtime1::initialize_pd() { | |
586 // nothing to do | |
587 } | |
588 | |
589 | |
590 // target: the entry point of the method that creates and posts the exception oop | |
591 // has_argument: true if the exception needs an argument (passed on stack because registers must be preserved) | |
592 | |
593 OopMapSet* Runtime1::generate_exception_throw(StubAssembler* sasm, address target, bool has_argument) { | |
1429
abc670a709dc
* -XX:TraceC1X=0...5 controls the native c1x tracing
Lukas Stadler <lukas.stadler@oracle.com>
parents:
1423
diff
changeset
|
594 OopMapSet* oop_maps = new OopMapSet(); |
2891
75a99b4f1c98
Rebranded C++ part from C1X to Graal.
Thomas Wuerthinger <thomas@wuerthinger.net>
parents:
2662
diff
changeset
|
595 if (UseGraal) { |
75a99b4f1c98
Rebranded C++ part from C1X to Graal.
Thomas Wuerthinger <thomas@wuerthinger.net>
parents:
2662
diff
changeset
|
596 // graal passes the argument in r10 |
1429
abc670a709dc
* -XX:TraceC1X=0...5 controls the native c1x tracing
Lukas Stadler <lukas.stadler@oracle.com>
parents:
1423
diff
changeset
|
597 OopMap* oop_map = save_live_registers(sasm, 1); |
abc670a709dc
* -XX:TraceC1X=0...5 controls the native c1x tracing
Lukas Stadler <lukas.stadler@oracle.com>
parents:
1423
diff
changeset
|
598 |
abc670a709dc
* -XX:TraceC1X=0...5 controls the native c1x tracing
Lukas Stadler <lukas.stadler@oracle.com>
parents:
1423
diff
changeset
|
599 // now all registers are saved and can be used freely |
abc670a709dc
* -XX:TraceC1X=0...5 controls the native c1x tracing
Lukas Stadler <lukas.stadler@oracle.com>
parents:
1423
diff
changeset
|
600 // verify that no old value is used accidentally |
abc670a709dc
* -XX:TraceC1X=0...5 controls the native c1x tracing
Lukas Stadler <lukas.stadler@oracle.com>
parents:
1423
diff
changeset
|
601 __ invalidate_registers(true, true, true, true, true, true); |
0 | 602 |
1429
abc670a709dc
* -XX:TraceC1X=0...5 controls the native c1x tracing
Lukas Stadler <lukas.stadler@oracle.com>
parents:
1423
diff
changeset
|
603 // registers used by this stub |
abc670a709dc
* -XX:TraceC1X=0...5 controls the native c1x tracing
Lukas Stadler <lukas.stadler@oracle.com>
parents:
1423
diff
changeset
|
604 const Register temp_reg = rbx; |
0 | 605 |
1429
abc670a709dc
* -XX:TraceC1X=0...5 controls the native c1x tracing
Lukas Stadler <lukas.stadler@oracle.com>
parents:
1423
diff
changeset
|
606 // load argument for exception that is passed as an argument into the stub |
abc670a709dc
* -XX:TraceC1X=0...5 controls the native c1x tracing
Lukas Stadler <lukas.stadler@oracle.com>
parents:
1423
diff
changeset
|
607 if (has_argument) { |
abc670a709dc
* -XX:TraceC1X=0...5 controls the native c1x tracing
Lukas Stadler <lukas.stadler@oracle.com>
parents:
1423
diff
changeset
|
608 __ movptr(c_rarg1, r10); |
abc670a709dc
* -XX:TraceC1X=0...5 controls the native c1x tracing
Lukas Stadler <lukas.stadler@oracle.com>
parents:
1423
diff
changeset
|
609 } |
abc670a709dc
* -XX:TraceC1X=0...5 controls the native c1x tracing
Lukas Stadler <lukas.stadler@oracle.com>
parents:
1423
diff
changeset
|
610 int call_offset = __ call_RT(noreg, noreg, target, has_argument ? 1 : 0); |
0 | 611 |
1429
abc670a709dc
* -XX:TraceC1X=0...5 controls the native c1x tracing
Lukas Stadler <lukas.stadler@oracle.com>
parents:
1423
diff
changeset
|
612 oop_maps->add_gc_map(call_offset, oop_map); |
abc670a709dc
* -XX:TraceC1X=0...5 controls the native c1x tracing
Lukas Stadler <lukas.stadler@oracle.com>
parents:
1423
diff
changeset
|
613 } else { |
abc670a709dc
* -XX:TraceC1X=0...5 controls the native c1x tracing
Lukas Stadler <lukas.stadler@oracle.com>
parents:
1423
diff
changeset
|
614 // preserve all registers |
abc670a709dc
* -XX:TraceC1X=0...5 controls the native c1x tracing
Lukas Stadler <lukas.stadler@oracle.com>
parents:
1423
diff
changeset
|
615 int num_rt_args = has_argument ? 2 : 1; |
abc670a709dc
* -XX:TraceC1X=0...5 controls the native c1x tracing
Lukas Stadler <lukas.stadler@oracle.com>
parents:
1423
diff
changeset
|
616 OopMap* oop_map = save_live_registers(sasm, num_rt_args); |
abc670a709dc
* -XX:TraceC1X=0...5 controls the native c1x tracing
Lukas Stadler <lukas.stadler@oracle.com>
parents:
1423
diff
changeset
|
617 |
abc670a709dc
* -XX:TraceC1X=0...5 controls the native c1x tracing
Lukas Stadler <lukas.stadler@oracle.com>
parents:
1423
diff
changeset
|
618 // now all registers are saved and can be used freely |
abc670a709dc
* -XX:TraceC1X=0...5 controls the native c1x tracing
Lukas Stadler <lukas.stadler@oracle.com>
parents:
1423
diff
changeset
|
619 // verify that no old value is used accidentally |
abc670a709dc
* -XX:TraceC1X=0...5 controls the native c1x tracing
Lukas Stadler <lukas.stadler@oracle.com>
parents:
1423
diff
changeset
|
620 __ invalidate_registers(true, true, true, true, true, true); |
abc670a709dc
* -XX:TraceC1X=0...5 controls the native c1x tracing
Lukas Stadler <lukas.stadler@oracle.com>
parents:
1423
diff
changeset
|
621 |
abc670a709dc
* -XX:TraceC1X=0...5 controls the native c1x tracing
Lukas Stadler <lukas.stadler@oracle.com>
parents:
1423
diff
changeset
|
622 // registers used by this stub |
abc670a709dc
* -XX:TraceC1X=0...5 controls the native c1x tracing
Lukas Stadler <lukas.stadler@oracle.com>
parents:
1423
diff
changeset
|
623 const Register temp_reg = rbx; |
abc670a709dc
* -XX:TraceC1X=0...5 controls the native c1x tracing
Lukas Stadler <lukas.stadler@oracle.com>
parents:
1423
diff
changeset
|
624 |
abc670a709dc
* -XX:TraceC1X=0...5 controls the native c1x tracing
Lukas Stadler <lukas.stadler@oracle.com>
parents:
1423
diff
changeset
|
625 // load argument for exception that is passed as an argument into the stub |
abc670a709dc
* -XX:TraceC1X=0...5 controls the native c1x tracing
Lukas Stadler <lukas.stadler@oracle.com>
parents:
1423
diff
changeset
|
626 if (has_argument) { |
abc670a709dc
* -XX:TraceC1X=0...5 controls the native c1x tracing
Lukas Stadler <lukas.stadler@oracle.com>
parents:
1423
diff
changeset
|
627 #ifdef _LP64 |
abc670a709dc
* -XX:TraceC1X=0...5 controls the native c1x tracing
Lukas Stadler <lukas.stadler@oracle.com>
parents:
1423
diff
changeset
|
628 __ movptr(c_rarg1, Address(rbp, 2*BytesPerWord)); |
abc670a709dc
* -XX:TraceC1X=0...5 controls the native c1x tracing
Lukas Stadler <lukas.stadler@oracle.com>
parents:
1423
diff
changeset
|
629 #else |
abc670a709dc
* -XX:TraceC1X=0...5 controls the native c1x tracing
Lukas Stadler <lukas.stadler@oracle.com>
parents:
1423
diff
changeset
|
630 __ movptr(temp_reg, Address(rbp, 2*BytesPerWord)); |
abc670a709dc
* -XX:TraceC1X=0...5 controls the native c1x tracing
Lukas Stadler <lukas.stadler@oracle.com>
parents:
1423
diff
changeset
|
631 __ push(temp_reg); |
abc670a709dc
* -XX:TraceC1X=0...5 controls the native c1x tracing
Lukas Stadler <lukas.stadler@oracle.com>
parents:
1423
diff
changeset
|
632 #endif // _LP64 |
abc670a709dc
* -XX:TraceC1X=0...5 controls the native c1x tracing
Lukas Stadler <lukas.stadler@oracle.com>
parents:
1423
diff
changeset
|
633 } |
abc670a709dc
* -XX:TraceC1X=0...5 controls the native c1x tracing
Lukas Stadler <lukas.stadler@oracle.com>
parents:
1423
diff
changeset
|
634 int call_offset = __ call_RT(noreg, noreg, target, num_rt_args - 1); |
abc670a709dc
* -XX:TraceC1X=0...5 controls the native c1x tracing
Lukas Stadler <lukas.stadler@oracle.com>
parents:
1423
diff
changeset
|
635 |
abc670a709dc
* -XX:TraceC1X=0...5 controls the native c1x tracing
Lukas Stadler <lukas.stadler@oracle.com>
parents:
1423
diff
changeset
|
636 oop_maps->add_gc_map(call_offset, oop_map); |
0 | 637 } |
638 | |
639 __ stop("should not reach here"); | |
640 | |
641 return oop_maps; | |
642 } | |
643 | |
644 | |
2321
1b4e6a5d98e0
7012914: JSR 292 MethodHandlesTest C1: frame::verify_return_pc(return_address) failed: must be a return pc
twisti
parents:
2168
diff
changeset
|
645 OopMapSet* Runtime1::generate_handle_exception(StubID id, StubAssembler *sasm) { |
1b4e6a5d98e0
7012914: JSR 292 MethodHandlesTest C1: frame::verify_return_pc(return_address) failed: must be a return pc
twisti
parents:
2168
diff
changeset
|
646 __ block_comment("generate_handle_exception"); |
1b4e6a5d98e0
7012914: JSR 292 MethodHandlesTest C1: frame::verify_return_pc(return_address) failed: must be a return pc
twisti
parents:
2168
diff
changeset
|
647 |
0 | 648 // incoming parameters |
649 const Register exception_oop = rax; | |
2321
1b4e6a5d98e0
7012914: JSR 292 MethodHandlesTest C1: frame::verify_return_pc(return_address) failed: must be a return pc
twisti
parents:
2168
diff
changeset
|
650 const Register exception_pc = rdx; |
0 | 651 // other registers used in this stub |
304 | 652 const Register thread = NOT_LP64(rdi) LP64_ONLY(r15_thread); |
0 | 653 |
2321
1b4e6a5d98e0
7012914: JSR 292 MethodHandlesTest C1: frame::verify_return_pc(return_address) failed: must be a return pc
twisti
parents:
2168
diff
changeset
|
654 // Save registers, if required. |
1b4e6a5d98e0
7012914: JSR 292 MethodHandlesTest C1: frame::verify_return_pc(return_address) failed: must be a return pc
twisti
parents:
2168
diff
changeset
|
655 OopMapSet* oop_maps = new OopMapSet(); |
1b4e6a5d98e0
7012914: JSR 292 MethodHandlesTest C1: frame::verify_return_pc(return_address) failed: must be a return pc
twisti
parents:
2168
diff
changeset
|
656 OopMap* oop_map = NULL; |
1b4e6a5d98e0
7012914: JSR 292 MethodHandlesTest C1: frame::verify_return_pc(return_address) failed: must be a return pc
twisti
parents:
2168
diff
changeset
|
657 switch (id) { |
1b4e6a5d98e0
7012914: JSR 292 MethodHandlesTest C1: frame::verify_return_pc(return_address) failed: must be a return pc
twisti
parents:
2168
diff
changeset
|
658 case forward_exception_id: |
1b4e6a5d98e0
7012914: JSR 292 MethodHandlesTest C1: frame::verify_return_pc(return_address) failed: must be a return pc
twisti
parents:
2168
diff
changeset
|
659 // We're handling an exception in the context of a compiled frame. |
1b4e6a5d98e0
7012914: JSR 292 MethodHandlesTest C1: frame::verify_return_pc(return_address) failed: must be a return pc
twisti
parents:
2168
diff
changeset
|
660 // The registers have been saved in the standard places. Perform |
1b4e6a5d98e0
7012914: JSR 292 MethodHandlesTest C1: frame::verify_return_pc(return_address) failed: must be a return pc
twisti
parents:
2168
diff
changeset
|
661 // an exception lookup in the caller and dispatch to the handler |
1b4e6a5d98e0
7012914: JSR 292 MethodHandlesTest C1: frame::verify_return_pc(return_address) failed: must be a return pc
twisti
parents:
2168
diff
changeset
|
662 // if found. Otherwise unwind and dispatch to the callers |
1b4e6a5d98e0
7012914: JSR 292 MethodHandlesTest C1: frame::verify_return_pc(return_address) failed: must be a return pc
twisti
parents:
2168
diff
changeset
|
663 // exception handler. |
1b4e6a5d98e0
7012914: JSR 292 MethodHandlesTest C1: frame::verify_return_pc(return_address) failed: must be a return pc
twisti
parents:
2168
diff
changeset
|
664 oop_map = generate_oop_map(sasm, 1 /*thread*/); |
1b4e6a5d98e0
7012914: JSR 292 MethodHandlesTest C1: frame::verify_return_pc(return_address) failed: must be a return pc
twisti
parents:
2168
diff
changeset
|
665 |
1b4e6a5d98e0
7012914: JSR 292 MethodHandlesTest C1: frame::verify_return_pc(return_address) failed: must be a return pc
twisti
parents:
2168
diff
changeset
|
666 // load and clear pending exception oop into RAX |
1b4e6a5d98e0
7012914: JSR 292 MethodHandlesTest C1: frame::verify_return_pc(return_address) failed: must be a return pc
twisti
parents:
2168
diff
changeset
|
667 __ movptr(exception_oop, Address(thread, Thread::pending_exception_offset())); |
1b4e6a5d98e0
7012914: JSR 292 MethodHandlesTest C1: frame::verify_return_pc(return_address) failed: must be a return pc
twisti
parents:
2168
diff
changeset
|
668 __ movptr(Address(thread, Thread::pending_exception_offset()), NULL_WORD); |
1b4e6a5d98e0
7012914: JSR 292 MethodHandlesTest C1: frame::verify_return_pc(return_address) failed: must be a return pc
twisti
parents:
2168
diff
changeset
|
669 |
1b4e6a5d98e0
7012914: JSR 292 MethodHandlesTest C1: frame::verify_return_pc(return_address) failed: must be a return pc
twisti
parents:
2168
diff
changeset
|
670 // load issuing PC (the return address for this stub) into rdx |
1b4e6a5d98e0
7012914: JSR 292 MethodHandlesTest C1: frame::verify_return_pc(return_address) failed: must be a return pc
twisti
parents:
2168
diff
changeset
|
671 __ movptr(exception_pc, Address(rbp, 1*BytesPerWord)); |
1b4e6a5d98e0
7012914: JSR 292 MethodHandlesTest C1: frame::verify_return_pc(return_address) failed: must be a return pc
twisti
parents:
2168
diff
changeset
|
672 |
1b4e6a5d98e0
7012914: JSR 292 MethodHandlesTest C1: frame::verify_return_pc(return_address) failed: must be a return pc
twisti
parents:
2168
diff
changeset
|
673 // make sure that the vm_results are cleared (may be unnecessary) |
1b4e6a5d98e0
7012914: JSR 292 MethodHandlesTest C1: frame::verify_return_pc(return_address) failed: must be a return pc
twisti
parents:
2168
diff
changeset
|
674 __ movptr(Address(thread, JavaThread::vm_result_offset()), NULL_WORD); |
1b4e6a5d98e0
7012914: JSR 292 MethodHandlesTest C1: frame::verify_return_pc(return_address) failed: must be a return pc
twisti
parents:
2168
diff
changeset
|
675 __ movptr(Address(thread, JavaThread::vm_result_2_offset()), NULL_WORD); |
1b4e6a5d98e0
7012914: JSR 292 MethodHandlesTest C1: frame::verify_return_pc(return_address) failed: must be a return pc
twisti
parents:
2168
diff
changeset
|
676 break; |
1b4e6a5d98e0
7012914: JSR 292 MethodHandlesTest C1: frame::verify_return_pc(return_address) failed: must be a return pc
twisti
parents:
2168
diff
changeset
|
677 case handle_exception_nofpu_id: |
1b4e6a5d98e0
7012914: JSR 292 MethodHandlesTest C1: frame::verify_return_pc(return_address) failed: must be a return pc
twisti
parents:
2168
diff
changeset
|
678 case handle_exception_id: |
1b4e6a5d98e0
7012914: JSR 292 MethodHandlesTest C1: frame::verify_return_pc(return_address) failed: must be a return pc
twisti
parents:
2168
diff
changeset
|
679 // At this point all registers MAY be live. |
1b4e6a5d98e0
7012914: JSR 292 MethodHandlesTest C1: frame::verify_return_pc(return_address) failed: must be a return pc
twisti
parents:
2168
diff
changeset
|
680 oop_map = save_live_registers(sasm, 1 /*thread*/, id == handle_exception_nofpu_id); |
1b4e6a5d98e0
7012914: JSR 292 MethodHandlesTest C1: frame::verify_return_pc(return_address) failed: must be a return pc
twisti
parents:
2168
diff
changeset
|
681 break; |
1b4e6a5d98e0
7012914: JSR 292 MethodHandlesTest C1: frame::verify_return_pc(return_address) failed: must be a return pc
twisti
parents:
2168
diff
changeset
|
682 case handle_exception_from_callee_id: { |
1b4e6a5d98e0
7012914: JSR 292 MethodHandlesTest C1: frame::verify_return_pc(return_address) failed: must be a return pc
twisti
parents:
2168
diff
changeset
|
683 // At this point all registers except exception oop (RAX) and |
1b4e6a5d98e0
7012914: JSR 292 MethodHandlesTest C1: frame::verify_return_pc(return_address) failed: must be a return pc
twisti
parents:
2168
diff
changeset
|
684 // exception pc (RDX) are dead. |
1b4e6a5d98e0
7012914: JSR 292 MethodHandlesTest C1: frame::verify_return_pc(return_address) failed: must be a return pc
twisti
parents:
2168
diff
changeset
|
685 const int frame_size = 2 /*BP, return address*/ NOT_LP64(+ 1 /*thread*/) WIN64_ONLY(+ frame::arg_reg_save_area_bytes / BytesPerWord); |
1b4e6a5d98e0
7012914: JSR 292 MethodHandlesTest C1: frame::verify_return_pc(return_address) failed: must be a return pc
twisti
parents:
2168
diff
changeset
|
686 oop_map = new OopMap(frame_size * VMRegImpl::slots_per_word, 0); |
1b4e6a5d98e0
7012914: JSR 292 MethodHandlesTest C1: frame::verify_return_pc(return_address) failed: must be a return pc
twisti
parents:
2168
diff
changeset
|
687 sasm->set_frame_size(frame_size); |
1b4e6a5d98e0
7012914: JSR 292 MethodHandlesTest C1: frame::verify_return_pc(return_address) failed: must be a return pc
twisti
parents:
2168
diff
changeset
|
688 WIN64_ONLY(__ subq(rsp, frame::arg_reg_save_area_bytes)); |
1b4e6a5d98e0
7012914: JSR 292 MethodHandlesTest C1: frame::verify_return_pc(return_address) failed: must be a return pc
twisti
parents:
2168
diff
changeset
|
689 break; |
1b4e6a5d98e0
7012914: JSR 292 MethodHandlesTest C1: frame::verify_return_pc(return_address) failed: must be a return pc
twisti
parents:
2168
diff
changeset
|
690 } |
1b4e6a5d98e0
7012914: JSR 292 MethodHandlesTest C1: frame::verify_return_pc(return_address) failed: must be a return pc
twisti
parents:
2168
diff
changeset
|
691 default: ShouldNotReachHere(); |
1b4e6a5d98e0
7012914: JSR 292 MethodHandlesTest C1: frame::verify_return_pc(return_address) failed: must be a return pc
twisti
parents:
2168
diff
changeset
|
692 } |
0 | 693 |
694 #ifdef TIERED | |
695 // C2 can leave the fpu stack dirty | |
2321
1b4e6a5d98e0
7012914: JSR 292 MethodHandlesTest C1: frame::verify_return_pc(return_address) failed: must be a return pc
twisti
parents:
2168
diff
changeset
|
696 if (UseSSE < 2) { |
0 | 697 __ empty_FPU_stack(); |
698 } | |
699 #endif // TIERED | |
700 | |
701 // verify that only rax, and rdx is valid at this time | |
702 __ invalidate_registers(false, true, true, false, true, true); | |
703 // verify that rax, contains a valid exception | |
704 __ verify_not_null_oop(exception_oop); | |
705 | |
706 // load address of JavaThread object for thread-local data | |
304 | 707 NOT_LP64(__ get_thread(thread);) |
0 | 708 |
709 #ifdef ASSERT | |
710 // check that fields in JavaThread for exception oop and issuing pc are | |
711 // empty before writing to them | |
712 Label oop_empty; | |
304 | 713 __ cmpptr(Address(thread, JavaThread::exception_oop_offset()), (int32_t) NULL_WORD); |
0 | 714 __ jcc(Assembler::equal, oop_empty); |
715 __ stop("exception oop already set"); | |
716 __ bind(oop_empty); | |
717 | |
718 Label pc_empty; | |
304 | 719 __ cmpptr(Address(thread, JavaThread::exception_pc_offset()), 0); |
0 | 720 __ jcc(Assembler::equal, pc_empty); |
721 __ stop("exception pc already set"); | |
722 __ bind(pc_empty); | |
723 #endif | |
724 | |
725 // save exception oop and issuing pc into JavaThread | |
726 // (exception handler will load it from here) | |
304 | 727 __ movptr(Address(thread, JavaThread::exception_oop_offset()), exception_oop); |
2321
1b4e6a5d98e0
7012914: JSR 292 MethodHandlesTest C1: frame::verify_return_pc(return_address) failed: must be a return pc
twisti
parents:
2168
diff
changeset
|
728 __ movptr(Address(thread, JavaThread::exception_pc_offset()), exception_pc); |
0 | 729 |
730 // patch throwing pc into return address (has bci & oop map) | |
304 | 731 __ movptr(Address(rbp, 1*BytesPerWord), exception_pc); |
0 | 732 |
733 // compute the exception handler. | |
734 // the exception oop and the throwing pc are read from the fields in JavaThread | |
735 int call_offset = __ call_RT(noreg, noreg, CAST_FROM_FN_PTR(address, exception_handler_for_pc)); | |
736 oop_maps->add_gc_map(call_offset, oop_map); | |
737 | |
2321
1b4e6a5d98e0
7012914: JSR 292 MethodHandlesTest C1: frame::verify_return_pc(return_address) failed: must be a return pc
twisti
parents:
2168
diff
changeset
|
738 // rax: handler address |
0 | 739 // will be the deopt blob if nmethod was deoptimized while we looked up |
740 // handler regardless of whether handler existed in the nmethod. | |
741 | |
742 // only rax, is valid at this time, all other registers have been destroyed by the runtime call | |
743 __ invalidate_registers(false, true, true, true, true, true); | |
744 | |
2321
1b4e6a5d98e0
7012914: JSR 292 MethodHandlesTest C1: frame::verify_return_pc(return_address) failed: must be a return pc
twisti
parents:
2168
diff
changeset
|
745 // patch the return address, this stub will directly return to the exception handler |
304 | 746 __ movptr(Address(rbp, 1*BytesPerWord), rax); |
0 | 747 |
2321
1b4e6a5d98e0
7012914: JSR 292 MethodHandlesTest C1: frame::verify_return_pc(return_address) failed: must be a return pc
twisti
parents:
2168
diff
changeset
|
748 switch (id) { |
1b4e6a5d98e0
7012914: JSR 292 MethodHandlesTest C1: frame::verify_return_pc(return_address) failed: must be a return pc
twisti
parents:
2168
diff
changeset
|
749 case forward_exception_id: |
1b4e6a5d98e0
7012914: JSR 292 MethodHandlesTest C1: frame::verify_return_pc(return_address) failed: must be a return pc
twisti
parents:
2168
diff
changeset
|
750 case handle_exception_nofpu_id: |
1b4e6a5d98e0
7012914: JSR 292 MethodHandlesTest C1: frame::verify_return_pc(return_address) failed: must be a return pc
twisti
parents:
2168
diff
changeset
|
751 case handle_exception_id: |
1b4e6a5d98e0
7012914: JSR 292 MethodHandlesTest C1: frame::verify_return_pc(return_address) failed: must be a return pc
twisti
parents:
2168
diff
changeset
|
752 // Restore the registers that were saved at the beginning. |
1b4e6a5d98e0
7012914: JSR 292 MethodHandlesTest C1: frame::verify_return_pc(return_address) failed: must be a return pc
twisti
parents:
2168
diff
changeset
|
753 restore_live_registers(sasm, id == handle_exception_nofpu_id); |
1b4e6a5d98e0
7012914: JSR 292 MethodHandlesTest C1: frame::verify_return_pc(return_address) failed: must be a return pc
twisti
parents:
2168
diff
changeset
|
754 break; |
1b4e6a5d98e0
7012914: JSR 292 MethodHandlesTest C1: frame::verify_return_pc(return_address) failed: must be a return pc
twisti
parents:
2168
diff
changeset
|
755 case handle_exception_from_callee_id: |
1b4e6a5d98e0
7012914: JSR 292 MethodHandlesTest C1: frame::verify_return_pc(return_address) failed: must be a return pc
twisti
parents:
2168
diff
changeset
|
756 // WIN64_ONLY: No need to add frame::arg_reg_save_area_bytes to SP |
1b4e6a5d98e0
7012914: JSR 292 MethodHandlesTest C1: frame::verify_return_pc(return_address) failed: must be a return pc
twisti
parents:
2168
diff
changeset
|
757 // since we do a leave anyway. |
0 | 758 |
2321
1b4e6a5d98e0
7012914: JSR 292 MethodHandlesTest C1: frame::verify_return_pc(return_address) failed: must be a return pc
twisti
parents:
2168
diff
changeset
|
759 // Pop the return address since we are possibly changing SP (restoring from BP). |
1b4e6a5d98e0
7012914: JSR 292 MethodHandlesTest C1: frame::verify_return_pc(return_address) failed: must be a return pc
twisti
parents:
2168
diff
changeset
|
760 __ leave(); |
1b4e6a5d98e0
7012914: JSR 292 MethodHandlesTest C1: frame::verify_return_pc(return_address) failed: must be a return pc
twisti
parents:
2168
diff
changeset
|
761 __ pop(rcx); |
0 | 762 |
2321
1b4e6a5d98e0
7012914: JSR 292 MethodHandlesTest C1: frame::verify_return_pc(return_address) failed: must be a return pc
twisti
parents:
2168
diff
changeset
|
763 // Restore SP from BP if the exception PC is a method handle call site. |
1b4e6a5d98e0
7012914: JSR 292 MethodHandlesTest C1: frame::verify_return_pc(return_address) failed: must be a return pc
twisti
parents:
2168
diff
changeset
|
764 NOT_LP64(__ get_thread(thread);) |
1b4e6a5d98e0
7012914: JSR 292 MethodHandlesTest C1: frame::verify_return_pc(return_address) failed: must be a return pc
twisti
parents:
2168
diff
changeset
|
765 __ cmpl(Address(thread, JavaThread::is_method_handle_return_offset()), 0); |
1b4e6a5d98e0
7012914: JSR 292 MethodHandlesTest C1: frame::verify_return_pc(return_address) failed: must be a return pc
twisti
parents:
2168
diff
changeset
|
766 __ cmovptr(Assembler::notEqual, rsp, rbp_mh_SP_save); |
1b4e6a5d98e0
7012914: JSR 292 MethodHandlesTest C1: frame::verify_return_pc(return_address) failed: must be a return pc
twisti
parents:
2168
diff
changeset
|
767 __ jmp(rcx); // jump to exception handler |
1b4e6a5d98e0
7012914: JSR 292 MethodHandlesTest C1: frame::verify_return_pc(return_address) failed: must be a return pc
twisti
parents:
2168
diff
changeset
|
768 break; |
1b4e6a5d98e0
7012914: JSR 292 MethodHandlesTest C1: frame::verify_return_pc(return_address) failed: must be a return pc
twisti
parents:
2168
diff
changeset
|
769 default: ShouldNotReachHere(); |
1b4e6a5d98e0
7012914: JSR 292 MethodHandlesTest C1: frame::verify_return_pc(return_address) failed: must be a return pc
twisti
parents:
2168
diff
changeset
|
770 } |
1b4e6a5d98e0
7012914: JSR 292 MethodHandlesTest C1: frame::verify_return_pc(return_address) failed: must be a return pc
twisti
parents:
2168
diff
changeset
|
771 |
1b4e6a5d98e0
7012914: JSR 292 MethodHandlesTest C1: frame::verify_return_pc(return_address) failed: must be a return pc
twisti
parents:
2168
diff
changeset
|
772 return oop_maps; |
0 | 773 } |
774 | |
2891
75a99b4f1c98
Rebranded C++ part from C1X to Graal.
Thomas Wuerthinger <thomas@wuerthinger.net>
parents:
2662
diff
changeset
|
775 void Runtime1::graal_generate_handle_exception(StubAssembler *sasm, OopMapSet* oop_maps, OopMap* oop_map) { |
1429
abc670a709dc
* -XX:TraceC1X=0...5 controls the native c1x tracing
Lukas Stadler <lukas.stadler@oracle.com>
parents:
1423
diff
changeset
|
776 NOT_LP64(fatal("64 bit only")); |
abc670a709dc
* -XX:TraceC1X=0...5 controls the native c1x tracing
Lukas Stadler <lukas.stadler@oracle.com>
parents:
1423
diff
changeset
|
777 // incoming parameters |
abc670a709dc
* -XX:TraceC1X=0...5 controls the native c1x tracing
Lukas Stadler <lukas.stadler@oracle.com>
parents:
1423
diff
changeset
|
778 const Register exception_oop = j_rarg0; |
abc670a709dc
* -XX:TraceC1X=0...5 controls the native c1x tracing
Lukas Stadler <lukas.stadler@oracle.com>
parents:
1423
diff
changeset
|
779 // other registers used in this stub |
abc670a709dc
* -XX:TraceC1X=0...5 controls the native c1x tracing
Lukas Stadler <lukas.stadler@oracle.com>
parents:
1423
diff
changeset
|
780 const Register exception_pc = j_rarg1; |
abc670a709dc
* -XX:TraceC1X=0...5 controls the native c1x tracing
Lukas Stadler <lukas.stadler@oracle.com>
parents:
1423
diff
changeset
|
781 const Register thread = r15_thread; |
abc670a709dc
* -XX:TraceC1X=0...5 controls the native c1x tracing
Lukas Stadler <lukas.stadler@oracle.com>
parents:
1423
diff
changeset
|
782 |
2891
75a99b4f1c98
Rebranded C++ part from C1X to Graal.
Thomas Wuerthinger <thomas@wuerthinger.net>
parents:
2662
diff
changeset
|
783 __ block_comment("graal_generate_handle_exception"); |
1429
abc670a709dc
* -XX:TraceC1X=0...5 controls the native c1x tracing
Lukas Stadler <lukas.stadler@oracle.com>
parents:
1423
diff
changeset
|
784 |
abc670a709dc
* -XX:TraceC1X=0...5 controls the native c1x tracing
Lukas Stadler <lukas.stadler@oracle.com>
parents:
1423
diff
changeset
|
785 // verify that rax, contains a valid exception |
abc670a709dc
* -XX:TraceC1X=0...5 controls the native c1x tracing
Lukas Stadler <lukas.stadler@oracle.com>
parents:
1423
diff
changeset
|
786 __ verify_not_null_oop(exception_oop); |
abc670a709dc
* -XX:TraceC1X=0...5 controls the native c1x tracing
Lukas Stadler <lukas.stadler@oracle.com>
parents:
1423
diff
changeset
|
787 |
abc670a709dc
* -XX:TraceC1X=0...5 controls the native c1x tracing
Lukas Stadler <lukas.stadler@oracle.com>
parents:
1423
diff
changeset
|
788 #ifdef ASSERT |
abc670a709dc
* -XX:TraceC1X=0...5 controls the native c1x tracing
Lukas Stadler <lukas.stadler@oracle.com>
parents:
1423
diff
changeset
|
789 // check that fields in JavaThread for exception oop and issuing pc are |
abc670a709dc
* -XX:TraceC1X=0...5 controls the native c1x tracing
Lukas Stadler <lukas.stadler@oracle.com>
parents:
1423
diff
changeset
|
790 // empty before writing to them |
abc670a709dc
* -XX:TraceC1X=0...5 controls the native c1x tracing
Lukas Stadler <lukas.stadler@oracle.com>
parents:
1423
diff
changeset
|
791 Label oop_empty; |
abc670a709dc
* -XX:TraceC1X=0...5 controls the native c1x tracing
Lukas Stadler <lukas.stadler@oracle.com>
parents:
1423
diff
changeset
|
792 __ cmpptr(Address(thread, JavaThread::exception_oop_offset()), (int32_t) NULL_WORD); |
abc670a709dc
* -XX:TraceC1X=0...5 controls the native c1x tracing
Lukas Stadler <lukas.stadler@oracle.com>
parents:
1423
diff
changeset
|
793 __ jcc(Assembler::equal, oop_empty); |
abc670a709dc
* -XX:TraceC1X=0...5 controls the native c1x tracing
Lukas Stadler <lukas.stadler@oracle.com>
parents:
1423
diff
changeset
|
794 __ stop("exception oop already set"); |
abc670a709dc
* -XX:TraceC1X=0...5 controls the native c1x tracing
Lukas Stadler <lukas.stadler@oracle.com>
parents:
1423
diff
changeset
|
795 __ bind(oop_empty); |
abc670a709dc
* -XX:TraceC1X=0...5 controls the native c1x tracing
Lukas Stadler <lukas.stadler@oracle.com>
parents:
1423
diff
changeset
|
796 |
abc670a709dc
* -XX:TraceC1X=0...5 controls the native c1x tracing
Lukas Stadler <lukas.stadler@oracle.com>
parents:
1423
diff
changeset
|
797 Label pc_empty; |
abc670a709dc
* -XX:TraceC1X=0...5 controls the native c1x tracing
Lukas Stadler <lukas.stadler@oracle.com>
parents:
1423
diff
changeset
|
798 __ cmpptr(Address(thread, JavaThread::exception_pc_offset()), 0); |
abc670a709dc
* -XX:TraceC1X=0...5 controls the native c1x tracing
Lukas Stadler <lukas.stadler@oracle.com>
parents:
1423
diff
changeset
|
799 __ jcc(Assembler::equal, pc_empty); |
abc670a709dc
* -XX:TraceC1X=0...5 controls the native c1x tracing
Lukas Stadler <lukas.stadler@oracle.com>
parents:
1423
diff
changeset
|
800 __ stop("exception pc already set"); |
abc670a709dc
* -XX:TraceC1X=0...5 controls the native c1x tracing
Lukas Stadler <lukas.stadler@oracle.com>
parents:
1423
diff
changeset
|
801 __ bind(pc_empty); |
abc670a709dc
* -XX:TraceC1X=0...5 controls the native c1x tracing
Lukas Stadler <lukas.stadler@oracle.com>
parents:
1423
diff
changeset
|
802 #endif |
abc670a709dc
* -XX:TraceC1X=0...5 controls the native c1x tracing
Lukas Stadler <lukas.stadler@oracle.com>
parents:
1423
diff
changeset
|
803 |
abc670a709dc
* -XX:TraceC1X=0...5 controls the native c1x tracing
Lukas Stadler <lukas.stadler@oracle.com>
parents:
1423
diff
changeset
|
804 // save exception oop and issuing pc into JavaThread |
abc670a709dc
* -XX:TraceC1X=0...5 controls the native c1x tracing
Lukas Stadler <lukas.stadler@oracle.com>
parents:
1423
diff
changeset
|
805 // (exception handler will load it from here) |
abc670a709dc
* -XX:TraceC1X=0...5 controls the native c1x tracing
Lukas Stadler <lukas.stadler@oracle.com>
parents:
1423
diff
changeset
|
806 __ movptr(Address(thread, JavaThread::exception_oop_offset()), exception_oop); |
abc670a709dc
* -XX:TraceC1X=0...5 controls the native c1x tracing
Lukas Stadler <lukas.stadler@oracle.com>
parents:
1423
diff
changeset
|
807 __ movptr(exception_pc, Address(rbp, 1*BytesPerWord)); |
abc670a709dc
* -XX:TraceC1X=0...5 controls the native c1x tracing
Lukas Stadler <lukas.stadler@oracle.com>
parents:
1423
diff
changeset
|
808 __ movptr(Address(thread, JavaThread::exception_pc_offset()), exception_pc); |
abc670a709dc
* -XX:TraceC1X=0...5 controls the native c1x tracing
Lukas Stadler <lukas.stadler@oracle.com>
parents:
1423
diff
changeset
|
809 |
abc670a709dc
* -XX:TraceC1X=0...5 controls the native c1x tracing
Lukas Stadler <lukas.stadler@oracle.com>
parents:
1423
diff
changeset
|
810 // compute the exception handler. |
abc670a709dc
* -XX:TraceC1X=0...5 controls the native c1x tracing
Lukas Stadler <lukas.stadler@oracle.com>
parents:
1423
diff
changeset
|
811 // the exception oop and the throwing pc are read from the fields in JavaThread |
abc670a709dc
* -XX:TraceC1X=0...5 controls the native c1x tracing
Lukas Stadler <lukas.stadler@oracle.com>
parents:
1423
diff
changeset
|
812 int call_offset = __ call_RT(noreg, noreg, CAST_FROM_FN_PTR(address, exception_handler_for_pc)); |
abc670a709dc
* -XX:TraceC1X=0...5 controls the native c1x tracing
Lukas Stadler <lukas.stadler@oracle.com>
parents:
1423
diff
changeset
|
813 oop_maps->add_gc_map(call_offset, oop_map); |
abc670a709dc
* -XX:TraceC1X=0...5 controls the native c1x tracing
Lukas Stadler <lukas.stadler@oracle.com>
parents:
1423
diff
changeset
|
814 |
abc670a709dc
* -XX:TraceC1X=0...5 controls the native c1x tracing
Lukas Stadler <lukas.stadler@oracle.com>
parents:
1423
diff
changeset
|
815 // rax,: handler address |
abc670a709dc
* -XX:TraceC1X=0...5 controls the native c1x tracing
Lukas Stadler <lukas.stadler@oracle.com>
parents:
1423
diff
changeset
|
816 // will be the deopt blob if nmethod was deoptimized while we looked up |
abc670a709dc
* -XX:TraceC1X=0...5 controls the native c1x tracing
Lukas Stadler <lukas.stadler@oracle.com>
parents:
1423
diff
changeset
|
817 // handler regardless of whether handler existed in the nmethod. |
abc670a709dc
* -XX:TraceC1X=0...5 controls the native c1x tracing
Lukas Stadler <lukas.stadler@oracle.com>
parents:
1423
diff
changeset
|
818 |
abc670a709dc
* -XX:TraceC1X=0...5 controls the native c1x tracing
Lukas Stadler <lukas.stadler@oracle.com>
parents:
1423
diff
changeset
|
819 // only rax, is valid at this time, all other registers have been destroyed by the runtime call |
abc670a709dc
* -XX:TraceC1X=0...5 controls the native c1x tracing
Lukas Stadler <lukas.stadler@oracle.com>
parents:
1423
diff
changeset
|
820 __ invalidate_registers(false, true, true, true, true, true); |
abc670a709dc
* -XX:TraceC1X=0...5 controls the native c1x tracing
Lukas Stadler <lukas.stadler@oracle.com>
parents:
1423
diff
changeset
|
821 |
abc670a709dc
* -XX:TraceC1X=0...5 controls the native c1x tracing
Lukas Stadler <lukas.stadler@oracle.com>
parents:
1423
diff
changeset
|
822 #ifdef ASSERT |
abc670a709dc
* -XX:TraceC1X=0...5 controls the native c1x tracing
Lukas Stadler <lukas.stadler@oracle.com>
parents:
1423
diff
changeset
|
823 // Do we have an exception handler in the nmethod? |
abc670a709dc
* -XX:TraceC1X=0...5 controls the native c1x tracing
Lukas Stadler <lukas.stadler@oracle.com>
parents:
1423
diff
changeset
|
824 Label done; |
abc670a709dc
* -XX:TraceC1X=0...5 controls the native c1x tracing
Lukas Stadler <lukas.stadler@oracle.com>
parents:
1423
diff
changeset
|
825 __ testptr(rax, rax); |
abc670a709dc
* -XX:TraceC1X=0...5 controls the native c1x tracing
Lukas Stadler <lukas.stadler@oracle.com>
parents:
1423
diff
changeset
|
826 __ jcc(Assembler::notZero, done); |
abc670a709dc
* -XX:TraceC1X=0...5 controls the native c1x tracing
Lukas Stadler <lukas.stadler@oracle.com>
parents:
1423
diff
changeset
|
827 __ stop("no handler found"); |
abc670a709dc
* -XX:TraceC1X=0...5 controls the native c1x tracing
Lukas Stadler <lukas.stadler@oracle.com>
parents:
1423
diff
changeset
|
828 __ bind(done); |
abc670a709dc
* -XX:TraceC1X=0...5 controls the native c1x tracing
Lukas Stadler <lukas.stadler@oracle.com>
parents:
1423
diff
changeset
|
829 #endif |
abc670a709dc
* -XX:TraceC1X=0...5 controls the native c1x tracing
Lukas Stadler <lukas.stadler@oracle.com>
parents:
1423
diff
changeset
|
830 |
abc670a709dc
* -XX:TraceC1X=0...5 controls the native c1x tracing
Lukas Stadler <lukas.stadler@oracle.com>
parents:
1423
diff
changeset
|
831 // exception handler found |
abc670a709dc
* -XX:TraceC1X=0...5 controls the native c1x tracing
Lukas Stadler <lukas.stadler@oracle.com>
parents:
1423
diff
changeset
|
832 // patch the return address -> the stub will directly return to the exception handler |
abc670a709dc
* -XX:TraceC1X=0...5 controls the native c1x tracing
Lukas Stadler <lukas.stadler@oracle.com>
parents:
1423
diff
changeset
|
833 __ movptr(Address(rbp, 1*BytesPerWord), rax); |
abc670a709dc
* -XX:TraceC1X=0...5 controls the native c1x tracing
Lukas Stadler <lukas.stadler@oracle.com>
parents:
1423
diff
changeset
|
834 |
abc670a709dc
* -XX:TraceC1X=0...5 controls the native c1x tracing
Lukas Stadler <lukas.stadler@oracle.com>
parents:
1423
diff
changeset
|
835 // restore registers |
abc670a709dc
* -XX:TraceC1X=0...5 controls the native c1x tracing
Lukas Stadler <lukas.stadler@oracle.com>
parents:
1423
diff
changeset
|
836 restore_live_registers(sasm, false); |
abc670a709dc
* -XX:TraceC1X=0...5 controls the native c1x tracing
Lukas Stadler <lukas.stadler@oracle.com>
parents:
1423
diff
changeset
|
837 |
abc670a709dc
* -XX:TraceC1X=0...5 controls the native c1x tracing
Lukas Stadler <lukas.stadler@oracle.com>
parents:
1423
diff
changeset
|
838 // return to exception handler |
abc670a709dc
* -XX:TraceC1X=0...5 controls the native c1x tracing
Lukas Stadler <lukas.stadler@oracle.com>
parents:
1423
diff
changeset
|
839 __ leave(); |
abc670a709dc
* -XX:TraceC1X=0...5 controls the native c1x tracing
Lukas Stadler <lukas.stadler@oracle.com>
parents:
1423
diff
changeset
|
840 __ ret(0); |
abc670a709dc
* -XX:TraceC1X=0...5 controls the native c1x tracing
Lukas Stadler <lukas.stadler@oracle.com>
parents:
1423
diff
changeset
|
841 } |
abc670a709dc
* -XX:TraceC1X=0...5 controls the native c1x tracing
Lukas Stadler <lukas.stadler@oracle.com>
parents:
1423
diff
changeset
|
842 |
0 | 843 |
844 void Runtime1::generate_unwind_exception(StubAssembler *sasm) { | |
845 // incoming parameters | |
846 const Register exception_oop = rax; | |
1295 | 847 // callee-saved copy of exception_oop during runtime call |
848 const Register exception_oop_callee_saved = NOT_LP64(rsi) LP64_ONLY(r14); | |
0 | 849 // other registers used in this stub |
850 const Register exception_pc = rdx; | |
851 const Register handler_addr = rbx; | |
304 | 852 const Register thread = NOT_LP64(rdi) LP64_ONLY(r15_thread); |
0 | 853 |
854 // verify that only rax, is valid at this time | |
855 __ invalidate_registers(false, true, true, true, true, true); | |
856 | |
857 #ifdef ASSERT | |
858 // check that fields in JavaThread for exception oop and issuing pc are empty | |
304 | 859 NOT_LP64(__ get_thread(thread);) |
0 | 860 Label oop_empty; |
304 | 861 __ cmpptr(Address(thread, JavaThread::exception_oop_offset()), 0); |
0 | 862 __ jcc(Assembler::equal, oop_empty); |
863 __ stop("exception oop must be empty"); | |
864 __ bind(oop_empty); | |
865 | |
866 Label pc_empty; | |
304 | 867 __ cmpptr(Address(thread, JavaThread::exception_pc_offset()), 0); |
0 | 868 __ jcc(Assembler::equal, pc_empty); |
869 __ stop("exception pc must be empty"); | |
870 __ bind(pc_empty); | |
871 #endif | |
872 | |
873 // clear the FPU stack in case any FPU results are left behind | |
874 __ empty_FPU_stack(); | |
875 | |
1295 | 876 // save exception_oop in callee-saved register to preserve it during runtime calls |
877 __ verify_not_null_oop(exception_oop); | |
878 __ movptr(exception_oop_callee_saved, exception_oop); | |
879 | |
880 NOT_LP64(__ get_thread(thread);) | |
881 // Get return address (is on top of stack after leave). | |
304 | 882 __ movptr(exception_pc, Address(rsp, 0)); |
0 | 883 |
1295 | 884 // search the exception handler address of the caller (using the return address) |
885 __ call_VM_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::exception_handler_for_return_address), thread, exception_pc); | |
886 // rax: exception handler address of the caller | |
0 | 887 |
1295 | 888 // Only RAX and RSI are valid at this time, all other registers have been destroyed by the call. |
889 __ invalidate_registers(false, true, true, true, false, true); | |
0 | 890 |
891 // move result of call into correct register | |
304 | 892 __ movptr(handler_addr, rax); |
0 | 893 |
1295 | 894 // Restore exception oop to RAX (required convention of exception handler). |
895 __ movptr(exception_oop, exception_oop_callee_saved); | |
0 | 896 |
1295 | 897 // verify that there is really a valid exception in rax |
898 __ verify_not_null_oop(exception_oop); | |
0 | 899 |
900 // get throwing pc (= return address). | |
901 // rdx has been destroyed by the call, so it must be set again | |
902 // the pop is also necessary to simulate the effect of a ret(0) | |
304 | 903 __ pop(exception_pc); |
0 | 904 |
2321
1b4e6a5d98e0
7012914: JSR 292 MethodHandlesTest C1: frame::verify_return_pc(return_address) failed: must be a return pc
twisti
parents:
2168
diff
changeset
|
905 // Restore SP from BP if the exception PC is a method handle call site. |
1295 | 906 NOT_LP64(__ get_thread(thread);) |
1368
93767e6a2dfd
6941529: SharedRuntime::raw_exception_handler_for_return_address must reset thread MethodHandle flag
twisti
parents:
1295
diff
changeset
|
907 __ cmpl(Address(thread, JavaThread::is_method_handle_return_offset()), 0); |
1564 | 908 __ cmovptr(Assembler::notEqual, rsp, rbp_mh_SP_save); |
0 | 909 |
910 // continue at exception handler (return address removed) | |
911 // note: do *not* remove arguments when unwinding the | |
912 // activation since the caller assumes having | |
913 // all arguments on the stack when entering the | |
914 // runtime to determine the exception handler | |
915 // (GC happens at call site with arguments!) | |
1295 | 916 // rax: exception oop |
0 | 917 // rdx: throwing pc |
1295 | 918 // rbx: exception handler |
0 | 919 __ jmp(handler_addr); |
920 } | |
921 | |
922 | |
923 OopMapSet* Runtime1::generate_patching(StubAssembler* sasm, address target) { | |
924 // use the maximum number of runtime-arguments here because it is difficult to | |
925 // distinguish each RT-Call. | |
926 // Note: This number affects also the RT-Call in generate_handle_exception because | |
927 // the oop-map is shared for all calls. | |
928 const int num_rt_args = 2; // thread + dummy | |
929 | |
930 DeoptimizationBlob* deopt_blob = SharedRuntime::deopt_blob(); | |
931 assert(deopt_blob != NULL, "deoptimization blob must have been created"); | |
932 | |
933 OopMap* oop_map = save_live_registers(sasm, num_rt_args); | |
934 | |
304 | 935 #ifdef _LP64 |
936 const Register thread = r15_thread; | |
937 // No need to worry about dummy | |
938 __ mov(c_rarg0, thread); | |
939 #else | |
940 __ push(rax); // push dummy | |
0 | 941 |
942 const Register thread = rdi; // is callee-saved register (Visual C++ calling conventions) | |
943 // push java thread (becomes first argument of C function) | |
944 __ get_thread(thread); | |
304 | 945 __ push(thread); |
946 #endif // _LP64 | |
0 | 947 __ set_last_Java_frame(thread, noreg, rbp, NULL); |
948 // do the call | |
949 __ call(RuntimeAddress(target)); | |
950 OopMapSet* oop_maps = new OopMapSet(); | |
951 oop_maps->add_gc_map(__ offset(), oop_map); | |
952 // verify callee-saved register | |
953 #ifdef ASSERT | |
954 guarantee(thread != rax, "change this code"); | |
304 | 955 __ push(rax); |
0 | 956 { Label L; |
957 __ get_thread(rax); | |
304 | 958 __ cmpptr(thread, rax); |
0 | 959 __ jcc(Assembler::equal, L); |
304 | 960 __ stop("StubAssembler::call_RT: rdi/r15 not callee saved?"); |
0 | 961 __ bind(L); |
962 } | |
304 | 963 __ pop(rax); |
0 | 964 #endif |
965 __ reset_last_Java_frame(thread, true, false); | |
304 | 966 #ifndef _LP64 |
967 __ pop(rcx); // discard thread arg | |
968 __ pop(rcx); // discard dummy | |
969 #endif // _LP64 | |
0 | 970 |
971 // check for pending exceptions | |
972 { Label L; | |
304 | 973 __ cmpptr(Address(thread, Thread::pending_exception_offset()), (int32_t)NULL_WORD); |
0 | 974 __ jcc(Assembler::equal, L); |
975 // exception pending => remove activation and forward to exception handler | |
976 | |
304 | 977 __ testptr(rax, rax); // have we deoptimized? |
0 | 978 __ jump_cc(Assembler::equal, |
979 RuntimeAddress(Runtime1::entry_for(Runtime1::forward_exception_id))); | |
980 | |
981 // the deopt blob expects exceptions in the special fields of | |
982 // JavaThread, so copy and clear pending exception. | |
983 | |
984 // load and clear pending exception | |
304 | 985 __ movptr(rax, Address(thread, Thread::pending_exception_offset())); |
512
db4caa99ef11
6787106: Hotspot 32 bit build fails on platforms having different definitions for intptr_t & int32_t
xlu
parents:
380
diff
changeset
|
986 __ movptr(Address(thread, Thread::pending_exception_offset()), NULL_WORD); |
0 | 987 |
988 // check that there is really a valid exception | |
989 __ verify_not_null_oop(rax); | |
990 | |
991 // load throwing pc: this is the return address of the stub | |
304 | 992 __ movptr(rdx, Address(rsp, return_off * VMRegImpl::stack_slot_size)); |
0 | 993 |
994 #ifdef ASSERT | |
995 // check that fields in JavaThread for exception oop and issuing pc are empty | |
996 Label oop_empty; | |
304 | 997 __ cmpptr(Address(thread, JavaThread::exception_oop_offset()), (int32_t)NULL_WORD); |
0 | 998 __ jcc(Assembler::equal, oop_empty); |
999 __ stop("exception oop must be empty"); | |
1000 __ bind(oop_empty); | |
1001 | |
1002 Label pc_empty; | |
304 | 1003 __ cmpptr(Address(thread, JavaThread::exception_pc_offset()), (int32_t)NULL_WORD); |
0 | 1004 __ jcc(Assembler::equal, pc_empty); |
1005 __ stop("exception pc must be empty"); | |
1006 __ bind(pc_empty); | |
1007 #endif | |
1008 | |
1009 // store exception oop and throwing pc to JavaThread | |
304 | 1010 __ movptr(Address(thread, JavaThread::exception_oop_offset()), rax); |
1011 __ movptr(Address(thread, JavaThread::exception_pc_offset()), rdx); | |
0 | 1012 |
1013 restore_live_registers(sasm); | |
1014 | |
1015 __ leave(); | |
304 | 1016 __ addptr(rsp, BytesPerWord); // remove return address from stack |
0 | 1017 |
1018 // Forward the exception directly to deopt blob. We can blow no | |
1019 // registers and must leave throwing pc on the stack. A patch may | |
1020 // have values live in registers so the entry point with the | |
1021 // exception in tls. | |
1022 __ jump(RuntimeAddress(deopt_blob->unpack_with_exception_in_tls())); | |
1023 | |
1024 __ bind(L); | |
1025 } | |
1026 | |
1027 | |
1028 // Runtime will return true if the nmethod has been deoptimized during | |
1029 // the patching process. In that case we must do a deopt reexecute instead. | |
1030 | |
1031 Label reexecuteEntry, cont; | |
1032 | |
304 | 1033 __ testptr(rax, rax); // have we deoptimized? |
0 | 1034 __ jcc(Assembler::equal, cont); // no |
1035 | |
1036 // Will reexecute. Proper return address is already on the stack we just restore | |
1037 // registers, pop all of our frame but the return address and jump to the deopt blob | |
1038 restore_live_registers(sasm); | |
1039 __ leave(); | |
1040 __ jump(RuntimeAddress(deopt_blob->unpack_with_reexecution())); | |
1041 | |
1042 __ bind(cont); | |
1043 restore_live_registers(sasm); | |
1044 __ leave(); | |
1045 __ ret(0); | |
1046 | |
1047 return oop_maps; | |
1048 } | |
1049 | |
2891
75a99b4f1c98
Rebranded C++ part from C1X to Graal.
Thomas Wuerthinger <thomas@wuerthinger.net>
parents:
2662
diff
changeset
|
1050 JRT_ENTRY(void, graal_create_null_exception(JavaThread* thread)) |
1429
abc670a709dc
* -XX:TraceC1X=0...5 controls the native c1x tracing
Lukas Stadler <lukas.stadler@oracle.com>
parents:
1423
diff
changeset
|
1051 thread->set_vm_result(Exceptions::new_exception(thread, vmSymbols::java_lang_NullPointerException(), NULL)()); |
abc670a709dc
* -XX:TraceC1X=0...5 controls the native c1x tracing
Lukas Stadler <lukas.stadler@oracle.com>
parents:
1423
diff
changeset
|
1052 JRT_END |
abc670a709dc
* -XX:TraceC1X=0...5 controls the native c1x tracing
Lukas Stadler <lukas.stadler@oracle.com>
parents:
1423
diff
changeset
|
1053 |
abc670a709dc
* -XX:TraceC1X=0...5 controls the native c1x tracing
Lukas Stadler <lukas.stadler@oracle.com>
parents:
1423
diff
changeset
|
1054 |
abc670a709dc
* -XX:TraceC1X=0...5 controls the native c1x tracing
Lukas Stadler <lukas.stadler@oracle.com>
parents:
1423
diff
changeset
|
1055 |
0 | 1056 |
1057 OopMapSet* Runtime1::generate_code_for(StubID id, StubAssembler* sasm) { | |
1058 | |
1059 // for better readability | |
1060 const bool must_gc_arguments = true; | |
1061 const bool dont_gc_arguments = false; | |
1062 | |
1063 // default value; overwritten for some optimized stubs that are called from methods that do not use the fpu | |
1064 bool save_fpu_registers = true; | |
1065 | |
1066 // stub code & info for the different stubs | |
1067 OopMapSet* oop_maps = NULL; | |
1068 switch (id) { | |
1069 case forward_exception_id: | |
1070 { | |
2321
1b4e6a5d98e0
7012914: JSR 292 MethodHandlesTest C1: frame::verify_return_pc(return_address) failed: must be a return pc
twisti
parents:
2168
diff
changeset
|
1071 oop_maps = generate_handle_exception(id, sasm); |
1b4e6a5d98e0
7012914: JSR 292 MethodHandlesTest C1: frame::verify_return_pc(return_address) failed: must be a return pc
twisti
parents:
2168
diff
changeset
|
1072 __ leave(); |
1b4e6a5d98e0
7012914: JSR 292 MethodHandlesTest C1: frame::verify_return_pc(return_address) failed: must be a return pc
twisti
parents:
2168
diff
changeset
|
1073 __ ret(0); |
0 | 1074 } |
1075 break; | |
1076 | |
1077 case new_instance_id: | |
1078 case fast_new_instance_id: | |
1079 case fast_new_instance_init_check_id: | |
1080 { | |
1081 Register klass = rdx; // Incoming | |
1082 Register obj = rax; // Result | |
1083 | |
1084 if (id == new_instance_id) { | |
1085 __ set_info("new_instance", dont_gc_arguments); | |
1086 } else if (id == fast_new_instance_id) { | |
1087 __ set_info("fast new_instance", dont_gc_arguments); | |
1088 } else { | |
1089 assert(id == fast_new_instance_init_check_id, "bad StubID"); | |
1090 __ set_info("fast new_instance init check", dont_gc_arguments); | |
1091 } | |
1092 | |
1093 if ((id == fast_new_instance_id || id == fast_new_instance_init_check_id) && | |
1094 UseTLAB && FastTLABRefill) { | |
1095 Label slow_path; | |
1096 Register obj_size = rcx; | |
1097 Register t1 = rbx; | |
1098 Register t2 = rsi; | |
1099 assert_different_registers(klass, obj, obj_size, t1, t2); | |
1100 | |
304 | 1101 __ push(rdi); |
1102 __ push(rbx); | |
0 | 1103 |
1104 if (id == fast_new_instance_init_check_id) { | |
1105 // make sure the klass is initialized | |
1106 __ cmpl(Address(klass, instanceKlass::init_state_offset_in_bytes() + sizeof(oopDesc)), instanceKlass::fully_initialized); | |
1107 __ jcc(Assembler::notEqual, slow_path); | |
1108 } | |
1109 | |
1110 #ifdef ASSERT | |
1111 // assert object can be fast path allocated | |
1112 { | |
1113 Label ok, not_ok; | |
1114 __ movl(obj_size, Address(klass, Klass::layout_helper_offset_in_bytes() + sizeof(oopDesc))); | |
1115 __ cmpl(obj_size, 0); // make sure it's an instance (LH > 0) | |
1116 __ jcc(Assembler::lessEqual, not_ok); | |
1117 __ testl(obj_size, Klass::_lh_instance_slow_path_bit); | |
1118 __ jcc(Assembler::zero, ok); | |
1119 __ bind(not_ok); | |
1120 __ stop("assert(can be fast path allocated)"); | |
1121 __ should_not_reach_here(); | |
1122 __ bind(ok); | |
1123 } | |
1124 #endif // ASSERT | |
1125 | |
1126 // if we got here then the TLAB allocation failed, so try | |
1127 // refilling the TLAB or allocating directly from eden. | |
1128 Label retry_tlab, try_eden; | |
2100
b1a2afa37ec4
7003271: Hotspot should track cumulative Java heap bytes allocated on a per-thread basis
phh
parents:
2002
diff
changeset
|
1129 const Register thread = |
b1a2afa37ec4
7003271: Hotspot should track cumulative Java heap bytes allocated on a per-thread basis
phh
parents:
2002
diff
changeset
|
1130 __ tlab_refill(retry_tlab, try_eden, slow_path); // does not destroy rdx (klass), returns rdi |
0 | 1131 |
1132 __ bind(retry_tlab); | |
1133 | |
304 | 1134 // get the instance size (size is postive so movl is fine for 64bit) |
0 | 1135 __ movl(obj_size, Address(klass, klassOopDesc::header_size() * HeapWordSize + Klass::layout_helper_offset_in_bytes())); |
2100
b1a2afa37ec4
7003271: Hotspot should track cumulative Java heap bytes allocated on a per-thread basis
phh
parents:
2002
diff
changeset
|
1136 |
0 | 1137 __ tlab_allocate(obj, obj_size, 0, t1, t2, slow_path); |
2100
b1a2afa37ec4
7003271: Hotspot should track cumulative Java heap bytes allocated on a per-thread basis
phh
parents:
2002
diff
changeset
|
1138 |
0 | 1139 __ initialize_object(obj, klass, obj_size, 0, t1, t2); |
1140 __ verify_oop(obj); | |
304 | 1141 __ pop(rbx); |
1142 __ pop(rdi); | |
0 | 1143 __ ret(0); |
1144 | |
1145 __ bind(try_eden); | |
304 | 1146 // get the instance size (size is postive so movl is fine for 64bit) |
0 | 1147 __ movl(obj_size, Address(klass, klassOopDesc::header_size() * HeapWordSize + Klass::layout_helper_offset_in_bytes())); |
2100
b1a2afa37ec4
7003271: Hotspot should track cumulative Java heap bytes allocated on a per-thread basis
phh
parents:
2002
diff
changeset
|
1148 |
0 | 1149 __ eden_allocate(obj, obj_size, 0, t1, slow_path); |
2100
b1a2afa37ec4
7003271: Hotspot should track cumulative Java heap bytes allocated on a per-thread basis
phh
parents:
2002
diff
changeset
|
1150 __ incr_allocated_bytes(thread, obj_size, 0); |
b1a2afa37ec4
7003271: Hotspot should track cumulative Java heap bytes allocated on a per-thread basis
phh
parents:
2002
diff
changeset
|
1151 |
0 | 1152 __ initialize_object(obj, klass, obj_size, 0, t1, t2); |
1153 __ verify_oop(obj); | |
304 | 1154 __ pop(rbx); |
1155 __ pop(rdi); | |
0 | 1156 __ ret(0); |
1157 | |
1158 __ bind(slow_path); | |
304 | 1159 __ pop(rbx); |
1160 __ pop(rdi); | |
0 | 1161 } |
1162 | |
1163 __ enter(); | |
1164 OopMap* map = save_live_registers(sasm, 2); | |
1165 int call_offset = __ call_RT(obj, noreg, CAST_FROM_FN_PTR(address, new_instance), klass); | |
1166 oop_maps = new OopMapSet(); | |
1167 oop_maps->add_gc_map(call_offset, map); | |
1168 restore_live_registers_except_rax(sasm); | |
1169 __ verify_oop(obj); | |
1170 __ leave(); | |
1171 __ ret(0); | |
1172 | |
1173 // rax,: new instance | |
1174 } | |
1175 | |
1176 break; | |
1177 | |
1178 case counter_overflow_id: | |
1179 { | |
1783 | 1180 Register bci = rax, method = rbx; |
0 | 1181 __ enter(); |
1783 | 1182 OopMap* map = save_live_registers(sasm, 3); |
0 | 1183 // Retrieve bci |
1184 __ movl(bci, Address(rbp, 2*BytesPerWord)); | |
1783 | 1185 // And a pointer to the methodOop |
1186 __ movptr(method, Address(rbp, 3*BytesPerWord)); | |
1187 int call_offset = __ call_RT(noreg, noreg, CAST_FROM_FN_PTR(address, counter_overflow), bci, method); | |
0 | 1188 oop_maps = new OopMapSet(); |
1189 oop_maps->add_gc_map(call_offset, map); | |
1190 restore_live_registers(sasm); | |
1191 __ leave(); | |
1192 __ ret(0); | |
1193 } | |
1194 break; | |
1195 | |
1196 case new_type_array_id: | |
1197 case new_object_array_id: | |
1198 { | |
1199 Register length = rbx; // Incoming | |
1200 Register klass = rdx; // Incoming | |
1201 Register obj = rax; // Result | |
1202 | |
1203 if (id == new_type_array_id) { | |
1204 __ set_info("new_type_array", dont_gc_arguments); | |
1205 } else { | |
1206 __ set_info("new_object_array", dont_gc_arguments); | |
1207 } | |
1208 | |
1209 #ifdef ASSERT | |
1210 // assert object type is really an array of the proper kind | |
1211 { | |
1212 Label ok; | |
1213 Register t0 = obj; | |
1214 __ movl(t0, Address(klass, Klass::layout_helper_offset_in_bytes() + sizeof(oopDesc))); | |
1215 __ sarl(t0, Klass::_lh_array_tag_shift); | |
1216 int tag = ((id == new_type_array_id) | |
1217 ? Klass::_lh_array_tag_type_value | |
1218 : Klass::_lh_array_tag_obj_value); | |
1219 __ cmpl(t0, tag); | |
1220 __ jcc(Assembler::equal, ok); | |
1221 __ stop("assert(is an array klass)"); | |
1222 __ should_not_reach_here(); | |
1223 __ bind(ok); | |
1224 } | |
1225 #endif // ASSERT | |
1226 | |
1227 if (UseTLAB && FastTLABRefill) { | |
1228 Register arr_size = rsi; | |
1229 Register t1 = rcx; // must be rcx for use as shift count | |
1230 Register t2 = rdi; | |
1231 Label slow_path; | |
1232 assert_different_registers(length, klass, obj, arr_size, t1, t2); | |
1233 | |
1234 // check that array length is small enough for fast path. | |
1235 __ cmpl(length, C1_MacroAssembler::max_array_allocation_length); | |
1236 __ jcc(Assembler::above, slow_path); | |
1237 | |
1238 // if we got here then the TLAB allocation failed, so try | |
1239 // refilling the TLAB or allocating directly from eden. | |
1240 Label retry_tlab, try_eden; | |
2100
b1a2afa37ec4
7003271: Hotspot should track cumulative Java heap bytes allocated on a per-thread basis
phh
parents:
2002
diff
changeset
|
1241 const Register thread = |
b1a2afa37ec4
7003271: Hotspot should track cumulative Java heap bytes allocated on a per-thread basis
phh
parents:
2002
diff
changeset
|
1242 __ tlab_refill(retry_tlab, try_eden, slow_path); // preserves rbx & rdx, returns rdi |
0 | 1243 |
1244 __ bind(retry_tlab); | |
1245 | |
1246 // get the allocation size: round_up(hdr + length << (layout_helper & 0x1F)) | |
2100
b1a2afa37ec4
7003271: Hotspot should track cumulative Java heap bytes allocated on a per-thread basis
phh
parents:
2002
diff
changeset
|
1247 // since size is positive movl does right thing on 64bit |
0 | 1248 __ movl(t1, Address(klass, klassOopDesc::header_size() * HeapWordSize + Klass::layout_helper_offset_in_bytes())); |
304 | 1249 // since size is postive movl does right thing on 64bit |
0 | 1250 __ movl(arr_size, length); |
1251 assert(t1 == rcx, "fixed register usage"); | |
304 | 1252 __ shlptr(arr_size /* by t1=rcx, mod 32 */); |
1253 __ shrptr(t1, Klass::_lh_header_size_shift); | |
1254 __ andptr(t1, Klass::_lh_header_size_mask); | |
1255 __ addptr(arr_size, t1); | |
1256 __ addptr(arr_size, MinObjAlignmentInBytesMask); // align up | |
1257 __ andptr(arr_size, ~MinObjAlignmentInBytesMask); | |
0 | 1258 |
1259 __ tlab_allocate(obj, arr_size, 0, t1, t2, slow_path); // preserves arr_size | |
1260 | |
1261 __ initialize_header(obj, klass, length, t1, t2); | |
1262 __ movb(t1, Address(klass, klassOopDesc::header_size() * HeapWordSize + Klass::layout_helper_offset_in_bytes() + (Klass::_lh_header_size_shift / BitsPerByte))); | |
1263 assert(Klass::_lh_header_size_shift % BitsPerByte == 0, "bytewise"); | |
1264 assert(Klass::_lh_header_size_mask <= 0xFF, "bytewise"); | |
304 | 1265 __ andptr(t1, Klass::_lh_header_size_mask); |
1266 __ subptr(arr_size, t1); // body length | |
1267 __ addptr(t1, obj); // body start | |
0 | 1268 __ initialize_body(t1, arr_size, 0, t2); |
1269 __ verify_oop(obj); | |
1270 __ ret(0); | |
1271 | |
1272 __ bind(try_eden); | |
1273 // get the allocation size: round_up(hdr + length << (layout_helper & 0x1F)) | |
2100
b1a2afa37ec4
7003271: Hotspot should track cumulative Java heap bytes allocated on a per-thread basis
phh
parents:
2002
diff
changeset
|
1274 // since size is positive movl does right thing on 64bit |
0 | 1275 __ movl(t1, Address(klass, klassOopDesc::header_size() * HeapWordSize + Klass::layout_helper_offset_in_bytes())); |
304 | 1276 // since size is postive movl does right thing on 64bit |
0 | 1277 __ movl(arr_size, length); |
1278 assert(t1 == rcx, "fixed register usage"); | |
304 | 1279 __ shlptr(arr_size /* by t1=rcx, mod 32 */); |
1280 __ shrptr(t1, Klass::_lh_header_size_shift); | |
1281 __ andptr(t1, Klass::_lh_header_size_mask); | |
1282 __ addptr(arr_size, t1); | |
1283 __ addptr(arr_size, MinObjAlignmentInBytesMask); // align up | |
1284 __ andptr(arr_size, ~MinObjAlignmentInBytesMask); | |
0 | 1285 |
1286 __ eden_allocate(obj, arr_size, 0, t1, slow_path); // preserves arr_size | |
2100
b1a2afa37ec4
7003271: Hotspot should track cumulative Java heap bytes allocated on a per-thread basis
phh
parents:
2002
diff
changeset
|
1287 __ incr_allocated_bytes(thread, arr_size, 0); |
0 | 1288 |
1289 __ initialize_header(obj, klass, length, t1, t2); | |
1290 __ movb(t1, Address(klass, klassOopDesc::header_size() * HeapWordSize + Klass::layout_helper_offset_in_bytes() + (Klass::_lh_header_size_shift / BitsPerByte))); | |
1291 assert(Klass::_lh_header_size_shift % BitsPerByte == 0, "bytewise"); | |
1292 assert(Klass::_lh_header_size_mask <= 0xFF, "bytewise"); | |
304 | 1293 __ andptr(t1, Klass::_lh_header_size_mask); |
1294 __ subptr(arr_size, t1); // body length | |
1295 __ addptr(t1, obj); // body start | |
0 | 1296 __ initialize_body(t1, arr_size, 0, t2); |
1297 __ verify_oop(obj); | |
1298 __ ret(0); | |
1299 | |
1300 __ bind(slow_path); | |
1301 } | |
1302 | |
1303 __ enter(); | |
1304 OopMap* map = save_live_registers(sasm, 3); | |
1305 int call_offset; | |
1306 if (id == new_type_array_id) { | |
1307 call_offset = __ call_RT(obj, noreg, CAST_FROM_FN_PTR(address, new_type_array), klass, length); | |
1308 } else { | |
1309 call_offset = __ call_RT(obj, noreg, CAST_FROM_FN_PTR(address, new_object_array), klass, length); | |
1310 } | |
1311 | |
1312 oop_maps = new OopMapSet(); | |
1313 oop_maps->add_gc_map(call_offset, map); | |
1314 restore_live_registers_except_rax(sasm); | |
1315 | |
1316 __ verify_oop(obj); | |
1317 __ leave(); | |
1318 __ ret(0); | |
1319 | |
1320 // rax,: new array | |
1321 } | |
1322 break; | |
1323 | |
1324 case new_multi_array_id: | |
1325 { StubFrame f(sasm, "new_multi_array", dont_gc_arguments); | |
1326 // rax,: klass | |
1327 // rbx,: rank | |
1328 // rcx: address of 1st dimension | |
1329 OopMap* map = save_live_registers(sasm, 4); | |
1330 int call_offset = __ call_RT(rax, noreg, CAST_FROM_FN_PTR(address, new_multi_array), rax, rbx, rcx); | |
1331 | |
1332 oop_maps = new OopMapSet(); | |
1333 oop_maps->add_gc_map(call_offset, map); | |
1334 restore_live_registers_except_rax(sasm); | |
1335 | |
1336 // rax,: new multi array | |
1337 __ verify_oop(rax); | |
1338 } | |
1339 break; | |
1340 | |
1341 case register_finalizer_id: | |
1342 { | |
1343 __ set_info("register_finalizer", dont_gc_arguments); | |
1344 | |
304 | 1345 // This is called via call_runtime so the arguments |
1346 // will be place in C abi locations | |
1347 | |
1348 #ifdef _LP64 | |
2891
75a99b4f1c98
Rebranded C++ part from C1X to Graal.
Thomas Wuerthinger <thomas@wuerthinger.net>
parents:
2662
diff
changeset
|
1349 __ verify_oop((UseGraal) ? j_rarg0 : c_rarg0); |
75a99b4f1c98
Rebranded C++ part from C1X to Graal.
Thomas Wuerthinger <thomas@wuerthinger.net>
parents:
2662
diff
changeset
|
1350 __ mov(rax, (UseGraal) ? j_rarg0 : c_rarg0); |
304 | 1351 #else |
0 | 1352 // The object is passed on the stack and we haven't pushed a |
1353 // frame yet so it's one work away from top of stack. | |
304 | 1354 __ movptr(rax, Address(rsp, 1 * BytesPerWord)); |
0 | 1355 __ verify_oop(rax); |
304 | 1356 #endif // _LP64 |
0 | 1357 |
1358 // load the klass and check the has finalizer flag | |
1359 Label register_finalizer; | |
1360 Register t = rsi; | |
2002 | 1361 __ load_klass(t, rax); |
0 | 1362 __ movl(t, Address(t, Klass::access_flags_offset_in_bytes() + sizeof(oopDesc))); |
1363 __ testl(t, JVM_ACC_HAS_FINALIZER); | |
1364 __ jcc(Assembler::notZero, register_finalizer); | |
1365 __ ret(0); | |
1366 | |
1367 __ bind(register_finalizer); | |
1368 __ enter(); | |
1369 OopMap* oop_map = save_live_registers(sasm, 2 /*num_rt_args */); | |
1370 int call_offset = __ call_RT(noreg, noreg, | |
1371 CAST_FROM_FN_PTR(address, SharedRuntime::register_finalizer), rax); | |
1372 oop_maps = new OopMapSet(); | |
1373 oop_maps->add_gc_map(call_offset, oop_map); | |
1374 | |
1375 // Now restore all the live registers | |
1376 restore_live_registers(sasm); | |
1377 | |
1378 __ leave(); | |
1379 __ ret(0); | |
1380 } | |
1381 break; | |
1382 | |
1383 case throw_range_check_failed_id: | |
1384 { StubFrame f(sasm, "range_check_failed", dont_gc_arguments); | |
1385 oop_maps = generate_exception_throw(sasm, CAST_FROM_FN_PTR(address, throw_range_check_exception), true); | |
1386 } | |
1387 break; | |
1388 | |
1389 case throw_index_exception_id: | |
1390 { StubFrame f(sasm, "index_range_check_failed", dont_gc_arguments); | |
1391 oop_maps = generate_exception_throw(sasm, CAST_FROM_FN_PTR(address, throw_index_exception), true); | |
1392 } | |
1393 break; | |
1394 | |
1395 case throw_div0_exception_id: | |
1396 { StubFrame f(sasm, "throw_div0_exception", dont_gc_arguments); | |
1397 oop_maps = generate_exception_throw(sasm, CAST_FROM_FN_PTR(address, throw_div0_exception), false); | |
1398 } | |
1399 break; | |
1400 | |
1401 case throw_null_pointer_exception_id: | |
1402 { StubFrame f(sasm, "throw_null_pointer_exception", dont_gc_arguments); | |
1403 oop_maps = generate_exception_throw(sasm, CAST_FROM_FN_PTR(address, throw_null_pointer_exception), false); | |
1404 } | |
1405 break; | |
1406 | |
1407 case handle_exception_nofpu_id: | |
1408 case handle_exception_id: | |
1409 { StubFrame f(sasm, "handle_exception", dont_gc_arguments); | |
2321
1b4e6a5d98e0
7012914: JSR 292 MethodHandlesTest C1: frame::verify_return_pc(return_address) failed: must be a return pc
twisti
parents:
2168
diff
changeset
|
1410 oop_maps = generate_handle_exception(id, sasm); |
1b4e6a5d98e0
7012914: JSR 292 MethodHandlesTest C1: frame::verify_return_pc(return_address) failed: must be a return pc
twisti
parents:
2168
diff
changeset
|
1411 } |
1b4e6a5d98e0
7012914: JSR 292 MethodHandlesTest C1: frame::verify_return_pc(return_address) failed: must be a return pc
twisti
parents:
2168
diff
changeset
|
1412 break; |
1b4e6a5d98e0
7012914: JSR 292 MethodHandlesTest C1: frame::verify_return_pc(return_address) failed: must be a return pc
twisti
parents:
2168
diff
changeset
|
1413 |
1b4e6a5d98e0
7012914: JSR 292 MethodHandlesTest C1: frame::verify_return_pc(return_address) failed: must be a return pc
twisti
parents:
2168
diff
changeset
|
1414 case handle_exception_from_callee_id: |
1b4e6a5d98e0
7012914: JSR 292 MethodHandlesTest C1: frame::verify_return_pc(return_address) failed: must be a return pc
twisti
parents:
2168
diff
changeset
|
1415 { StubFrame f(sasm, "handle_exception_from_callee", dont_gc_arguments); |
1b4e6a5d98e0
7012914: JSR 292 MethodHandlesTest C1: frame::verify_return_pc(return_address) failed: must be a return pc
twisti
parents:
2168
diff
changeset
|
1416 oop_maps = generate_handle_exception(id, sasm); |
0 | 1417 } |
1418 break; | |
1419 | |
1420 case unwind_exception_id: | |
1429
abc670a709dc
* -XX:TraceC1X=0...5 controls the native c1x tracing
Lukas Stadler <lukas.stadler@oracle.com>
parents:
1423
diff
changeset
|
1421 { |
abc670a709dc
* -XX:TraceC1X=0...5 controls the native c1x tracing
Lukas Stadler <lukas.stadler@oracle.com>
parents:
1423
diff
changeset
|
1422 __ set_info("unwind_exception", dont_gc_arguments); |
0 | 1423 // note: no stubframe since we are about to leave the current |
1424 // activation and we are calling a leaf VM function only. | |
1425 generate_unwind_exception(sasm); | |
1426 } | |
1427 break; | |
1428 | |
1429 case throw_array_store_exception_id: | |
1430 { StubFrame f(sasm, "throw_array_store_exception", dont_gc_arguments); | |
1431 // tos + 0: link | |
1432 // + 1: return address | |
2168
e4fee0bdaa85
7008809: should report the class in ArrayStoreExceptions from compiled code
never
parents:
2100
diff
changeset
|
1433 oop_maps = generate_exception_throw(sasm, CAST_FROM_FN_PTR(address, throw_array_store_exception), true); |
0 | 1434 } |
1435 break; | |
1436 | |
1437 case throw_class_cast_exception_id: | |
1438 { StubFrame f(sasm, "throw_class_cast_exception", dont_gc_arguments); | |
1439 oop_maps = generate_exception_throw(sasm, CAST_FROM_FN_PTR(address, throw_class_cast_exception), true); | |
1440 } | |
1441 break; | |
1442 | |
1443 case throw_incompatible_class_change_error_id: | |
1444 { StubFrame f(sasm, "throw_incompatible_class_cast_exception", dont_gc_arguments); | |
1445 oop_maps = generate_exception_throw(sasm, CAST_FROM_FN_PTR(address, throw_incompatible_class_change_error), false); | |
1446 } | |
1447 break; | |
1448 | |
1449 case slow_subtype_check_id: | |
1450 { | |
644
c517646eef23
6813212: factor duplicated assembly code for general subclass check (for 6655638)
jrose
parents:
533
diff
changeset
|
1451 // Typical calling sequence: |
c517646eef23
6813212: factor duplicated assembly code for general subclass check (for 6655638)
jrose
parents:
533
diff
changeset
|
1452 // __ push(klass_RInfo); // object klass or other subclass |
c517646eef23
6813212: factor duplicated assembly code for general subclass check (for 6655638)
jrose
parents:
533
diff
changeset
|
1453 // __ push(sup_k_RInfo); // array element klass or other superclass |
c517646eef23
6813212: factor duplicated assembly code for general subclass check (for 6655638)
jrose
parents:
533
diff
changeset
|
1454 // __ call(slow_subtype_check); |
c517646eef23
6813212: factor duplicated assembly code for general subclass check (for 6655638)
jrose
parents:
533
diff
changeset
|
1455 // Note that the subclass is pushed first, and is therefore deepest. |
c517646eef23
6813212: factor duplicated assembly code for general subclass check (for 6655638)
jrose
parents:
533
diff
changeset
|
1456 // Previous versions of this code reversed the names 'sub' and 'super'. |
c517646eef23
6813212: factor duplicated assembly code for general subclass check (for 6655638)
jrose
parents:
533
diff
changeset
|
1457 // This was operationally harmless but made the code unreadable. |
0 | 1458 enum layout { |
304 | 1459 rax_off, SLOT2(raxH_off) |
1460 rcx_off, SLOT2(rcxH_off) | |
1461 rsi_off, SLOT2(rsiH_off) | |
1462 rdi_off, SLOT2(rdiH_off) | |
1463 // saved_rbp_off, SLOT2(saved_rbpH_off) | |
1464 return_off, SLOT2(returnH_off) | |
644
c517646eef23
6813212: factor duplicated assembly code for general subclass check (for 6655638)
jrose
parents:
533
diff
changeset
|
1465 sup_k_off, SLOT2(sup_kH_off) |
c517646eef23
6813212: factor duplicated assembly code for general subclass check (for 6655638)
jrose
parents:
533
diff
changeset
|
1466 klass_off, SLOT2(superH_off) |
c517646eef23
6813212: factor duplicated assembly code for general subclass check (for 6655638)
jrose
parents:
533
diff
changeset
|
1467 framesize, |
c517646eef23
6813212: factor duplicated assembly code for general subclass check (for 6655638)
jrose
parents:
533
diff
changeset
|
1468 result_off = klass_off // deepest argument is also the return value |
0 | 1469 }; |
1470 | |
1471 __ set_info("slow_subtype_check", dont_gc_arguments); | |
304 | 1472 __ push(rdi); |
1473 __ push(rsi); | |
1474 __ push(rcx); | |
1475 __ push(rax); | |
0 | 1476 |
304 | 1477 // This is called by pushing args and not with C abi |
644
c517646eef23
6813212: factor duplicated assembly code for general subclass check (for 6655638)
jrose
parents:
533
diff
changeset
|
1478 __ movptr(rsi, Address(rsp, (klass_off) * VMRegImpl::stack_slot_size)); // subclass |
c517646eef23
6813212: factor duplicated assembly code for general subclass check (for 6655638)
jrose
parents:
533
diff
changeset
|
1479 __ movptr(rax, Address(rsp, (sup_k_off) * VMRegImpl::stack_slot_size)); // superclass |
0 | 1480 |
1423
760213a60e8b
* rewrite of the code installation
Lukas Stadler <lukas.stadler@oracle.com>
parents:
1414
diff
changeset
|
1481 Label success; |
0 | 1482 Label miss; |
2891
75a99b4f1c98
Rebranded C++ part from C1X to Graal.
Thomas Wuerthinger <thomas@wuerthinger.net>
parents:
2662
diff
changeset
|
1483 if (UseGraal) { |
1423
760213a60e8b
* rewrite of the code installation
Lukas Stadler <lukas.stadler@oracle.com>
parents:
1414
diff
changeset
|
1484 // TODO this should really be within the XirSnippets |
760213a60e8b
* rewrite of the code installation
Lukas Stadler <lukas.stadler@oracle.com>
parents:
1414
diff
changeset
|
1485 __ check_klass_subtype_fast_path(rsi, rax, rcx, &success, &miss, NULL); |
760213a60e8b
* rewrite of the code installation
Lukas Stadler <lukas.stadler@oracle.com>
parents:
1414
diff
changeset
|
1486 }; |
760213a60e8b
* rewrite of the code installation
Lukas Stadler <lukas.stadler@oracle.com>
parents:
1414
diff
changeset
|
1487 |
644
c517646eef23
6813212: factor duplicated assembly code for general subclass check (for 6655638)
jrose
parents:
533
diff
changeset
|
1488 __ check_klass_subtype_slow_path(rsi, rax, rcx, rdi, NULL, &miss); |
c517646eef23
6813212: factor duplicated assembly code for general subclass check (for 6655638)
jrose
parents:
533
diff
changeset
|
1489 |
c517646eef23
6813212: factor duplicated assembly code for general subclass check (for 6655638)
jrose
parents:
533
diff
changeset
|
1490 // fallthrough on success: |
1423
760213a60e8b
* rewrite of the code installation
Lukas Stadler <lukas.stadler@oracle.com>
parents:
1414
diff
changeset
|
1491 __ bind(success); |
644
c517646eef23
6813212: factor duplicated assembly code for general subclass check (for 6655638)
jrose
parents:
533
diff
changeset
|
1492 __ movptr(Address(rsp, (result_off) * VMRegImpl::stack_slot_size), 1); // result |
304 | 1493 __ pop(rax); |
1494 __ pop(rcx); | |
1495 __ pop(rsi); | |
1496 __ pop(rdi); | |
0 | 1497 __ ret(0); |
1498 | |
1499 __ bind(miss); | |
644
c517646eef23
6813212: factor duplicated assembly code for general subclass check (for 6655638)
jrose
parents:
533
diff
changeset
|
1500 __ movptr(Address(rsp, (result_off) * VMRegImpl::stack_slot_size), NULL_WORD); // result |
304 | 1501 __ pop(rax); |
1502 __ pop(rcx); | |
1503 __ pop(rsi); | |
1504 __ pop(rdi); | |
0 | 1505 __ ret(0); |
1506 } | |
1507 break; | |
1508 | |
1509 case monitorenter_nofpu_id: | |
1510 save_fpu_registers = false; | |
1511 // fall through | |
1512 case monitorenter_id: | |
1513 { | |
1514 StubFrame f(sasm, "monitorenter", dont_gc_arguments); | |
1515 OopMap* map = save_live_registers(sasm, 3, save_fpu_registers); | |
1516 | |
304 | 1517 // Called with store_parameter and not C abi |
1518 | |
0 | 1519 f.load_argument(1, rax); // rax,: object |
1520 f.load_argument(0, rbx); // rbx,: lock address | |
1521 | |
1522 int call_offset = __ call_RT(noreg, noreg, CAST_FROM_FN_PTR(address, monitorenter), rax, rbx); | |
1523 | |
1524 oop_maps = new OopMapSet(); | |
1525 oop_maps->add_gc_map(call_offset, map); | |
1526 restore_live_registers(sasm, save_fpu_registers); | |
1527 } | |
1528 break; | |
1529 | |
1530 case monitorexit_nofpu_id: | |
1531 save_fpu_registers = false; | |
1532 // fall through | |
1533 case monitorexit_id: | |
1534 { | |
1535 StubFrame f(sasm, "monitorexit", dont_gc_arguments); | |
1536 OopMap* map = save_live_registers(sasm, 2, save_fpu_registers); | |
1537 | |
304 | 1538 // Called with store_parameter and not C abi |
1539 | |
0 | 1540 f.load_argument(0, rax); // rax,: lock address |
1541 | |
1542 // note: really a leaf routine but must setup last java sp | |
1543 // => use call_RT for now (speed can be improved by | |
1544 // doing last java sp setup manually) | |
1545 int call_offset = __ call_RT(noreg, noreg, CAST_FROM_FN_PTR(address, monitorexit), rax); | |
1546 | |
1547 oop_maps = new OopMapSet(); | |
1548 oop_maps->add_gc_map(call_offset, map); | |
1549 restore_live_registers(sasm, save_fpu_registers); | |
1550 | |
1551 } | |
1552 break; | |
1553 | |
1554 case access_field_patching_id: | |
1555 { StubFrame f(sasm, "access_field_patching", dont_gc_arguments); | |
1556 // we should set up register map | |
1557 oop_maps = generate_patching(sasm, CAST_FROM_FN_PTR(address, access_field_patching)); | |
1558 } | |
1559 break; | |
1560 | |
1561 case load_klass_patching_id: | |
1562 { StubFrame f(sasm, "load_klass_patching", dont_gc_arguments); | |
1563 // we should set up register map | |
1564 oop_maps = generate_patching(sasm, CAST_FROM_FN_PTR(address, move_klass_patching)); | |
1565 } | |
1566 break; | |
1567 | |
1568 case jvmti_exception_throw_id: | |
1569 { // rax,: exception oop | |
1570 StubFrame f(sasm, "jvmti_exception_throw", dont_gc_arguments); | |
1571 // Preserve all registers across this potentially blocking call | |
1572 const int num_rt_args = 2; // thread, exception oop | |
1573 OopMap* map = save_live_registers(sasm, num_rt_args); | |
1574 int call_offset = __ call_RT(noreg, noreg, CAST_FROM_FN_PTR(address, Runtime1::post_jvmti_exception_throw), rax); | |
1575 oop_maps = new OopMapSet(); | |
1576 oop_maps->add_gc_map(call_offset, map); | |
1577 restore_live_registers(sasm); | |
1578 } | |
1579 break; | |
1580 | |
1581 case dtrace_object_alloc_id: | |
1582 { // rax,: object | |
1583 StubFrame f(sasm, "dtrace_object_alloc", dont_gc_arguments); | |
1584 // we can't gc here so skip the oopmap but make sure that all | |
1585 // the live registers get saved. | |
1586 save_live_registers(sasm, 1); | |
1587 | |
304 | 1588 __ NOT_LP64(push(rax)) LP64_ONLY(mov(c_rarg0, rax)); |
0 | 1589 __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, SharedRuntime::dtrace_object_alloc))); |
304 | 1590 NOT_LP64(__ pop(rax)); |
0 | 1591 |
1592 restore_live_registers(sasm); | |
1593 } | |
1594 break; | |
1595 | |
1596 case fpu2long_stub_id: | |
1597 { | |
1598 // rax, and rdx are destroyed, but should be free since the result is returned there | |
1599 // preserve rsi,ecx | |
304 | 1600 __ push(rsi); |
1601 __ push(rcx); | |
1602 LP64_ONLY(__ push(rdx);) | |
0 | 1603 |
1604 // check for NaN | |
1605 Label return0, do_return, return_min_jlong, do_convert; | |
1606 | |
304 | 1607 Address value_high_word(rsp, wordSize + 4); |
1608 Address value_low_word(rsp, wordSize); | |
1609 Address result_high_word(rsp, 3*wordSize + 4); | |
1610 Address result_low_word(rsp, 3*wordSize); | |
0 | 1611 |
304 | 1612 __ subptr(rsp, 32); // more than enough on 32bit |
0 | 1613 __ fst_d(value_low_word); |
1614 __ movl(rax, value_high_word); | |
1615 __ andl(rax, 0x7ff00000); | |
1616 __ cmpl(rax, 0x7ff00000); | |
1617 __ jcc(Assembler::notEqual, do_convert); | |
1618 __ movl(rax, value_high_word); | |
1619 __ andl(rax, 0xfffff); | |
1620 __ orl(rax, value_low_word); | |
1621 __ jcc(Assembler::notZero, return0); | |
1622 | |
1623 __ bind(do_convert); | |
1624 __ fnstcw(Address(rsp, 0)); | |
304 | 1625 __ movzwl(rax, Address(rsp, 0)); |
0 | 1626 __ orl(rax, 0xc00); |
1627 __ movw(Address(rsp, 2), rax); | |
1628 __ fldcw(Address(rsp, 2)); | |
1629 __ fwait(); | |
1630 __ fistp_d(result_low_word); | |
1631 __ fldcw(Address(rsp, 0)); | |
1632 __ fwait(); | |
304 | 1633 // This gets the entire long in rax on 64bit |
1634 __ movptr(rax, result_low_word); | |
1635 // testing of high bits | |
0 | 1636 __ movl(rdx, result_high_word); |
304 | 1637 __ mov(rcx, rax); |
0 | 1638 // What the heck is the point of the next instruction??? |
1639 __ xorl(rcx, 0x0); | |
1640 __ movl(rsi, 0x80000000); | |
1641 __ xorl(rsi, rdx); | |
1642 __ orl(rcx, rsi); | |
1643 __ jcc(Assembler::notEqual, do_return); | |
1644 __ fldz(); | |
1645 __ fcomp_d(value_low_word); | |
1646 __ fnstsw_ax(); | |
304 | 1647 #ifdef _LP64 |
1648 __ testl(rax, 0x4100); // ZF & CF == 0 | |
1649 __ jcc(Assembler::equal, return_min_jlong); | |
1650 #else | |
0 | 1651 __ sahf(); |
1652 __ jcc(Assembler::above, return_min_jlong); | |
304 | 1653 #endif // _LP64 |
0 | 1654 // return max_jlong |
304 | 1655 #ifndef _LP64 |
0 | 1656 __ movl(rdx, 0x7fffffff); |
1657 __ movl(rax, 0xffffffff); | |
304 | 1658 #else |
1659 __ mov64(rax, CONST64(0x7fffffffffffffff)); | |
1660 #endif // _LP64 | |
0 | 1661 __ jmp(do_return); |
1662 | |
1663 __ bind(return_min_jlong); | |
304 | 1664 #ifndef _LP64 |
0 | 1665 __ movl(rdx, 0x80000000); |
1666 __ xorl(rax, rax); | |
304 | 1667 #else |
1668 __ mov64(rax, CONST64(0x8000000000000000)); | |
1669 #endif // _LP64 | |
0 | 1670 __ jmp(do_return); |
1671 | |
1672 __ bind(return0); | |
1673 __ fpop(); | |
304 | 1674 #ifndef _LP64 |
1675 __ xorptr(rdx,rdx); | |
1676 __ xorptr(rax,rax); | |
1677 #else | |
1678 __ xorptr(rax, rax); | |
1679 #endif // _LP64 | |
0 | 1680 |
1681 __ bind(do_return); | |
304 | 1682 __ addptr(rsp, 32); |
1683 LP64_ONLY(__ pop(rdx);) | |
1684 __ pop(rcx); | |
1685 __ pop(rsi); | |
0 | 1686 __ ret(0); |
1687 } | |
1688 break; | |
1689 | |
342 | 1690 #ifndef SERIALGC |
1691 case g1_pre_barrier_slow_id: | |
1692 { | |
1693 StubFrame f(sasm, "g1_pre_barrier", dont_gc_arguments); | |
1694 // arg0 : previous value of memory | |
1695 | |
1696 BarrierSet* bs = Universe::heap()->barrier_set(); | |
1697 if (bs->kind() != BarrierSet::G1SATBCTLogging) { | |
362 | 1698 __ movptr(rax, (int)id); |
342 | 1699 __ call_RT(noreg, noreg, CAST_FROM_FN_PTR(address, unimplemented_entry), rax); |
1700 __ should_not_reach_here(); | |
1701 break; | |
1702 } | |
362 | 1703 __ push(rax); |
1704 __ push(rdx); | |
342 | 1705 |
1706 const Register pre_val = rax; | |
362 | 1707 const Register thread = NOT_LP64(rax) LP64_ONLY(r15_thread); |
342 | 1708 const Register tmp = rdx; |
1709 | |
362 | 1710 NOT_LP64(__ get_thread(thread);) |
342 | 1711 |
1712 Address in_progress(thread, in_bytes(JavaThread::satb_mark_queue_offset() + | |
1713 PtrQueue::byte_offset_of_active())); | |
1714 | |
1715 Address queue_index(thread, in_bytes(JavaThread::satb_mark_queue_offset() + | |
1716 PtrQueue::byte_offset_of_index())); | |
1717 Address buffer(thread, in_bytes(JavaThread::satb_mark_queue_offset() + | |
1718 PtrQueue::byte_offset_of_buf())); | |
1719 | |
1720 | |
1721 Label done; | |
1722 Label runtime; | |
1723 | |
1724 // Can we store original value in the thread's buffer? | |
1725 | |
362 | 1726 #ifdef _LP64 |
1572 | 1727 __ movslq(tmp, queue_index); |
362 | 1728 __ cmpq(tmp, 0); |
1729 #else | |
342 | 1730 __ cmpl(queue_index, 0); |
362 | 1731 #endif |
342 | 1732 __ jcc(Assembler::equal, runtime); |
362 | 1733 #ifdef _LP64 |
1734 __ subq(tmp, wordSize); | |
1735 __ movl(queue_index, tmp); | |
1736 __ addq(tmp, buffer); | |
1737 #else | |
342 | 1738 __ subl(queue_index, wordSize); |
1739 __ movl(tmp, buffer); | |
1740 __ addl(tmp, queue_index); | |
362 | 1741 #endif |
1742 | |
342 | 1743 // prev_val (rax) |
1744 f.load_argument(0, pre_val); | |
362 | 1745 __ movptr(Address(tmp, 0), pre_val); |
342 | 1746 __ jmp(done); |
1747 | |
1748 __ bind(runtime); | |
1572 | 1749 __ push(rcx); |
1750 #ifdef _LP64 | |
1751 __ push(r8); | |
1752 __ push(r9); | |
1753 __ push(r10); | |
1754 __ push(r11); | |
1755 # ifndef _WIN64 | |
1756 __ push(rdi); | |
1757 __ push(rsi); | |
1758 # endif | |
1759 #endif | |
342 | 1760 // load the pre-value |
1761 f.load_argument(0, rcx); | |
1762 __ call_VM_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::g1_wb_pre), rcx, thread); | |
1572 | 1763 #ifdef _LP64 |
1764 # ifndef _WIN64 | |
1765 __ pop(rsi); | |
1766 __ pop(rdi); | |
1767 # endif | |
1768 __ pop(r11); | |
1769 __ pop(r10); | |
1770 __ pop(r9); | |
1771 __ pop(r8); | |
1772 #endif | |
362 | 1773 __ pop(rcx); |
1572 | 1774 __ bind(done); |
342 | 1775 |
362 | 1776 __ pop(rdx); |
1777 __ pop(rax); | |
342 | 1778 } |
1779 break; | |
1780 | |
1781 case g1_post_barrier_slow_id: | |
1782 { | |
1783 StubFrame f(sasm, "g1_post_barrier", dont_gc_arguments); | |
1784 | |
1785 | |
1786 // arg0: store_address | |
1787 Address store_addr(rbp, 2*BytesPerWord); | |
1788 | |
1789 BarrierSet* bs = Universe::heap()->barrier_set(); | |
1790 CardTableModRefBS* ct = (CardTableModRefBS*)bs; | |
1791 Label done; | |
1792 Label runtime; | |
1793 | |
1794 // At this point we know new_value is non-NULL and the new_value crosses regsion. | |
1795 // Must check to see if card is already dirty | |
1796 | |
362 | 1797 const Register thread = NOT_LP64(rax) LP64_ONLY(r15_thread); |
342 | 1798 |
1799 Address queue_index(thread, in_bytes(JavaThread::dirty_card_queue_offset() + | |
1800 PtrQueue::byte_offset_of_index())); | |
1801 Address buffer(thread, in_bytes(JavaThread::dirty_card_queue_offset() + | |
1802 PtrQueue::byte_offset_of_buf())); | |
1803 | |
362 | 1804 __ push(rax); |
1572 | 1805 __ push(rcx); |
342 | 1806 |
362 | 1807 NOT_LP64(__ get_thread(thread);) |
1808 ExternalAddress cardtable((address)ct->byte_map_base); | |
342 | 1809 assert(sizeof(*ct->byte_map_base) == sizeof(jbyte), "adjust this code"); |
1810 | |
1572 | 1811 const Register card_addr = rcx; |
362 | 1812 #ifdef _LP64 |
1813 const Register tmp = rscratch1; | |
1814 f.load_argument(0, card_addr); | |
1815 __ shrq(card_addr, CardTableModRefBS::card_shift); | |
1816 __ lea(tmp, cardtable); | |
1817 // get the address of the card | |
1818 __ addq(card_addr, tmp); | |
1819 #else | |
1572 | 1820 const Register card_index = rcx; |
362 | 1821 f.load_argument(0, card_index); |
1822 __ shrl(card_index, CardTableModRefBS::card_shift); | |
1823 | |
342 | 1824 Address index(noreg, card_index, Address::times_1); |
1825 __ leal(card_addr, __ as_Address(ArrayAddress(cardtable, index))); | |
362 | 1826 #endif |
1827 | |
342 | 1828 __ cmpb(Address(card_addr, 0), 0); |
1829 __ jcc(Assembler::equal, done); | |
1830 | |
1831 // storing region crossing non-NULL, card is clean. | |
1832 // dirty card and log. | |
1833 | |
1834 __ movb(Address(card_addr, 0), 0); | |
1835 | |
1836 __ cmpl(queue_index, 0); | |
1837 __ jcc(Assembler::equal, runtime); | |
1838 __ subl(queue_index, wordSize); | |
1839 | |
1840 const Register buffer_addr = rbx; | |
362 | 1841 __ push(rbx); |
1842 | |
1843 __ movptr(buffer_addr, buffer); | |
342 | 1844 |
362 | 1845 #ifdef _LP64 |
1846 __ movslq(rscratch1, queue_index); | |
1847 __ addptr(buffer_addr, rscratch1); | |
1848 #else | |
1849 __ addptr(buffer_addr, queue_index); | |
1850 #endif | |
1851 __ movptr(Address(buffer_addr, 0), card_addr); | |
1852 | |
1853 __ pop(rbx); | |
342 | 1854 __ jmp(done); |
1855 | |
1856 __ bind(runtime); | |
1572 | 1857 __ push(rdx); |
1858 #ifdef _LP64 | |
1859 __ push(r8); | |
1860 __ push(r9); | |
1861 __ push(r10); | |
1862 __ push(r11); | |
1863 # ifndef _WIN64 | |
1864 __ push(rdi); | |
1865 __ push(rsi); | |
1866 # endif | |
1867 #endif | |
342 | 1868 __ call_VM_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::g1_wb_post), card_addr, thread); |
1572 | 1869 #ifdef _LP64 |
1870 # ifndef _WIN64 | |
1871 __ pop(rsi); | |
1872 __ pop(rdi); | |
1873 # endif | |
1874 __ pop(r11); | |
1875 __ pop(r10); | |
1876 __ pop(r9); | |
1877 __ pop(r8); | |
1878 #endif | |
1879 __ pop(rdx); | |
1880 __ bind(done); | |
342 | 1881 |
1572 | 1882 __ pop(rcx); |
362 | 1883 __ pop(rax); |
342 | 1884 |
1885 } | |
1886 break; | |
1887 #endif // !SERIALGC | |
1888 | |
2891
75a99b4f1c98
Rebranded C++ part from C1X to Graal.
Thomas Wuerthinger <thomas@wuerthinger.net>
parents:
2662
diff
changeset
|
1889 case graal_unwind_exception_call_id: { |
1434
72cfb36c6bb2
* enabled all jtt tests
Lukas Stadler <lukas.stadler@oracle.com>
parents:
1429
diff
changeset
|
1890 // remove the frame from the stack |
72cfb36c6bb2
* enabled all jtt tests
Lukas Stadler <lukas.stadler@oracle.com>
parents:
1429
diff
changeset
|
1891 __ movptr(rsp, rbp); |
72cfb36c6bb2
* enabled all jtt tests
Lukas Stadler <lukas.stadler@oracle.com>
parents:
1429
diff
changeset
|
1892 __ pop(rbp); |
72cfb36c6bb2
* enabled all jtt tests
Lukas Stadler <lukas.stadler@oracle.com>
parents:
1429
diff
changeset
|
1893 // exception_oop is passed using ordinary java calling conventions |
72cfb36c6bb2
* enabled all jtt tests
Lukas Stadler <lukas.stadler@oracle.com>
parents:
1429
diff
changeset
|
1894 __ movptr(rax, j_rarg0); |
72cfb36c6bb2
* enabled all jtt tests
Lukas Stadler <lukas.stadler@oracle.com>
parents:
1429
diff
changeset
|
1895 |
72cfb36c6bb2
* enabled all jtt tests
Lukas Stadler <lukas.stadler@oracle.com>
parents:
1429
diff
changeset
|
1896 Label nonNullExceptionOop; |
72cfb36c6bb2
* enabled all jtt tests
Lukas Stadler <lukas.stadler@oracle.com>
parents:
1429
diff
changeset
|
1897 __ testptr(rax, rax); |
72cfb36c6bb2
* enabled all jtt tests
Lukas Stadler <lukas.stadler@oracle.com>
parents:
1429
diff
changeset
|
1898 __ jcc(Assembler::notZero, nonNullExceptionOop); |
1429
abc670a709dc
* -XX:TraceC1X=0...5 controls the native c1x tracing
Lukas Stadler <lukas.stadler@oracle.com>
parents:
1423
diff
changeset
|
1899 { |
1434
72cfb36c6bb2
* enabled all jtt tests
Lukas Stadler <lukas.stadler@oracle.com>
parents:
1429
diff
changeset
|
1900 __ enter(); |
72cfb36c6bb2
* enabled all jtt tests
Lukas Stadler <lukas.stadler@oracle.com>
parents:
1429
diff
changeset
|
1901 oop_maps = new OopMapSet(); |
72cfb36c6bb2
* enabled all jtt tests
Lukas Stadler <lukas.stadler@oracle.com>
parents:
1429
diff
changeset
|
1902 OopMap* oop_map = save_live_registers(sasm, 0); |
2891
75a99b4f1c98
Rebranded C++ part from C1X to Graal.
Thomas Wuerthinger <thomas@wuerthinger.net>
parents:
2662
diff
changeset
|
1903 int call_offset = __ call_RT(rax, noreg, (address)graal_create_null_exception, 0); |
1434
72cfb36c6bb2
* enabled all jtt tests
Lukas Stadler <lukas.stadler@oracle.com>
parents:
1429
diff
changeset
|
1904 oop_maps->add_gc_map(call_offset, oop_map); |
72cfb36c6bb2
* enabled all jtt tests
Lukas Stadler <lukas.stadler@oracle.com>
parents:
1429
diff
changeset
|
1905 __ leave(); |
72cfb36c6bb2
* enabled all jtt tests
Lukas Stadler <lukas.stadler@oracle.com>
parents:
1429
diff
changeset
|
1906 } |
72cfb36c6bb2
* enabled all jtt tests
Lukas Stadler <lukas.stadler@oracle.com>
parents:
1429
diff
changeset
|
1907 __ bind(nonNullExceptionOop); |
1429
abc670a709dc
* -XX:TraceC1X=0...5 controls the native c1x tracing
Lukas Stadler <lukas.stadler@oracle.com>
parents:
1423
diff
changeset
|
1908 |
1434
72cfb36c6bb2
* enabled all jtt tests
Lukas Stadler <lukas.stadler@oracle.com>
parents:
1429
diff
changeset
|
1909 __ set_info("unwind_exception", dont_gc_arguments); |
72cfb36c6bb2
* enabled all jtt tests
Lukas Stadler <lukas.stadler@oracle.com>
parents:
1429
diff
changeset
|
1910 // note: no stubframe since we are about to leave the current |
72cfb36c6bb2
* enabled all jtt tests
Lukas Stadler <lukas.stadler@oracle.com>
parents:
1429
diff
changeset
|
1911 // activation and we are calling a leaf VM function only. |
72cfb36c6bb2
* enabled all jtt tests
Lukas Stadler <lukas.stadler@oracle.com>
parents:
1429
diff
changeset
|
1912 generate_unwind_exception(sasm); |
72cfb36c6bb2
* enabled all jtt tests
Lukas Stadler <lukas.stadler@oracle.com>
parents:
1429
diff
changeset
|
1913 __ should_not_reach_here(); |
72cfb36c6bb2
* enabled all jtt tests
Lukas Stadler <lukas.stadler@oracle.com>
parents:
1429
diff
changeset
|
1914 break; |
72cfb36c6bb2
* enabled all jtt tests
Lukas Stadler <lukas.stadler@oracle.com>
parents:
1429
diff
changeset
|
1915 } |
1429
abc670a709dc
* -XX:TraceC1X=0...5 controls the native c1x tracing
Lukas Stadler <lukas.stadler@oracle.com>
parents:
1423
diff
changeset
|
1916 |
2891
75a99b4f1c98
Rebranded C++ part from C1X to Graal.
Thomas Wuerthinger <thomas@wuerthinger.net>
parents:
2662
diff
changeset
|
1917 case graal_handle_exception_id: { |
75a99b4f1c98
Rebranded C++ part from C1X to Graal.
Thomas Wuerthinger <thomas@wuerthinger.net>
parents:
2662
diff
changeset
|
1918 StubFrame f(sasm, "graal_handle_exception", dont_gc_arguments); |
1434
72cfb36c6bb2
* enabled all jtt tests
Lukas Stadler <lukas.stadler@oracle.com>
parents:
1429
diff
changeset
|
1919 oop_maps = new OopMapSet(); |
72cfb36c6bb2
* enabled all jtt tests
Lukas Stadler <lukas.stadler@oracle.com>
parents:
1429
diff
changeset
|
1920 OopMap* oop_map = save_live_registers(sasm, 1, false); |
2891
75a99b4f1c98
Rebranded C++ part from C1X to Graal.
Thomas Wuerthinger <thomas@wuerthinger.net>
parents:
2662
diff
changeset
|
1921 graal_generate_handle_exception(sasm, oop_maps, oop_map); |
1434
72cfb36c6bb2
* enabled all jtt tests
Lukas Stadler <lukas.stadler@oracle.com>
parents:
1429
diff
changeset
|
1922 break; |
72cfb36c6bb2
* enabled all jtt tests
Lukas Stadler <lukas.stadler@oracle.com>
parents:
1429
diff
changeset
|
1923 } |
72cfb36c6bb2
* enabled all jtt tests
Lukas Stadler <lukas.stadler@oracle.com>
parents:
1429
diff
changeset
|
1924 |
2891
75a99b4f1c98
Rebranded C++ part from C1X to Graal.
Thomas Wuerthinger <thomas@wuerthinger.net>
parents:
2662
diff
changeset
|
1925 case graal_slow_subtype_check_id: { |
1434
72cfb36c6bb2
* enabled all jtt tests
Lukas Stadler <lukas.stadler@oracle.com>
parents:
1429
diff
changeset
|
1926 Label success; |
72cfb36c6bb2
* enabled all jtt tests
Lukas Stadler <lukas.stadler@oracle.com>
parents:
1429
diff
changeset
|
1927 Label miss; |
72cfb36c6bb2
* enabled all jtt tests
Lukas Stadler <lukas.stadler@oracle.com>
parents:
1429
diff
changeset
|
1928 |
72cfb36c6bb2
* enabled all jtt tests
Lukas Stadler <lukas.stadler@oracle.com>
parents:
1429
diff
changeset
|
1929 // TODO this should really be within the XirSnippets |
72cfb36c6bb2
* enabled all jtt tests
Lukas Stadler <lukas.stadler@oracle.com>
parents:
1429
diff
changeset
|
1930 __ check_klass_subtype_fast_path(j_rarg0, j_rarg1, j_rarg2, &success, &miss, NULL); |
72cfb36c6bb2
* enabled all jtt tests
Lukas Stadler <lukas.stadler@oracle.com>
parents:
1429
diff
changeset
|
1931 __ check_klass_subtype_slow_path(j_rarg0, j_rarg1, j_rarg2, j_rarg3, NULL, &miss); |
72cfb36c6bb2
* enabled all jtt tests
Lukas Stadler <lukas.stadler@oracle.com>
parents:
1429
diff
changeset
|
1932 |
72cfb36c6bb2
* enabled all jtt tests
Lukas Stadler <lukas.stadler@oracle.com>
parents:
1429
diff
changeset
|
1933 // fallthrough on success: |
72cfb36c6bb2
* enabled all jtt tests
Lukas Stadler <lukas.stadler@oracle.com>
parents:
1429
diff
changeset
|
1934 __ bind(success); |
72cfb36c6bb2
* enabled all jtt tests
Lukas Stadler <lukas.stadler@oracle.com>
parents:
1429
diff
changeset
|
1935 __ movptr(rax, 1); |
72cfb36c6bb2
* enabled all jtt tests
Lukas Stadler <lukas.stadler@oracle.com>
parents:
1429
diff
changeset
|
1936 __ ret(0); |
72cfb36c6bb2
* enabled all jtt tests
Lukas Stadler <lukas.stadler@oracle.com>
parents:
1429
diff
changeset
|
1937 |
72cfb36c6bb2
* enabled all jtt tests
Lukas Stadler <lukas.stadler@oracle.com>
parents:
1429
diff
changeset
|
1938 __ bind(miss); |
72cfb36c6bb2
* enabled all jtt tests
Lukas Stadler <lukas.stadler@oracle.com>
parents:
1429
diff
changeset
|
1939 __ movptr(rax, NULL_WORD); |
72cfb36c6bb2
* enabled all jtt tests
Lukas Stadler <lukas.stadler@oracle.com>
parents:
1429
diff
changeset
|
1940 __ ret(0); |
72cfb36c6bb2
* enabled all jtt tests
Lukas Stadler <lukas.stadler@oracle.com>
parents:
1429
diff
changeset
|
1941 break; |
72cfb36c6bb2
* enabled all jtt tests
Lukas Stadler <lukas.stadler@oracle.com>
parents:
1429
diff
changeset
|
1942 } |
1429
abc670a709dc
* -XX:TraceC1X=0...5 controls the native c1x tracing
Lukas Stadler <lukas.stadler@oracle.com>
parents:
1423
diff
changeset
|
1943 |
2891
75a99b4f1c98
Rebranded C++ part from C1X to Graal.
Thomas Wuerthinger <thomas@wuerthinger.net>
parents:
2662
diff
changeset
|
1944 case graal_verify_pointer_id: { |
75a99b4f1c98
Rebranded C++ part from C1X to Graal.
Thomas Wuerthinger <thomas@wuerthinger.net>
parents:
2662
diff
changeset
|
1945 __ verify_oop(r13, "graal verify pointer"); |
1449
8cfe3537a0d3
Pointer verification stub. Two loose oop fixes in C1X C++ part. Logging which methods have been compiled.
Thomas Wuerthinger <wuerthinger@ssw.jku.at>
parents:
1434
diff
changeset
|
1946 __ ret(0); |
8cfe3537a0d3
Pointer verification stub. Two loose oop fixes in C1X C++ part. Logging which methods have been compiled.
Thomas Wuerthinger <wuerthinger@ssw.jku.at>
parents:
1434
diff
changeset
|
1947 break; |
8cfe3537a0d3
Pointer verification stub. Two loose oop fixes in C1X C++ part. Logging which methods have been compiled.
Thomas Wuerthinger <wuerthinger@ssw.jku.at>
parents:
1434
diff
changeset
|
1948 } |
8cfe3537a0d3
Pointer verification stub. Two loose oop fixes in C1X C++ part. Logging which methods have been compiled.
Thomas Wuerthinger <wuerthinger@ssw.jku.at>
parents:
1434
diff
changeset
|
1949 |
2891
75a99b4f1c98
Rebranded C++ part from C1X to Graal.
Thomas Wuerthinger <thomas@wuerthinger.net>
parents:
2662
diff
changeset
|
1950 case graal_arithmetic_frem_id: { |
1434
72cfb36c6bb2
* enabled all jtt tests
Lukas Stadler <lukas.stadler@oracle.com>
parents:
1429
diff
changeset
|
1951 __ subptr(rsp, 8); |
72cfb36c6bb2
* enabled all jtt tests
Lukas Stadler <lukas.stadler@oracle.com>
parents:
1429
diff
changeset
|
1952 __ movflt(Address(rsp, 0), xmm1); |
72cfb36c6bb2
* enabled all jtt tests
Lukas Stadler <lukas.stadler@oracle.com>
parents:
1429
diff
changeset
|
1953 __ fld_s(Address(rsp, 0)); |
72cfb36c6bb2
* enabled all jtt tests
Lukas Stadler <lukas.stadler@oracle.com>
parents:
1429
diff
changeset
|
1954 __ movflt(Address(rsp, 0), xmm0); |
72cfb36c6bb2
* enabled all jtt tests
Lukas Stadler <lukas.stadler@oracle.com>
parents:
1429
diff
changeset
|
1955 __ fld_s(Address(rsp, 0)); |
72cfb36c6bb2
* enabled all jtt tests
Lukas Stadler <lukas.stadler@oracle.com>
parents:
1429
diff
changeset
|
1956 Label L; |
72cfb36c6bb2
* enabled all jtt tests
Lukas Stadler <lukas.stadler@oracle.com>
parents:
1429
diff
changeset
|
1957 __ bind(L); |
72cfb36c6bb2
* enabled all jtt tests
Lukas Stadler <lukas.stadler@oracle.com>
parents:
1429
diff
changeset
|
1958 __ fprem(); |
72cfb36c6bb2
* enabled all jtt tests
Lukas Stadler <lukas.stadler@oracle.com>
parents:
1429
diff
changeset
|
1959 __ fwait(); |
72cfb36c6bb2
* enabled all jtt tests
Lukas Stadler <lukas.stadler@oracle.com>
parents:
1429
diff
changeset
|
1960 __ fnstsw_ax(); |
72cfb36c6bb2
* enabled all jtt tests
Lukas Stadler <lukas.stadler@oracle.com>
parents:
1429
diff
changeset
|
1961 __ testl(rax, 0x400); |
72cfb36c6bb2
* enabled all jtt tests
Lukas Stadler <lukas.stadler@oracle.com>
parents:
1429
diff
changeset
|
1962 __ jcc(Assembler::notZero, L); |
72cfb36c6bb2
* enabled all jtt tests
Lukas Stadler <lukas.stadler@oracle.com>
parents:
1429
diff
changeset
|
1963 __ fxch(1); |
72cfb36c6bb2
* enabled all jtt tests
Lukas Stadler <lukas.stadler@oracle.com>
parents:
1429
diff
changeset
|
1964 __ fpop(); |
72cfb36c6bb2
* enabled all jtt tests
Lukas Stadler <lukas.stadler@oracle.com>
parents:
1429
diff
changeset
|
1965 __ fstp_s(Address(rsp, 0)); |
72cfb36c6bb2
* enabled all jtt tests
Lukas Stadler <lukas.stadler@oracle.com>
parents:
1429
diff
changeset
|
1966 __ movflt(xmm0, Address(rsp, 0)); |
72cfb36c6bb2
* enabled all jtt tests
Lukas Stadler <lukas.stadler@oracle.com>
parents:
1429
diff
changeset
|
1967 __ addptr(rsp, 8); |
72cfb36c6bb2
* enabled all jtt tests
Lukas Stadler <lukas.stadler@oracle.com>
parents:
1429
diff
changeset
|
1968 __ ret(0); |
72cfb36c6bb2
* enabled all jtt tests
Lukas Stadler <lukas.stadler@oracle.com>
parents:
1429
diff
changeset
|
1969 break; |
72cfb36c6bb2
* enabled all jtt tests
Lukas Stadler <lukas.stadler@oracle.com>
parents:
1429
diff
changeset
|
1970 } |
2891
75a99b4f1c98
Rebranded C++ part from C1X to Graal.
Thomas Wuerthinger <thomas@wuerthinger.net>
parents:
2662
diff
changeset
|
1971 case graal_arithmetic_drem_id: { |
1434
72cfb36c6bb2
* enabled all jtt tests
Lukas Stadler <lukas.stadler@oracle.com>
parents:
1429
diff
changeset
|
1972 __ subptr(rsp, 8); |
72cfb36c6bb2
* enabled all jtt tests
Lukas Stadler <lukas.stadler@oracle.com>
parents:
1429
diff
changeset
|
1973 __ movdbl(Address(rsp, 0), xmm1); |
72cfb36c6bb2
* enabled all jtt tests
Lukas Stadler <lukas.stadler@oracle.com>
parents:
1429
diff
changeset
|
1974 __ fld_d(Address(rsp, 0)); |
72cfb36c6bb2
* enabled all jtt tests
Lukas Stadler <lukas.stadler@oracle.com>
parents:
1429
diff
changeset
|
1975 __ movdbl(Address(rsp, 0), xmm0); |
72cfb36c6bb2
* enabled all jtt tests
Lukas Stadler <lukas.stadler@oracle.com>
parents:
1429
diff
changeset
|
1976 __ fld_d(Address(rsp, 0)); |
72cfb36c6bb2
* enabled all jtt tests
Lukas Stadler <lukas.stadler@oracle.com>
parents:
1429
diff
changeset
|
1977 Label L; |
72cfb36c6bb2
* enabled all jtt tests
Lukas Stadler <lukas.stadler@oracle.com>
parents:
1429
diff
changeset
|
1978 __ bind(L); |
72cfb36c6bb2
* enabled all jtt tests
Lukas Stadler <lukas.stadler@oracle.com>
parents:
1429
diff
changeset
|
1979 __ fprem(); |
72cfb36c6bb2
* enabled all jtt tests
Lukas Stadler <lukas.stadler@oracle.com>
parents:
1429
diff
changeset
|
1980 __ fwait(); |
72cfb36c6bb2
* enabled all jtt tests
Lukas Stadler <lukas.stadler@oracle.com>
parents:
1429
diff
changeset
|
1981 __ fnstsw_ax(); |
72cfb36c6bb2
* enabled all jtt tests
Lukas Stadler <lukas.stadler@oracle.com>
parents:
1429
diff
changeset
|
1982 __ testl(rax, 0x400); |
72cfb36c6bb2
* enabled all jtt tests
Lukas Stadler <lukas.stadler@oracle.com>
parents:
1429
diff
changeset
|
1983 __ jcc(Assembler::notZero, L); |
72cfb36c6bb2
* enabled all jtt tests
Lukas Stadler <lukas.stadler@oracle.com>
parents:
1429
diff
changeset
|
1984 __ fxch(1); |
72cfb36c6bb2
* enabled all jtt tests
Lukas Stadler <lukas.stadler@oracle.com>
parents:
1429
diff
changeset
|
1985 __ fpop(); |
72cfb36c6bb2
* enabled all jtt tests
Lukas Stadler <lukas.stadler@oracle.com>
parents:
1429
diff
changeset
|
1986 __ fstp_d(Address(rsp, 0)); |
72cfb36c6bb2
* enabled all jtt tests
Lukas Stadler <lukas.stadler@oracle.com>
parents:
1429
diff
changeset
|
1987 __ movdbl(xmm0, Address(rsp, 0)); |
72cfb36c6bb2
* enabled all jtt tests
Lukas Stadler <lukas.stadler@oracle.com>
parents:
1429
diff
changeset
|
1988 __ addptr(rsp, 8); |
72cfb36c6bb2
* enabled all jtt tests
Lukas Stadler <lukas.stadler@oracle.com>
parents:
1429
diff
changeset
|
1989 __ ret(0); |
72cfb36c6bb2
* enabled all jtt tests
Lukas Stadler <lukas.stadler@oracle.com>
parents:
1429
diff
changeset
|
1990 break; |
72cfb36c6bb2
* enabled all jtt tests
Lukas Stadler <lukas.stadler@oracle.com>
parents:
1429
diff
changeset
|
1991 } |
2891
75a99b4f1c98
Rebranded C++ part from C1X to Graal.
Thomas Wuerthinger <thomas@wuerthinger.net>
parents:
2662
diff
changeset
|
1992 case graal_monitorenter_id: { |
1434
72cfb36c6bb2
* enabled all jtt tests
Lukas Stadler <lukas.stadler@oracle.com>
parents:
1429
diff
changeset
|
1993 Label slow_case; |
72cfb36c6bb2
* enabled all jtt tests
Lukas Stadler <lukas.stadler@oracle.com>
parents:
1429
diff
changeset
|
1994 |
72cfb36c6bb2
* enabled all jtt tests
Lukas Stadler <lukas.stadler@oracle.com>
parents:
1429
diff
changeset
|
1995 Register obj = j_rarg0; |
72cfb36c6bb2
* enabled all jtt tests
Lukas Stadler <lukas.stadler@oracle.com>
parents:
1429
diff
changeset
|
1996 Register lock = j_rarg1; |
72cfb36c6bb2
* enabled all jtt tests
Lukas Stadler <lukas.stadler@oracle.com>
parents:
1429
diff
changeset
|
1997 |
72cfb36c6bb2
* enabled all jtt tests
Lukas Stadler <lukas.stadler@oracle.com>
parents:
1429
diff
changeset
|
1998 Register scratch1 = rax; |
72cfb36c6bb2
* enabled all jtt tests
Lukas Stadler <lukas.stadler@oracle.com>
parents:
1429
diff
changeset
|
1999 Register scratch2 = rbx; |
1942
00bc9eaf0e24
Support for -XX:+UseFastLocking flag. Fixed monitor enter XIR template for correct debug info at the runtime call.
Thomas Wuerthinger <wuerthinger@ssw.jku.at>
parents:
1930
diff
changeset
|
2000 assert_different_registers(obj, lock, scratch1, scratch2); |
1434
72cfb36c6bb2
* enabled all jtt tests
Lukas Stadler <lukas.stadler@oracle.com>
parents:
1429
diff
changeset
|
2001 |
72cfb36c6bb2
* enabled all jtt tests
Lukas Stadler <lukas.stadler@oracle.com>
parents:
1429
diff
changeset
|
2002 // copied from LIR_Assembler::emit_lock |
72cfb36c6bb2
* enabled all jtt tests
Lukas Stadler <lukas.stadler@oracle.com>
parents:
1429
diff
changeset
|
2003 if (UseFastLocking) { |
72cfb36c6bb2
* enabled all jtt tests
Lukas Stadler <lukas.stadler@oracle.com>
parents:
1429
diff
changeset
|
2004 assert(BasicLock::displaced_header_offset_in_bytes() == 0, "lock_reg must point to the displaced header"); |
72cfb36c6bb2
* enabled all jtt tests
Lukas Stadler <lukas.stadler@oracle.com>
parents:
1429
diff
changeset
|
2005 __ lock_object(scratch1, obj, lock, scratch2, slow_case); |
72cfb36c6bb2
* enabled all jtt tests
Lukas Stadler <lukas.stadler@oracle.com>
parents:
1429
diff
changeset
|
2006 __ ret(0); |
1429
abc670a709dc
* -XX:TraceC1X=0...5 controls the native c1x tracing
Lukas Stadler <lukas.stadler@oracle.com>
parents:
1423
diff
changeset
|
2007 } |
abc670a709dc
* -XX:TraceC1X=0...5 controls the native c1x tracing
Lukas Stadler <lukas.stadler@oracle.com>
parents:
1423
diff
changeset
|
2008 |
1434
72cfb36c6bb2
* enabled all jtt tests
Lukas Stadler <lukas.stadler@oracle.com>
parents:
1429
diff
changeset
|
2009 __ bind(slow_case); |
1429
abc670a709dc
* -XX:TraceC1X=0...5 controls the native c1x tracing
Lukas Stadler <lukas.stadler@oracle.com>
parents:
1423
diff
changeset
|
2010 { |
2891
75a99b4f1c98
Rebranded C++ part from C1X to Graal.
Thomas Wuerthinger <thomas@wuerthinger.net>
parents:
2662
diff
changeset
|
2011 StubFrame f(sasm, "graal_monitorenter", dont_gc_arguments); |
1434
72cfb36c6bb2
* enabled all jtt tests
Lukas Stadler <lukas.stadler@oracle.com>
parents:
1429
diff
changeset
|
2012 OopMap* map = save_live_registers(sasm, 1, save_fpu_registers); |
72cfb36c6bb2
* enabled all jtt tests
Lukas Stadler <lukas.stadler@oracle.com>
parents:
1429
diff
changeset
|
2013 |
72cfb36c6bb2
* enabled all jtt tests
Lukas Stadler <lukas.stadler@oracle.com>
parents:
1429
diff
changeset
|
2014 // Called with store_parameter and not C abi |
72cfb36c6bb2
* enabled all jtt tests
Lukas Stadler <lukas.stadler@oracle.com>
parents:
1429
diff
changeset
|
2015 int call_offset = __ call_RT(noreg, noreg, CAST_FROM_FN_PTR(address, monitorenter), obj, lock); |
72cfb36c6bb2
* enabled all jtt tests
Lukas Stadler <lukas.stadler@oracle.com>
parents:
1429
diff
changeset
|
2016 |
72cfb36c6bb2
* enabled all jtt tests
Lukas Stadler <lukas.stadler@oracle.com>
parents:
1429
diff
changeset
|
2017 oop_maps = new OopMapSet(); |
72cfb36c6bb2
* enabled all jtt tests
Lukas Stadler <lukas.stadler@oracle.com>
parents:
1429
diff
changeset
|
2018 oop_maps->add_gc_map(call_offset, map); |
72cfb36c6bb2
* enabled all jtt tests
Lukas Stadler <lukas.stadler@oracle.com>
parents:
1429
diff
changeset
|
2019 restore_live_registers(sasm, save_fpu_registers); |
72cfb36c6bb2
* enabled all jtt tests
Lukas Stadler <lukas.stadler@oracle.com>
parents:
1429
diff
changeset
|
2020 } |
72cfb36c6bb2
* enabled all jtt tests
Lukas Stadler <lukas.stadler@oracle.com>
parents:
1429
diff
changeset
|
2021 __ ret(0); |
72cfb36c6bb2
* enabled all jtt tests
Lukas Stadler <lukas.stadler@oracle.com>
parents:
1429
diff
changeset
|
2022 break; |
72cfb36c6bb2
* enabled all jtt tests
Lukas Stadler <lukas.stadler@oracle.com>
parents:
1429
diff
changeset
|
2023 } |
2891
75a99b4f1c98
Rebranded C++ part from C1X to Graal.
Thomas Wuerthinger <thomas@wuerthinger.net>
parents:
2662
diff
changeset
|
2024 case graal_monitorexit_id: { |
1434
72cfb36c6bb2
* enabled all jtt tests
Lukas Stadler <lukas.stadler@oracle.com>
parents:
1429
diff
changeset
|
2025 Label slow_case; |
1429
abc670a709dc
* -XX:TraceC1X=0...5 controls the native c1x tracing
Lukas Stadler <lukas.stadler@oracle.com>
parents:
1423
diff
changeset
|
2026 |
1434
72cfb36c6bb2
* enabled all jtt tests
Lukas Stadler <lukas.stadler@oracle.com>
parents:
1429
diff
changeset
|
2027 Register obj = j_rarg0; |
72cfb36c6bb2
* enabled all jtt tests
Lukas Stadler <lukas.stadler@oracle.com>
parents:
1429
diff
changeset
|
2028 Register lock = j_rarg1; |
72cfb36c6bb2
* enabled all jtt tests
Lukas Stadler <lukas.stadler@oracle.com>
parents:
1429
diff
changeset
|
2029 |
72cfb36c6bb2
* enabled all jtt tests
Lukas Stadler <lukas.stadler@oracle.com>
parents:
1429
diff
changeset
|
2030 // needed in rax later on... |
72cfb36c6bb2
* enabled all jtt tests
Lukas Stadler <lukas.stadler@oracle.com>
parents:
1429
diff
changeset
|
2031 Register lock2 = rax; |
72cfb36c6bb2
* enabled all jtt tests
Lukas Stadler <lukas.stadler@oracle.com>
parents:
1429
diff
changeset
|
2032 __ mov(lock2, lock); |
72cfb36c6bb2
* enabled all jtt tests
Lukas Stadler <lukas.stadler@oracle.com>
parents:
1429
diff
changeset
|
2033 Register scratch1 = rbx; |
1942
00bc9eaf0e24
Support for -XX:+UseFastLocking flag. Fixed monitor enter XIR template for correct debug info at the runtime call.
Thomas Wuerthinger <wuerthinger@ssw.jku.at>
parents:
1930
diff
changeset
|
2034 assert_different_registers(obj, lock, scratch1, lock2); |
1434
72cfb36c6bb2
* enabled all jtt tests
Lukas Stadler <lukas.stadler@oracle.com>
parents:
1429
diff
changeset
|
2035 |
72cfb36c6bb2
* enabled all jtt tests
Lukas Stadler <lukas.stadler@oracle.com>
parents:
1429
diff
changeset
|
2036 // copied from LIR_Assembler::emit_lock |
72cfb36c6bb2
* enabled all jtt tests
Lukas Stadler <lukas.stadler@oracle.com>
parents:
1429
diff
changeset
|
2037 if (UseFastLocking) { |
72cfb36c6bb2
* enabled all jtt tests
Lukas Stadler <lukas.stadler@oracle.com>
parents:
1429
diff
changeset
|
2038 assert(BasicLock::displaced_header_offset_in_bytes() == 0, "lock_reg must point to the displaced header"); |
72cfb36c6bb2
* enabled all jtt tests
Lukas Stadler <lukas.stadler@oracle.com>
parents:
1429
diff
changeset
|
2039 __ unlock_object(scratch1, obj, lock2, slow_case); |
72cfb36c6bb2
* enabled all jtt tests
Lukas Stadler <lukas.stadler@oracle.com>
parents:
1429
diff
changeset
|
2040 __ ret(0); |
1429
abc670a709dc
* -XX:TraceC1X=0...5 controls the native c1x tracing
Lukas Stadler <lukas.stadler@oracle.com>
parents:
1423
diff
changeset
|
2041 } |
abc670a709dc
* -XX:TraceC1X=0...5 controls the native c1x tracing
Lukas Stadler <lukas.stadler@oracle.com>
parents:
1423
diff
changeset
|
2042 |
1434
72cfb36c6bb2
* enabled all jtt tests
Lukas Stadler <lukas.stadler@oracle.com>
parents:
1429
diff
changeset
|
2043 __ bind(slow_case); |
1429
abc670a709dc
* -XX:TraceC1X=0...5 controls the native c1x tracing
Lukas Stadler <lukas.stadler@oracle.com>
parents:
1423
diff
changeset
|
2044 { |
2891
75a99b4f1c98
Rebranded C++ part from C1X to Graal.
Thomas Wuerthinger <thomas@wuerthinger.net>
parents:
2662
diff
changeset
|
2045 StubFrame f(sasm, "graal_monitorexit", dont_gc_arguments); |
1434
72cfb36c6bb2
* enabled all jtt tests
Lukas Stadler <lukas.stadler@oracle.com>
parents:
1429
diff
changeset
|
2046 OopMap* map = save_live_registers(sasm, 2, save_fpu_registers); |
1429
abc670a709dc
* -XX:TraceC1X=0...5 controls the native c1x tracing
Lukas Stadler <lukas.stadler@oracle.com>
parents:
1423
diff
changeset
|
2047 |
1434
72cfb36c6bb2
* enabled all jtt tests
Lukas Stadler <lukas.stadler@oracle.com>
parents:
1429
diff
changeset
|
2048 // note: really a leaf routine but must setup last java sp |
72cfb36c6bb2
* enabled all jtt tests
Lukas Stadler <lukas.stadler@oracle.com>
parents:
1429
diff
changeset
|
2049 // => use call_RT for now (speed can be improved by |
72cfb36c6bb2
* enabled all jtt tests
Lukas Stadler <lukas.stadler@oracle.com>
parents:
1429
diff
changeset
|
2050 // doing last java sp setup manually) |
72cfb36c6bb2
* enabled all jtt tests
Lukas Stadler <lukas.stadler@oracle.com>
parents:
1429
diff
changeset
|
2051 int call_offset = __ call_RT(noreg, noreg, CAST_FROM_FN_PTR(address, monitorexit), lock); |
1429
abc670a709dc
* -XX:TraceC1X=0...5 controls the native c1x tracing
Lukas Stadler <lukas.stadler@oracle.com>
parents:
1423
diff
changeset
|
2052 |
1434
72cfb36c6bb2
* enabled all jtt tests
Lukas Stadler <lukas.stadler@oracle.com>
parents:
1429
diff
changeset
|
2053 oop_maps = new OopMapSet(); |
72cfb36c6bb2
* enabled all jtt tests
Lukas Stadler <lukas.stadler@oracle.com>
parents:
1429
diff
changeset
|
2054 oop_maps->add_gc_map(call_offset, map); |
72cfb36c6bb2
* enabled all jtt tests
Lukas Stadler <lukas.stadler@oracle.com>
parents:
1429
diff
changeset
|
2055 restore_live_registers(sasm, save_fpu_registers); |
72cfb36c6bb2
* enabled all jtt tests
Lukas Stadler <lukas.stadler@oracle.com>
parents:
1429
diff
changeset
|
2056 } |
72cfb36c6bb2
* enabled all jtt tests
Lukas Stadler <lukas.stadler@oracle.com>
parents:
1429
diff
changeset
|
2057 __ ret(0); |
72cfb36c6bb2
* enabled all jtt tests
Lukas Stadler <lukas.stadler@oracle.com>
parents:
1429
diff
changeset
|
2058 break; |
72cfb36c6bb2
* enabled all jtt tests
Lukas Stadler <lukas.stadler@oracle.com>
parents:
1429
diff
changeset
|
2059 } |
1429
abc670a709dc
* -XX:TraceC1X=0...5 controls the native c1x tracing
Lukas Stadler <lukas.stadler@oracle.com>
parents:
1423
diff
changeset
|
2060 |
1434
72cfb36c6bb2
* enabled all jtt tests
Lukas Stadler <lukas.stadler@oracle.com>
parents:
1429
diff
changeset
|
2061 |
72cfb36c6bb2
* enabled all jtt tests
Lukas Stadler <lukas.stadler@oracle.com>
parents:
1429
diff
changeset
|
2062 |
72cfb36c6bb2
* enabled all jtt tests
Lukas Stadler <lukas.stadler@oracle.com>
parents:
1429
diff
changeset
|
2063 |
0 | 2064 default: |
2065 { StubFrame f(sasm, "unimplemented entry", dont_gc_arguments); | |
304 | 2066 __ movptr(rax, (int)id); |
0 | 2067 __ call_RT(noreg, noreg, CAST_FROM_FN_PTR(address, unimplemented_entry), rax); |
2068 __ should_not_reach_here(); | |
2069 } | |
2070 break; | |
2071 } | |
2072 return oop_maps; | |
2073 } | |
2074 | |
2075 #undef __ | |
1681
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1579
diff
changeset
|
2076 |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1579
diff
changeset
|
2077 const char *Runtime1::pd_name_for_address(address entry) { |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1579
diff
changeset
|
2078 return "<unknown function>"; |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1579
diff
changeset
|
2079 } |