Mercurial > hg > truffle
annotate src/cpu/x86/vm/sharedRuntime_x86_64.cpp @ 2013:ec8c74742417
7005241: C1: SEGV in java.util.concurrent.LinkedTransferQueue.xfer() with compressed oops
Summary: Implementation of the CAS primitive for x64 compressed oops was incorrect. It kills rscratch2 register (r11), which is allocatable in C1. Also, we don't need to restore cmpval as it's never used after that, so we need only one temporary register, which can be scratch1.
Reviewed-by: kvn, never
author | iveresov |
---|---|
date | Wed, 08 Dec 2010 02:36:36 -0800 |
parents | f95d63e2154a |
children | 9508a52cbd32 3582bf76420e |
rev | line source |
---|---|
0 | 1 /* |
1552
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1506
diff
changeset
|
2 * Copyright (c) 2003, 2010, 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:
1506
diff
changeset
|
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1506
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:
1506
diff
changeset
|
21 * questions. |
0 | 22 * |
23 */ | |
24 | |
1972 | 25 #include "precompiled.hpp" |
26 #include "asm/assembler.hpp" | |
27 #include "assembler_x86.inline.hpp" | |
28 #include "code/debugInfoRec.hpp" | |
29 #include "code/icBuffer.hpp" | |
30 #include "code/vtableStubs.hpp" | |
31 #include "interpreter/interpreter.hpp" | |
32 #include "oops/compiledICHolderOop.hpp" | |
33 #include "prims/jvmtiRedefineClassesTrace.hpp" | |
34 #include "runtime/sharedRuntime.hpp" | |
35 #include "runtime/vframeArray.hpp" | |
36 #include "vmreg_x86.inline.hpp" | |
37 #ifdef COMPILER1 | |
38 #include "c1/c1_Runtime1.hpp" | |
39 #endif | |
40 #ifdef COMPILER2 | |
41 #include "opto/runtime.hpp" | |
42 #endif | |
0 | 43 |
44 DeoptimizationBlob *SharedRuntime::_deopt_blob; | |
45 #ifdef COMPILER2 | |
46 UncommonTrapBlob *SharedRuntime::_uncommon_trap_blob; | |
47 ExceptionBlob *OptoRuntime::_exception_blob; | |
48 #endif // COMPILER2 | |
49 | |
50 SafepointBlob *SharedRuntime::_polling_page_safepoint_handler_blob; | |
51 SafepointBlob *SharedRuntime::_polling_page_return_handler_blob; | |
52 RuntimeStub* SharedRuntime::_wrong_method_blob; | |
53 RuntimeStub* SharedRuntime::_ic_miss_blob; | |
54 RuntimeStub* SharedRuntime::_resolve_opt_virtual_call_blob; | |
55 RuntimeStub* SharedRuntime::_resolve_virtual_call_blob; | |
56 RuntimeStub* SharedRuntime::_resolve_static_call_blob; | |
57 | |
524
c9004fe53695
6792301: StackAlignmentInBytes not honored for compiled native methods
xlu
parents:
520
diff
changeset
|
58 const int StackAlignmentInSlots = StackAlignmentInBytes / VMRegImpl::stack_slot_size; |
c9004fe53695
6792301: StackAlignmentInBytes not honored for compiled native methods
xlu
parents:
520
diff
changeset
|
59 |
0 | 60 #define __ masm-> |
61 | |
62 class SimpleRuntimeFrame { | |
63 | |
64 public: | |
65 | |
66 // Most of the runtime stubs have this simple frame layout. | |
67 // This class exists to make the layout shared in one place. | |
68 // Offsets are for compiler stack slots, which are jints. | |
69 enum layout { | |
70 // The frame sender code expects that rbp will be in the "natural" place and | |
71 // will override any oopMap setting for it. We must therefore force the layout | |
72 // so that it agrees with the frame sender code. | |
73 rbp_off = frame::arg_reg_save_area_bytes/BytesPerInt, | |
74 rbp_off2, | |
75 return_off, return_off2, | |
76 framesize | |
77 }; | |
78 }; | |
79 | |
80 class RegisterSaver { | |
81 // Capture info about frame layout. Layout offsets are in jint | |
82 // units because compiler frame slots are jints. | |
83 #define DEF_XMM_OFFS(regnum) xmm ## regnum ## _off = xmm_off + (regnum)*16/BytesPerInt, xmm ## regnum ## H_off | |
84 enum layout { | |
85 fpu_state_off = frame::arg_reg_save_area_bytes/BytesPerInt, // fxsave save area | |
86 xmm_off = fpu_state_off + 160/BytesPerInt, // offset in fxsave save area | |
87 DEF_XMM_OFFS(0), | |
88 DEF_XMM_OFFS(1), | |
89 DEF_XMM_OFFS(2), | |
90 DEF_XMM_OFFS(3), | |
91 DEF_XMM_OFFS(4), | |
92 DEF_XMM_OFFS(5), | |
93 DEF_XMM_OFFS(6), | |
94 DEF_XMM_OFFS(7), | |
95 DEF_XMM_OFFS(8), | |
96 DEF_XMM_OFFS(9), | |
97 DEF_XMM_OFFS(10), | |
98 DEF_XMM_OFFS(11), | |
99 DEF_XMM_OFFS(12), | |
100 DEF_XMM_OFFS(13), | |
101 DEF_XMM_OFFS(14), | |
102 DEF_XMM_OFFS(15), | |
103 fpu_state_end = fpu_state_off + ((FPUStateSizeInWords-1)*wordSize / BytesPerInt), | |
104 fpu_stateH_end, | |
105 r15_off, r15H_off, | |
106 r14_off, r14H_off, | |
107 r13_off, r13H_off, | |
108 r12_off, r12H_off, | |
109 r11_off, r11H_off, | |
110 r10_off, r10H_off, | |
111 r9_off, r9H_off, | |
112 r8_off, r8H_off, | |
113 rdi_off, rdiH_off, | |
114 rsi_off, rsiH_off, | |
115 ignore_off, ignoreH_off, // extra copy of rbp | |
116 rsp_off, rspH_off, | |
117 rbx_off, rbxH_off, | |
118 rdx_off, rdxH_off, | |
119 rcx_off, rcxH_off, | |
120 rax_off, raxH_off, | |
121 // 16-byte stack alignment fill word: see MacroAssembler::push/pop_IU_state | |
122 align_off, alignH_off, | |
123 flags_off, flagsH_off, | |
124 // The frame sender code expects that rbp will be in the "natural" place and | |
125 // will override any oopMap setting for it. We must therefore force the layout | |
126 // so that it agrees with the frame sender code. | |
127 rbp_off, rbpH_off, // copy of rbp we will restore | |
128 return_off, returnH_off, // slot for return address | |
129 reg_save_size // size in compiler stack slots | |
130 }; | |
131 | |
132 public: | |
133 static OopMap* save_live_registers(MacroAssembler* masm, int additional_frame_words, int* total_frame_words); | |
134 static void restore_live_registers(MacroAssembler* masm); | |
135 | |
136 // Offsets into the register save area | |
137 // Used by deoptimization when it is managing result register | |
138 // values on its own | |
139 | |
140 static int rax_offset_in_bytes(void) { return BytesPerInt * rax_off; } | |
304 | 141 static int rdx_offset_in_bytes(void) { return BytesPerInt * rdx_off; } |
0 | 142 static int rbx_offset_in_bytes(void) { return BytesPerInt * rbx_off; } |
143 static int xmm0_offset_in_bytes(void) { return BytesPerInt * xmm0_off; } | |
144 static int return_offset_in_bytes(void) { return BytesPerInt * return_off; } | |
145 | |
146 // During deoptimization only the result registers need to be restored, | |
147 // all the other values have already been extracted. | |
148 static void restore_result_registers(MacroAssembler* masm); | |
149 }; | |
150 | |
151 OopMap* RegisterSaver::save_live_registers(MacroAssembler* masm, int additional_frame_words, int* total_frame_words) { | |
152 | |
153 // Always make the frame size 16-byte aligned | |
154 int frame_size_in_bytes = round_to(additional_frame_words*wordSize + | |
155 reg_save_size*BytesPerInt, 16); | |
156 // OopMap frame size is in compiler stack slots (jint's) not bytes or words | |
157 int frame_size_in_slots = frame_size_in_bytes / BytesPerInt; | |
158 // The caller will allocate additional_frame_words | |
159 int additional_frame_slots = additional_frame_words*wordSize / BytesPerInt; | |
160 // CodeBlob frame size is in words. | |
161 int frame_size_in_words = frame_size_in_bytes / wordSize; | |
162 *total_frame_words = frame_size_in_words; | |
163 | |
164 // Save registers, fpu state, and flags. | |
165 // We assume caller has already pushed the return address onto the | |
166 // stack, so rsp is 8-byte aligned here. | |
167 // We push rpb twice in this sequence because we want the real rbp | |
168 // to be under the return like a normal enter. | |
169 | |
170 __ enter(); // rsp becomes 16-byte aligned here | |
171 __ push_CPU_state(); // Push a multiple of 16 bytes | |
172 if (frame::arg_reg_save_area_bytes != 0) { | |
173 // Allocate argument register save area | |
304 | 174 __ subptr(rsp, frame::arg_reg_save_area_bytes); |
0 | 175 } |
176 | |
177 // Set an oopmap for the call site. This oopmap will map all | |
178 // oop-registers and debug-info registers as callee-saved. This | |
179 // will allow deoptimization at this safepoint to find all possible | |
180 // debug-info recordings, as well as let GC find all oops. | |
181 | |
182 OopMapSet *oop_maps = new OopMapSet(); | |
183 OopMap* map = new OopMap(frame_size_in_slots, 0); | |
184 map->set_callee_saved(VMRegImpl::stack2reg( rax_off + additional_frame_slots), rax->as_VMReg()); | |
185 map->set_callee_saved(VMRegImpl::stack2reg( rcx_off + additional_frame_slots), rcx->as_VMReg()); | |
186 map->set_callee_saved(VMRegImpl::stack2reg( rdx_off + additional_frame_slots), rdx->as_VMReg()); | |
187 map->set_callee_saved(VMRegImpl::stack2reg( rbx_off + additional_frame_slots), rbx->as_VMReg()); | |
188 // rbp location is known implicitly by the frame sender code, needs no oopmap | |
189 // and the location where rbp was saved by is ignored | |
190 map->set_callee_saved(VMRegImpl::stack2reg( rsi_off + additional_frame_slots), rsi->as_VMReg()); | |
191 map->set_callee_saved(VMRegImpl::stack2reg( rdi_off + additional_frame_slots), rdi->as_VMReg()); | |
192 map->set_callee_saved(VMRegImpl::stack2reg( r8_off + additional_frame_slots), r8->as_VMReg()); | |
193 map->set_callee_saved(VMRegImpl::stack2reg( r9_off + additional_frame_slots), r9->as_VMReg()); | |
194 map->set_callee_saved(VMRegImpl::stack2reg( r10_off + additional_frame_slots), r10->as_VMReg()); | |
195 map->set_callee_saved(VMRegImpl::stack2reg( r11_off + additional_frame_slots), r11->as_VMReg()); | |
196 map->set_callee_saved(VMRegImpl::stack2reg( r12_off + additional_frame_slots), r12->as_VMReg()); | |
197 map->set_callee_saved(VMRegImpl::stack2reg( r13_off + additional_frame_slots), r13->as_VMReg()); | |
198 map->set_callee_saved(VMRegImpl::stack2reg( r14_off + additional_frame_slots), r14->as_VMReg()); | |
199 map->set_callee_saved(VMRegImpl::stack2reg( r15_off + additional_frame_slots), r15->as_VMReg()); | |
200 map->set_callee_saved(VMRegImpl::stack2reg(xmm0_off + additional_frame_slots), xmm0->as_VMReg()); | |
201 map->set_callee_saved(VMRegImpl::stack2reg(xmm1_off + additional_frame_slots), xmm1->as_VMReg()); | |
202 map->set_callee_saved(VMRegImpl::stack2reg(xmm2_off + additional_frame_slots), xmm2->as_VMReg()); | |
203 map->set_callee_saved(VMRegImpl::stack2reg(xmm3_off + additional_frame_slots), xmm3->as_VMReg()); | |
204 map->set_callee_saved(VMRegImpl::stack2reg(xmm4_off + additional_frame_slots), xmm4->as_VMReg()); | |
205 map->set_callee_saved(VMRegImpl::stack2reg(xmm5_off + additional_frame_slots), xmm5->as_VMReg()); | |
206 map->set_callee_saved(VMRegImpl::stack2reg(xmm6_off + additional_frame_slots), xmm6->as_VMReg()); | |
207 map->set_callee_saved(VMRegImpl::stack2reg(xmm7_off + additional_frame_slots), xmm7->as_VMReg()); | |
208 map->set_callee_saved(VMRegImpl::stack2reg(xmm8_off + additional_frame_slots), xmm8->as_VMReg()); | |
209 map->set_callee_saved(VMRegImpl::stack2reg(xmm9_off + additional_frame_slots), xmm9->as_VMReg()); | |
210 map->set_callee_saved(VMRegImpl::stack2reg(xmm10_off + additional_frame_slots), xmm10->as_VMReg()); | |
211 map->set_callee_saved(VMRegImpl::stack2reg(xmm11_off + additional_frame_slots), xmm11->as_VMReg()); | |
212 map->set_callee_saved(VMRegImpl::stack2reg(xmm12_off + additional_frame_slots), xmm12->as_VMReg()); | |
213 map->set_callee_saved(VMRegImpl::stack2reg(xmm13_off + additional_frame_slots), xmm13->as_VMReg()); | |
214 map->set_callee_saved(VMRegImpl::stack2reg(xmm14_off + additional_frame_slots), xmm14->as_VMReg()); | |
215 map->set_callee_saved(VMRegImpl::stack2reg(xmm15_off + additional_frame_slots), xmm15->as_VMReg()); | |
216 | |
217 // %%% These should all be a waste but we'll keep things as they were for now | |
218 if (true) { | |
219 map->set_callee_saved(VMRegImpl::stack2reg( raxH_off + additional_frame_slots), | |
220 rax->as_VMReg()->next()); | |
221 map->set_callee_saved(VMRegImpl::stack2reg( rcxH_off + additional_frame_slots), | |
222 rcx->as_VMReg()->next()); | |
223 map->set_callee_saved(VMRegImpl::stack2reg( rdxH_off + additional_frame_slots), | |
224 rdx->as_VMReg()->next()); | |
225 map->set_callee_saved(VMRegImpl::stack2reg( rbxH_off + additional_frame_slots), | |
226 rbx->as_VMReg()->next()); | |
227 // rbp location is known implicitly by the frame sender code, needs no oopmap | |
228 map->set_callee_saved(VMRegImpl::stack2reg( rsiH_off + additional_frame_slots), | |
229 rsi->as_VMReg()->next()); | |
230 map->set_callee_saved(VMRegImpl::stack2reg( rdiH_off + additional_frame_slots), | |
231 rdi->as_VMReg()->next()); | |
232 map->set_callee_saved(VMRegImpl::stack2reg( r8H_off + additional_frame_slots), | |
233 r8->as_VMReg()->next()); | |
234 map->set_callee_saved(VMRegImpl::stack2reg( r9H_off + additional_frame_slots), | |
235 r9->as_VMReg()->next()); | |
236 map->set_callee_saved(VMRegImpl::stack2reg( r10H_off + additional_frame_slots), | |
237 r10->as_VMReg()->next()); | |
238 map->set_callee_saved(VMRegImpl::stack2reg( r11H_off + additional_frame_slots), | |
239 r11->as_VMReg()->next()); | |
240 map->set_callee_saved(VMRegImpl::stack2reg( r12H_off + additional_frame_slots), | |
241 r12->as_VMReg()->next()); | |
242 map->set_callee_saved(VMRegImpl::stack2reg( r13H_off + additional_frame_slots), | |
243 r13->as_VMReg()->next()); | |
244 map->set_callee_saved(VMRegImpl::stack2reg( r14H_off + additional_frame_slots), | |
245 r14->as_VMReg()->next()); | |
246 map->set_callee_saved(VMRegImpl::stack2reg( r15H_off + additional_frame_slots), | |
247 r15->as_VMReg()->next()); | |
248 map->set_callee_saved(VMRegImpl::stack2reg(xmm0H_off + additional_frame_slots), | |
249 xmm0->as_VMReg()->next()); | |
250 map->set_callee_saved(VMRegImpl::stack2reg(xmm1H_off + additional_frame_slots), | |
251 xmm1->as_VMReg()->next()); | |
252 map->set_callee_saved(VMRegImpl::stack2reg(xmm2H_off + additional_frame_slots), | |
253 xmm2->as_VMReg()->next()); | |
254 map->set_callee_saved(VMRegImpl::stack2reg(xmm3H_off + additional_frame_slots), | |
255 xmm3->as_VMReg()->next()); | |
256 map->set_callee_saved(VMRegImpl::stack2reg(xmm4H_off + additional_frame_slots), | |
257 xmm4->as_VMReg()->next()); | |
258 map->set_callee_saved(VMRegImpl::stack2reg(xmm5H_off + additional_frame_slots), | |
259 xmm5->as_VMReg()->next()); | |
260 map->set_callee_saved(VMRegImpl::stack2reg(xmm6H_off + additional_frame_slots), | |
261 xmm6->as_VMReg()->next()); | |
262 map->set_callee_saved(VMRegImpl::stack2reg(xmm7H_off + additional_frame_slots), | |
263 xmm7->as_VMReg()->next()); | |
264 map->set_callee_saved(VMRegImpl::stack2reg(xmm8H_off + additional_frame_slots), | |
265 xmm8->as_VMReg()->next()); | |
266 map->set_callee_saved(VMRegImpl::stack2reg(xmm9H_off + additional_frame_slots), | |
267 xmm9->as_VMReg()->next()); | |
268 map->set_callee_saved(VMRegImpl::stack2reg(xmm10H_off + additional_frame_slots), | |
269 xmm10->as_VMReg()->next()); | |
270 map->set_callee_saved(VMRegImpl::stack2reg(xmm11H_off + additional_frame_slots), | |
271 xmm11->as_VMReg()->next()); | |
272 map->set_callee_saved(VMRegImpl::stack2reg(xmm12H_off + additional_frame_slots), | |
273 xmm12->as_VMReg()->next()); | |
274 map->set_callee_saved(VMRegImpl::stack2reg(xmm13H_off + additional_frame_slots), | |
275 xmm13->as_VMReg()->next()); | |
276 map->set_callee_saved(VMRegImpl::stack2reg(xmm14H_off + additional_frame_slots), | |
277 xmm14->as_VMReg()->next()); | |
278 map->set_callee_saved(VMRegImpl::stack2reg(xmm15H_off + additional_frame_slots), | |
279 xmm15->as_VMReg()->next()); | |
280 } | |
281 | |
282 return map; | |
283 } | |
284 | |
285 void RegisterSaver::restore_live_registers(MacroAssembler* masm) { | |
286 if (frame::arg_reg_save_area_bytes != 0) { | |
287 // Pop arg register save area | |
304 | 288 __ addptr(rsp, frame::arg_reg_save_area_bytes); |
0 | 289 } |
290 // Recover CPU state | |
291 __ pop_CPU_state(); | |
292 // Get the rbp described implicitly by the calling convention (no oopMap) | |
304 | 293 __ pop(rbp); |
0 | 294 } |
295 | |
296 void RegisterSaver::restore_result_registers(MacroAssembler* masm) { | |
297 | |
298 // Just restore result register. Only used by deoptimization. By | |
299 // now any callee save register that needs to be restored to a c2 | |
300 // caller of the deoptee has been extracted into the vframeArray | |
301 // and will be stuffed into the c2i adapter we create for later | |
302 // restoration so only result registers need to be restored here. | |
303 | |
304 // Restore fp result register | |
305 __ movdbl(xmm0, Address(rsp, xmm0_offset_in_bytes())); | |
306 // Restore integer result register | |
304 | 307 __ movptr(rax, Address(rsp, rax_offset_in_bytes())); |
308 __ movptr(rdx, Address(rsp, rdx_offset_in_bytes())); | |
309 | |
0 | 310 // Pop all of the register save are off the stack except the return address |
304 | 311 __ addptr(rsp, return_offset_in_bytes()); |
0 | 312 } |
313 | |
314 // The java_calling_convention describes stack locations as ideal slots on | |
315 // a frame with no abi restrictions. Since we must observe abi restrictions | |
316 // (like the placement of the register window) the slots must be biased by | |
317 // the following value. | |
318 static int reg2offset_in(VMReg r) { | |
319 // Account for saved rbp and return address | |
320 // This should really be in_preserve_stack_slots | |
321 return (r->reg2stack() + 4) * VMRegImpl::stack_slot_size; | |
322 } | |
323 | |
324 static int reg2offset_out(VMReg r) { | |
325 return (r->reg2stack() + SharedRuntime::out_preserve_stack_slots()) * VMRegImpl::stack_slot_size; | |
326 } | |
327 | |
328 // --------------------------------------------------------------------------- | |
329 // Read the array of BasicTypes from a signature, and compute where the | |
330 // arguments should go. Values in the VMRegPair regs array refer to 4-byte | |
331 // quantities. Values less than VMRegImpl::stack0 are registers, those above | |
332 // refer to 4-byte stack slots. All stack slots are based off of the stack pointer | |
333 // as framesizes are fixed. | |
334 // VMRegImpl::stack0 refers to the first slot 0(sp). | |
335 // and VMRegImpl::stack0+1 refers to the memory word 4-byes higher. Register | |
336 // up to RegisterImpl::number_of_registers) are the 64-bit | |
337 // integer registers. | |
338 | |
339 // Note: the INPUTS in sig_bt are in units of Java argument words, which are | |
340 // either 32-bit or 64-bit depending on the build. The OUTPUTS are in 32-bit | |
341 // units regardless of build. Of course for i486 there is no 64 bit build | |
342 | |
343 // The Java calling convention is a "shifted" version of the C ABI. | |
344 // By skipping the first C ABI register we can call non-static jni methods | |
345 // with small numbers of arguments without having to shuffle the arguments | |
346 // at all. Since we control the java ABI we ought to at least get some | |
347 // advantage out of it. | |
348 | |
349 int SharedRuntime::java_calling_convention(const BasicType *sig_bt, | |
350 VMRegPair *regs, | |
351 int total_args_passed, | |
352 int is_outgoing) { | |
353 | |
354 // Create the mapping between argument positions and | |
355 // registers. | |
356 static const Register INT_ArgReg[Argument::n_int_register_parameters_j] = { | |
357 j_rarg0, j_rarg1, j_rarg2, j_rarg3, j_rarg4, j_rarg5 | |
358 }; | |
359 static const XMMRegister FP_ArgReg[Argument::n_float_register_parameters_j] = { | |
360 j_farg0, j_farg1, j_farg2, j_farg3, | |
361 j_farg4, j_farg5, j_farg6, j_farg7 | |
362 }; | |
363 | |
364 | |
365 uint int_args = 0; | |
366 uint fp_args = 0; | |
367 uint stk_args = 0; // inc by 2 each time | |
368 | |
369 for (int i = 0; i < total_args_passed; i++) { | |
370 switch (sig_bt[i]) { | |
371 case T_BOOLEAN: | |
372 case T_CHAR: | |
373 case T_BYTE: | |
374 case T_SHORT: | |
375 case T_INT: | |
376 if (int_args < Argument::n_int_register_parameters_j) { | |
377 regs[i].set1(INT_ArgReg[int_args++]->as_VMReg()); | |
378 } else { | |
379 regs[i].set1(VMRegImpl::stack2reg(stk_args)); | |
380 stk_args += 2; | |
381 } | |
382 break; | |
383 case T_VOID: | |
384 // halves of T_LONG or T_DOUBLE | |
385 assert(i != 0 && (sig_bt[i - 1] == T_LONG || sig_bt[i - 1] == T_DOUBLE), "expecting half"); | |
386 regs[i].set_bad(); | |
387 break; | |
388 case T_LONG: | |
389 assert(sig_bt[i + 1] == T_VOID, "expecting half"); | |
390 // fall through | |
391 case T_OBJECT: | |
392 case T_ARRAY: | |
393 case T_ADDRESS: | |
394 if (int_args < Argument::n_int_register_parameters_j) { | |
395 regs[i].set2(INT_ArgReg[int_args++]->as_VMReg()); | |
396 } else { | |
397 regs[i].set2(VMRegImpl::stack2reg(stk_args)); | |
398 stk_args += 2; | |
399 } | |
400 break; | |
401 case T_FLOAT: | |
402 if (fp_args < Argument::n_float_register_parameters_j) { | |
403 regs[i].set1(FP_ArgReg[fp_args++]->as_VMReg()); | |
404 } else { | |
405 regs[i].set1(VMRegImpl::stack2reg(stk_args)); | |
406 stk_args += 2; | |
407 } | |
408 break; | |
409 case T_DOUBLE: | |
410 assert(sig_bt[i + 1] == T_VOID, "expecting half"); | |
411 if (fp_args < Argument::n_float_register_parameters_j) { | |
412 regs[i].set2(FP_ArgReg[fp_args++]->as_VMReg()); | |
413 } else { | |
414 regs[i].set2(VMRegImpl::stack2reg(stk_args)); | |
415 stk_args += 2; | |
416 } | |
417 break; | |
418 default: | |
419 ShouldNotReachHere(); | |
420 break; | |
421 } | |
422 } | |
423 | |
424 return round_to(stk_args, 2); | |
425 } | |
426 | |
427 // Patch the callers callsite with entry to compiled code if it exists. | |
428 static void patch_callers_callsite(MacroAssembler *masm) { | |
429 Label L; | |
430 __ verify_oop(rbx); | |
304 | 431 __ cmpptr(Address(rbx, in_bytes(methodOopDesc::code_offset())), (int32_t)NULL_WORD); |
0 | 432 __ jcc(Assembler::equal, L); |
433 | |
434 // Save the current stack pointer | |
304 | 435 __ mov(r13, rsp); |
0 | 436 // Schedule the branch target address early. |
437 // Call into the VM to patch the caller, then jump to compiled callee | |
438 // rax isn't live so capture return address while we easily can | |
304 | 439 __ movptr(rax, Address(rsp, 0)); |
0 | 440 |
441 // align stack so push_CPU_state doesn't fault | |
304 | 442 __ andptr(rsp, -(StackAlignmentInBytes)); |
0 | 443 __ push_CPU_state(); |
444 | |
445 | |
446 __ verify_oop(rbx); | |
447 // VM needs caller's callsite | |
448 // VM needs target method | |
449 // This needs to be a long call since we will relocate this adapter to | |
450 // the codeBuffer and it may not reach | |
451 | |
452 // Allocate argument register save area | |
453 if (frame::arg_reg_save_area_bytes != 0) { | |
304 | 454 __ subptr(rsp, frame::arg_reg_save_area_bytes); |
0 | 455 } |
304 | 456 __ mov(c_rarg0, rbx); |
457 __ mov(c_rarg1, rax); | |
0 | 458 __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, SharedRuntime::fixup_callers_callsite))); |
459 | |
460 // De-allocate argument register save area | |
461 if (frame::arg_reg_save_area_bytes != 0) { | |
304 | 462 __ addptr(rsp, frame::arg_reg_save_area_bytes); |
0 | 463 } |
464 | |
465 __ pop_CPU_state(); | |
466 // restore sp | |
304 | 467 __ mov(rsp, r13); |
0 | 468 __ bind(L); |
469 } | |
470 | |
471 | |
472 static void gen_c2i_adapter(MacroAssembler *masm, | |
473 int total_args_passed, | |
474 int comp_args_on_stack, | |
475 const BasicType *sig_bt, | |
476 const VMRegPair *regs, | |
477 Label& skip_fixup) { | |
478 // Before we get into the guts of the C2I adapter, see if we should be here | |
479 // at all. We've come from compiled code and are attempting to jump to the | |
480 // interpreter, which means the caller made a static call to get here | |
481 // (vcalls always get a compiled target if there is one). Check for a | |
482 // compiled target. If there is one, we need to patch the caller's call. | |
483 patch_callers_callsite(masm); | |
484 | |
485 __ bind(skip_fixup); | |
486 | |
487 // Since all args are passed on the stack, total_args_passed * | |
488 // Interpreter::stackElementSize is the space we need. Plus 1 because | |
489 // we also account for the return address location since | |
490 // we store it first rather than hold it in rax across all the shuffling | |
491 | |
1506 | 492 int extraspace = (total_args_passed * Interpreter::stackElementSize) + wordSize; |
0 | 493 |
494 // stack is aligned, keep it that way | |
495 extraspace = round_to(extraspace, 2*wordSize); | |
496 | |
497 // Get return address | |
304 | 498 __ pop(rax); |
0 | 499 |
500 // set senderSP value | |
304 | 501 __ mov(r13, rsp); |
502 | |
503 __ subptr(rsp, extraspace); | |
0 | 504 |
505 // Store the return address in the expected location | |
304 | 506 __ movptr(Address(rsp, 0), rax); |
0 | 507 |
508 // Now write the args into the outgoing interpreter space | |
509 for (int i = 0; i < total_args_passed; i++) { | |
510 if (sig_bt[i] == T_VOID) { | |
511 assert(i > 0 && (sig_bt[i-1] == T_LONG || sig_bt[i-1] == T_DOUBLE), "missing half"); | |
512 continue; | |
513 } | |
514 | |
515 // offset to start parameters | |
1506 | 516 int st_off = (total_args_passed - i) * Interpreter::stackElementSize; |
517 int next_off = st_off - Interpreter::stackElementSize; | |
0 | 518 |
519 // Say 4 args: | |
520 // i st_off | |
521 // 0 32 T_LONG | |
522 // 1 24 T_VOID | |
523 // 2 16 T_OBJECT | |
524 // 3 8 T_BOOL | |
525 // - 0 return address | |
526 // | |
527 // However to make thing extra confusing. Because we can fit a long/double in | |
528 // a single slot on a 64 bt vm and it would be silly to break them up, the interpreter | |
529 // leaves one slot empty and only stores to a single slot. In this case the | |
530 // slot that is occupied is the T_VOID slot. See I said it was confusing. | |
531 | |
532 VMReg r_1 = regs[i].first(); | |
533 VMReg r_2 = regs[i].second(); | |
534 if (!r_1->is_valid()) { | |
535 assert(!r_2->is_valid(), ""); | |
536 continue; | |
537 } | |
538 if (r_1->is_stack()) { | |
539 // memory to memory use rax | |
540 int ld_off = r_1->reg2stack() * VMRegImpl::stack_slot_size + extraspace; | |
541 if (!r_2->is_valid()) { | |
542 // sign extend?? | |
543 __ movl(rax, Address(rsp, ld_off)); | |
304 | 544 __ movptr(Address(rsp, st_off), rax); |
0 | 545 |
546 } else { | |
547 | |
548 __ movq(rax, Address(rsp, ld_off)); | |
549 | |
550 // Two VMREgs|OptoRegs can be T_OBJECT, T_ADDRESS, T_DOUBLE, T_LONG | |
551 // T_DOUBLE and T_LONG use two slots in the interpreter | |
552 if ( sig_bt[i] == T_LONG || sig_bt[i] == T_DOUBLE) { | |
553 // ld_off == LSW, ld_off+wordSize == MSW | |
554 // st_off == MSW, next_off == LSW | |
555 __ movq(Address(rsp, next_off), rax); | |
556 #ifdef ASSERT | |
557 // Overwrite the unused slot with known junk | |
558 __ mov64(rax, CONST64(0xdeadffffdeadaaaa)); | |
304 | 559 __ movptr(Address(rsp, st_off), rax); |
0 | 560 #endif /* ASSERT */ |
561 } else { | |
562 __ movq(Address(rsp, st_off), rax); | |
563 } | |
564 } | |
565 } else if (r_1->is_Register()) { | |
566 Register r = r_1->as_Register(); | |
567 if (!r_2->is_valid()) { | |
568 // must be only an int (or less ) so move only 32bits to slot | |
569 // why not sign extend?? | |
570 __ movl(Address(rsp, st_off), r); | |
571 } else { | |
572 // Two VMREgs|OptoRegs can be T_OBJECT, T_ADDRESS, T_DOUBLE, T_LONG | |
573 // T_DOUBLE and T_LONG use two slots in the interpreter | |
574 if ( sig_bt[i] == T_LONG || sig_bt[i] == T_DOUBLE) { | |
575 // long/double in gpr | |
576 #ifdef ASSERT | |
577 // Overwrite the unused slot with known junk | |
578 __ mov64(rax, CONST64(0xdeadffffdeadaaab)); | |
304 | 579 __ movptr(Address(rsp, st_off), rax); |
0 | 580 #endif /* ASSERT */ |
581 __ movq(Address(rsp, next_off), r); | |
582 } else { | |
304 | 583 __ movptr(Address(rsp, st_off), r); |
0 | 584 } |
585 } | |
586 } else { | |
587 assert(r_1->is_XMMRegister(), ""); | |
588 if (!r_2->is_valid()) { | |
589 // only a float use just part of the slot | |
590 __ movflt(Address(rsp, st_off), r_1->as_XMMRegister()); | |
591 } else { | |
592 #ifdef ASSERT | |
593 // Overwrite the unused slot with known junk | |
594 __ mov64(rax, CONST64(0xdeadffffdeadaaac)); | |
304 | 595 __ movptr(Address(rsp, st_off), rax); |
0 | 596 #endif /* ASSERT */ |
597 __ movdbl(Address(rsp, next_off), r_1->as_XMMRegister()); | |
598 } | |
599 } | |
600 } | |
601 | |
602 // Schedule the branch target address early. | |
304 | 603 __ movptr(rcx, Address(rbx, in_bytes(methodOopDesc::interpreter_entry_offset()))); |
0 | 604 __ jmp(rcx); |
605 } | |
606 | |
607 static void gen_i2c_adapter(MacroAssembler *masm, | |
608 int total_args_passed, | |
609 int comp_args_on_stack, | |
610 const BasicType *sig_bt, | |
611 const VMRegPair *regs) { | |
612 | |
613 // | |
614 // We will only enter here from an interpreted frame and never from after | |
615 // passing thru a c2i. Azul allowed this but we do not. If we lose the | |
616 // race and use a c2i we will remain interpreted for the race loser(s). | |
617 // This removes all sorts of headaches on the x86 side and also eliminates | |
618 // the possibility of having c2i -> i2c -> c2i -> ... endless transitions. | |
619 | |
620 | |
621 // Note: r13 contains the senderSP on entry. We must preserve it since | |
622 // we may do a i2c -> c2i transition if we lose a race where compiled | |
623 // code goes non-entrant while we get args ready. | |
624 // In addition we use r13 to locate all the interpreter args as | |
625 // we must align the stack to 16 bytes on an i2c entry else we | |
626 // lose alignment we expect in all compiled code and register | |
627 // save code can segv when fxsave instructions find improperly | |
628 // aligned stack pointer. | |
629 | |
304 | 630 __ movptr(rax, Address(rsp, 0)); |
0 | 631 |
1135
e66fd840cb6b
6893081: method handle & invokedynamic code needs additional cleanup (post 6815692, 6858164)
twisti
parents:
848
diff
changeset
|
632 // Must preserve original SP for loading incoming arguments because |
e66fd840cb6b
6893081: method handle & invokedynamic code needs additional cleanup (post 6815692, 6858164)
twisti
parents:
848
diff
changeset
|
633 // we need to align the outgoing SP for compiled code. |
e66fd840cb6b
6893081: method handle & invokedynamic code needs additional cleanup (post 6815692, 6858164)
twisti
parents:
848
diff
changeset
|
634 __ movptr(r11, rsp); |
e66fd840cb6b
6893081: method handle & invokedynamic code needs additional cleanup (post 6815692, 6858164)
twisti
parents:
848
diff
changeset
|
635 |
0 | 636 // Cut-out for having no stack args. Since up to 2 int/oop args are passed |
637 // in registers, we will occasionally have no stack args. | |
638 int comp_words_on_stack = 0; | |
639 if (comp_args_on_stack) { | |
640 // Sig words on the stack are greater-than VMRegImpl::stack0. Those in | |
641 // registers are below. By subtracting stack0, we either get a negative | |
642 // number (all values in registers) or the maximum stack slot accessed. | |
643 | |
644 // Convert 4-byte c2 stack slots to words. | |
645 comp_words_on_stack = round_to(comp_args_on_stack*VMRegImpl::stack_slot_size, wordSize)>>LogBytesPerWord; | |
646 // Round up to miminum stack alignment, in wordSize | |
647 comp_words_on_stack = round_to(comp_words_on_stack, 2); | |
304 | 648 __ subptr(rsp, comp_words_on_stack * wordSize); |
0 | 649 } |
650 | |
651 | |
652 // Ensure compiled code always sees stack at proper alignment | |
304 | 653 __ andptr(rsp, -16); |
0 | 654 |
655 // push the return address and misalign the stack that youngest frame always sees | |
656 // as far as the placement of the call instruction | |
304 | 657 __ push(rax); |
0 | 658 |
1135
e66fd840cb6b
6893081: method handle & invokedynamic code needs additional cleanup (post 6815692, 6858164)
twisti
parents:
848
diff
changeset
|
659 // Put saved SP in another register |
e66fd840cb6b
6893081: method handle & invokedynamic code needs additional cleanup (post 6815692, 6858164)
twisti
parents:
848
diff
changeset
|
660 const Register saved_sp = rax; |
e66fd840cb6b
6893081: method handle & invokedynamic code needs additional cleanup (post 6815692, 6858164)
twisti
parents:
848
diff
changeset
|
661 __ movptr(saved_sp, r11); |
e66fd840cb6b
6893081: method handle & invokedynamic code needs additional cleanup (post 6815692, 6858164)
twisti
parents:
848
diff
changeset
|
662 |
0 | 663 // Will jump to the compiled code just as if compiled code was doing it. |
664 // Pre-load the register-jump target early, to schedule it better. | |
304 | 665 __ movptr(r11, Address(rbx, in_bytes(methodOopDesc::from_compiled_offset()))); |
0 | 666 |
667 // Now generate the shuffle code. Pick up all register args and move the | |
668 // rest through the floating point stack top. | |
669 for (int i = 0; i < total_args_passed; i++) { | |
670 if (sig_bt[i] == T_VOID) { | |
671 // Longs and doubles are passed in native word order, but misaligned | |
672 // in the 32-bit build. | |
673 assert(i > 0 && (sig_bt[i-1] == T_LONG || sig_bt[i-1] == T_DOUBLE), "missing half"); | |
674 continue; | |
675 } | |
676 | |
677 // Pick up 0, 1 or 2 words from SP+offset. | |
678 | |
679 assert(!regs[i].second()->is_valid() || regs[i].first()->next() == regs[i].second(), | |
680 "scrambled load targets?"); | |
681 // Load in argument order going down. | |
1506 | 682 int ld_off = (total_args_passed - i)*Interpreter::stackElementSize; |
0 | 683 // Point to interpreter value (vs. tag) |
1506 | 684 int next_off = ld_off - Interpreter::stackElementSize; |
0 | 685 // |
686 // | |
687 // | |
688 VMReg r_1 = regs[i].first(); | |
689 VMReg r_2 = regs[i].second(); | |
690 if (!r_1->is_valid()) { | |
691 assert(!r_2->is_valid(), ""); | |
692 continue; | |
693 } | |
694 if (r_1->is_stack()) { | |
695 // Convert stack slot to an SP offset (+ wordSize to account for return address ) | |
696 int st_off = regs[i].first()->reg2stack()*VMRegImpl::stack_slot_size + wordSize; | |
1135
e66fd840cb6b
6893081: method handle & invokedynamic code needs additional cleanup (post 6815692, 6858164)
twisti
parents:
848
diff
changeset
|
697 |
e66fd840cb6b
6893081: method handle & invokedynamic code needs additional cleanup (post 6815692, 6858164)
twisti
parents:
848
diff
changeset
|
698 // We can use r13 as a temp here because compiled code doesn't need r13 as an input |
e66fd840cb6b
6893081: method handle & invokedynamic code needs additional cleanup (post 6815692, 6858164)
twisti
parents:
848
diff
changeset
|
699 // and if we end up going thru a c2i because of a miss a reasonable value of r13 |
e66fd840cb6b
6893081: method handle & invokedynamic code needs additional cleanup (post 6815692, 6858164)
twisti
parents:
848
diff
changeset
|
700 // will be generated. |
0 | 701 if (!r_2->is_valid()) { |
702 // sign extend??? | |
1135
e66fd840cb6b
6893081: method handle & invokedynamic code needs additional cleanup (post 6815692, 6858164)
twisti
parents:
848
diff
changeset
|
703 __ movl(r13, Address(saved_sp, ld_off)); |
e66fd840cb6b
6893081: method handle & invokedynamic code needs additional cleanup (post 6815692, 6858164)
twisti
parents:
848
diff
changeset
|
704 __ movptr(Address(rsp, st_off), r13); |
0 | 705 } else { |
706 // | |
707 // We are using two optoregs. This can be either T_OBJECT, T_ADDRESS, T_LONG, or T_DOUBLE | |
708 // the interpreter allocates two slots but only uses one for thr T_LONG or T_DOUBLE case | |
709 // So we must adjust where to pick up the data to match the interpreter. | |
710 // | |
711 // Interpreter local[n] == MSW, local[n+1] == LSW however locals | |
712 // are accessed as negative so LSW is at LOW address | |
713 | |
714 // ld_off is MSW so get LSW | |
715 const int offset = (sig_bt[i]==T_LONG||sig_bt[i]==T_DOUBLE)? | |
716 next_off : ld_off; | |
1135
e66fd840cb6b
6893081: method handle & invokedynamic code needs additional cleanup (post 6815692, 6858164)
twisti
parents:
848
diff
changeset
|
717 __ movq(r13, Address(saved_sp, offset)); |
0 | 718 // st_off is LSW (i.e. reg.first()) |
1135
e66fd840cb6b
6893081: method handle & invokedynamic code needs additional cleanup (post 6815692, 6858164)
twisti
parents:
848
diff
changeset
|
719 __ movq(Address(rsp, st_off), r13); |
0 | 720 } |
721 } else if (r_1->is_Register()) { // Register argument | |
722 Register r = r_1->as_Register(); | |
723 assert(r != rax, "must be different"); | |
724 if (r_2->is_valid()) { | |
725 // | |
726 // We are using two VMRegs. This can be either T_OBJECT, T_ADDRESS, T_LONG, or T_DOUBLE | |
727 // the interpreter allocates two slots but only uses one for thr T_LONG or T_DOUBLE case | |
728 // So we must adjust where to pick up the data to match the interpreter. | |
729 | |
730 const int offset = (sig_bt[i]==T_LONG||sig_bt[i]==T_DOUBLE)? | |
731 next_off : ld_off; | |
732 | |
733 // this can be a misaligned move | |
1135
e66fd840cb6b
6893081: method handle & invokedynamic code needs additional cleanup (post 6815692, 6858164)
twisti
parents:
848
diff
changeset
|
734 __ movq(r, Address(saved_sp, offset)); |
0 | 735 } else { |
736 // sign extend and use a full word? | |
1135
e66fd840cb6b
6893081: method handle & invokedynamic code needs additional cleanup (post 6815692, 6858164)
twisti
parents:
848
diff
changeset
|
737 __ movl(r, Address(saved_sp, ld_off)); |
0 | 738 } |
739 } else { | |
740 if (!r_2->is_valid()) { | |
1135
e66fd840cb6b
6893081: method handle & invokedynamic code needs additional cleanup (post 6815692, 6858164)
twisti
parents:
848
diff
changeset
|
741 __ movflt(r_1->as_XMMRegister(), Address(saved_sp, ld_off)); |
0 | 742 } else { |
1135
e66fd840cb6b
6893081: method handle & invokedynamic code needs additional cleanup (post 6815692, 6858164)
twisti
parents:
848
diff
changeset
|
743 __ movdbl(r_1->as_XMMRegister(), Address(saved_sp, next_off)); |
0 | 744 } |
745 } | |
746 } | |
747 | |
748 // 6243940 We might end up in handle_wrong_method if | |
749 // the callee is deoptimized as we race thru here. If that | |
750 // happens we don't want to take a safepoint because the | |
751 // caller frame will look interpreted and arguments are now | |
752 // "compiled" so it is much better to make this transition | |
753 // invisible to the stack walking code. Unfortunately if | |
754 // we try and find the callee by normal means a safepoint | |
755 // is possible. So we stash the desired callee in the thread | |
756 // and the vm will find there should this case occur. | |
757 | |
304 | 758 __ movptr(Address(r15_thread, JavaThread::callee_target_offset()), rbx); |
0 | 759 |
760 // put methodOop where a c2i would expect should we end up there | |
761 // only needed becaus eof c2 resolve stubs return methodOop as a result in | |
762 // rax | |
304 | 763 __ mov(rax, rbx); |
0 | 764 __ jmp(r11); |
765 } | |
766 | |
767 // --------------------------------------------------------------- | |
768 AdapterHandlerEntry* SharedRuntime::generate_i2c2i_adapters(MacroAssembler *masm, | |
769 int total_args_passed, | |
770 int comp_args_on_stack, | |
771 const BasicType *sig_bt, | |
1187
cf0685d550f1
6911204: generated adapters with large signatures can fill up the code cache
never
parents:
1135
diff
changeset
|
772 const VMRegPair *regs, |
cf0685d550f1
6911204: generated adapters with large signatures can fill up the code cache
never
parents:
1135
diff
changeset
|
773 AdapterFingerPrint* fingerprint) { |
0 | 774 address i2c_entry = __ pc(); |
775 | |
776 gen_i2c_adapter(masm, total_args_passed, comp_args_on_stack, sig_bt, regs); | |
777 | |
778 // ------------------------------------------------------------------------- | |
779 // Generate a C2I adapter. On entry we know rbx holds the methodOop during calls | |
780 // to the interpreter. The args start out packed in the compiled layout. They | |
781 // need to be unpacked into the interpreter layout. This will almost always | |
782 // require some stack space. We grow the current (compiled) stack, then repack | |
783 // the args. We finally end in a jump to the generic interpreter entry point. | |
784 // On exit from the interpreter, the interpreter will restore our SP (lest the | |
785 // compiled code, which relys solely on SP and not RBP, get sick). | |
786 | |
787 address c2i_unverified_entry = __ pc(); | |
788 Label skip_fixup; | |
789 Label ok; | |
790 | |
791 Register holder = rax; | |
792 Register receiver = j_rarg0; | |
793 Register temp = rbx; | |
794 | |
795 { | |
796 __ verify_oop(holder); | |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
0
diff
changeset
|
797 __ load_klass(temp, receiver); |
0 | 798 __ verify_oop(temp); |
799 | |
304 | 800 __ cmpptr(temp, Address(holder, compiledICHolderOopDesc::holder_klass_offset())); |
801 __ movptr(rbx, Address(holder, compiledICHolderOopDesc::holder_method_offset())); | |
0 | 802 __ jcc(Assembler::equal, ok); |
803 __ jump(RuntimeAddress(SharedRuntime::get_ic_miss_stub())); | |
804 | |
805 __ bind(ok); | |
806 // Method might have been compiled since the call site was patched to | |
807 // interpreted if that is the case treat it as a miss so we can get | |
808 // the call site corrected. | |
304 | 809 __ cmpptr(Address(rbx, in_bytes(methodOopDesc::code_offset())), (int32_t)NULL_WORD); |
0 | 810 __ jcc(Assembler::equal, skip_fixup); |
811 __ jump(RuntimeAddress(SharedRuntime::get_ic_miss_stub())); | |
812 } | |
813 | |
814 address c2i_entry = __ pc(); | |
815 | |
816 gen_c2i_adapter(masm, total_args_passed, comp_args_on_stack, sig_bt, regs, skip_fixup); | |
817 | |
818 __ flush(); | |
1187
cf0685d550f1
6911204: generated adapters with large signatures can fill up the code cache
never
parents:
1135
diff
changeset
|
819 return AdapterHandlerLibrary::new_entry(fingerprint, i2c_entry, c2i_entry, c2i_unverified_entry); |
0 | 820 } |
821 | |
822 int SharedRuntime::c_calling_convention(const BasicType *sig_bt, | |
823 VMRegPair *regs, | |
824 int total_args_passed) { | |
825 // We return the amount of VMRegImpl stack slots we need to reserve for all | |
826 // the arguments NOT counting out_preserve_stack_slots. | |
827 | |
828 // NOTE: These arrays will have to change when c1 is ported | |
829 #ifdef _WIN64 | |
830 static const Register INT_ArgReg[Argument::n_int_register_parameters_c] = { | |
831 c_rarg0, c_rarg1, c_rarg2, c_rarg3 | |
832 }; | |
833 static const XMMRegister FP_ArgReg[Argument::n_float_register_parameters_c] = { | |
834 c_farg0, c_farg1, c_farg2, c_farg3 | |
835 }; | |
836 #else | |
837 static const Register INT_ArgReg[Argument::n_int_register_parameters_c] = { | |
838 c_rarg0, c_rarg1, c_rarg2, c_rarg3, c_rarg4, c_rarg5 | |
839 }; | |
840 static const XMMRegister FP_ArgReg[Argument::n_float_register_parameters_c] = { | |
841 c_farg0, c_farg1, c_farg2, c_farg3, | |
842 c_farg4, c_farg5, c_farg6, c_farg7 | |
843 }; | |
844 #endif // _WIN64 | |
845 | |
846 | |
847 uint int_args = 0; | |
848 uint fp_args = 0; | |
849 uint stk_args = 0; // inc by 2 each time | |
850 | |
851 for (int i = 0; i < total_args_passed; i++) { | |
852 switch (sig_bt[i]) { | |
853 case T_BOOLEAN: | |
854 case T_CHAR: | |
855 case T_BYTE: | |
856 case T_SHORT: | |
857 case T_INT: | |
858 if (int_args < Argument::n_int_register_parameters_c) { | |
859 regs[i].set1(INT_ArgReg[int_args++]->as_VMReg()); | |
860 #ifdef _WIN64 | |
861 fp_args++; | |
862 // Allocate slots for callee to stuff register args the stack. | |
863 stk_args += 2; | |
864 #endif | |
865 } else { | |
866 regs[i].set1(VMRegImpl::stack2reg(stk_args)); | |
867 stk_args += 2; | |
868 } | |
869 break; | |
870 case T_LONG: | |
871 assert(sig_bt[i + 1] == T_VOID, "expecting half"); | |
872 // fall through | |
873 case T_OBJECT: | |
874 case T_ARRAY: | |
875 case T_ADDRESS: | |
876 if (int_args < Argument::n_int_register_parameters_c) { | |
877 regs[i].set2(INT_ArgReg[int_args++]->as_VMReg()); | |
878 #ifdef _WIN64 | |
879 fp_args++; | |
880 stk_args += 2; | |
881 #endif | |
882 } else { | |
883 regs[i].set2(VMRegImpl::stack2reg(stk_args)); | |
884 stk_args += 2; | |
885 } | |
886 break; | |
887 case T_FLOAT: | |
888 if (fp_args < Argument::n_float_register_parameters_c) { | |
889 regs[i].set1(FP_ArgReg[fp_args++]->as_VMReg()); | |
890 #ifdef _WIN64 | |
891 int_args++; | |
892 // Allocate slots for callee to stuff register args the stack. | |
893 stk_args += 2; | |
894 #endif | |
895 } else { | |
896 regs[i].set1(VMRegImpl::stack2reg(stk_args)); | |
897 stk_args += 2; | |
898 } | |
899 break; | |
900 case T_DOUBLE: | |
901 assert(sig_bt[i + 1] == T_VOID, "expecting half"); | |
902 if (fp_args < Argument::n_float_register_parameters_c) { | |
903 regs[i].set2(FP_ArgReg[fp_args++]->as_VMReg()); | |
904 #ifdef _WIN64 | |
905 int_args++; | |
906 // Allocate slots for callee to stuff register args the stack. | |
907 stk_args += 2; | |
908 #endif | |
909 } else { | |
910 regs[i].set2(VMRegImpl::stack2reg(stk_args)); | |
911 stk_args += 2; | |
912 } | |
913 break; | |
914 case T_VOID: // Halves of longs and doubles | |
915 assert(i != 0 && (sig_bt[i - 1] == T_LONG || sig_bt[i - 1] == T_DOUBLE), "expecting half"); | |
916 regs[i].set_bad(); | |
917 break; | |
918 default: | |
919 ShouldNotReachHere(); | |
920 break; | |
921 } | |
922 } | |
923 #ifdef _WIN64 | |
924 // windows abi requires that we always allocate enough stack space | |
925 // for 4 64bit registers to be stored down. | |
926 if (stk_args < 8) { | |
927 stk_args = 8; | |
928 } | |
929 #endif // _WIN64 | |
930 | |
931 return stk_args; | |
932 } | |
933 | |
934 // On 64 bit we will store integer like items to the stack as | |
935 // 64 bits items (sparc abi) even though java would only store | |
936 // 32bits for a parameter. On 32bit it will simply be 32 bits | |
937 // So this routine will do 32->32 on 32bit and 32->64 on 64bit | |
938 static void move32_64(MacroAssembler* masm, VMRegPair src, VMRegPair dst) { | |
939 if (src.first()->is_stack()) { | |
940 if (dst.first()->is_stack()) { | |
941 // stack to stack | |
942 __ movslq(rax, Address(rbp, reg2offset_in(src.first()))); | |
943 __ movq(Address(rsp, reg2offset_out(dst.first())), rax); | |
944 } else { | |
945 // stack to reg | |
946 __ movslq(dst.first()->as_Register(), Address(rbp, reg2offset_in(src.first()))); | |
947 } | |
948 } else if (dst.first()->is_stack()) { | |
949 // reg to stack | |
950 // Do we really have to sign extend??? | |
951 // __ movslq(src.first()->as_Register(), src.first()->as_Register()); | |
952 __ movq(Address(rsp, reg2offset_out(dst.first())), src.first()->as_Register()); | |
953 } else { | |
954 // Do we really have to sign extend??? | |
955 // __ movslq(dst.first()->as_Register(), src.first()->as_Register()); | |
956 if (dst.first() != src.first()) { | |
957 __ movq(dst.first()->as_Register(), src.first()->as_Register()); | |
958 } | |
959 } | |
960 } | |
961 | |
962 | |
963 // An oop arg. Must pass a handle not the oop itself | |
964 static void object_move(MacroAssembler* masm, | |
965 OopMap* map, | |
966 int oop_handle_offset, | |
967 int framesize_in_slots, | |
968 VMRegPair src, | |
969 VMRegPair dst, | |
970 bool is_receiver, | |
971 int* receiver_offset) { | |
972 | |
973 // must pass a handle. First figure out the location we use as a handle | |
974 | |
975 Register rHandle = dst.first()->is_stack() ? rax : dst.first()->as_Register(); | |
976 | |
977 // See if oop is NULL if it is we need no handle | |
978 | |
979 if (src.first()->is_stack()) { | |
980 | |
981 // Oop is already on the stack as an argument | |
982 int offset_in_older_frame = src.first()->reg2stack() + SharedRuntime::out_preserve_stack_slots(); | |
983 map->set_oop(VMRegImpl::stack2reg(offset_in_older_frame + framesize_in_slots)); | |
984 if (is_receiver) { | |
985 *receiver_offset = (offset_in_older_frame + framesize_in_slots) * VMRegImpl::stack_slot_size; | |
986 } | |
987 | |
304 | 988 __ cmpptr(Address(rbp, reg2offset_in(src.first())), (int32_t)NULL_WORD); |
989 __ lea(rHandle, Address(rbp, reg2offset_in(src.first()))); | |
0 | 990 // conditionally move a NULL |
304 | 991 __ cmovptr(Assembler::equal, rHandle, Address(rbp, reg2offset_in(src.first()))); |
0 | 992 } else { |
993 | |
994 // Oop is in an a register we must store it to the space we reserve | |
995 // on the stack for oop_handles and pass a handle if oop is non-NULL | |
996 | |
997 const Register rOop = src.first()->as_Register(); | |
998 int oop_slot; | |
999 if (rOop == j_rarg0) | |
1000 oop_slot = 0; | |
1001 else if (rOop == j_rarg1) | |
1002 oop_slot = 1; | |
1003 else if (rOop == j_rarg2) | |
1004 oop_slot = 2; | |
1005 else if (rOop == j_rarg3) | |
1006 oop_slot = 3; | |
1007 else if (rOop == j_rarg4) | |
1008 oop_slot = 4; | |
1009 else { | |
1010 assert(rOop == j_rarg5, "wrong register"); | |
1011 oop_slot = 5; | |
1012 } | |
1013 | |
1014 oop_slot = oop_slot * VMRegImpl::slots_per_word + oop_handle_offset; | |
1015 int offset = oop_slot*VMRegImpl::stack_slot_size; | |
1016 | |
1017 map->set_oop(VMRegImpl::stack2reg(oop_slot)); | |
1018 // Store oop in handle area, may be NULL | |
304 | 1019 __ movptr(Address(rsp, offset), rOop); |
0 | 1020 if (is_receiver) { |
1021 *receiver_offset = offset; | |
1022 } | |
1023 | |
304 | 1024 __ cmpptr(rOop, (int32_t)NULL_WORD); |
1025 __ lea(rHandle, Address(rsp, offset)); | |
0 | 1026 // conditionally move a NULL from the handle area where it was just stored |
304 | 1027 __ cmovptr(Assembler::equal, rHandle, Address(rsp, offset)); |
0 | 1028 } |
1029 | |
1030 // If arg is on the stack then place it otherwise it is already in correct reg. | |
1031 if (dst.first()->is_stack()) { | |
304 | 1032 __ movptr(Address(rsp, reg2offset_out(dst.first())), rHandle); |
0 | 1033 } |
1034 } | |
1035 | |
1036 // A float arg may have to do float reg int reg conversion | |
1037 static void float_move(MacroAssembler* masm, VMRegPair src, VMRegPair dst) { | |
1038 assert(!src.second()->is_valid() && !dst.second()->is_valid(), "bad float_move"); | |
1039 | |
1040 // The calling conventions assures us that each VMregpair is either | |
1041 // all really one physical register or adjacent stack slots. | |
1042 // This greatly simplifies the cases here compared to sparc. | |
1043 | |
1044 if (src.first()->is_stack()) { | |
1045 if (dst.first()->is_stack()) { | |
1046 __ movl(rax, Address(rbp, reg2offset_in(src.first()))); | |
304 | 1047 __ movptr(Address(rsp, reg2offset_out(dst.first())), rax); |
0 | 1048 } else { |
1049 // stack to reg | |
1050 assert(dst.first()->is_XMMRegister(), "only expect xmm registers as parameters"); | |
1051 __ movflt(dst.first()->as_XMMRegister(), Address(rbp, reg2offset_in(src.first()))); | |
1052 } | |
1053 } else if (dst.first()->is_stack()) { | |
1054 // reg to stack | |
1055 assert(src.first()->is_XMMRegister(), "only expect xmm registers as parameters"); | |
1056 __ movflt(Address(rsp, reg2offset_out(dst.first())), src.first()->as_XMMRegister()); | |
1057 } else { | |
1058 // reg to reg | |
1059 // In theory these overlap but the ordering is such that this is likely a nop | |
1060 if ( src.first() != dst.first()) { | |
1061 __ movdbl(dst.first()->as_XMMRegister(), src.first()->as_XMMRegister()); | |
1062 } | |
1063 } | |
1064 } | |
1065 | |
1066 // A long move | |
1067 static void long_move(MacroAssembler* masm, VMRegPair src, VMRegPair dst) { | |
1068 | |
1069 // The calling conventions assures us that each VMregpair is either | |
1070 // all really one physical register or adjacent stack slots. | |
1071 // This greatly simplifies the cases here compared to sparc. | |
1072 | |
1073 if (src.is_single_phys_reg() ) { | |
1074 if (dst.is_single_phys_reg()) { | |
1075 if (dst.first() != src.first()) { | |
304 | 1076 __ mov(dst.first()->as_Register(), src.first()->as_Register()); |
0 | 1077 } |
1078 } else { | |
1079 assert(dst.is_single_reg(), "not a stack pair"); | |
1080 __ movq(Address(rsp, reg2offset_out(dst.first())), src.first()->as_Register()); | |
1081 } | |
1082 } else if (dst.is_single_phys_reg()) { | |
1083 assert(src.is_single_reg(), "not a stack pair"); | |
1084 __ movq(dst.first()->as_Register(), Address(rbp, reg2offset_out(src.first()))); | |
1085 } else { | |
1086 assert(src.is_single_reg() && dst.is_single_reg(), "not stack pairs"); | |
1087 __ movq(rax, Address(rbp, reg2offset_in(src.first()))); | |
1088 __ movq(Address(rsp, reg2offset_out(dst.first())), rax); | |
1089 } | |
1090 } | |
1091 | |
1092 // A double move | |
1093 static void double_move(MacroAssembler* masm, VMRegPair src, VMRegPair dst) { | |
1094 | |
1095 // The calling conventions assures us that each VMregpair is either | |
1096 // all really one physical register or adjacent stack slots. | |
1097 // This greatly simplifies the cases here compared to sparc. | |
1098 | |
1099 if (src.is_single_phys_reg() ) { | |
1100 if (dst.is_single_phys_reg()) { | |
1101 // In theory these overlap but the ordering is such that this is likely a nop | |
1102 if ( src.first() != dst.first()) { | |
1103 __ movdbl(dst.first()->as_XMMRegister(), src.first()->as_XMMRegister()); | |
1104 } | |
1105 } else { | |
1106 assert(dst.is_single_reg(), "not a stack pair"); | |
1107 __ movdbl(Address(rsp, reg2offset_out(dst.first())), src.first()->as_XMMRegister()); | |
1108 } | |
1109 } else if (dst.is_single_phys_reg()) { | |
1110 assert(src.is_single_reg(), "not a stack pair"); | |
1111 __ movdbl(dst.first()->as_XMMRegister(), Address(rbp, reg2offset_out(src.first()))); | |
1112 } else { | |
1113 assert(src.is_single_reg() && dst.is_single_reg(), "not stack pairs"); | |
1114 __ movq(rax, Address(rbp, reg2offset_in(src.first()))); | |
1115 __ movq(Address(rsp, reg2offset_out(dst.first())), rax); | |
1116 } | |
1117 } | |
1118 | |
1119 | |
1120 void SharedRuntime::save_native_result(MacroAssembler *masm, BasicType ret_type, int frame_slots) { | |
1121 // We always ignore the frame_slots arg and just use the space just below frame pointer | |
1122 // which by this time is free to use | |
1123 switch (ret_type) { | |
1124 case T_FLOAT: | |
1125 __ movflt(Address(rbp, -wordSize), xmm0); | |
1126 break; | |
1127 case T_DOUBLE: | |
1128 __ movdbl(Address(rbp, -wordSize), xmm0); | |
1129 break; | |
1130 case T_VOID: break; | |
1131 default: { | |
304 | 1132 __ movptr(Address(rbp, -wordSize), rax); |
0 | 1133 } |
1134 } | |
1135 } | |
1136 | |
1137 void SharedRuntime::restore_native_result(MacroAssembler *masm, BasicType ret_type, int frame_slots) { | |
1138 // We always ignore the frame_slots arg and just use the space just below frame pointer | |
1139 // which by this time is free to use | |
1140 switch (ret_type) { | |
1141 case T_FLOAT: | |
1142 __ movflt(xmm0, Address(rbp, -wordSize)); | |
1143 break; | |
1144 case T_DOUBLE: | |
1145 __ movdbl(xmm0, Address(rbp, -wordSize)); | |
1146 break; | |
1147 case T_VOID: break; | |
1148 default: { | |
304 | 1149 __ movptr(rax, Address(rbp, -wordSize)); |
0 | 1150 } |
1151 } | |
1152 } | |
1153 | |
1154 static void save_args(MacroAssembler *masm, int arg_count, int first_arg, VMRegPair *args) { | |
1155 for ( int i = first_arg ; i < arg_count ; i++ ) { | |
1156 if (args[i].first()->is_Register()) { | |
304 | 1157 __ push(args[i].first()->as_Register()); |
0 | 1158 } else if (args[i].first()->is_XMMRegister()) { |
304 | 1159 __ subptr(rsp, 2*wordSize); |
0 | 1160 __ movdbl(Address(rsp, 0), args[i].first()->as_XMMRegister()); |
1161 } | |
1162 } | |
1163 } | |
1164 | |
1165 static void restore_args(MacroAssembler *masm, int arg_count, int first_arg, VMRegPair *args) { | |
1166 for ( int i = arg_count - 1 ; i >= first_arg ; i-- ) { | |
1167 if (args[i].first()->is_Register()) { | |
304 | 1168 __ pop(args[i].first()->as_Register()); |
0 | 1169 } else if (args[i].first()->is_XMMRegister()) { |
1170 __ movdbl(args[i].first()->as_XMMRegister(), Address(rsp, 0)); | |
304 | 1171 __ addptr(rsp, 2*wordSize); |
0 | 1172 } |
1173 } | |
1174 } | |
1175 | |
1176 // --------------------------------------------------------------------------- | |
1177 // Generate a native wrapper for a given method. The method takes arguments | |
1178 // in the Java compiled code convention, marshals them to the native | |
1179 // convention (handlizes oops, etc), transitions to native, makes the call, | |
1180 // returns to java state (possibly blocking), unhandlizes any result and | |
1181 // returns. | |
1182 nmethod *SharedRuntime::generate_native_wrapper(MacroAssembler *masm, | |
1183 methodHandle method, | |
1184 int total_in_args, | |
1185 int comp_args_on_stack, | |
1186 BasicType *in_sig_bt, | |
1187 VMRegPair *in_regs, | |
1188 BasicType ret_type) { | |
1189 // Native nmethod wrappers never take possesion of the oop arguments. | |
1190 // So the caller will gc the arguments. The only thing we need an | |
1191 // oopMap for is if the call is static | |
1192 // | |
1193 // An OopMap for lock (and class if static) | |
1194 OopMapSet *oop_maps = new OopMapSet(); | |
1195 intptr_t start = (intptr_t)__ pc(); | |
1196 | |
1197 // We have received a description of where all the java arg are located | |
1198 // on entry to the wrapper. We need to convert these args to where | |
1199 // the jni function will expect them. To figure out where they go | |
1200 // we convert the java signature to a C signature by inserting | |
1201 // the hidden arguments as arg[0] and possibly arg[1] (static method) | |
1202 | |
1203 int total_c_args = total_in_args + 1; | |
1204 if (method->is_static()) { | |
1205 total_c_args++; | |
1206 } | |
1207 | |
1208 BasicType* out_sig_bt = NEW_RESOURCE_ARRAY(BasicType, total_c_args); | |
1209 VMRegPair* out_regs = NEW_RESOURCE_ARRAY(VMRegPair, total_c_args); | |
1210 | |
1211 int argc = 0; | |
1212 out_sig_bt[argc++] = T_ADDRESS; | |
1213 if (method->is_static()) { | |
1214 out_sig_bt[argc++] = T_OBJECT; | |
1215 } | |
1216 | |
1217 for (int i = 0; i < total_in_args ; i++ ) { | |
1218 out_sig_bt[argc++] = in_sig_bt[i]; | |
1219 } | |
1220 | |
1221 // Now figure out where the args must be stored and how much stack space | |
1222 // they require. | |
1223 // | |
1224 int out_arg_slots; | |
1225 out_arg_slots = c_calling_convention(out_sig_bt, out_regs, total_c_args); | |
1226 | |
1227 // Compute framesize for the wrapper. We need to handlize all oops in | |
1228 // incoming registers | |
1229 | |
1230 // Calculate the total number of stack slots we will need. | |
1231 | |
1232 // First count the abi requirement plus all of the outgoing args | |
1233 int stack_slots = SharedRuntime::out_preserve_stack_slots() + out_arg_slots; | |
1234 | |
1235 // Now the space for the inbound oop handle area | |
1236 | |
1237 int oop_handle_offset = stack_slots; | |
1238 stack_slots += 6*VMRegImpl::slots_per_word; | |
1239 | |
1240 // Now any space we need for handlizing a klass if static method | |
1241 | |
1242 int oop_temp_slot_offset = 0; | |
1243 int klass_slot_offset = 0; | |
1244 int klass_offset = -1; | |
1245 int lock_slot_offset = 0; | |
1246 bool is_static = false; | |
1247 | |
1248 if (method->is_static()) { | |
1249 klass_slot_offset = stack_slots; | |
1250 stack_slots += VMRegImpl::slots_per_word; | |
1251 klass_offset = klass_slot_offset * VMRegImpl::stack_slot_size; | |
1252 is_static = true; | |
1253 } | |
1254 | |
1255 // Plus a lock if needed | |
1256 | |
1257 if (method->is_synchronized()) { | |
1258 lock_slot_offset = stack_slots; | |
1259 stack_slots += VMRegImpl::slots_per_word; | |
1260 } | |
1261 | |
1262 // Now a place (+2) to save return values or temp during shuffling | |
1263 // + 4 for return address (which we own) and saved rbp | |
1264 stack_slots += 6; | |
1265 | |
1266 // Ok The space we have allocated will look like: | |
1267 // | |
1268 // | |
1269 // FP-> | | | |
1270 // |---------------------| | |
1271 // | 2 slots for moves | | |
1272 // |---------------------| | |
1273 // | lock box (if sync) | | |
1274 // |---------------------| <- lock_slot_offset | |
1275 // | klass (if static) | | |
1276 // |---------------------| <- klass_slot_offset | |
1277 // | oopHandle area | | |
1278 // |---------------------| <- oop_handle_offset (6 java arg registers) | |
1279 // | outbound memory | | |
1280 // | based arguments | | |
1281 // | | | |
1282 // |---------------------| | |
1283 // | | | |
1284 // SP-> | out_preserved_slots | | |
1285 // | |
1286 // | |
1287 | |
1288 | |
1289 // Now compute actual number of stack words we need rounding to make | |
1290 // stack properly aligned. | |
524
c9004fe53695
6792301: StackAlignmentInBytes not honored for compiled native methods
xlu
parents:
520
diff
changeset
|
1291 stack_slots = round_to(stack_slots, StackAlignmentInSlots); |
0 | 1292 |
1293 int stack_size = stack_slots * VMRegImpl::stack_slot_size; | |
1294 | |
1295 | |
1296 // First thing make an ic check to see if we should even be here | |
1297 | |
1298 // We are free to use all registers as temps without saving them and | |
1299 // restoring them except rbp. rbp is the only callee save register | |
1300 // as far as the interpreter and the compiler(s) are concerned. | |
1301 | |
1302 | |
1303 const Register ic_reg = rax; | |
1304 const Register receiver = j_rarg0; | |
1305 | |
1306 Label ok; | |
1307 Label exception_pending; | |
1308 | |
848
fe95187e8882
6859338: amd64 native unverified entry point pushes values before implicit null check
never
parents:
682
diff
changeset
|
1309 assert_different_registers(ic_reg, receiver, rscratch1); |
0 | 1310 __ verify_oop(receiver); |
848
fe95187e8882
6859338: amd64 native unverified entry point pushes values before implicit null check
never
parents:
682
diff
changeset
|
1311 __ load_klass(rscratch1, receiver); |
fe95187e8882
6859338: amd64 native unverified entry point pushes values before implicit null check
never
parents:
682
diff
changeset
|
1312 __ cmpq(ic_reg, rscratch1); |
0 | 1313 __ jcc(Assembler::equal, ok); |
1314 | |
1315 __ jump(RuntimeAddress(SharedRuntime::get_ic_miss_stub())); | |
1316 | |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
0
diff
changeset
|
1317 __ bind(ok); |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
0
diff
changeset
|
1318 |
0 | 1319 // Verified entry point must be aligned |
1320 __ align(8); | |
1321 | |
1322 int vep_offset = ((intptr_t)__ pc()) - start; | |
1323 | |
1324 // The instruction at the verified entry point must be 5 bytes or longer | |
1325 // because it can be patched on the fly by make_non_entrant. The stack bang | |
1326 // instruction fits that requirement. | |
1327 | |
1328 // Generate stack overflow check | |
1329 | |
1330 if (UseStackBanging) { | |
1331 __ bang_stack_with_offset(StackShadowPages*os::vm_page_size()); | |
1332 } else { | |
1333 // need a 5 byte instruction to allow MT safe patching to non-entrant | |
1334 __ fat_nop(); | |
1335 } | |
1336 | |
1337 // Generate a new frame for the wrapper. | |
1338 __ enter(); | |
1339 // -2 because return address is already present and so is saved rbp | |
304 | 1340 __ subptr(rsp, stack_size - 2*wordSize); |
0 | 1341 |
1342 // Frame is now completed as far as size and linkage. | |
1343 | |
1344 int frame_complete = ((intptr_t)__ pc()) - start; | |
1345 | |
1346 #ifdef ASSERT | |
1347 { | |
1348 Label L; | |
304 | 1349 __ mov(rax, rsp); |
605 | 1350 __ andptr(rax, -16); // must be 16 byte boundary (see amd64 ABI) |
304 | 1351 __ cmpptr(rax, rsp); |
0 | 1352 __ jcc(Assembler::equal, L); |
1353 __ stop("improperly aligned stack"); | |
1354 __ bind(L); | |
1355 } | |
1356 #endif /* ASSERT */ | |
1357 | |
1358 | |
1359 // We use r14 as the oop handle for the receiver/klass | |
1360 // It is callee save so it survives the call to native | |
1361 | |
1362 const Register oop_handle_reg = r14; | |
1363 | |
1364 | |
1365 | |
1366 // | |
1367 // We immediately shuffle the arguments so that any vm call we have to | |
1368 // make from here on out (sync slow path, jvmti, etc.) we will have | |
1369 // captured the oops from our caller and have a valid oopMap for | |
1370 // them. | |
1371 | |
1372 // ----------------- | |
1373 // The Grand Shuffle | |
1374 | |
1375 // The Java calling convention is either equal (linux) or denser (win64) than the | |
1376 // c calling convention. However the because of the jni_env argument the c calling | |
1377 // convention always has at least one more (and two for static) arguments than Java. | |
1378 // Therefore if we move the args from java -> c backwards then we will never have | |
1379 // a register->register conflict and we don't have to build a dependency graph | |
1380 // and figure out how to break any cycles. | |
1381 // | |
1382 | |
1383 // Record esp-based slot for receiver on stack for non-static methods | |
1384 int receiver_offset = -1; | |
1385 | |
1386 // This is a trick. We double the stack slots so we can claim | |
1387 // the oops in the caller's frame. Since we are sure to have | |
1388 // more args than the caller doubling is enough to make | |
1389 // sure we can capture all the incoming oop args from the | |
1390 // caller. | |
1391 // | |
1392 OopMap* map = new OopMap(stack_slots * 2, 0 /* arg_slots*/); | |
1393 | |
1394 // Mark location of rbp (someday) | |
1395 // map->set_callee_saved(VMRegImpl::stack2reg( stack_slots - 2), stack_slots * 2, 0, vmreg(rbp)); | |
1396 | |
1397 // Use eax, ebx as temporaries during any memory-memory moves we have to do | |
1398 // All inbound args are referenced based on rbp and all outbound args via rsp. | |
1399 | |
1400 | |
1401 #ifdef ASSERT | |
1402 bool reg_destroyed[RegisterImpl::number_of_registers]; | |
1403 bool freg_destroyed[XMMRegisterImpl::number_of_registers]; | |
1404 for ( int r = 0 ; r < RegisterImpl::number_of_registers ; r++ ) { | |
1405 reg_destroyed[r] = false; | |
1406 } | |
1407 for ( int f = 0 ; f < XMMRegisterImpl::number_of_registers ; f++ ) { | |
1408 freg_destroyed[f] = false; | |
1409 } | |
1410 | |
1411 #endif /* ASSERT */ | |
1412 | |
1413 | |
1414 int c_arg = total_c_args - 1; | |
1415 for ( int i = total_in_args - 1; i >= 0 ; i--, c_arg-- ) { | |
1416 #ifdef ASSERT | |
1417 if (in_regs[i].first()->is_Register()) { | |
1418 assert(!reg_destroyed[in_regs[i].first()->as_Register()->encoding()], "destroyed reg!"); | |
1419 } else if (in_regs[i].first()->is_XMMRegister()) { | |
1420 assert(!freg_destroyed[in_regs[i].first()->as_XMMRegister()->encoding()], "destroyed reg!"); | |
1421 } | |
1422 if (out_regs[c_arg].first()->is_Register()) { | |
1423 reg_destroyed[out_regs[c_arg].first()->as_Register()->encoding()] = true; | |
1424 } else if (out_regs[c_arg].first()->is_XMMRegister()) { | |
1425 freg_destroyed[out_regs[c_arg].first()->as_XMMRegister()->encoding()] = true; | |
1426 } | |
1427 #endif /* ASSERT */ | |
1428 switch (in_sig_bt[i]) { | |
1429 case T_ARRAY: | |
1430 case T_OBJECT: | |
1431 object_move(masm, map, oop_handle_offset, stack_slots, in_regs[i], out_regs[c_arg], | |
1432 ((i == 0) && (!is_static)), | |
1433 &receiver_offset); | |
1434 break; | |
1435 case T_VOID: | |
1436 break; | |
1437 | |
1438 case T_FLOAT: | |
1439 float_move(masm, in_regs[i], out_regs[c_arg]); | |
1440 break; | |
1441 | |
1442 case T_DOUBLE: | |
1443 assert( i + 1 < total_in_args && | |
1444 in_sig_bt[i + 1] == T_VOID && | |
1445 out_sig_bt[c_arg+1] == T_VOID, "bad arg list"); | |
1446 double_move(masm, in_regs[i], out_regs[c_arg]); | |
1447 break; | |
1448 | |
1449 case T_LONG : | |
1450 long_move(masm, in_regs[i], out_regs[c_arg]); | |
1451 break; | |
1452 | |
1453 case T_ADDRESS: assert(false, "found T_ADDRESS in java args"); | |
1454 | |
1455 default: | |
1456 move32_64(masm, in_regs[i], out_regs[c_arg]); | |
1457 } | |
1458 } | |
1459 | |
1460 // point c_arg at the first arg that is already loaded in case we | |
1461 // need to spill before we call out | |
1462 c_arg++; | |
1463 | |
1464 // Pre-load a static method's oop into r14. Used both by locking code and | |
1465 // the normal JNI call code. | |
1466 if (method->is_static()) { | |
1467 | |
1468 // load oop into a register | |
1469 __ movoop(oop_handle_reg, JNIHandles::make_local(Klass::cast(method->method_holder())->java_mirror())); | |
1470 | |
1471 // Now handlize the static class mirror it's known not-null. | |
304 | 1472 __ movptr(Address(rsp, klass_offset), oop_handle_reg); |
0 | 1473 map->set_oop(VMRegImpl::stack2reg(klass_slot_offset)); |
1474 | |
1475 // Now get the handle | |
304 | 1476 __ lea(oop_handle_reg, Address(rsp, klass_offset)); |
0 | 1477 // store the klass handle as second argument |
304 | 1478 __ movptr(c_rarg1, oop_handle_reg); |
0 | 1479 // and protect the arg if we must spill |
1480 c_arg--; | |
1481 } | |
1482 | |
1483 // Change state to native (we save the return address in the thread, since it might not | |
1484 // be pushed on the stack when we do a a stack traversal). It is enough that the pc() | |
1485 // points into the right code segment. It does not have to be the correct return pc. | |
1486 // We use the same pc/oopMap repeatedly when we call out | |
1487 | |
1488 intptr_t the_pc = (intptr_t) __ pc(); | |
1489 oop_maps->add_gc_map(the_pc - start, map); | |
1490 | |
1491 __ set_last_Java_frame(rsp, noreg, (address)the_pc); | |
1492 | |
1493 | |
1494 // We have all of the arguments setup at this point. We must not touch any register | |
1495 // argument registers at this point (what if we save/restore them there are no oop? | |
1496 | |
1497 { | |
1498 SkipIfEqual skip(masm, &DTraceMethodProbes, false); | |
1499 // protect the args we've loaded | |
1500 save_args(masm, total_c_args, c_arg, out_regs); | |
1501 __ movoop(c_rarg1, JNIHandles::make_local(method())); | |
1502 __ call_VM_leaf( | |
1503 CAST_FROM_FN_PTR(address, SharedRuntime::dtrace_method_entry), | |
1504 r15_thread, c_rarg1); | |
1505 restore_args(masm, total_c_args, c_arg, out_regs); | |
1506 } | |
1507 | |
610
70998f2e05ef
6805864: 4/3 Problem with jvmti->redefineClasses: some methods don't get redefined
dcubed
parents:
304
diff
changeset
|
1508 // RedefineClasses() tracing support for obsolete method entry |
70998f2e05ef
6805864: 4/3 Problem with jvmti->redefineClasses: some methods don't get redefined
dcubed
parents:
304
diff
changeset
|
1509 if (RC_TRACE_IN_RANGE(0x00001000, 0x00002000)) { |
70998f2e05ef
6805864: 4/3 Problem with jvmti->redefineClasses: some methods don't get redefined
dcubed
parents:
304
diff
changeset
|
1510 // protect the args we've loaded |
70998f2e05ef
6805864: 4/3 Problem with jvmti->redefineClasses: some methods don't get redefined
dcubed
parents:
304
diff
changeset
|
1511 save_args(masm, total_c_args, c_arg, out_regs); |
70998f2e05ef
6805864: 4/3 Problem with jvmti->redefineClasses: some methods don't get redefined
dcubed
parents:
304
diff
changeset
|
1512 __ movoop(c_rarg1, JNIHandles::make_local(method())); |
70998f2e05ef
6805864: 4/3 Problem with jvmti->redefineClasses: some methods don't get redefined
dcubed
parents:
304
diff
changeset
|
1513 __ call_VM_leaf( |
70998f2e05ef
6805864: 4/3 Problem with jvmti->redefineClasses: some methods don't get redefined
dcubed
parents:
304
diff
changeset
|
1514 CAST_FROM_FN_PTR(address, SharedRuntime::rc_trace_method_entry), |
70998f2e05ef
6805864: 4/3 Problem with jvmti->redefineClasses: some methods don't get redefined
dcubed
parents:
304
diff
changeset
|
1515 r15_thread, c_rarg1); |
70998f2e05ef
6805864: 4/3 Problem with jvmti->redefineClasses: some methods don't get redefined
dcubed
parents:
304
diff
changeset
|
1516 restore_args(masm, total_c_args, c_arg, out_regs); |
70998f2e05ef
6805864: 4/3 Problem with jvmti->redefineClasses: some methods don't get redefined
dcubed
parents:
304
diff
changeset
|
1517 } |
70998f2e05ef
6805864: 4/3 Problem with jvmti->redefineClasses: some methods don't get redefined
dcubed
parents:
304
diff
changeset
|
1518 |
0 | 1519 // Lock a synchronized method |
1520 | |
1521 // Register definitions used by locking and unlocking | |
1522 | |
1523 const Register swap_reg = rax; // Must use rax for cmpxchg instruction | |
1524 const Register obj_reg = rbx; // Will contain the oop | |
1525 const Register lock_reg = r13; // Address of compiler lock object (BasicLock) | |
1526 const Register old_hdr = r13; // value of old header at unlock time | |
1527 | |
1528 Label slow_path_lock; | |
1529 Label lock_done; | |
1530 | |
1531 if (method->is_synchronized()) { | |
1532 | |
1533 | |
1534 const int mark_word_offset = BasicLock::displaced_header_offset_in_bytes(); | |
1535 | |
1536 // Get the handle (the 2nd argument) | |
304 | 1537 __ mov(oop_handle_reg, c_rarg1); |
0 | 1538 |
1539 // Get address of the box | |
1540 | |
304 | 1541 __ lea(lock_reg, Address(rsp, lock_slot_offset * VMRegImpl::stack_slot_size)); |
0 | 1542 |
1543 // Load the oop from the handle | |
304 | 1544 __ movptr(obj_reg, Address(oop_handle_reg, 0)); |
0 | 1545 |
1546 if (UseBiasedLocking) { | |
1547 __ biased_locking_enter(lock_reg, obj_reg, swap_reg, rscratch1, false, lock_done, &slow_path_lock); | |
1548 } | |
1549 | |
1550 // Load immediate 1 into swap_reg %rax | |
1551 __ movl(swap_reg, 1); | |
1552 | |
1553 // Load (object->mark() | 1) into swap_reg %rax | |
304 | 1554 __ orptr(swap_reg, Address(obj_reg, 0)); |
0 | 1555 |
1556 // Save (object->mark() | 1) into BasicLock's displaced header | |
304 | 1557 __ movptr(Address(lock_reg, mark_word_offset), swap_reg); |
0 | 1558 |
1559 if (os::is_MP()) { | |
1560 __ lock(); | |
1561 } | |
1562 | |
1563 // src -> dest iff dest == rax else rax <- dest | |
304 | 1564 __ cmpxchgptr(lock_reg, Address(obj_reg, 0)); |
0 | 1565 __ jcc(Assembler::equal, lock_done); |
1566 | |
1567 // Hmm should this move to the slow path code area??? | |
1568 | |
1569 // Test if the oopMark is an obvious stack pointer, i.e., | |
1570 // 1) (mark & 3) == 0, and | |
1571 // 2) rsp <= mark < mark + os::pagesize() | |
1572 // These 3 tests can be done by evaluating the following | |
1573 // expression: ((mark - rsp) & (3 - os::vm_page_size())), | |
1574 // assuming both stack pointer and pagesize have their | |
1575 // least significant 2 bits clear. | |
1576 // NOTE: the oopMark is in swap_reg %rax as the result of cmpxchg | |
1577 | |
304 | 1578 __ subptr(swap_reg, rsp); |
1579 __ andptr(swap_reg, 3 - os::vm_page_size()); | |
0 | 1580 |
1581 // Save the test result, for recursive case, the result is zero | |
304 | 1582 __ movptr(Address(lock_reg, mark_word_offset), swap_reg); |
0 | 1583 __ jcc(Assembler::notEqual, slow_path_lock); |
1584 | |
1585 // Slow path will re-enter here | |
1586 | |
1587 __ bind(lock_done); | |
1588 } | |
1589 | |
1590 | |
1591 // Finally just about ready to make the JNI call | |
1592 | |
1593 | |
1594 // get JNIEnv* which is first argument to native | |
1595 | |
304 | 1596 __ lea(c_rarg0, Address(r15_thread, in_bytes(JavaThread::jni_environment_offset()))); |
0 | 1597 |
1598 // Now set thread in native | |
304 | 1599 __ movl(Address(r15_thread, JavaThread::thread_state_offset()), _thread_in_native); |
0 | 1600 |
1601 __ call(RuntimeAddress(method->native_function())); | |
1602 | |
1603 // Either restore the MXCSR register after returning from the JNI Call | |
1604 // or verify that it wasn't changed. | |
1605 if (RestoreMXCSROnJNICalls) { | |
304 | 1606 __ ldmxcsr(ExternalAddress(StubRoutines::x86::mxcsr_std())); |
0 | 1607 |
1608 } | |
1609 else if (CheckJNICalls ) { | |
304 | 1610 __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, StubRoutines::x86::verify_mxcsr_entry()))); |
0 | 1611 } |
1612 | |
1613 | |
1614 // Unpack native results. | |
1615 switch (ret_type) { | |
1616 case T_BOOLEAN: __ c2bool(rax); break; | |
1617 case T_CHAR : __ movzwl(rax, rax); break; | |
1618 case T_BYTE : __ sign_extend_byte (rax); break; | |
1619 case T_SHORT : __ sign_extend_short(rax); break; | |
1620 case T_INT : /* nothing to do */ break; | |
1621 case T_DOUBLE : | |
1622 case T_FLOAT : | |
1623 // Result is in xmm0 we'll save as needed | |
1624 break; | |
1625 case T_ARRAY: // Really a handle | |
1626 case T_OBJECT: // Really a handle | |
1627 break; // can't de-handlize until after safepoint check | |
1628 case T_VOID: break; | |
1629 case T_LONG: break; | |
1630 default : ShouldNotReachHere(); | |
1631 } | |
1632 | |
1633 // Switch thread to "native transition" state before reading the synchronization state. | |
1634 // This additional state is necessary because reading and testing the synchronization | |
1635 // state is not atomic w.r.t. GC, as this scenario demonstrates: | |
1636 // Java thread A, in _thread_in_native state, loads _not_synchronized and is preempted. | |
1637 // VM thread changes sync state to synchronizing and suspends threads for GC. | |
1638 // Thread A is resumed to finish this native method, but doesn't block here since it | |
1639 // didn't see any synchronization is progress, and escapes. | |
304 | 1640 __ movl(Address(r15_thread, JavaThread::thread_state_offset()), _thread_in_native_trans); |
0 | 1641 |
1642 if(os::is_MP()) { | |
1643 if (UseMembar) { | |
1644 // Force this write out before the read below | |
1645 __ membar(Assembler::Membar_mask_bits( | |
1646 Assembler::LoadLoad | Assembler::LoadStore | | |
1647 Assembler::StoreLoad | Assembler::StoreStore)); | |
1648 } else { | |
1649 // Write serialization page so VM thread can do a pseudo remote membar. | |
1650 // We use the current thread pointer to calculate a thread specific | |
1651 // offset to write to within the page. This minimizes bus traffic | |
1652 // due to cache line collision. | |
1653 __ serialize_memory(r15_thread, rcx); | |
1654 } | |
1655 } | |
1656 | |
1657 | |
1658 // check for safepoint operation in progress and/or pending suspend requests | |
1659 { | |
1660 Label Continue; | |
1661 | |
1662 __ cmp32(ExternalAddress((address)SafepointSynchronize::address_of_state()), | |
1663 SafepointSynchronize::_not_synchronized); | |
1664 | |
1665 Label L; | |
1666 __ jcc(Assembler::notEqual, L); | |
1667 __ cmpl(Address(r15_thread, JavaThread::suspend_flags_offset()), 0); | |
1668 __ jcc(Assembler::equal, Continue); | |
1669 __ bind(L); | |
1670 | |
1671 // Don't use call_VM as it will see a possible pending exception and forward it | |
1672 // and never return here preventing us from clearing _last_native_pc down below. | |
1673 // Also can't use call_VM_leaf either as it will check to see if rsi & rdi are | |
1674 // preserved and correspond to the bcp/locals pointers. So we do a runtime call | |
1675 // by hand. | |
1676 // | |
1677 save_native_result(masm, ret_type, stack_slots); | |
304 | 1678 __ mov(c_rarg0, r15_thread); |
1679 __ mov(r12, rsp); // remember sp | |
1680 __ subptr(rsp, frame::arg_reg_save_area_bytes); // windows | |
1681 __ andptr(rsp, -16); // align stack as required by ABI | |
0 | 1682 __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, JavaThread::check_special_condition_for_native_trans))); |
304 | 1683 __ mov(rsp, r12); // restore sp |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
0
diff
changeset
|
1684 __ reinit_heapbase(); |
0 | 1685 // Restore any method result value |
1686 restore_native_result(masm, ret_type, stack_slots); | |
1687 __ bind(Continue); | |
1688 } | |
1689 | |
1690 // change thread state | |
1691 __ movl(Address(r15_thread, JavaThread::thread_state_offset()), _thread_in_Java); | |
1692 | |
1693 Label reguard; | |
1694 Label reguard_done; | |
1695 __ cmpl(Address(r15_thread, JavaThread::stack_guard_state_offset()), JavaThread::stack_guard_yellow_disabled); | |
1696 __ jcc(Assembler::equal, reguard); | |
1697 __ bind(reguard_done); | |
1698 | |
1699 // native result if any is live | |
1700 | |
1701 // Unlock | |
1702 Label unlock_done; | |
1703 Label slow_path_unlock; | |
1704 if (method->is_synchronized()) { | |
1705 | |
1706 // Get locked oop from the handle we passed to jni | |
304 | 1707 __ movptr(obj_reg, Address(oop_handle_reg, 0)); |
0 | 1708 |
1709 Label done; | |
1710 | |
1711 if (UseBiasedLocking) { | |
1712 __ biased_locking_exit(obj_reg, old_hdr, done); | |
1713 } | |
1714 | |
1715 // Simple recursive lock? | |
1716 | |
304 | 1717 __ cmpptr(Address(rsp, lock_slot_offset * VMRegImpl::stack_slot_size), (int32_t)NULL_WORD); |
0 | 1718 __ jcc(Assembler::equal, done); |
1719 | |
1720 // Must save rax if if it is live now because cmpxchg must use it | |
1721 if (ret_type != T_FLOAT && ret_type != T_DOUBLE && ret_type != T_VOID) { | |
1722 save_native_result(masm, ret_type, stack_slots); | |
1723 } | |
1724 | |
1725 | |
1726 // get address of the stack lock | |
304 | 1727 __ lea(rax, Address(rsp, lock_slot_offset * VMRegImpl::stack_slot_size)); |
0 | 1728 // get old displaced header |
304 | 1729 __ movptr(old_hdr, Address(rax, 0)); |
0 | 1730 |
1731 // Atomic swap old header if oop still contains the stack lock | |
1732 if (os::is_MP()) { | |
1733 __ lock(); | |
1734 } | |
304 | 1735 __ cmpxchgptr(old_hdr, Address(obj_reg, 0)); |
0 | 1736 __ jcc(Assembler::notEqual, slow_path_unlock); |
1737 | |
1738 // slow path re-enters here | |
1739 __ bind(unlock_done); | |
1740 if (ret_type != T_FLOAT && ret_type != T_DOUBLE && ret_type != T_VOID) { | |
1741 restore_native_result(masm, ret_type, stack_slots); | |
1742 } | |
1743 | |
1744 __ bind(done); | |
1745 | |
1746 } | |
1747 { | |
1748 SkipIfEqual skip(masm, &DTraceMethodProbes, false); | |
1749 save_native_result(masm, ret_type, stack_slots); | |
1750 __ movoop(c_rarg1, JNIHandles::make_local(method())); | |
1751 __ call_VM_leaf( | |
1752 CAST_FROM_FN_PTR(address, SharedRuntime::dtrace_method_exit), | |
1753 r15_thread, c_rarg1); | |
1754 restore_native_result(masm, ret_type, stack_slots); | |
1755 } | |
1756 | |
1757 __ reset_last_Java_frame(false, true); | |
1758 | |
1759 // Unpack oop result | |
1760 if (ret_type == T_OBJECT || ret_type == T_ARRAY) { | |
1761 Label L; | |
304 | 1762 __ testptr(rax, rax); |
0 | 1763 __ jcc(Assembler::zero, L); |
304 | 1764 __ movptr(rax, Address(rax, 0)); |
0 | 1765 __ bind(L); |
1766 __ verify_oop(rax); | |
1767 } | |
1768 | |
1769 // reset handle block | |
304 | 1770 __ movptr(rcx, Address(r15_thread, JavaThread::active_handles_offset())); |
1771 __ movptr(Address(rcx, JNIHandleBlock::top_offset_in_bytes()), (int32_t)NULL_WORD); | |
0 | 1772 |
1773 // pop our frame | |
1774 | |
1775 __ leave(); | |
1776 | |
1777 // Any exception pending? | |
304 | 1778 __ cmpptr(Address(r15_thread, in_bytes(Thread::pending_exception_offset())), (int32_t)NULL_WORD); |
0 | 1779 __ jcc(Assembler::notEqual, exception_pending); |
1780 | |
1781 // Return | |
1782 | |
1783 __ ret(0); | |
1784 | |
1785 // Unexpected paths are out of line and go here | |
1786 | |
1787 // forward the exception | |
1788 __ bind(exception_pending); | |
1789 | |
1790 // and forward the exception | |
1791 __ jump(RuntimeAddress(StubRoutines::forward_exception_entry())); | |
1792 | |
1793 | |
1794 // Slow path locking & unlocking | |
1795 if (method->is_synchronized()) { | |
1796 | |
1797 // BEGIN Slow path lock | |
1798 __ bind(slow_path_lock); | |
1799 | |
1800 // has last_Java_frame setup. No exceptions so do vanilla call not call_VM | |
1801 // args are (oop obj, BasicLock* lock, JavaThread* thread) | |
1802 | |
1803 // protect the args we've loaded | |
1804 save_args(masm, total_c_args, c_arg, out_regs); | |
1805 | |
304 | 1806 __ mov(c_rarg0, obj_reg); |
1807 __ mov(c_rarg1, lock_reg); | |
1808 __ mov(c_rarg2, r15_thread); | |
0 | 1809 |
1810 // Not a leaf but we have last_Java_frame setup as we want | |
1811 __ call_VM_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::complete_monitor_locking_C), 3); | |
1812 restore_args(masm, total_c_args, c_arg, out_regs); | |
1813 | |
1814 #ifdef ASSERT | |
1815 { Label L; | |
304 | 1816 __ cmpptr(Address(r15_thread, in_bytes(Thread::pending_exception_offset())), (int32_t)NULL_WORD); |
0 | 1817 __ jcc(Assembler::equal, L); |
1818 __ stop("no pending exception allowed on exit from monitorenter"); | |
1819 __ bind(L); | |
1820 } | |
1821 #endif | |
1822 __ jmp(lock_done); | |
1823 | |
1824 // END Slow path lock | |
1825 | |
1826 // BEGIN Slow path unlock | |
1827 __ bind(slow_path_unlock); | |
1828 | |
1829 // If we haven't already saved the native result we must save it now as xmm registers | |
1830 // are still exposed. | |
1831 | |
1832 if (ret_type == T_FLOAT || ret_type == T_DOUBLE ) { | |
1833 save_native_result(masm, ret_type, stack_slots); | |
1834 } | |
1835 | |
304 | 1836 __ lea(c_rarg1, Address(rsp, lock_slot_offset * VMRegImpl::stack_slot_size)); |
1837 | |
1838 __ mov(c_rarg0, obj_reg); | |
1839 __ mov(r12, rsp); // remember sp | |
1840 __ subptr(rsp, frame::arg_reg_save_area_bytes); // windows | |
1841 __ andptr(rsp, -16); // align stack as required by ABI | |
0 | 1842 |
1843 // Save pending exception around call to VM (which contains an EXCEPTION_MARK) | |
1844 // NOTE that obj_reg == rbx currently | |
304 | 1845 __ movptr(rbx, Address(r15_thread, in_bytes(Thread::pending_exception_offset()))); |
1846 __ movptr(Address(r15_thread, in_bytes(Thread::pending_exception_offset())), (int32_t)NULL_WORD); | |
0 | 1847 |
1848 __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, SharedRuntime::complete_monitor_unlocking_C))); | |
304 | 1849 __ mov(rsp, r12); // restore sp |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
0
diff
changeset
|
1850 __ reinit_heapbase(); |
0 | 1851 #ifdef ASSERT |
1852 { | |
1853 Label L; | |
304 | 1854 __ cmpptr(Address(r15_thread, in_bytes(Thread::pending_exception_offset())), (int)NULL_WORD); |
0 | 1855 __ jcc(Assembler::equal, L); |
1856 __ stop("no pending exception allowed on exit complete_monitor_unlocking_C"); | |
1857 __ bind(L); | |
1858 } | |
1859 #endif /* ASSERT */ | |
1860 | |
304 | 1861 __ movptr(Address(r15_thread, in_bytes(Thread::pending_exception_offset())), rbx); |
0 | 1862 |
1863 if (ret_type == T_FLOAT || ret_type == T_DOUBLE ) { | |
1864 restore_native_result(masm, ret_type, stack_slots); | |
1865 } | |
1866 __ jmp(unlock_done); | |
1867 | |
1868 // END Slow path unlock | |
1869 | |
1870 } // synchronized | |
1871 | |
1872 // SLOW PATH Reguard the stack if needed | |
1873 | |
1874 __ bind(reguard); | |
1875 save_native_result(masm, ret_type, stack_slots); | |
304 | 1876 __ mov(r12, rsp); // remember sp |
1877 __ subptr(rsp, frame::arg_reg_save_area_bytes); // windows | |
1878 __ andptr(rsp, -16); // align stack as required by ABI | |
0 | 1879 __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, SharedRuntime::reguard_yellow_pages))); |
304 | 1880 __ mov(rsp, r12); // restore sp |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
0
diff
changeset
|
1881 __ reinit_heapbase(); |
0 | 1882 restore_native_result(masm, ret_type, stack_slots); |
1883 // and continue | |
1884 __ jmp(reguard_done); | |
1885 | |
1886 | |
1887 | |
1888 __ flush(); | |
1889 | |
1890 nmethod *nm = nmethod::new_native_nmethod(method, | |
1891 masm->code(), | |
1892 vep_offset, | |
1893 frame_complete, | |
1894 stack_slots / VMRegImpl::slots_per_word, | |
1895 (is_static ? in_ByteSize(klass_offset) : in_ByteSize(receiver_offset)), | |
1896 in_ByteSize(lock_slot_offset*VMRegImpl::stack_slot_size), | |
1897 oop_maps); | |
1898 return nm; | |
1899 | |
1900 } | |
1901 | |
116
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
1902 #ifdef HAVE_DTRACE_H |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
1903 // --------------------------------------------------------------------------- |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
1904 // Generate a dtrace nmethod for a given signature. The method takes arguments |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
1905 // in the Java compiled code convention, marshals them to the native |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
1906 // abi and then leaves nops at the position you would expect to call a native |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
1907 // function. When the probe is enabled the nops are replaced with a trap |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
1908 // instruction that dtrace inserts and the trace will cause a notification |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
1909 // to dtrace. |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
1910 // |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
1911 // The probes are only able to take primitive types and java/lang/String as |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
1912 // arguments. No other java types are allowed. Strings are converted to utf8 |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
1913 // strings so that from dtrace point of view java strings are converted to C |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
1914 // strings. There is an arbitrary fixed limit on the total space that a method |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
1915 // can use for converting the strings. (256 chars per string in the signature). |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
1916 // So any java string larger then this is truncated. |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
1917 |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
1918 static int fp_offset[ConcreteRegisterImpl::number_of_registers] = { 0 }; |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
1919 static bool offsets_initialized = false; |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
1920 |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
1921 |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
1922 nmethod *SharedRuntime::generate_dtrace_nmethod(MacroAssembler *masm, |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
1923 methodHandle method) { |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
1924 |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
1925 |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
1926 // generate_dtrace_nmethod is guarded by a mutex so we are sure to |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
1927 // be single threaded in this method. |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
1928 assert(AdapterHandlerLibrary_lock->owned_by_self(), "must be"); |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
1929 |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
1930 if (!offsets_initialized) { |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
1931 fp_offset[c_rarg0->as_VMReg()->value()] = -1 * wordSize; |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
1932 fp_offset[c_rarg1->as_VMReg()->value()] = -2 * wordSize; |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
1933 fp_offset[c_rarg2->as_VMReg()->value()] = -3 * wordSize; |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
1934 fp_offset[c_rarg3->as_VMReg()->value()] = -4 * wordSize; |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
1935 fp_offset[c_rarg4->as_VMReg()->value()] = -5 * wordSize; |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
1936 fp_offset[c_rarg5->as_VMReg()->value()] = -6 * wordSize; |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
1937 |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
1938 fp_offset[c_farg0->as_VMReg()->value()] = -7 * wordSize; |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
1939 fp_offset[c_farg1->as_VMReg()->value()] = -8 * wordSize; |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
1940 fp_offset[c_farg2->as_VMReg()->value()] = -9 * wordSize; |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
1941 fp_offset[c_farg3->as_VMReg()->value()] = -10 * wordSize; |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
1942 fp_offset[c_farg4->as_VMReg()->value()] = -11 * wordSize; |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
1943 fp_offset[c_farg5->as_VMReg()->value()] = -12 * wordSize; |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
1944 fp_offset[c_farg6->as_VMReg()->value()] = -13 * wordSize; |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
1945 fp_offset[c_farg7->as_VMReg()->value()] = -14 * wordSize; |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
1946 |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
1947 offsets_initialized = true; |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
1948 } |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
1949 // Fill in the signature array, for the calling-convention call. |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
1950 int total_args_passed = method->size_of_parameters(); |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
1951 |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
1952 BasicType* in_sig_bt = NEW_RESOURCE_ARRAY(BasicType, total_args_passed); |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
1953 VMRegPair *in_regs = NEW_RESOURCE_ARRAY(VMRegPair, total_args_passed); |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
1954 |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
1955 // The signature we are going to use for the trap that dtrace will see |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
1956 // java/lang/String is converted. We drop "this" and any other object |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
1957 // is converted to NULL. (A one-slot java/lang/Long object reference |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
1958 // is converted to a two-slot long, which is why we double the allocation). |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
1959 BasicType* out_sig_bt = NEW_RESOURCE_ARRAY(BasicType, total_args_passed * 2); |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
1960 VMRegPair* out_regs = NEW_RESOURCE_ARRAY(VMRegPair, total_args_passed * 2); |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
1961 |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
1962 int i=0; |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
1963 int total_strings = 0; |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
1964 int first_arg_to_pass = 0; |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
1965 int total_c_args = 0; |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
1966 |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
1967 // Skip the receiver as dtrace doesn't want to see it |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
1968 if( !method->is_static() ) { |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
1969 in_sig_bt[i++] = T_OBJECT; |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
1970 first_arg_to_pass = 1; |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
1971 } |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
1972 |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
1973 // We need to convert the java args to where a native (non-jni) function |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
1974 // would expect them. To figure out where they go we convert the java |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
1975 // signature to a C signature. |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
1976 |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
1977 SignatureStream ss(method->signature()); |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
1978 for ( ; !ss.at_return_type(); ss.next()) { |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
1979 BasicType bt = ss.type(); |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
1980 in_sig_bt[i++] = bt; // Collect remaining bits of signature |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
1981 out_sig_bt[total_c_args++] = bt; |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
1982 if( bt == T_OBJECT) { |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
1983 symbolOop s = ss.as_symbol_or_null(); |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
1984 if (s == vmSymbols::java_lang_String()) { |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
1985 total_strings++; |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
1986 out_sig_bt[total_c_args-1] = T_ADDRESS; |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
1987 } else if (s == vmSymbols::java_lang_Boolean() || |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
1988 s == vmSymbols::java_lang_Character() || |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
1989 s == vmSymbols::java_lang_Byte() || |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
1990 s == vmSymbols::java_lang_Short() || |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
1991 s == vmSymbols::java_lang_Integer() || |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
1992 s == vmSymbols::java_lang_Float()) { |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
1993 out_sig_bt[total_c_args-1] = T_INT; |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
1994 } else if (s == vmSymbols::java_lang_Long() || |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
1995 s == vmSymbols::java_lang_Double()) { |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
1996 out_sig_bt[total_c_args-1] = T_LONG; |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
1997 out_sig_bt[total_c_args++] = T_VOID; |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
1998 } |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
1999 } else if ( bt == T_LONG || bt == T_DOUBLE ) { |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2000 in_sig_bt[i++] = T_VOID; // Longs & doubles take 2 Java slots |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2001 // We convert double to long |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2002 out_sig_bt[total_c_args-1] = T_LONG; |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2003 out_sig_bt[total_c_args++] = T_VOID; |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2004 } else if ( bt == T_FLOAT) { |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2005 // We convert float to int |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2006 out_sig_bt[total_c_args-1] = T_INT; |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2007 } |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2008 } |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2009 |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2010 assert(i==total_args_passed, "validly parsed signature"); |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2011 |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2012 // Now get the compiled-Java layout as input arguments |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2013 int comp_args_on_stack; |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2014 comp_args_on_stack = SharedRuntime::java_calling_convention( |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2015 in_sig_bt, in_regs, total_args_passed, false); |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2016 |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2017 // Now figure out where the args must be stored and how much stack space |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2018 // they require (neglecting out_preserve_stack_slots but space for storing |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2019 // the 1st six register arguments). It's weird see int_stk_helper. |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2020 |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2021 int out_arg_slots; |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2022 out_arg_slots = c_calling_convention(out_sig_bt, out_regs, total_c_args); |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2023 |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2024 // Calculate the total number of stack slots we will need. |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2025 |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2026 // First count the abi requirement plus all of the outgoing args |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2027 int stack_slots = SharedRuntime::out_preserve_stack_slots() + out_arg_slots; |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2028 |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2029 // Now space for the string(s) we must convert |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2030 int* string_locs = NEW_RESOURCE_ARRAY(int, total_strings + 1); |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2031 for (i = 0; i < total_strings ; i++) { |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2032 string_locs[i] = stack_slots; |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2033 stack_slots += max_dtrace_string_size / VMRegImpl::stack_slot_size; |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2034 } |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2035 |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2036 // Plus the temps we might need to juggle register args |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2037 // regs take two slots each |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2038 stack_slots += (Argument::n_int_register_parameters_c + |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2039 Argument::n_float_register_parameters_c) * 2; |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2040 |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2041 |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2042 // + 4 for return address (which we own) and saved rbp, |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2043 |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2044 stack_slots += 4; |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2045 |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2046 // Ok The space we have allocated will look like: |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2047 // |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2048 // |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2049 // FP-> | | |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2050 // |---------------------| |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2051 // | string[n] | |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2052 // |---------------------| <- string_locs[n] |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2053 // | string[n-1] | |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2054 // |---------------------| <- string_locs[n-1] |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2055 // | ... | |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2056 // | ... | |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2057 // |---------------------| <- string_locs[1] |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2058 // | string[0] | |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2059 // |---------------------| <- string_locs[0] |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2060 // | outbound memory | |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2061 // | based arguments | |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2062 // | | |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2063 // |---------------------| |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2064 // | | |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2065 // SP-> | out_preserved_slots | |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2066 // |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2067 // |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2068 |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2069 // Now compute actual number of stack words we need rounding to make |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2070 // stack properly aligned. |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2071 stack_slots = round_to(stack_slots, 4 * VMRegImpl::slots_per_word); |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2072 |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2073 int stack_size = stack_slots * VMRegImpl::stack_slot_size; |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2074 |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2075 intptr_t start = (intptr_t)__ pc(); |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2076 |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2077 // First thing make an ic check to see if we should even be here |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2078 |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2079 // We are free to use all registers as temps without saving them and |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2080 // restoring them except rbp. rbp, is the only callee save register |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2081 // as far as the interpreter and the compiler(s) are concerned. |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2082 |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2083 const Register ic_reg = rax; |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2084 const Register receiver = rcx; |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2085 Label hit; |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2086 Label exception_pending; |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2087 |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2088 |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2089 __ verify_oop(receiver); |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2090 __ cmpl(ic_reg, Address(receiver, oopDesc::klass_offset_in_bytes())); |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2091 __ jcc(Assembler::equal, hit); |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2092 |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2093 __ jump(RuntimeAddress(SharedRuntime::get_ic_miss_stub())); |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2094 |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2095 // verified entry must be aligned for code patching. |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2096 // and the first 5 bytes must be in the same cache line |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2097 // if we align at 8 then we will be sure 5 bytes are in the same line |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2098 __ align(8); |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2099 |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2100 __ bind(hit); |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2101 |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2102 int vep_offset = ((intptr_t)__ pc()) - start; |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2103 |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2104 |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2105 // The instruction at the verified entry point must be 5 bytes or longer |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2106 // because it can be patched on the fly by make_non_entrant. The stack bang |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2107 // instruction fits that requirement. |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2108 |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2109 // Generate stack overflow check |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2110 |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2111 if (UseStackBanging) { |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2112 if (stack_size <= StackShadowPages*os::vm_page_size()) { |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2113 __ bang_stack_with_offset(StackShadowPages*os::vm_page_size()); |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2114 } else { |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2115 __ movl(rax, stack_size); |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2116 __ bang_stack_size(rax, rbx); |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2117 } |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2118 } else { |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2119 // need a 5 byte instruction to allow MT safe patching to non-entrant |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2120 __ fat_nop(); |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2121 } |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2122 |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2123 assert(((uintptr_t)__ pc() - start - vep_offset) >= 5, |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2124 "valid size for make_non_entrant"); |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2125 |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2126 // Generate a new frame for the wrapper. |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2127 __ enter(); |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2128 |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2129 // -4 because return address is already present and so is saved rbp, |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2130 if (stack_size - 2*wordSize != 0) { |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2131 __ subq(rsp, stack_size - 2*wordSize); |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2132 } |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2133 |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2134 // Frame is now completed as far a size and linkage. |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2135 |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2136 int frame_complete = ((intptr_t)__ pc()) - start; |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2137 |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2138 int c_arg, j_arg; |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2139 |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2140 // State of input register args |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2141 |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2142 bool live[ConcreteRegisterImpl::number_of_registers]; |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2143 |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2144 live[j_rarg0->as_VMReg()->value()] = false; |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2145 live[j_rarg1->as_VMReg()->value()] = false; |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2146 live[j_rarg2->as_VMReg()->value()] = false; |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2147 live[j_rarg3->as_VMReg()->value()] = false; |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2148 live[j_rarg4->as_VMReg()->value()] = false; |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2149 live[j_rarg5->as_VMReg()->value()] = false; |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2150 |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2151 live[j_farg0->as_VMReg()->value()] = false; |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2152 live[j_farg1->as_VMReg()->value()] = false; |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2153 live[j_farg2->as_VMReg()->value()] = false; |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2154 live[j_farg3->as_VMReg()->value()] = false; |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2155 live[j_farg4->as_VMReg()->value()] = false; |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2156 live[j_farg5->as_VMReg()->value()] = false; |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2157 live[j_farg6->as_VMReg()->value()] = false; |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2158 live[j_farg7->as_VMReg()->value()] = false; |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2159 |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2160 |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2161 bool rax_is_zero = false; |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2162 |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2163 // All args (except strings) destined for the stack are moved first |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2164 for (j_arg = first_arg_to_pass, c_arg = 0 ; |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2165 j_arg < total_args_passed ; j_arg++, c_arg++ ) { |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2166 VMRegPair src = in_regs[j_arg]; |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2167 VMRegPair dst = out_regs[c_arg]; |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2168 |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2169 // Get the real reg value or a dummy (rsp) |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2170 |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2171 int src_reg = src.first()->is_reg() ? |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2172 src.first()->value() : |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2173 rsp->as_VMReg()->value(); |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2174 |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2175 bool useless = in_sig_bt[j_arg] == T_ARRAY || |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2176 (in_sig_bt[j_arg] == T_OBJECT && |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2177 out_sig_bt[c_arg] != T_INT && |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2178 out_sig_bt[c_arg] != T_ADDRESS && |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2179 out_sig_bt[c_arg] != T_LONG); |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2180 |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2181 live[src_reg] = !useless; |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2182 |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2183 if (dst.first()->is_stack()) { |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2184 |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2185 // Even though a string arg in a register is still live after this loop |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2186 // after the string conversion loop (next) it will be dead so we take |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2187 // advantage of that now for simpler code to manage live. |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2188 |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2189 live[src_reg] = false; |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2190 switch (in_sig_bt[j_arg]) { |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2191 |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2192 case T_ARRAY: |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2193 case T_OBJECT: |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2194 { |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2195 Address stack_dst(rsp, reg2offset_out(dst.first())); |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2196 |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2197 if (out_sig_bt[c_arg] == T_INT || out_sig_bt[c_arg] == T_LONG) { |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2198 // need to unbox a one-word value |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2199 Register in_reg = rax; |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2200 if ( src.first()->is_reg() ) { |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2201 in_reg = src.first()->as_Register(); |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2202 } else { |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2203 __ movq(rax, Address(rbp, reg2offset_in(src.first()))); |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2204 rax_is_zero = false; |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2205 } |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2206 Label skipUnbox; |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2207 __ movptr(Address(rsp, reg2offset_out(dst.first())), |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2208 (int32_t)NULL_WORD); |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2209 __ testq(in_reg, in_reg); |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2210 __ jcc(Assembler::zero, skipUnbox); |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2211 |
165
437d03ea40b1
6703888: Compressed Oops: use the 32-bits gap after klass in a object
kvn
parents:
116
diff
changeset
|
2212 BasicType bt = out_sig_bt[c_arg]; |
437d03ea40b1
6703888: Compressed Oops: use the 32-bits gap after klass in a object
kvn
parents:
116
diff
changeset
|
2213 int box_offset = java_lang_boxing_object::value_offset_in_bytes(bt); |
116
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2214 Address src1(in_reg, box_offset); |
165
437d03ea40b1
6703888: Compressed Oops: use the 32-bits gap after klass in a object
kvn
parents:
116
diff
changeset
|
2215 if ( bt == T_LONG ) { |
116
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2216 __ movq(in_reg, src1); |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2217 __ movq(stack_dst, in_reg); |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2218 assert(out_sig_bt[c_arg+1] == T_VOID, "must be"); |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2219 ++c_arg; // skip over T_VOID to keep the loop indices in sync |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2220 } else { |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2221 __ movl(in_reg, src1); |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2222 __ movl(stack_dst, in_reg); |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2223 } |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2224 |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2225 __ bind(skipUnbox); |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2226 } else if (out_sig_bt[c_arg] != T_ADDRESS) { |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2227 // Convert the arg to NULL |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2228 if (!rax_is_zero) { |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2229 __ xorq(rax, rax); |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2230 rax_is_zero = true; |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2231 } |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2232 __ movq(stack_dst, rax); |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2233 } |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2234 } |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2235 break; |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2236 |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2237 case T_VOID: |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2238 break; |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2239 |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2240 case T_FLOAT: |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2241 // This does the right thing since we know it is destined for the |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2242 // stack |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2243 float_move(masm, src, dst); |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2244 break; |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2245 |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2246 case T_DOUBLE: |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2247 // This does the right thing since we know it is destined for the |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2248 // stack |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2249 double_move(masm, src, dst); |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2250 break; |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2251 |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2252 case T_LONG : |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2253 long_move(masm, src, dst); |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2254 break; |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2255 |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2256 case T_ADDRESS: assert(false, "found T_ADDRESS in java args"); |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2257 |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2258 default: |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2259 move32_64(masm, src, dst); |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2260 } |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2261 } |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2262 |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2263 } |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2264 |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2265 // If we have any strings we must store any register based arg to the stack |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2266 // This includes any still live xmm registers too. |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2267 |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2268 int sid = 0; |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2269 |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2270 if (total_strings > 0 ) { |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2271 for (j_arg = first_arg_to_pass, c_arg = 0 ; |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2272 j_arg < total_args_passed ; j_arg++, c_arg++ ) { |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2273 VMRegPair src = in_regs[j_arg]; |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2274 VMRegPair dst = out_regs[c_arg]; |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2275 |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2276 if (src.first()->is_reg()) { |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2277 Address src_tmp(rbp, fp_offset[src.first()->value()]); |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2278 |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2279 // string oops were left untouched by the previous loop even if the |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2280 // eventual (converted) arg is destined for the stack so park them |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2281 // away now (except for first) |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2282 |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2283 if (out_sig_bt[c_arg] == T_ADDRESS) { |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2284 Address utf8_addr = Address( |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2285 rsp, string_locs[sid++] * VMRegImpl::stack_slot_size); |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2286 if (sid != 1) { |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2287 // The first string arg won't be killed until after the utf8 |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2288 // conversion |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2289 __ movq(utf8_addr, src.first()->as_Register()); |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2290 } |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2291 } else if (dst.first()->is_reg()) { |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2292 if (in_sig_bt[j_arg] == T_FLOAT || in_sig_bt[j_arg] == T_DOUBLE) { |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2293 |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2294 // Convert the xmm register to an int and store it in the reserved |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2295 // location for the eventual c register arg |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2296 XMMRegister f = src.first()->as_XMMRegister(); |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2297 if (in_sig_bt[j_arg] == T_FLOAT) { |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2298 __ movflt(src_tmp, f); |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2299 } else { |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2300 __ movdbl(src_tmp, f); |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2301 } |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2302 } else { |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2303 // If the arg is an oop type we don't support don't bother to store |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2304 // it remember string was handled above. |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2305 bool useless = in_sig_bt[j_arg] == T_ARRAY || |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2306 (in_sig_bt[j_arg] == T_OBJECT && |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2307 out_sig_bt[c_arg] != T_INT && |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2308 out_sig_bt[c_arg] != T_LONG); |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2309 |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2310 if (!useless) { |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2311 __ movq(src_tmp, src.first()->as_Register()); |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2312 } |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2313 } |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2314 } |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2315 } |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2316 if (in_sig_bt[j_arg] == T_OBJECT && out_sig_bt[c_arg] == T_LONG) { |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2317 assert(out_sig_bt[c_arg+1] == T_VOID, "must be"); |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2318 ++c_arg; // skip over T_VOID to keep the loop indices in sync |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2319 } |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2320 } |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2321 |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2322 // Now that the volatile registers are safe, convert all the strings |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2323 sid = 0; |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2324 |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2325 for (j_arg = first_arg_to_pass, c_arg = 0 ; |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2326 j_arg < total_args_passed ; j_arg++, c_arg++ ) { |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2327 if (out_sig_bt[c_arg] == T_ADDRESS) { |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2328 // It's a string |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2329 Address utf8_addr = Address( |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2330 rsp, string_locs[sid++] * VMRegImpl::stack_slot_size); |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2331 // The first string we find might still be in the original java arg |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2332 // register |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2333 |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2334 VMReg src = in_regs[j_arg].first(); |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2335 |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2336 // We will need to eventually save the final argument to the trap |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2337 // in the von-volatile location dedicated to src. This is the offset |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2338 // from fp we will use. |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2339 int src_off = src->is_reg() ? |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2340 fp_offset[src->value()] : reg2offset_in(src); |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2341 |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2342 // This is where the argument will eventually reside |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2343 VMRegPair dst = out_regs[c_arg]; |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2344 |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2345 if (src->is_reg()) { |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2346 if (sid == 1) { |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2347 __ movq(c_rarg0, src->as_Register()); |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2348 } else { |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2349 __ movq(c_rarg0, utf8_addr); |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2350 } |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2351 } else { |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2352 // arg is still in the original location |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2353 __ movq(c_rarg0, Address(rbp, reg2offset_in(src))); |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2354 } |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2355 Label done, convert; |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2356 |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2357 // see if the oop is NULL |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2358 __ testq(c_rarg0, c_rarg0); |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2359 __ jcc(Assembler::notEqual, convert); |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2360 |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2361 if (dst.first()->is_reg()) { |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2362 // Save the ptr to utf string in the origina src loc or the tmp |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2363 // dedicated to it |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2364 __ movq(Address(rbp, src_off), c_rarg0); |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2365 } else { |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2366 __ movq(Address(rsp, reg2offset_out(dst.first())), c_rarg0); |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2367 } |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2368 __ jmp(done); |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2369 |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2370 __ bind(convert); |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2371 |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2372 __ lea(c_rarg1, utf8_addr); |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2373 if (dst.first()->is_reg()) { |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2374 __ movq(Address(rbp, src_off), c_rarg1); |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2375 } else { |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2376 __ movq(Address(rsp, reg2offset_out(dst.first())), c_rarg1); |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2377 } |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2378 // And do the conversion |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2379 __ call(RuntimeAddress( |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2380 CAST_FROM_FN_PTR(address, SharedRuntime::get_utf))); |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2381 |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2382 __ bind(done); |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2383 } |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2384 if (in_sig_bt[j_arg] == T_OBJECT && out_sig_bt[c_arg] == T_LONG) { |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2385 assert(out_sig_bt[c_arg+1] == T_VOID, "must be"); |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2386 ++c_arg; // skip over T_VOID to keep the loop indices in sync |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2387 } |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2388 } |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2389 // The get_utf call killed all the c_arg registers |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2390 live[c_rarg0->as_VMReg()->value()] = false; |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2391 live[c_rarg1->as_VMReg()->value()] = false; |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2392 live[c_rarg2->as_VMReg()->value()] = false; |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2393 live[c_rarg3->as_VMReg()->value()] = false; |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2394 live[c_rarg4->as_VMReg()->value()] = false; |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2395 live[c_rarg5->as_VMReg()->value()] = false; |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2396 |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2397 live[c_farg0->as_VMReg()->value()] = false; |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2398 live[c_farg1->as_VMReg()->value()] = false; |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2399 live[c_farg2->as_VMReg()->value()] = false; |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2400 live[c_farg3->as_VMReg()->value()] = false; |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2401 live[c_farg4->as_VMReg()->value()] = false; |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2402 live[c_farg5->as_VMReg()->value()] = false; |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2403 live[c_farg6->as_VMReg()->value()] = false; |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2404 live[c_farg7->as_VMReg()->value()] = false; |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2405 } |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2406 |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2407 // Now we can finally move the register args to their desired locations |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2408 |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2409 rax_is_zero = false; |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2410 |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2411 for (j_arg = first_arg_to_pass, c_arg = 0 ; |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2412 j_arg < total_args_passed ; j_arg++, c_arg++ ) { |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2413 |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2414 VMRegPair src = in_regs[j_arg]; |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2415 VMRegPair dst = out_regs[c_arg]; |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2416 |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2417 // Only need to look for args destined for the interger registers (since we |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2418 // convert float/double args to look like int/long outbound) |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2419 if (dst.first()->is_reg()) { |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2420 Register r = dst.first()->as_Register(); |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2421 |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2422 // Check if the java arg is unsupported and thereofre useless |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2423 bool useless = in_sig_bt[j_arg] == T_ARRAY || |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2424 (in_sig_bt[j_arg] == T_OBJECT && |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2425 out_sig_bt[c_arg] != T_INT && |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2426 out_sig_bt[c_arg] != T_ADDRESS && |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2427 out_sig_bt[c_arg] != T_LONG); |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2428 |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2429 |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2430 // If we're going to kill an existing arg save it first |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2431 if (live[dst.first()->value()]) { |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2432 // you can't kill yourself |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2433 if (src.first() != dst.first()) { |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2434 __ movq(Address(rbp, fp_offset[dst.first()->value()]), r); |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2435 } |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2436 } |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2437 if (src.first()->is_reg()) { |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2438 if (live[src.first()->value()] ) { |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2439 if (in_sig_bt[j_arg] == T_FLOAT) { |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2440 __ movdl(r, src.first()->as_XMMRegister()); |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2441 } else if (in_sig_bt[j_arg] == T_DOUBLE) { |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2442 __ movdq(r, src.first()->as_XMMRegister()); |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2443 } else if (r != src.first()->as_Register()) { |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2444 if (!useless) { |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2445 __ movq(r, src.first()->as_Register()); |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2446 } |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2447 } |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2448 } else { |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2449 // If the arg is an oop type we don't support don't bother to store |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2450 // it |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2451 if (!useless) { |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2452 if (in_sig_bt[j_arg] == T_DOUBLE || |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2453 in_sig_bt[j_arg] == T_LONG || |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2454 in_sig_bt[j_arg] == T_OBJECT ) { |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2455 __ movq(r, Address(rbp, fp_offset[src.first()->value()])); |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2456 } else { |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2457 __ movl(r, Address(rbp, fp_offset[src.first()->value()])); |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2458 } |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2459 } |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2460 } |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2461 live[src.first()->value()] = false; |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2462 } else if (!useless) { |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2463 // full sized move even for int should be ok |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2464 __ movq(r, Address(rbp, reg2offset_in(src.first()))); |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2465 } |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2466 |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2467 // At this point r has the original java arg in the final location |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2468 // (assuming it wasn't useless). If the java arg was an oop |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2469 // we have a bit more to do |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2470 |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2471 if (in_sig_bt[j_arg] == T_ARRAY || in_sig_bt[j_arg] == T_OBJECT ) { |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2472 if (out_sig_bt[c_arg] == T_INT || out_sig_bt[c_arg] == T_LONG) { |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2473 // need to unbox a one-word value |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2474 Label skip; |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2475 __ testq(r, r); |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2476 __ jcc(Assembler::equal, skip); |
165
437d03ea40b1
6703888: Compressed Oops: use the 32-bits gap after klass in a object
kvn
parents:
116
diff
changeset
|
2477 BasicType bt = out_sig_bt[c_arg]; |
437d03ea40b1
6703888: Compressed Oops: use the 32-bits gap after klass in a object
kvn
parents:
116
diff
changeset
|
2478 int box_offset = java_lang_boxing_object::value_offset_in_bytes(bt); |
116
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2479 Address src1(r, box_offset); |
165
437d03ea40b1
6703888: Compressed Oops: use the 32-bits gap after klass in a object
kvn
parents:
116
diff
changeset
|
2480 if ( bt == T_LONG ) { |
116
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2481 __ movq(r, src1); |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2482 } else { |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2483 __ movl(r, src1); |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2484 } |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2485 __ bind(skip); |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2486 |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2487 } else if (out_sig_bt[c_arg] != T_ADDRESS) { |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2488 // Convert the arg to NULL |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2489 __ xorq(r, r); |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2490 } |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2491 } |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2492 |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2493 // dst can longer be holding an input value |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2494 live[dst.first()->value()] = false; |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2495 } |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2496 if (in_sig_bt[j_arg] == T_OBJECT && out_sig_bt[c_arg] == T_LONG) { |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2497 assert(out_sig_bt[c_arg+1] == T_VOID, "must be"); |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2498 ++c_arg; // skip over T_VOID to keep the loop indices in sync |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2499 } |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2500 } |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2501 |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2502 |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2503 // Ok now we are done. Need to place the nop that dtrace wants in order to |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2504 // patch in the trap |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2505 int patch_offset = ((intptr_t)__ pc()) - start; |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2506 |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2507 __ nop(); |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2508 |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2509 |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2510 // Return |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2511 |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2512 __ leave(); |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2513 __ ret(0); |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2514 |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2515 __ flush(); |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2516 |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2517 nmethod *nm = nmethod::new_dtrace_nmethod( |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2518 method, masm->code(), vep_offset, patch_offset, frame_complete, |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2519 stack_slots / VMRegImpl::slots_per_word); |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2520 return nm; |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2521 |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2522 } |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2523 |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2524 #endif // HAVE_DTRACE_H |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
113
diff
changeset
|
2525 |
0 | 2526 // this function returns the adjust size (in number of words) to a c2i adapter |
2527 // activation for use during deoptimization | |
2528 int Deoptimization::last_frame_adjust(int callee_parameters, int callee_locals ) { | |
1506 | 2529 return (callee_locals - callee_parameters) * Interpreter::stackElementWords; |
0 | 2530 } |
2531 | |
2532 | |
2533 uint SharedRuntime::out_preserve_stack_slots() { | |
2534 return 0; | |
2535 } | |
2536 | |
2537 | |
2538 //------------------------------generate_deopt_blob---------------------------- | |
2539 void SharedRuntime::generate_deopt_blob() { | |
2540 // Allocate space for the code | |
2541 ResourceMark rm; | |
2542 // Setup code generation tools | |
2543 CodeBuffer buffer("deopt_blob", 2048, 1024); | |
2544 MacroAssembler* masm = new MacroAssembler(&buffer); | |
2545 int frame_size_in_words; | |
2546 OopMap* map = NULL; | |
2547 OopMapSet *oop_maps = new OopMapSet(); | |
2548 | |
2549 // ------------- | |
2550 // This code enters when returning to a de-optimized nmethod. A return | |
2551 // address has been pushed on the the stack, and return values are in | |
2552 // registers. | |
2553 // If we are doing a normal deopt then we were called from the patched | |
2554 // nmethod from the point we returned to the nmethod. So the return | |
2555 // address on the stack is wrong by NativeCall::instruction_size | |
2556 // We will adjust the value so it looks like we have the original return | |
2557 // address on the stack (like when we eagerly deoptimized). | |
2558 // In the case of an exception pending when deoptimizing, we enter | |
2559 // with a return address on the stack that points after the call we patched | |
2560 // into the exception handler. We have the following register state from, | |
2561 // e.g., the forward exception stub (see stubGenerator_x86_64.cpp). | |
2562 // rax: exception oop | |
2563 // rbx: exception handler | |
2564 // rdx: throwing pc | |
2565 // So in this case we simply jam rdx into the useless return address and | |
2566 // the stack looks just like we want. | |
2567 // | |
2568 // At this point we need to de-opt. We save the argument return | |
2569 // registers. We call the first C routine, fetch_unroll_info(). This | |
2570 // routine captures the return values and returns a structure which | |
2571 // describes the current frame size and the sizes of all replacement frames. | |
2572 // The current frame is compiled code and may contain many inlined | |
2573 // functions, each with their own JVM state. We pop the current frame, then | |
2574 // push all the new frames. Then we call the C routine unpack_frames() to | |
2575 // populate these frames. Finally unpack_frames() returns us the new target | |
2576 // address. Notice that callee-save registers are BLOWN here; they have | |
2577 // already been captured in the vframeArray at the time the return PC was | |
2578 // patched. | |
2579 address start = __ pc(); | |
2580 Label cont; | |
2581 | |
2582 // Prolog for non exception case! | |
2583 | |
2584 // Save everything in sight. | |
2585 map = RegisterSaver::save_live_registers(masm, 0, &frame_size_in_words); | |
2586 | |
2587 // Normal deoptimization. Save exec mode for unpack_frames. | |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
0
diff
changeset
|
2588 __ movl(r14, Deoptimization::Unpack_deopt); // callee-saved |
0 | 2589 __ jmp(cont); |
304 | 2590 |
2591 int reexecute_offset = __ pc() - start; | |
2592 | |
2593 // Reexecute case | |
2594 // return address is the pc describes what bci to do re-execute at | |
2595 | |
2596 // No need to update map as each call to save_live_registers will produce identical oopmap | |
2597 (void) RegisterSaver::save_live_registers(masm, 0, &frame_size_in_words); | |
2598 | |
2599 __ movl(r14, Deoptimization::Unpack_reexecute); // callee-saved | |
2600 __ jmp(cont); | |
2601 | |
0 | 2602 int exception_offset = __ pc() - start; |
2603 | |
2604 // Prolog for exception case | |
2605 | |
304 | 2606 // all registers are dead at this entry point, except for rax, and |
2607 // rdx which contain the exception oop and exception pc | |
2608 // respectively. Set them in TLS and fall thru to the | |
2609 // unpack_with_exception_in_tls entry point. | |
2610 | |
2611 __ movptr(Address(r15_thread, JavaThread::exception_pc_offset()), rdx); | |
2612 __ movptr(Address(r15_thread, JavaThread::exception_oop_offset()), rax); | |
2613 | |
2614 int exception_in_tls_offset = __ pc() - start; | |
2615 | |
2616 // new implementation because exception oop is now passed in JavaThread | |
2617 | |
2618 // Prolog for exception case | |
2619 // All registers must be preserved because they might be used by LinearScan | |
2620 // Exceptiop oop and throwing PC are passed in JavaThread | |
2621 // tos: stack at point of call to method that threw the exception (i.e. only | |
2622 // args are on the stack, no return address) | |
2623 | |
2624 // make room on stack for the return address | |
2625 // It will be patched later with the throwing pc. The correct value is not | |
2626 // available now because loading it from memory would destroy registers. | |
2627 __ push(0); | |
0 | 2628 |
2629 // Save everything in sight. | |
2630 map = RegisterSaver::save_live_registers(masm, 0, &frame_size_in_words); | |
2631 | |
304 | 2632 // Now it is safe to overwrite any register |
2633 | |
0 | 2634 // Deopt during an exception. Save exec mode for unpack_frames. |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
0
diff
changeset
|
2635 __ movl(r14, Deoptimization::Unpack_exception); // callee-saved |
0 | 2636 |
304 | 2637 // load throwing pc from JavaThread and patch it as the return address |
2638 // of the current frame. Then clear the field in JavaThread | |
2639 | |
2640 __ movptr(rdx, Address(r15_thread, JavaThread::exception_pc_offset())); | |
2641 __ movptr(Address(rbp, wordSize), rdx); | |
2642 __ movptr(Address(r15_thread, JavaThread::exception_pc_offset()), (int32_t)NULL_WORD); | |
2643 | |
2644 #ifdef ASSERT | |
2645 // verify that there is really an exception oop in JavaThread | |
2646 __ movptr(rax, Address(r15_thread, JavaThread::exception_oop_offset())); | |
2647 __ verify_oop(rax); | |
2648 | |
2649 // verify that there is no pending exception | |
2650 Label no_pending_exception; | |
2651 __ movptr(rax, Address(r15_thread, Thread::pending_exception_offset())); | |
2652 __ testptr(rax, rax); | |
2653 __ jcc(Assembler::zero, no_pending_exception); | |
2654 __ stop("must not have pending exception here"); | |
2655 __ bind(no_pending_exception); | |
2656 #endif | |
2657 | |
0 | 2658 __ bind(cont); |
2659 | |
2660 // Call C code. Need thread and this frame, but NOT official VM entry | |
2661 // crud. We cannot block on this call, no GC can happen. | |
2662 // | |
2663 // UnrollBlock* fetch_unroll_info(JavaThread* thread) | |
2664 | |
2665 // fetch_unroll_info needs to call last_java_frame(). | |
2666 | |
2667 __ set_last_Java_frame(noreg, noreg, NULL); | |
2668 #ifdef ASSERT | |
2669 { Label L; | |
304 | 2670 __ cmpptr(Address(r15_thread, |
0 | 2671 JavaThread::last_Java_fp_offset()), |
304 | 2672 (int32_t)0); |
0 | 2673 __ jcc(Assembler::equal, L); |
2674 __ stop("SharedRuntime::generate_deopt_blob: last_Java_fp not cleared"); | |
2675 __ bind(L); | |
2676 } | |
2677 #endif // ASSERT | |
304 | 2678 __ mov(c_rarg0, r15_thread); |
0 | 2679 __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, Deoptimization::fetch_unroll_info))); |
2680 | |
2681 // Need to have an oopmap that tells fetch_unroll_info where to | |
2682 // find any register it might need. | |
2683 oop_maps->add_gc_map(__ pc() - start, map); | |
2684 | |
2685 __ reset_last_Java_frame(false, false); | |
2686 | |
2687 // Load UnrollBlock* into rdi | |
304 | 2688 __ mov(rdi, rax); |
2689 | |
2690 Label noException; | |
682
69aefafe69c1
6824463: deopt blob is testing wrong register on 64-bit x86
never
parents:
628
diff
changeset
|
2691 __ cmpl(r14, Deoptimization::Unpack_exception); // Was exception pending? |
304 | 2692 __ jcc(Assembler::notEqual, noException); |
2693 __ movptr(rax, Address(r15_thread, JavaThread::exception_oop_offset())); | |
2694 // QQQ this is useless it was NULL above | |
2695 __ movptr(rdx, Address(r15_thread, JavaThread::exception_pc_offset())); | |
2696 __ movptr(Address(r15_thread, JavaThread::exception_oop_offset()), (int32_t)NULL_WORD); | |
2697 __ movptr(Address(r15_thread, JavaThread::exception_pc_offset()), (int32_t)NULL_WORD); | |
2698 | |
2699 __ verify_oop(rax); | |
2700 | |
2701 // Overwrite the result registers with the exception results. | |
2702 __ movptr(Address(rsp, RegisterSaver::rax_offset_in_bytes()), rax); | |
2703 // I think this is useless | |
2704 __ movptr(Address(rsp, RegisterSaver::rdx_offset_in_bytes()), rdx); | |
2705 | |
2706 __ bind(noException); | |
0 | 2707 |
2708 // Only register save data is on the stack. | |
2709 // Now restore the result registers. Everything else is either dead | |
2710 // or captured in the vframeArray. | |
2711 RegisterSaver::restore_result_registers(masm); | |
2712 | |
2713 // All of the register save area has been popped of the stack. Only the | |
2714 // return address remains. | |
2715 | |
2716 // Pop all the frames we must move/replace. | |
2717 // | |
2718 // Frame picture (youngest to oldest) | |
2719 // 1: self-frame (no frame link) | |
2720 // 2: deopting frame (no frame link) | |
2721 // 3: caller of deopting frame (could be compiled/interpreted). | |
2722 // | |
2723 // Note: by leaving the return address of self-frame on the stack | |
2724 // and using the size of frame 2 to adjust the stack | |
2725 // when we are done the return to frame 3 will still be on the stack. | |
2726 | |
2727 // Pop deoptimized frame | |
2728 __ movl(rcx, Address(rdi, Deoptimization::UnrollBlock::size_of_deoptimized_frame_offset_in_bytes())); | |
304 | 2729 __ addptr(rsp, rcx); |
0 | 2730 |
2731 // rsp should be pointing at the return address to the caller (3) | |
2732 | |
2733 // Stack bang to make sure there's enough room for these interpreter frames. | |
2734 if (UseStackBanging) { | |
2735 __ movl(rbx, Address(rdi, Deoptimization::UnrollBlock::total_frame_sizes_offset_in_bytes())); | |
2736 __ bang_stack_size(rbx, rcx); | |
2737 } | |
2738 | |
2739 // Load address of array of frame pcs into rcx | |
304 | 2740 __ movptr(rcx, Address(rdi, Deoptimization::UnrollBlock::frame_pcs_offset_in_bytes())); |
0 | 2741 |
2742 // Trash the old pc | |
304 | 2743 __ addptr(rsp, wordSize); |
0 | 2744 |
2745 // Load address of array of frame sizes into rsi | |
304 | 2746 __ movptr(rsi, Address(rdi, Deoptimization::UnrollBlock::frame_sizes_offset_in_bytes())); |
0 | 2747 |
2748 // Load counter into rdx | |
2749 __ movl(rdx, Address(rdi, Deoptimization::UnrollBlock::number_of_frames_offset_in_bytes())); | |
2750 | |
2751 // Pick up the initial fp we should save | |
304 | 2752 __ movptr(rbp, Address(rdi, Deoptimization::UnrollBlock::initial_fp_offset_in_bytes())); |
0 | 2753 |
2754 // Now adjust the caller's stack to make up for the extra locals | |
2755 // but record the original sp so that we can save it in the skeletal interpreter | |
2756 // frame and the stack walking of interpreter_sender will get the unextended sp | |
2757 // value and not the "real" sp value. | |
2758 | |
2759 const Register sender_sp = r8; | |
2760 | |
304 | 2761 __ mov(sender_sp, rsp); |
0 | 2762 __ movl(rbx, Address(rdi, |
2763 Deoptimization::UnrollBlock:: | |
2764 caller_adjustment_offset_in_bytes())); | |
304 | 2765 __ subptr(rsp, rbx); |
0 | 2766 |
2767 // Push interpreter frames in a loop | |
2768 Label loop; | |
2769 __ bind(loop); | |
304 | 2770 __ movptr(rbx, Address(rsi, 0)); // Load frame size |
2771 #ifdef CC_INTERP | |
2772 __ subptr(rbx, 4*wordSize); // we'll push pc and ebp by hand and | |
2773 #ifdef ASSERT | |
2774 __ push(0xDEADDEAD); // Make a recognizable pattern | |
2775 __ push(0xDEADDEAD); | |
2776 #else /* ASSERT */ | |
2777 __ subptr(rsp, 2*wordSize); // skip the "static long no_param" | |
2778 #endif /* ASSERT */ | |
2779 #else | |
2780 __ subptr(rbx, 2*wordSize); // We'll push pc and ebp by hand | |
2781 #endif // CC_INTERP | |
2782 __ pushptr(Address(rcx, 0)); // Save return address | |
0 | 2783 __ enter(); // Save old & set new ebp |
304 | 2784 __ subptr(rsp, rbx); // Prolog |
2785 #ifdef CC_INTERP | |
2786 __ movptr(Address(rbp, | |
2787 -(sizeof(BytecodeInterpreter)) + in_bytes(byte_offset_of(BytecodeInterpreter, _sender_sp))), | |
2788 sender_sp); // Make it walkable | |
2789 #else /* CC_INTERP */ | |
0 | 2790 // This value is corrected by layout_activation_impl |
304 | 2791 __ movptr(Address(rbp, frame::interpreter_frame_last_sp_offset * wordSize), (int32_t)NULL_WORD ); |
2792 __ movptr(Address(rbp, frame::interpreter_frame_sender_sp_offset * wordSize), sender_sp); // Make it walkable | |
2793 #endif /* CC_INTERP */ | |
2794 __ mov(sender_sp, rsp); // Pass sender_sp to next frame | |
2795 __ addptr(rsi, wordSize); // Bump array pointer (sizes) | |
2796 __ addptr(rcx, wordSize); // Bump array pointer (pcs) | |
0 | 2797 __ decrementl(rdx); // Decrement counter |
2798 __ jcc(Assembler::notZero, loop); | |
304 | 2799 __ pushptr(Address(rcx, 0)); // Save final return address |
0 | 2800 |
2801 // Re-push self-frame | |
2802 __ enter(); // Save old & set new ebp | |
2803 | |
2804 // Allocate a full sized register save area. | |
2805 // Return address and rbp are in place, so we allocate two less words. | |
304 | 2806 __ subptr(rsp, (frame_size_in_words - 2) * wordSize); |
0 | 2807 |
2808 // Restore frame locals after moving the frame | |
2809 __ movdbl(Address(rsp, RegisterSaver::xmm0_offset_in_bytes()), xmm0); | |
304 | 2810 __ movptr(Address(rsp, RegisterSaver::rax_offset_in_bytes()), rax); |
0 | 2811 |
2812 // Call C code. Need thread but NOT official VM entry | |
2813 // crud. We cannot block on this call, no GC can happen. Call should | |
2814 // restore return values to their stack-slots with the new SP. | |
2815 // | |
2816 // void Deoptimization::unpack_frames(JavaThread* thread, int exec_mode) | |
2817 | |
2818 // Use rbp because the frames look interpreted now | |
2819 __ set_last_Java_frame(noreg, rbp, NULL); | |
2820 | |
304 | 2821 __ mov(c_rarg0, r15_thread); |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
0
diff
changeset
|
2822 __ movl(c_rarg1, r14); // second arg: exec_mode |
0 | 2823 __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, Deoptimization::unpack_frames))); |
2824 | |
2825 // Set an oopmap for the call site | |
2826 oop_maps->add_gc_map(__ pc() - start, | |
2827 new OopMap( frame_size_in_words, 0 )); | |
2828 | |
2829 __ reset_last_Java_frame(true, false); | |
2830 | |
2831 // Collect return values | |
2832 __ movdbl(xmm0, Address(rsp, RegisterSaver::xmm0_offset_in_bytes())); | |
304 | 2833 __ movptr(rax, Address(rsp, RegisterSaver::rax_offset_in_bytes())); |
2834 // I think this is useless (throwing pc?) | |
2835 __ movptr(rdx, Address(rsp, RegisterSaver::rdx_offset_in_bytes())); | |
0 | 2836 |
2837 // Pop self-frame. | |
2838 __ leave(); // Epilog | |
2839 | |
2840 // Jump to interpreter | |
2841 __ ret(0); | |
2842 | |
2843 // Make sure all code is generated | |
2844 masm->flush(); | |
2845 | |
304 | 2846 _deopt_blob = DeoptimizationBlob::create(&buffer, oop_maps, 0, exception_offset, reexecute_offset, frame_size_in_words); |
2847 _deopt_blob->set_unpack_with_exception_in_tls_offset(exception_in_tls_offset); | |
0 | 2848 } |
2849 | |
2850 #ifdef COMPILER2 | |
2851 //------------------------------generate_uncommon_trap_blob-------------------- | |
2852 void SharedRuntime::generate_uncommon_trap_blob() { | |
2853 // Allocate space for the code | |
2854 ResourceMark rm; | |
2855 // Setup code generation tools | |
2856 CodeBuffer buffer("uncommon_trap_blob", 2048, 1024); | |
2857 MacroAssembler* masm = new MacroAssembler(&buffer); | |
2858 | |
2859 assert(SimpleRuntimeFrame::framesize % 4 == 0, "sp not 16-byte aligned"); | |
2860 | |
2861 address start = __ pc(); | |
2862 | |
2863 // Push self-frame. We get here with a return address on the | |
2864 // stack, so rsp is 8-byte aligned until we allocate our frame. | |
304 | 2865 __ subptr(rsp, SimpleRuntimeFrame::return_off << LogBytesPerInt); // Epilog! |
0 | 2866 |
2867 // No callee saved registers. rbp is assumed implicitly saved | |
304 | 2868 __ movptr(Address(rsp, SimpleRuntimeFrame::rbp_off << LogBytesPerInt), rbp); |
0 | 2869 |
2870 // compiler left unloaded_class_index in j_rarg0 move to where the | |
2871 // runtime expects it. | |
2872 __ movl(c_rarg1, j_rarg0); | |
2873 | |
2874 __ set_last_Java_frame(noreg, noreg, NULL); | |
2875 | |
2876 // Call C code. Need thread but NOT official VM entry | |
2877 // crud. We cannot block on this call, no GC can happen. Call should | |
2878 // capture callee-saved registers as well as return values. | |
2879 // Thread is in rdi already. | |
2880 // | |
2881 // UnrollBlock* uncommon_trap(JavaThread* thread, jint unloaded_class_index); | |
2882 | |
304 | 2883 __ mov(c_rarg0, r15_thread); |
0 | 2884 __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, Deoptimization::uncommon_trap))); |
2885 | |
2886 // Set an oopmap for the call site | |
2887 OopMapSet* oop_maps = new OopMapSet(); | |
2888 OopMap* map = new OopMap(SimpleRuntimeFrame::framesize, 0); | |
2889 | |
2890 // location of rbp is known implicitly by the frame sender code | |
2891 | |
2892 oop_maps->add_gc_map(__ pc() - start, map); | |
2893 | |
2894 __ reset_last_Java_frame(false, false); | |
2895 | |
2896 // Load UnrollBlock* into rdi | |
304 | 2897 __ mov(rdi, rax); |
0 | 2898 |
2899 // Pop all the frames we must move/replace. | |
2900 // | |
2901 // Frame picture (youngest to oldest) | |
2902 // 1: self-frame (no frame link) | |
2903 // 2: deopting frame (no frame link) | |
2904 // 3: caller of deopting frame (could be compiled/interpreted). | |
2905 | |
2906 // Pop self-frame. We have no frame, and must rely only on rax and rsp. | |
304 | 2907 __ addptr(rsp, (SimpleRuntimeFrame::framesize - 2) << LogBytesPerInt); // Epilog! |
0 | 2908 |
2909 // Pop deoptimized frame (int) | |
2910 __ movl(rcx, Address(rdi, | |
2911 Deoptimization::UnrollBlock:: | |
2912 size_of_deoptimized_frame_offset_in_bytes())); | |
304 | 2913 __ addptr(rsp, rcx); |
0 | 2914 |
2915 // rsp should be pointing at the return address to the caller (3) | |
2916 | |
2917 // Stack bang to make sure there's enough room for these interpreter frames. | |
2918 if (UseStackBanging) { | |
2919 __ movl(rbx, Address(rdi ,Deoptimization::UnrollBlock::total_frame_sizes_offset_in_bytes())); | |
2920 __ bang_stack_size(rbx, rcx); | |
2921 } | |
2922 | |
2923 // Load address of array of frame pcs into rcx (address*) | |
304 | 2924 __ movptr(rcx, |
2925 Address(rdi, | |
2926 Deoptimization::UnrollBlock::frame_pcs_offset_in_bytes())); | |
0 | 2927 |
2928 // Trash the return pc | |
304 | 2929 __ addptr(rsp, wordSize); |
0 | 2930 |
2931 // Load address of array of frame sizes into rsi (intptr_t*) | |
304 | 2932 __ movptr(rsi, Address(rdi, |
2933 Deoptimization::UnrollBlock:: | |
2934 frame_sizes_offset_in_bytes())); | |
0 | 2935 |
2936 // Counter | |
2937 __ movl(rdx, Address(rdi, | |
2938 Deoptimization::UnrollBlock:: | |
2939 number_of_frames_offset_in_bytes())); // (int) | |
2940 | |
2941 // Pick up the initial fp we should save | |
304 | 2942 __ movptr(rbp, |
2943 Address(rdi, | |
2944 Deoptimization::UnrollBlock::initial_fp_offset_in_bytes())); | |
0 | 2945 |
2946 // Now adjust the caller's stack to make up for the extra locals but | |
2947 // record the original sp so that we can save it in the skeletal | |
2948 // interpreter frame and the stack walking of interpreter_sender | |
2949 // will get the unextended sp value and not the "real" sp value. | |
2950 | |
2951 const Register sender_sp = r8; | |
2952 | |
304 | 2953 __ mov(sender_sp, rsp); |
0 | 2954 __ movl(rbx, Address(rdi, |
2955 Deoptimization::UnrollBlock:: | |
2956 caller_adjustment_offset_in_bytes())); // (int) | |
304 | 2957 __ subptr(rsp, rbx); |
0 | 2958 |
2959 // Push interpreter frames in a loop | |
2960 Label loop; | |
2961 __ bind(loop); | |
304 | 2962 __ movptr(rbx, Address(rsi, 0)); // Load frame size |
2963 __ subptr(rbx, 2 * wordSize); // We'll push pc and rbp by hand | |
2964 __ pushptr(Address(rcx, 0)); // Save return address | |
2965 __ enter(); // Save old & set new rbp | |
2966 __ subptr(rsp, rbx); // Prolog | |
520
52a431267315
6791168: Fix invalid code in bytecodeInterpreter that can cause gcc ICE
coleenp
parents:
304
diff
changeset
|
2967 #ifdef CC_INTERP |
52a431267315
6791168: Fix invalid code in bytecodeInterpreter that can cause gcc ICE
coleenp
parents:
304
diff
changeset
|
2968 __ movptr(Address(rbp, |
52a431267315
6791168: Fix invalid code in bytecodeInterpreter that can cause gcc ICE
coleenp
parents:
304
diff
changeset
|
2969 -(sizeof(BytecodeInterpreter)) + in_bytes(byte_offset_of(BytecodeInterpreter, _sender_sp))), |
52a431267315
6791168: Fix invalid code in bytecodeInterpreter that can cause gcc ICE
coleenp
parents:
304
diff
changeset
|
2970 sender_sp); // Make it walkable |
52a431267315
6791168: Fix invalid code in bytecodeInterpreter that can cause gcc ICE
coleenp
parents:
304
diff
changeset
|
2971 #else // CC_INTERP |
304 | 2972 __ movptr(Address(rbp, frame::interpreter_frame_sender_sp_offset * wordSize), |
2973 sender_sp); // Make it walkable | |
0 | 2974 // This value is corrected by layout_activation_impl |
304 | 2975 __ movptr(Address(rbp, frame::interpreter_frame_last_sp_offset * wordSize), (int32_t)NULL_WORD ); |
520
52a431267315
6791168: Fix invalid code in bytecodeInterpreter that can cause gcc ICE
coleenp
parents:
304
diff
changeset
|
2976 #endif // CC_INTERP |
304 | 2977 __ mov(sender_sp, rsp); // Pass sender_sp to next frame |
2978 __ addptr(rsi, wordSize); // Bump array pointer (sizes) | |
2979 __ addptr(rcx, wordSize); // Bump array pointer (pcs) | |
2980 __ decrementl(rdx); // Decrement counter | |
0 | 2981 __ jcc(Assembler::notZero, loop); |
304 | 2982 __ pushptr(Address(rcx, 0)); // Save final return address |
0 | 2983 |
2984 // Re-push self-frame | |
2985 __ enter(); // Save old & set new rbp | |
304 | 2986 __ subptr(rsp, (SimpleRuntimeFrame::framesize - 4) << LogBytesPerInt); |
0 | 2987 // Prolog |
2988 | |
2989 // Use rbp because the frames look interpreted now | |
2990 __ set_last_Java_frame(noreg, rbp, NULL); | |
2991 | |
2992 // Call C code. Need thread but NOT official VM entry | |
2993 // crud. We cannot block on this call, no GC can happen. Call should | |
2994 // restore return values to their stack-slots with the new SP. | |
2995 // Thread is in rdi already. | |
2996 // | |
2997 // BasicType unpack_frames(JavaThread* thread, int exec_mode); | |
2998 | |
304 | 2999 __ mov(c_rarg0, r15_thread); |
0 | 3000 __ movl(c_rarg1, Deoptimization::Unpack_uncommon_trap); |
3001 __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, Deoptimization::unpack_frames))); | |
3002 | |
3003 // Set an oopmap for the call site | |
3004 oop_maps->add_gc_map(__ pc() - start, new OopMap(SimpleRuntimeFrame::framesize, 0)); | |
3005 | |
3006 __ reset_last_Java_frame(true, false); | |
3007 | |
3008 // Pop self-frame. | |
3009 __ leave(); // Epilog | |
3010 | |
3011 // Jump to interpreter | |
3012 __ ret(0); | |
3013 | |
3014 // Make sure all code is generated | |
3015 masm->flush(); | |
3016 | |
3017 _uncommon_trap_blob = UncommonTrapBlob::create(&buffer, oop_maps, | |
3018 SimpleRuntimeFrame::framesize >> 1); | |
3019 } | |
3020 #endif // COMPILER2 | |
3021 | |
3022 | |
3023 //------------------------------generate_handler_blob------ | |
3024 // | |
3025 // Generate a special Compile2Runtime blob that saves all registers, | |
3026 // and setup oopmap. | |
3027 // | |
3028 static SafepointBlob* generate_handler_blob(address call_ptr, bool cause_return) { | |
3029 assert(StubRoutines::forward_exception_entry() != NULL, | |
3030 "must be generated before"); | |
3031 | |
3032 ResourceMark rm; | |
3033 OopMapSet *oop_maps = new OopMapSet(); | |
3034 OopMap* map; | |
3035 | |
3036 // Allocate space for the code. Setup code generation tools. | |
3037 CodeBuffer buffer("handler_blob", 2048, 1024); | |
3038 MacroAssembler* masm = new MacroAssembler(&buffer); | |
3039 | |
3040 address start = __ pc(); | |
3041 address call_pc = NULL; | |
3042 int frame_size_in_words; | |
3043 | |
3044 // Make room for return address (or push it again) | |
3045 if (!cause_return) { | |
304 | 3046 __ push(rbx); |
0 | 3047 } |
3048 | |
3049 // Save registers, fpu state, and flags | |
3050 map = RegisterSaver::save_live_registers(masm, 0, &frame_size_in_words); | |
3051 | |
3052 // The following is basically a call_VM. However, we need the precise | |
3053 // address of the call in order to generate an oopmap. Hence, we do all the | |
3054 // work outselves. | |
3055 | |
3056 __ set_last_Java_frame(noreg, noreg, NULL); | |
3057 | |
3058 // The return address must always be correct so that frame constructor never | |
3059 // sees an invalid pc. | |
3060 | |
3061 if (!cause_return) { | |
3062 // overwrite the dummy value we pushed on entry | |
304 | 3063 __ movptr(c_rarg0, Address(r15_thread, JavaThread::saved_exception_pc_offset())); |
3064 __ movptr(Address(rbp, wordSize), c_rarg0); | |
0 | 3065 } |
3066 | |
3067 // Do the call | |
304 | 3068 __ mov(c_rarg0, r15_thread); |
0 | 3069 __ call(RuntimeAddress(call_ptr)); |
3070 | |
3071 // Set an oopmap for the call site. This oopmap will map all | |
3072 // oop-registers and debug-info registers as callee-saved. This | |
3073 // will allow deoptimization at this safepoint to find all possible | |
3074 // debug-info recordings, as well as let GC find all oops. | |
3075 | |
3076 oop_maps->add_gc_map( __ pc() - start, map); | |
3077 | |
3078 Label noException; | |
3079 | |
3080 __ reset_last_Java_frame(false, false); | |
3081 | |
304 | 3082 __ cmpptr(Address(r15_thread, Thread::pending_exception_offset()), (int32_t)NULL_WORD); |
0 | 3083 __ jcc(Assembler::equal, noException); |
3084 | |
3085 // Exception pending | |
3086 | |
3087 RegisterSaver::restore_live_registers(masm); | |
3088 | |
3089 __ jump(RuntimeAddress(StubRoutines::forward_exception_entry())); | |
3090 | |
3091 // No exception case | |
3092 __ bind(noException); | |
3093 | |
3094 // Normal exit, restore registers and exit. | |
3095 RegisterSaver::restore_live_registers(masm); | |
3096 | |
3097 __ ret(0); | |
3098 | |
3099 // Make sure all code is generated | |
3100 masm->flush(); | |
3101 | |
3102 // Fill-out other meta info | |
3103 return SafepointBlob::create(&buffer, oop_maps, frame_size_in_words); | |
3104 } | |
3105 | |
3106 // | |
3107 // generate_resolve_blob - call resolution (static/virtual/opt-virtual/ic-miss | |
3108 // | |
3109 // Generate a stub that calls into vm to find out the proper destination | |
3110 // of a java call. All the argument registers are live at this point | |
3111 // but since this is generic code we don't know what they are and the caller | |
3112 // must do any gc of the args. | |
3113 // | |
3114 static RuntimeStub* generate_resolve_blob(address destination, const char* name) { | |
3115 assert (StubRoutines::forward_exception_entry() != NULL, "must be generated before"); | |
3116 | |
3117 // allocate space for the code | |
3118 ResourceMark rm; | |
3119 | |
3120 CodeBuffer buffer(name, 1000, 512); | |
3121 MacroAssembler* masm = new MacroAssembler(&buffer); | |
3122 | |
3123 int frame_size_in_words; | |
3124 | |
3125 OopMapSet *oop_maps = new OopMapSet(); | |
3126 OopMap* map = NULL; | |
3127 | |
3128 int start = __ offset(); | |
3129 | |
3130 map = RegisterSaver::save_live_registers(masm, 0, &frame_size_in_words); | |
3131 | |
3132 int frame_complete = __ offset(); | |
3133 | |
3134 __ set_last_Java_frame(noreg, noreg, NULL); | |
3135 | |
304 | 3136 __ mov(c_rarg0, r15_thread); |
0 | 3137 |
3138 __ call(RuntimeAddress(destination)); | |
3139 | |
3140 | |
3141 // Set an oopmap for the call site. | |
3142 // We need this not only for callee-saved registers, but also for volatile | |
3143 // registers that the compiler might be keeping live across a safepoint. | |
3144 | |
3145 oop_maps->add_gc_map( __ offset() - start, map); | |
3146 | |
3147 // rax contains the address we are going to jump to assuming no exception got installed | |
3148 | |
3149 // clear last_Java_sp | |
3150 __ reset_last_Java_frame(false, false); | |
3151 // check for pending exceptions | |
3152 Label pending; | |
304 | 3153 __ cmpptr(Address(r15_thread, Thread::pending_exception_offset()), (int32_t)NULL_WORD); |
0 | 3154 __ jcc(Assembler::notEqual, pending); |
3155 | |
3156 // get the returned methodOop | |
304 | 3157 __ movptr(rbx, Address(r15_thread, JavaThread::vm_result_offset())); |
3158 __ movptr(Address(rsp, RegisterSaver::rbx_offset_in_bytes()), rbx); | |
3159 | |
3160 __ movptr(Address(rsp, RegisterSaver::rax_offset_in_bytes()), rax); | |
0 | 3161 |
3162 RegisterSaver::restore_live_registers(masm); | |
3163 | |
3164 // We are back the the original state on entry and ready to go. | |
3165 | |
3166 __ jmp(rax); | |
3167 | |
3168 // Pending exception after the safepoint | |
3169 | |
3170 __ bind(pending); | |
3171 | |
3172 RegisterSaver::restore_live_registers(masm); | |
3173 | |
3174 // exception pending => remove activation and forward to exception handler | |
3175 | |
3176 __ movptr(Address(r15_thread, JavaThread::vm_result_offset()), (int)NULL_WORD); | |
3177 | |
304 | 3178 __ movptr(rax, Address(r15_thread, Thread::pending_exception_offset())); |
0 | 3179 __ jump(RuntimeAddress(StubRoutines::forward_exception_entry())); |
3180 | |
3181 // ------------- | |
3182 // make sure all code is generated | |
3183 masm->flush(); | |
3184 | |
3185 // return the blob | |
3186 // frame_size_words or bytes?? | |
3187 return RuntimeStub::new_runtime_stub(name, &buffer, frame_complete, frame_size_in_words, oop_maps, true); | |
3188 } | |
3189 | |
3190 | |
3191 void SharedRuntime::generate_stubs() { | |
3192 | |
3193 _wrong_method_blob = generate_resolve_blob(CAST_FROM_FN_PTR(address, SharedRuntime::handle_wrong_method), | |
3194 "wrong_method_stub"); | |
3195 _ic_miss_blob = generate_resolve_blob(CAST_FROM_FN_PTR(address, SharedRuntime::handle_wrong_method_ic_miss), | |
3196 "ic_miss_stub"); | |
3197 _resolve_opt_virtual_call_blob = generate_resolve_blob(CAST_FROM_FN_PTR(address, SharedRuntime::resolve_opt_virtual_call_C), | |
3198 "resolve_opt_virtual_call"); | |
3199 | |
3200 _resolve_virtual_call_blob = generate_resolve_blob(CAST_FROM_FN_PTR(address, SharedRuntime::resolve_virtual_call_C), | |
3201 "resolve_virtual_call"); | |
3202 | |
3203 _resolve_static_call_blob = generate_resolve_blob(CAST_FROM_FN_PTR(address, SharedRuntime::resolve_static_call_C), | |
3204 "resolve_static_call"); | |
3205 _polling_page_safepoint_handler_blob = | |
3206 generate_handler_blob(CAST_FROM_FN_PTR(address, | |
3207 SafepointSynchronize::handle_polling_page_exception), false); | |
3208 | |
3209 _polling_page_return_handler_blob = | |
3210 generate_handler_blob(CAST_FROM_FN_PTR(address, | |
3211 SafepointSynchronize::handle_polling_page_exception), true); | |
3212 | |
3213 generate_deopt_blob(); | |
3214 | |
3215 #ifdef COMPILER2 | |
3216 generate_uncommon_trap_blob(); | |
3217 #endif // COMPILER2 | |
3218 } | |
3219 | |
3220 | |
3221 #ifdef COMPILER2 | |
3222 // This is here instead of runtime_x86_64.cpp because it uses SimpleRuntimeFrame | |
3223 // | |
3224 //------------------------------generate_exception_blob--------------------------- | |
3225 // creates exception blob at the end | |
3226 // Using exception blob, this code is jumped from a compiled method. | |
3227 // (see emit_exception_handler in x86_64.ad file) | |
3228 // | |
3229 // Given an exception pc at a call we call into the runtime for the | |
3230 // handler in this method. This handler might merely restore state | |
3231 // (i.e. callee save registers) unwind the frame and jump to the | |
3232 // exception handler for the nmethod if there is no Java level handler | |
3233 // for the nmethod. | |
3234 // | |
3235 // This code is entered with a jmp. | |
3236 // | |
3237 // Arguments: | |
3238 // rax: exception oop | |
3239 // rdx: exception pc | |
3240 // | |
3241 // Results: | |
3242 // rax: exception oop | |
3243 // rdx: exception pc in caller or ??? | |
3244 // destination: exception handler of caller | |
3245 // | |
3246 // Note: the exception pc MUST be at a call (precise debug information) | |
3247 // Registers rax, rdx, rcx, rsi, rdi, r8-r11 are not callee saved. | |
3248 // | |
3249 | |
3250 void OptoRuntime::generate_exception_blob() { | |
3251 assert(!OptoRuntime::is_callee_saved_register(RDX_num), ""); | |
3252 assert(!OptoRuntime::is_callee_saved_register(RAX_num), ""); | |
3253 assert(!OptoRuntime::is_callee_saved_register(RCX_num), ""); | |
3254 | |
3255 assert(SimpleRuntimeFrame::framesize % 4 == 0, "sp not 16-byte aligned"); | |
3256 | |
3257 // Allocate space for the code | |
3258 ResourceMark rm; | |
3259 // Setup code generation tools | |
3260 CodeBuffer buffer("exception_blob", 2048, 1024); | |
3261 MacroAssembler* masm = new MacroAssembler(&buffer); | |
3262 | |
3263 | |
3264 address start = __ pc(); | |
3265 | |
3266 // Exception pc is 'return address' for stack walker | |
304 | 3267 __ push(rdx); |
3268 __ subptr(rsp, SimpleRuntimeFrame::return_off << LogBytesPerInt); // Prolog | |
0 | 3269 |
3270 // Save callee-saved registers. See x86_64.ad. | |
3271 | |
3272 // rbp is an implicitly saved callee saved register (i.e. the calling | |
3273 // convention will save restore it in prolog/epilog) Other than that | |
3274 // there are no callee save registers now that adapter frames are gone. | |
3275 | |
304 | 3276 __ movptr(Address(rsp, SimpleRuntimeFrame::rbp_off << LogBytesPerInt), rbp); |
0 | 3277 |
3278 // Store exception in Thread object. We cannot pass any arguments to the | |
3279 // handle_exception call, since we do not want to make any assumption | |
3280 // about the size of the frame where the exception happened in. | |
3281 // c_rarg0 is either rdi (Linux) or rcx (Windows). | |
304 | 3282 __ movptr(Address(r15_thread, JavaThread::exception_oop_offset()),rax); |
3283 __ movptr(Address(r15_thread, JavaThread::exception_pc_offset()), rdx); | |
0 | 3284 |
3285 // This call does all the hard work. It checks if an exception handler | |
3286 // exists in the method. | |
3287 // If so, it returns the handler address. | |
3288 // If not, it prepares for stack-unwinding, restoring the callee-save | |
3289 // registers of the frame being removed. | |
3290 // | |
3291 // address OptoRuntime::handle_exception_C(JavaThread* thread) | |
3292 | |
3293 __ set_last_Java_frame(noreg, noreg, NULL); | |
304 | 3294 __ mov(c_rarg0, r15_thread); |
0 | 3295 __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, OptoRuntime::handle_exception_C))); |
3296 | |
3297 // Set an oopmap for the call site. This oopmap will only be used if we | |
3298 // are unwinding the stack. Hence, all locations will be dead. | |
3299 // Callee-saved registers will be the same as the frame above (i.e., | |
3300 // handle_exception_stub), since they were restored when we got the | |
3301 // exception. | |
3302 | |
3303 OopMapSet* oop_maps = new OopMapSet(); | |
3304 | |
3305 oop_maps->add_gc_map( __ pc()-start, new OopMap(SimpleRuntimeFrame::framesize, 0)); | |
3306 | |
3307 __ reset_last_Java_frame(false, false); | |
3308 | |
3309 // Restore callee-saved registers | |
3310 | |
3311 // rbp is an implicitly saved callee saved register (i.e. the calling | |
3312 // convention will save restore it in prolog/epilog) Other than that | |
3313 // there are no callee save registers no that adapter frames are gone. | |
3314 | |
304 | 3315 __ movptr(rbp, Address(rsp, SimpleRuntimeFrame::rbp_off << LogBytesPerInt)); |
3316 | |
3317 __ addptr(rsp, SimpleRuntimeFrame::return_off << LogBytesPerInt); // Epilog | |
3318 __ pop(rdx); // No need for exception pc anymore | |
0 | 3319 |
3320 // rax: exception handler | |
3321 | |
1368
93767e6a2dfd
6941529: SharedRuntime::raw_exception_handler_for_return_address must reset thread MethodHandle flag
twisti
parents:
1187
diff
changeset
|
3322 // Restore SP from BP if the exception PC is a MethodHandle call site. |
93767e6a2dfd
6941529: SharedRuntime::raw_exception_handler_for_return_address must reset thread MethodHandle flag
twisti
parents:
1187
diff
changeset
|
3323 __ cmpl(Address(r15_thread, JavaThread::is_method_handle_return_offset()), 0); |
1567 | 3324 __ cmovptr(Assembler::notEqual, rsp, rbp_mh_SP_save); |
1135
e66fd840cb6b
6893081: method handle & invokedynamic code needs additional cleanup (post 6815692, 6858164)
twisti
parents:
848
diff
changeset
|
3325 |
0 | 3326 // We have a handler in rax (could be deopt blob). |
304 | 3327 __ mov(r8, rax); |
0 | 3328 |
3329 // Get the exception oop | |
304 | 3330 __ movptr(rax, Address(r15_thread, JavaThread::exception_oop_offset())); |
0 | 3331 // Get the exception pc in case we are deoptimized |
304 | 3332 __ movptr(rdx, Address(r15_thread, JavaThread::exception_pc_offset())); |
0 | 3333 #ifdef ASSERT |
3334 __ movptr(Address(r15_thread, JavaThread::exception_handler_pc_offset()), (int)NULL_WORD); | |
3335 __ movptr(Address(r15_thread, JavaThread::exception_pc_offset()), (int)NULL_WORD); | |
3336 #endif | |
3337 // Clear the exception oop so GC no longer processes it as a root. | |
3338 __ movptr(Address(r15_thread, JavaThread::exception_oop_offset()), (int)NULL_WORD); | |
3339 | |
3340 // rax: exception oop | |
3341 // r8: exception handler | |
3342 // rdx: exception pc | |
3343 // Jump to handler | |
3344 | |
3345 __ jmp(r8); | |
3346 | |
3347 // Make sure all code is generated | |
3348 masm->flush(); | |
3349 | |
3350 // Set exception blob | |
3351 _exception_blob = ExceptionBlob::create(&buffer, oop_maps, SimpleRuntimeFrame::framesize >> 1); | |
3352 } | |
3353 #endif // COMPILER2 |