Mercurial > hg > truffle
annotate src/cpu/x86/vm/interpreterRT_x86_64.cpp @ 1978:2ca799d83d3c
Merge
author | ohair |
---|---|
date | Tue, 30 Nov 2010 18:10:20 -0800 |
parents | f95d63e2154a |
children | da91efe96a93 |
rev | line source |
---|---|
0 | 1 /* |
1552
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1506
diff
changeset
|
2 * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved. |
0 | 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
4 * | |
5 * This code is free software; you can redistribute it and/or modify it | |
6 * under the terms of the GNU General Public License version 2 only, as | |
7 * published by the Free Software Foundation. | |
8 * | |
9 * This code is distributed in the hope that it will be useful, but WITHOUT | |
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
12 * version 2 for more details (a copy is included in the LICENSE file that | |
13 * accompanied this code). | |
14 * | |
15 * You should have received a copy of the GNU General Public License version | |
16 * 2 along with this work; if not, write to the Free Software Foundation, | |
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | |
18 * | |
1552
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1506
diff
changeset
|
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1506
diff
changeset
|
20 * or visit www.oracle.com if you need additional information or have any |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1506
diff
changeset
|
21 * questions. |
0 | 22 * |
23 */ | |
24 | |
1972 | 25 #include "precompiled.hpp" |
26 #include "interpreter/interpreter.hpp" | |
27 #include "interpreter/interpreterRuntime.hpp" | |
28 #include "memory/allocation.inline.hpp" | |
29 #include "memory/universe.inline.hpp" | |
30 #include "oops/methodOop.hpp" | |
31 #include "oops/oop.inline.hpp" | |
32 #include "runtime/handles.inline.hpp" | |
33 #include "runtime/icache.hpp" | |
34 #include "runtime/interfaceSupport.hpp" | |
35 #include "runtime/signature.hpp" | |
0 | 36 |
37 #define __ _masm-> | |
38 | |
39 // Implementation of SignatureHandlerGenerator | |
40 | |
41 Register InterpreterRuntime::SignatureHandlerGenerator::from() { return r14; } | |
42 Register InterpreterRuntime::SignatureHandlerGenerator::to() { return rsp; } | |
43 Register InterpreterRuntime::SignatureHandlerGenerator::temp() { return rscratch1; } | |
44 | |
45 void InterpreterRuntime::SignatureHandlerGenerator::pass_int() { | |
46 const Address src(from(), Interpreter::local_offset_in_bytes(offset())); | |
47 | |
48 #ifdef _WIN64 | |
49 switch (_num_args) { | |
50 case 0: | |
51 __ movl(c_rarg1, src); | |
52 _num_args++; | |
53 break; | |
54 case 1: | |
55 __ movl(c_rarg2, src); | |
56 _num_args++; | |
57 break; | |
58 case 2: | |
59 __ movl(c_rarg3, src); | |
60 _num_args++; | |
61 break; | |
62 default: | |
63 __ movl(rax, src); | |
64 __ movl(Address(to(), _stack_offset), rax); | |
65 _stack_offset += wordSize; | |
66 break; | |
67 } | |
68 #else | |
69 switch (_num_int_args) { | |
70 case 0: | |
71 __ movl(c_rarg1, src); | |
72 _num_int_args++; | |
73 break; | |
74 case 1: | |
75 __ movl(c_rarg2, src); | |
76 _num_int_args++; | |
77 break; | |
78 case 2: | |
79 __ movl(c_rarg3, src); | |
80 _num_int_args++; | |
81 break; | |
82 case 3: | |
83 __ movl(c_rarg4, src); | |
84 _num_int_args++; | |
85 break; | |
86 case 4: | |
87 __ movl(c_rarg5, src); | |
88 _num_int_args++; | |
89 break; | |
90 default: | |
91 __ movl(rax, src); | |
92 __ movl(Address(to(), _stack_offset), rax); | |
93 _stack_offset += wordSize; | |
94 break; | |
95 } | |
96 #endif | |
97 } | |
98 | |
99 void InterpreterRuntime::SignatureHandlerGenerator::pass_long() { | |
100 const Address src(from(), Interpreter::local_offset_in_bytes(offset() + 1)); | |
101 | |
102 #ifdef _WIN64 | |
103 switch (_num_args) { | |
104 case 0: | |
304 | 105 __ movptr(c_rarg1, src); |
0 | 106 _num_args++; |
107 break; | |
108 case 1: | |
304 | 109 __ movptr(c_rarg2, src); |
0 | 110 _num_args++; |
111 break; | |
112 case 2: | |
304 | 113 __ movptr(c_rarg3, src); |
0 | 114 _num_args++; |
115 break; | |
116 case 3: | |
117 default: | |
304 | 118 __ movptr(rax, src); |
119 __ movptr(Address(to(), _stack_offset), rax); | |
0 | 120 _stack_offset += wordSize; |
121 break; | |
122 } | |
123 #else | |
124 switch (_num_int_args) { | |
125 case 0: | |
304 | 126 __ movptr(c_rarg1, src); |
0 | 127 _num_int_args++; |
128 break; | |
129 case 1: | |
304 | 130 __ movptr(c_rarg2, src); |
0 | 131 _num_int_args++; |
132 break; | |
133 case 2: | |
304 | 134 __ movptr(c_rarg3, src); |
0 | 135 _num_int_args++; |
136 break; | |
137 case 3: | |
304 | 138 __ movptr(c_rarg4, src); |
0 | 139 _num_int_args++; |
140 break; | |
141 case 4: | |
304 | 142 __ movptr(c_rarg5, src); |
0 | 143 _num_int_args++; |
144 break; | |
145 default: | |
304 | 146 __ movptr(rax, src); |
147 __ movptr(Address(to(), _stack_offset), rax); | |
0 | 148 _stack_offset += wordSize; |
149 break; | |
150 } | |
151 #endif | |
152 } | |
153 | |
154 void InterpreterRuntime::SignatureHandlerGenerator::pass_float() { | |
155 const Address src(from(), Interpreter::local_offset_in_bytes(offset())); | |
156 | |
157 #ifdef _WIN64 | |
158 if (_num_args < Argument::n_float_register_parameters_c-1) { | |
159 __ movflt(as_XMMRegister(++_num_args), src); | |
160 } else { | |
161 __ movl(rax, src); | |
162 __ movl(Address(to(), _stack_offset), rax); | |
163 _stack_offset += wordSize; | |
164 } | |
165 #else | |
166 if (_num_fp_args < Argument::n_float_register_parameters_c) { | |
167 __ movflt(as_XMMRegister(_num_fp_args++), src); | |
168 } else { | |
169 __ movl(rax, src); | |
170 __ movl(Address(to(), _stack_offset), rax); | |
171 _stack_offset += wordSize; | |
172 } | |
173 #endif | |
174 } | |
175 | |
176 void InterpreterRuntime::SignatureHandlerGenerator::pass_double() { | |
177 const Address src(from(), Interpreter::local_offset_in_bytes(offset() + 1)); | |
178 | |
179 #ifdef _WIN64 | |
180 if (_num_args < Argument::n_float_register_parameters_c-1) { | |
181 __ movdbl(as_XMMRegister(++_num_args), src); | |
182 } else { | |
304 | 183 __ movptr(rax, src); |
184 __ movptr(Address(to(), _stack_offset), rax); | |
0 | 185 _stack_offset += wordSize; |
186 } | |
187 #else | |
188 if (_num_fp_args < Argument::n_float_register_parameters_c) { | |
189 __ movdbl(as_XMMRegister(_num_fp_args++), src); | |
190 } else { | |
304 | 191 __ movptr(rax, src); |
192 __ movptr(Address(to(), _stack_offset), rax); | |
0 | 193 _stack_offset += wordSize; |
194 } | |
195 #endif | |
196 } | |
197 | |
198 void InterpreterRuntime::SignatureHandlerGenerator::pass_object() { | |
199 const Address src(from(), Interpreter::local_offset_in_bytes(offset())); | |
200 | |
201 #ifdef _WIN64 | |
202 switch (_num_args) { | |
203 case 0: | |
204 assert(offset() == 0, "argument register 1 can only be (non-null) receiver"); | |
304 | 205 __ lea(c_rarg1, src); |
0 | 206 _num_args++; |
207 break; | |
208 case 1: | |
304 | 209 __ lea(rax, src); |
0 | 210 __ xorl(c_rarg2, c_rarg2); |
304 | 211 __ cmpptr(src, 0); |
212 __ cmov(Assembler::notEqual, c_rarg2, rax); | |
0 | 213 _num_args++; |
214 break; | |
215 case 2: | |
304 | 216 __ lea(rax, src); |
0 | 217 __ xorl(c_rarg3, c_rarg3); |
304 | 218 __ cmpptr(src, 0); |
219 __ cmov(Assembler::notEqual, c_rarg3, rax); | |
0 | 220 _num_args++; |
221 break; | |
222 default: | |
304 | 223 __ lea(rax, src); |
0 | 224 __ xorl(temp(), temp()); |
304 | 225 __ cmpptr(src, 0); |
226 __ cmov(Assembler::notEqual, temp(), rax); | |
227 __ movptr(Address(to(), _stack_offset), temp()); | |
0 | 228 _stack_offset += wordSize; |
229 break; | |
230 } | |
231 #else | |
232 switch (_num_int_args) { | |
233 case 0: | |
234 assert(offset() == 0, "argument register 1 can only be (non-null) receiver"); | |
304 | 235 __ lea(c_rarg1, src); |
0 | 236 _num_int_args++; |
237 break; | |
238 case 1: | |
304 | 239 __ lea(rax, src); |
0 | 240 __ xorl(c_rarg2, c_rarg2); |
304 | 241 __ cmpptr(src, 0); |
242 __ cmov(Assembler::notEqual, c_rarg2, rax); | |
0 | 243 _num_int_args++; |
244 break; | |
245 case 2: | |
304 | 246 __ lea(rax, src); |
0 | 247 __ xorl(c_rarg3, c_rarg3); |
304 | 248 __ cmpptr(src, 0); |
249 __ cmov(Assembler::notEqual, c_rarg3, rax); | |
0 | 250 _num_int_args++; |
251 break; | |
252 case 3: | |
304 | 253 __ lea(rax, src); |
0 | 254 __ xorl(c_rarg4, c_rarg4); |
304 | 255 __ cmpptr(src, 0); |
256 __ cmov(Assembler::notEqual, c_rarg4, rax); | |
0 | 257 _num_int_args++; |
258 break; | |
259 case 4: | |
304 | 260 __ lea(rax, src); |
0 | 261 __ xorl(c_rarg5, c_rarg5); |
304 | 262 __ cmpptr(src, 0); |
263 __ cmov(Assembler::notEqual, c_rarg5, rax); | |
0 | 264 _num_int_args++; |
265 break; | |
266 default: | |
304 | 267 __ lea(rax, src); |
0 | 268 __ xorl(temp(), temp()); |
304 | 269 __ cmpptr(src, 0); |
270 __ cmov(Assembler::notEqual, temp(), rax); | |
271 __ movptr(Address(to(), _stack_offset), temp()); | |
0 | 272 _stack_offset += wordSize; |
273 break; | |
274 } | |
275 #endif | |
276 } | |
277 | |
278 void InterpreterRuntime::SignatureHandlerGenerator::generate(uint64_t fingerprint) { | |
279 // generate code to handle arguments | |
280 iterate(fingerprint); | |
281 | |
282 // return result handler | |
283 __ lea(rax, ExternalAddress(Interpreter::result_handler(method()->result_type()))); | |
284 __ ret(0); | |
285 | |
286 __ flush(); | |
287 } | |
288 | |
289 | |
290 // Implementation of SignatureHandlerLibrary | |
291 | |
292 void SignatureHandlerLibrary::pd_set_handler(address handler) {} | |
293 | |
294 | |
295 #ifdef _WIN64 | |
296 class SlowSignatureHandler | |
297 : public NativeSignatureIterator { | |
298 private: | |
299 address _from; | |
300 intptr_t* _to; | |
301 intptr_t* _reg_args; | |
302 intptr_t* _fp_identifiers; | |
303 unsigned int _num_args; | |
304 | |
305 virtual void pass_int() | |
306 { | |
307 jint from_obj = *(jint *)(_from+Interpreter::local_offset_in_bytes(0)); | |
1506 | 308 _from -= Interpreter::stackElementSize; |
0 | 309 |
310 if (_num_args < Argument::n_int_register_parameters_c-1) { | |
311 *_reg_args++ = from_obj; | |
312 _num_args++; | |
313 } else { | |
314 *_to++ = from_obj; | |
315 } | |
316 } | |
317 | |
318 virtual void pass_long() | |
319 { | |
320 intptr_t from_obj = *(intptr_t*)(_from+Interpreter::local_offset_in_bytes(1)); | |
1506 | 321 _from -= 2*Interpreter::stackElementSize; |
0 | 322 |
323 if (_num_args < Argument::n_int_register_parameters_c-1) { | |
324 *_reg_args++ = from_obj; | |
325 _num_args++; | |
326 } else { | |
327 *_to++ = from_obj; | |
328 } | |
329 } | |
330 | |
331 virtual void pass_object() | |
332 { | |
333 intptr_t *from_addr = (intptr_t*)(_from + Interpreter::local_offset_in_bytes(0)); | |
1506 | 334 _from -= Interpreter::stackElementSize; |
0 | 335 if (_num_args < Argument::n_int_register_parameters_c-1) { |
336 *_reg_args++ = (*from_addr == 0) ? NULL : (intptr_t) from_addr; | |
337 _num_args++; | |
338 } else { | |
339 *_to++ = (*from_addr == 0) ? NULL : (intptr_t) from_addr; | |
340 } | |
341 } | |
342 | |
343 virtual void pass_float() | |
344 { | |
345 jint from_obj = *(jint *)(_from+Interpreter::local_offset_in_bytes(0)); | |
1506 | 346 _from -= Interpreter::stackElementSize; |
0 | 347 |
348 if (_num_args < Argument::n_float_register_parameters_c-1) { | |
349 *_reg_args++ = from_obj; | |
645
c3a720eefe82
6816308: Changes to allow builds with latest Windows SDK 6.1 on 64bit Windows 2003
kvn
parents:
337
diff
changeset
|
350 *_fp_identifiers |= (intptr_t)(0x01 << (_num_args*2)); // mark as float |
0 | 351 _num_args++; |
352 } else { | |
353 *_to++ = from_obj; | |
354 } | |
355 } | |
356 | |
357 virtual void pass_double() | |
358 { | |
359 intptr_t from_obj = *(intptr_t*)(_from+Interpreter::local_offset_in_bytes(1)); | |
1506 | 360 _from -= 2*Interpreter::stackElementSize; |
0 | 361 |
362 if (_num_args < Argument::n_float_register_parameters_c-1) { | |
363 *_reg_args++ = from_obj; | |
645
c3a720eefe82
6816308: Changes to allow builds with latest Windows SDK 6.1 on 64bit Windows 2003
kvn
parents:
337
diff
changeset
|
364 *_fp_identifiers |= (intptr_t)(0x3 << (_num_args*2)); // mark as double |
0 | 365 _num_args++; |
366 } else { | |
367 *_to++ = from_obj; | |
368 } | |
369 } | |
370 | |
371 public: | |
372 SlowSignatureHandler(methodHandle method, address from, intptr_t* to) | |
373 : NativeSignatureIterator(method) | |
374 { | |
375 _from = from; | |
376 _to = to; | |
377 | |
378 _reg_args = to - (method->is_static() ? 4 : 5); | |
379 _fp_identifiers = to - 2; | |
380 _to = _to + 4; // Windows reserves stack space for register arguments | |
381 *(int*) _fp_identifiers = 0; | |
382 _num_args = (method->is_static() ? 1 : 0); | |
383 } | |
384 }; | |
385 #else | |
386 class SlowSignatureHandler | |
387 : public NativeSignatureIterator { | |
388 private: | |
389 address _from; | |
390 intptr_t* _to; | |
391 intptr_t* _int_args; | |
392 intptr_t* _fp_args; | |
393 intptr_t* _fp_identifiers; | |
394 unsigned int _num_int_args; | |
395 unsigned int _num_fp_args; | |
396 | |
397 virtual void pass_int() | |
398 { | |
399 jint from_obj = *(jint *)(_from+Interpreter::local_offset_in_bytes(0)); | |
1506 | 400 _from -= Interpreter::stackElementSize; |
0 | 401 |
402 if (_num_int_args < Argument::n_int_register_parameters_c-1) { | |
403 *_int_args++ = from_obj; | |
404 _num_int_args++; | |
405 } else { | |
406 *_to++ = from_obj; | |
407 } | |
408 } | |
409 | |
410 virtual void pass_long() | |
411 { | |
412 intptr_t from_obj = *(intptr_t*)(_from+Interpreter::local_offset_in_bytes(1)); | |
1506 | 413 _from -= 2*Interpreter::stackElementSize; |
0 | 414 |
415 if (_num_int_args < Argument::n_int_register_parameters_c-1) { | |
416 *_int_args++ = from_obj; | |
417 _num_int_args++; | |
418 } else { | |
419 *_to++ = from_obj; | |
420 } | |
421 } | |
422 | |
423 virtual void pass_object() | |
424 { | |
425 intptr_t *from_addr = (intptr_t*)(_from + Interpreter::local_offset_in_bytes(0)); | |
1506 | 426 _from -= Interpreter::stackElementSize; |
0 | 427 |
428 if (_num_int_args < Argument::n_int_register_parameters_c-1) { | |
429 *_int_args++ = (*from_addr == 0) ? NULL : (intptr_t)from_addr; | |
430 _num_int_args++; | |
431 } else { | |
432 *_to++ = (*from_addr == 0) ? NULL : (intptr_t) from_addr; | |
433 } | |
434 } | |
435 | |
436 virtual void pass_float() | |
437 { | |
438 jint from_obj = *(jint*)(_from+Interpreter::local_offset_in_bytes(0)); | |
1506 | 439 _from -= Interpreter::stackElementSize; |
0 | 440 |
441 if (_num_fp_args < Argument::n_float_register_parameters_c) { | |
442 *_fp_args++ = from_obj; | |
443 _num_fp_args++; | |
444 } else { | |
445 *_to++ = from_obj; | |
446 } | |
447 } | |
448 | |
449 virtual void pass_double() | |
450 { | |
451 intptr_t from_obj = *(intptr_t*)(_from+Interpreter::local_offset_in_bytes(1)); | |
1506 | 452 _from -= 2*Interpreter::stackElementSize; |
0 | 453 |
454 if (_num_fp_args < Argument::n_float_register_parameters_c) { | |
455 *_fp_args++ = from_obj; | |
456 *_fp_identifiers |= (1 << _num_fp_args); // mark as double | |
457 _num_fp_args++; | |
458 } else { | |
459 *_to++ = from_obj; | |
460 } | |
461 } | |
462 | |
463 public: | |
464 SlowSignatureHandler(methodHandle method, address from, intptr_t* to) | |
465 : NativeSignatureIterator(method) | |
466 { | |
467 _from = from; | |
468 _to = to; | |
469 | |
470 _int_args = to - (method->is_static() ? 14 : 15); | |
471 _fp_args = to - 9; | |
472 _fp_identifiers = to - 10; | |
473 *(int*) _fp_identifiers = 0; | |
474 _num_int_args = (method->is_static() ? 1 : 0); | |
475 _num_fp_args = 0; | |
476 } | |
477 }; | |
478 #endif | |
479 | |
480 | |
481 IRT_ENTRY(address, | |
482 InterpreterRuntime::slow_signature_handler(JavaThread* thread, | |
483 methodOopDesc* method, | |
484 intptr_t* from, | |
485 intptr_t* to)) | |
486 methodHandle m(thread, (methodOop)method); | |
487 assert(m->is_native(), "sanity check"); | |
488 | |
489 // handle arguments | |
490 SlowSignatureHandler(m, (address)from, to + 1).iterate(UCONST64(-1)); | |
491 | |
492 // return result handler | |
493 return Interpreter::result_handler(m->result_type()); | |
494 IRT_END |