jdk

Форк
0
/
interpreterRT_x86_64.cpp 
511 строк · 13.4 Кб
1
/*
2
 * Copyright (c) 2003, 2022, Oracle and/or its affiliates. All rights reserved.
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
 *
19
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20
 * or visit www.oracle.com if you need additional information or have any
21
 * questions.
22
 *
23
 */
24

25
#include "precompiled.hpp"
26
#include "interpreter/interp_masm.hpp"
27
#include "interpreter/interpreter.hpp"
28
#include "interpreter/interpreterRuntime.hpp"
29
#include "memory/allocation.inline.hpp"
30
#include "oops/method.hpp"
31
#include "oops/oop.inline.hpp"
32
#include "runtime/handles.inline.hpp"
33
#include "runtime/icache.hpp"
34
#include "runtime/interfaceSupport.inline.hpp"
35
#include "runtime/signature.hpp"
36

37
#define __ _masm->
38

39
// Implementation of SignatureHandlerGenerator
40

41
InterpreterRuntime::SignatureHandlerGenerator::SignatureHandlerGenerator(const methodHandle& method, CodeBuffer* buffer) :
42
    NativeSignatureIterator(method) {
43
  _masm = new MacroAssembler(buffer);
44
#ifdef AMD64
45
#ifdef _WIN64
46
  _num_args = (method->is_static() ? 1 : 0);
47
  _stack_offset = (Argument::n_int_register_parameters_c+1)* wordSize; // don't overwrite return address
48
#else
49
  _num_int_args = (method->is_static() ? 1 : 0);
50
  _num_fp_args = 0;
51
  _stack_offset = wordSize; // don't overwrite return address
52
#endif // _WIN64
53
#endif // AMD64
54
}
55

56
Register InterpreterRuntime::SignatureHandlerGenerator::from() { return r14; }
57
Register InterpreterRuntime::SignatureHandlerGenerator::to()   { return rsp; }
58
Register InterpreterRuntime::SignatureHandlerGenerator::temp() { return rscratch1; }
59

60
void InterpreterRuntime::SignatureHandlerGenerator::pass_int() {
61
  const Address src(from(), Interpreter::local_offset_in_bytes(offset()));
62

63
#ifdef _WIN64
64
  switch (_num_args) {
65
  case 0:
66
    __ movl(c_rarg1, src);
67
    _num_args++;
68
    break;
69
  case 1:
70
    __ movl(c_rarg2, src);
71
    _num_args++;
72
    break;
73
  case 2:
74
    __ movl(c_rarg3, src);
75
    _num_args++;
76
    break;
77
  default:
78
    __ movl(rax, src);
79
    __ movl(Address(to(), _stack_offset), rax);
80
    _stack_offset += wordSize;
81
    break;
82
  }
83
#else
84
  switch (_num_int_args) {
85
  case 0:
86
    __ movl(c_rarg1, src);
87
    _num_int_args++;
88
    break;
89
  case 1:
90
    __ movl(c_rarg2, src);
91
    _num_int_args++;
92
    break;
93
  case 2:
94
    __ movl(c_rarg3, src);
95
    _num_int_args++;
96
    break;
97
  case 3:
98
    __ movl(c_rarg4, src);
99
    _num_int_args++;
100
    break;
101
  case 4:
102
    __ movl(c_rarg5, src);
103
    _num_int_args++;
104
    break;
105
  default:
106
    __ movl(rax, src);
107
    __ movl(Address(to(), _stack_offset), rax);
108
    _stack_offset += wordSize;
109
    break;
110
  }
111
#endif
112
}
113

114
void InterpreterRuntime::SignatureHandlerGenerator::pass_long() {
115
  const Address src(from(), Interpreter::local_offset_in_bytes(offset() + 1));
116

117
#ifdef _WIN64
118
  switch (_num_args) {
119
  case 0:
120
    __ movptr(c_rarg1, src);
121
    _num_args++;
122
    break;
123
  case 1:
124
    __ movptr(c_rarg2, src);
125
    _num_args++;
126
    break;
127
  case 2:
128
    __ movptr(c_rarg3, src);
129
    _num_args++;
130
    break;
131
  case 3:
132
  default:
133
    __ movptr(rax, src);
134
    __ movptr(Address(to(), _stack_offset), rax);
135
    _stack_offset += wordSize;
136
    break;
137
  }
138
#else
139
  switch (_num_int_args) {
140
  case 0:
141
    __ movptr(c_rarg1, src);
142
    _num_int_args++;
143
    break;
144
  case 1:
145
    __ movptr(c_rarg2, src);
146
    _num_int_args++;
147
    break;
148
  case 2:
149
    __ movptr(c_rarg3, src);
150
    _num_int_args++;
151
    break;
152
  case 3:
153
    __ movptr(c_rarg4, src);
154
    _num_int_args++;
155
    break;
156
  case 4:
157
    __ movptr(c_rarg5, src);
158
    _num_int_args++;
159
    break;
160
  default:
161
    __ movptr(rax, src);
162
    __ movptr(Address(to(), _stack_offset), rax);
163
    _stack_offset += wordSize;
164
    break;
165
  }
166
#endif
167
}
168

169
void InterpreterRuntime::SignatureHandlerGenerator::pass_float() {
170
  const Address src(from(), Interpreter::local_offset_in_bytes(offset()));
171

172
#ifdef _WIN64
173
  if (_num_args < Argument::n_float_register_parameters_c-1) {
174
    __ movflt(as_XMMRegister(++_num_args), src);
175
  } else {
176
    __ movl(rax, src);
177
    __ movl(Address(to(), _stack_offset), rax);
178
    _stack_offset += wordSize;
179
  }
180
#else
181
  if (_num_fp_args < Argument::n_float_register_parameters_c) {
182
    __ movflt(as_XMMRegister(_num_fp_args++), src);
183
  } else {
184
    __ movl(rax, src);
185
    __ movl(Address(to(), _stack_offset), rax);
186
    _stack_offset += wordSize;
187
  }
188
#endif
189
}
190

191
void InterpreterRuntime::SignatureHandlerGenerator::pass_double() {
192
  const Address src(from(), Interpreter::local_offset_in_bytes(offset() + 1));
193

194
#ifdef _WIN64
195
  if (_num_args < Argument::n_float_register_parameters_c-1) {
196
    __ movdbl(as_XMMRegister(++_num_args), src);
197
  } else {
198
    __ movptr(rax, src);
199
    __ movptr(Address(to(), _stack_offset), rax);
200
    _stack_offset += wordSize;
201
  }
202
#else
203
  if (_num_fp_args < Argument::n_float_register_parameters_c) {
204
    __ movdbl(as_XMMRegister(_num_fp_args++), src);
205
  } else {
206
    __ movptr(rax, src);
207
    __ movptr(Address(to(), _stack_offset), rax);
208
    _stack_offset += wordSize;
209
  }
210
#endif
211
}
212

213
void InterpreterRuntime::SignatureHandlerGenerator::pass_object() {
214
  const Address src(from(), Interpreter::local_offset_in_bytes(offset()));
215

216
#ifdef _WIN64
217
  switch (_num_args) {
218
  case 0:
219
    assert(offset() == 0, "argument register 1 can only be (non-null) receiver");
220
    __ lea(c_rarg1, src);
221
    _num_args++;
222
    break;
223
  case 1:
224
    __ lea(rax, src);
225
    __ xorl(c_rarg2, c_rarg2);
226
    __ cmpptr(src, 0);
227
    __ cmov(Assembler::notEqual, c_rarg2, rax);
228
    _num_args++;
229
    break;
230
  case 2:
231
    __ lea(rax, src);
232
    __ xorl(c_rarg3, c_rarg3);
233
    __ cmpptr(src, 0);
234
    __ cmov(Assembler::notEqual, c_rarg3, rax);
235
    _num_args++;
236
    break;
237
  default:
238
    __ lea(rax, src);
239
    __ xorl(temp(), temp());
240
    __ cmpptr(src, 0);
241
    __ cmov(Assembler::notEqual, temp(), rax);
242
    __ movptr(Address(to(), _stack_offset), temp());
243
    _stack_offset += wordSize;
244
    break;
245
  }
246
#else
247
  switch (_num_int_args) {
248
  case 0:
249
    assert(offset() == 0, "argument register 1 can only be (non-null) receiver");
250
    __ lea(c_rarg1, src);
251
    _num_int_args++;
252
    break;
253
  case 1:
254
    __ lea(rax, src);
255
    __ xorl(c_rarg2, c_rarg2);
256
    __ cmpptr(src, 0);
257
    __ cmov(Assembler::notEqual, c_rarg2, rax);
258
    _num_int_args++;
259
    break;
260
  case 2:
261
    __ lea(rax, src);
262
    __ xorl(c_rarg3, c_rarg3);
263
    __ cmpptr(src, 0);
264
    __ cmov(Assembler::notEqual, c_rarg3, rax);
265
    _num_int_args++;
266
    break;
267
  case 3:
268
    __ lea(rax, src);
269
    __ xorl(c_rarg4, c_rarg4);
270
    __ cmpptr(src, 0);
271
    __ cmov(Assembler::notEqual, c_rarg4, rax);
272
    _num_int_args++;
273
    break;
274
  case 4:
275
    __ lea(rax, src);
276
    __ xorl(c_rarg5, c_rarg5);
277
    __ cmpptr(src, 0);
278
    __ cmov(Assembler::notEqual, c_rarg5, rax);
279
    _num_int_args++;
280
    break;
281
  default:
282
    __ lea(rax, src);
283
    __ xorl(temp(), temp());
284
    __ cmpptr(src, 0);
285
    __ cmov(Assembler::notEqual, temp(), rax);
286
    __ movptr(Address(to(), _stack_offset), temp());
287
    _stack_offset += wordSize;
288
    break;
289
  }
290
#endif
291
}
292

293
void InterpreterRuntime::SignatureHandlerGenerator::generate(uint64_t fingerprint) {
294
  // generate code to handle arguments
295
  iterate(fingerprint);
296

297
  // return result handler
298
  __ lea(rax, ExternalAddress(Interpreter::result_handler(method()->result_type())));
299
  __ ret(0);
300

301
  __ flush();
302
}
303

304

305
// Implementation of SignatureHandlerLibrary
306

307
void SignatureHandlerLibrary::pd_set_handler(address handler) {}
308

309

310
#ifdef _WIN64
311
class SlowSignatureHandler
312
  : public NativeSignatureIterator {
313
 private:
314
  address   _from;
315
  intptr_t* _to;
316
  intptr_t* _reg_args;
317
  intptr_t* _fp_identifiers;
318
  unsigned int _num_args;
319

320
  virtual void pass_int()
321
  {
322
    jint from_obj = *(jint *)(_from+Interpreter::local_offset_in_bytes(0));
323
    _from -= Interpreter::stackElementSize;
324

325
    if (_num_args < Argument::n_int_register_parameters_c-1) {
326
      *_reg_args++ = from_obj;
327
      _num_args++;
328
    } else {
329
      *_to++ = from_obj;
330
    }
331
  }
332

333
  virtual void pass_long()
334
  {
335
    intptr_t from_obj = *(intptr_t*)(_from+Interpreter::local_offset_in_bytes(1));
336
    _from -= 2*Interpreter::stackElementSize;
337

338
    if (_num_args < Argument::n_int_register_parameters_c-1) {
339
      *_reg_args++ = from_obj;
340
      _num_args++;
341
    } else {
342
      *_to++ = from_obj;
343
    }
344
  }
345

346
  virtual void pass_object()
347
  {
348
    intptr_t *from_addr = (intptr_t*)(_from + Interpreter::local_offset_in_bytes(0));
349
    _from -= Interpreter::stackElementSize;
350
    if (_num_args < Argument::n_int_register_parameters_c-1) {
351
      *_reg_args++ = (*from_addr == 0) ? NULL_WORD : (intptr_t) from_addr;
352
      _num_args++;
353
    } else {
354
      *_to++ = (*from_addr == 0) ? NULL_WORD : (intptr_t) from_addr;
355
    }
356
  }
357

358
  virtual void pass_float()
359
  {
360
    jint from_obj = *(jint *)(_from+Interpreter::local_offset_in_bytes(0));
361
    _from -= Interpreter::stackElementSize;
362

363
    if (_num_args < Argument::n_float_register_parameters_c-1) {
364
      assert((_num_args*2) < BitsPerWord, "_num_args*2 is out of range");
365
      *_reg_args++ = from_obj;
366
      *_fp_identifiers |= ((intptr_t)0x01 << (_num_args*2)); // mark as float
367
      _num_args++;
368
    } else {
369
      *_to++ = from_obj;
370
    }
371
  }
372

373
  virtual void pass_double()
374
  {
375
    intptr_t from_obj = *(intptr_t*)(_from+Interpreter::local_offset_in_bytes(1));
376
    _from -= 2*Interpreter::stackElementSize;
377

378
    if (_num_args < Argument::n_float_register_parameters_c-1) {
379
      assert((_num_args*2) < BitsPerWord, "_num_args*2 is out of range");
380
      *_reg_args++ = from_obj;
381
      *_fp_identifiers |= ((intptr_t)0x3 << (_num_args*2)); // mark as double
382
      _num_args++;
383
    } else {
384
      *_to++ = from_obj;
385
    }
386
  }
387

388
 public:
389
  SlowSignatureHandler(const methodHandle& method, address from, intptr_t* to)
390
    : NativeSignatureIterator(method)
391
  {
392
    _from = from;
393
    _to   = to;
394

395
    _reg_args = to - (method->is_static() ? 4 : 5);
396
    _fp_identifiers = to - 2;
397
    _to = _to + 4;  // Windows reserves stack space for register arguments
398
    *(int*) _fp_identifiers = 0;
399
    _num_args = (method->is_static() ? 1 : 0);
400
  }
401
};
402
#else
403
class SlowSignatureHandler
404
  : public NativeSignatureIterator {
405
 private:
406
  address   _from;
407
  intptr_t* _to;
408
  intptr_t* _int_args;
409
  intptr_t* _fp_args;
410
  intptr_t* _fp_identifiers;
411
  unsigned int _num_int_args;
412
  unsigned int _num_fp_args;
413

414
  virtual void pass_int()
415
  {
416
    jint from_obj = *(jint *)(_from+Interpreter::local_offset_in_bytes(0));
417
    _from -= Interpreter::stackElementSize;
418

419
    if (_num_int_args < Argument::n_int_register_parameters_c-1) {
420
      *_int_args++ = from_obj;
421
      _num_int_args++;
422
    } else {
423
      *_to++ = from_obj;
424
    }
425
  }
426

427
  virtual void pass_long()
428
  {
429
    intptr_t from_obj = *(intptr_t*)(_from+Interpreter::local_offset_in_bytes(1));
430
    _from -= 2*Interpreter::stackElementSize;
431

432
    if (_num_int_args < Argument::n_int_register_parameters_c-1) {
433
      *_int_args++ = from_obj;
434
      _num_int_args++;
435
    } else {
436
      *_to++ = from_obj;
437
    }
438
  }
439

440
  virtual void pass_object()
441
  {
442
    intptr_t *from_addr = (intptr_t*)(_from + Interpreter::local_offset_in_bytes(0));
443
    _from -= Interpreter::stackElementSize;
444

445
    if (_num_int_args < Argument::n_int_register_parameters_c-1) {
446
      *_int_args++ = (*from_addr == 0) ? NULL_WORD : (intptr_t)from_addr;
447
      _num_int_args++;
448
    } else {
449
      *_to++ = (*from_addr == 0) ? NULL_WORD : (intptr_t) from_addr;
450
    }
451
  }
452

453
  virtual void pass_float()
454
  {
455
    jint from_obj = *(jint*)(_from+Interpreter::local_offset_in_bytes(0));
456
    _from -= Interpreter::stackElementSize;
457

458
    if (_num_fp_args < Argument::n_float_register_parameters_c) {
459
      *_fp_args++ = from_obj;
460
      _num_fp_args++;
461
    } else {
462
      *_to++ = from_obj;
463
    }
464
  }
465

466
  virtual void pass_double()
467
  {
468
    intptr_t from_obj = *(intptr_t*)(_from+Interpreter::local_offset_in_bytes(1));
469
    _from -= 2*Interpreter::stackElementSize;
470

471
    if (_num_fp_args < Argument::n_float_register_parameters_c) {
472
      *_fp_args++ = from_obj;
473
      *_fp_identifiers |= (1 << _num_fp_args); // mark as double
474
      _num_fp_args++;
475
    } else {
476
      *_to++ = from_obj;
477
    }
478
  }
479

480
 public:
481
  SlowSignatureHandler(const methodHandle& method, address from, intptr_t* to)
482
    : NativeSignatureIterator(method)
483
  {
484
    _from = from;
485
    _to   = to;
486

487
    _int_args = to - (method->is_static() ? 14 : 15);
488
    _fp_args =  to - 9;
489
    _fp_identifiers = to - 10;
490
    *(int*) _fp_identifiers = 0;
491
    _num_int_args = (method->is_static() ? 1 : 0);
492
    _num_fp_args = 0;
493
  }
494
};
495
#endif
496

497

498
JRT_ENTRY(address,
499
          InterpreterRuntime::slow_signature_handler(JavaThread* current,
500
                                                     Method* method,
501
                                                     intptr_t* from,
502
                                                     intptr_t* to))
503
  methodHandle m(current, (Method*)method);
504
  assert(m->is_native(), "sanity check");
505

506
  // handle arguments
507
  SlowSignatureHandler(m, (address)from, to + 1).iterate((uint64_t)CONST64(-1));
508

509
  // return result handler
510
  return Interpreter::result_handler(m->result_type());
511
JRT_END
512

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.