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