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