jdk

Форк
0
/
interpreterRT_aarch64.cpp 
325 строк · 9.4 Кб
1
/*
2
 * Copyright (c) 2003, 2023, Oracle and/or its affiliates. All rights reserved.
3
 * Copyright (c) 2014, 2020, Red Hat Inc. All rights reserved.
4
 * Copyright (c) 2021, Azul Systems, Inc. All rights reserved.
5
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
6
 *
7
 * This code is free software; you can redistribute it and/or modify it
8
 * under the terms of the GNU General Public License version 2 only, as
9
 * published by the Free Software Foundation.
10
 *
11
 * This code is distributed in the hope that it will be useful, but WITHOUT
12
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14
 * version 2 for more details (a copy is included in the LICENSE file that
15
 * accompanied this code).
16
 *
17
 * You should have received a copy of the GNU General Public License version
18
 * 2 along with this work; if not, write to the Free Software Foundation,
19
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20
 *
21
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22
 * or visit www.oracle.com if you need additional information or have any
23
 * questions.
24
 *
25
 */
26

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

40
#define __ _masm->
41

42
// Implementation of SignatureHandlerGenerator
43
Register InterpreterRuntime::SignatureHandlerGenerator::from() { return rlocals; }
44
Register InterpreterRuntime::SignatureHandlerGenerator::to()   { return sp; }
45
Register InterpreterRuntime::SignatureHandlerGenerator::temp() { return rscratch1; }
46

47
Register InterpreterRuntime::SignatureHandlerGenerator::next_gpr() {
48
  if (_num_reg_int_args < Argument::n_int_register_parameters_c-1) {
49
    return as_Register(_num_reg_int_args++ + c_rarg1->encoding());
50
  }
51
  return noreg;
52
}
53

54
FloatRegister InterpreterRuntime::SignatureHandlerGenerator::next_fpr() {
55
  if (_num_reg_fp_args < Argument::n_float_register_parameters_c) {
56
    return as_FloatRegister(_num_reg_fp_args++);
57
  }
58
  return fnoreg;
59
}
60

61
// On macos/aarch64 native stack is packed, int/float are using only 4 bytes
62
// on stack. Natural alignment for types are still in place,
63
// for example double/long should be 8 bytes aligned.
64

65
int InterpreterRuntime::SignatureHandlerGenerator::next_stack_offset(unsigned elem_size) {
66
  MACOS_ONLY(_stack_offset = align_up(_stack_offset, elem_size));
67
  int ret = _stack_offset;
68
  _stack_offset += NOT_MACOS(wordSize) MACOS_ONLY(elem_size);
69
  return ret;
70
}
71

72
InterpreterRuntime::SignatureHandlerGenerator::SignatureHandlerGenerator(
73
      const methodHandle& method, CodeBuffer* buffer) : NativeSignatureIterator(method) {
74
  _masm = new MacroAssembler(buffer);
75
  _num_reg_int_args = (method->is_static() ? 1 : 0);
76
  _num_reg_fp_args = 0;
77
  _stack_offset = 0;
78
}
79

80
void InterpreterRuntime::SignatureHandlerGenerator::pass_byte() {
81
  const Address src(from(), Interpreter::local_offset_in_bytes(offset()));
82

83
  Register reg = next_gpr();
84
  if (reg != noreg) {
85
    __ ldr(reg, src);
86
  } else {
87
    __ ldrb(r0, src);
88
    __ strb(r0, Address(to(), next_stack_offset(sizeof(jbyte))));
89
  }
90
}
91

92
void InterpreterRuntime::SignatureHandlerGenerator::pass_short() {
93
  const Address src(from(), Interpreter::local_offset_in_bytes(offset()));
94

95
  Register reg = next_gpr();
96
  if (reg != noreg) {
97
    __ ldr(reg, src);
98
  } else {
99
    __ ldrh(r0, src);
100
    __ strh(r0, Address(to(), next_stack_offset(sizeof(jshort))));
101
  }
102
}
103

104
void InterpreterRuntime::SignatureHandlerGenerator::pass_int() {
105
  const Address src(from(), Interpreter::local_offset_in_bytes(offset()));
106

107
  Register reg = next_gpr();
108
  if (reg != noreg) {
109
    __ ldr(reg, src);
110
  } else {
111
    __ ldrw(r0, src);
112
    __ strw(r0, Address(to(), next_stack_offset(sizeof(jint))));
113
  }
114
}
115

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

119
  Register reg = next_gpr();
120
  if (reg != noreg) {
121
    __ ldr(reg, src);
122
  } else {
123
    __ ldr(r0, src);
124
    __ str(r0, Address(to(), next_stack_offset(sizeof(jlong))));
125
  }
126
}
127

128
void InterpreterRuntime::SignatureHandlerGenerator::pass_float() {
129
  const Address src(from(), Interpreter::local_offset_in_bytes(offset()));
130

131
  FloatRegister reg = next_fpr();
132
  if (reg != fnoreg) {
133
    __ ldrs(reg, src);
134
  } else {
135
    __ ldrw(r0, src);
136
    __ strw(r0, Address(to(), next_stack_offset(sizeof(jfloat))));
137
  }
138
}
139

140
void InterpreterRuntime::SignatureHandlerGenerator::pass_double() {
141
  const Address src(from(), Interpreter::local_offset_in_bytes(offset() + 1));
142

143
  FloatRegister reg = next_fpr();
144
  if (reg != fnoreg) {
145
    __ ldrd(reg, src);
146
  } else {
147
    __ ldr(r0, src);
148
    __ str(r0, Address(to(), next_stack_offset(sizeof(jdouble))));
149
  }
150
}
151

152
void InterpreterRuntime::SignatureHandlerGenerator::pass_object() {
153
  Register reg = next_gpr();
154
  if (reg == c_rarg1) {
155
    assert(offset() == 0, "argument register 1 can only be (non-null) receiver");
156
    __ add(c_rarg1, from(), Interpreter::local_offset_in_bytes(offset()));
157
  } else if (reg != noreg) {
158
    __ add(r0, from(), Interpreter::local_offset_in_bytes(offset()));
159
    __ mov(reg, 0);
160
    __ ldr(temp(), r0);
161
    Label L;
162
    __ cbz(temp(), L);
163
    __ mov(reg, r0);
164
    __ bind(L);
165
  } else {
166
    __ add(r0, from(), Interpreter::local_offset_in_bytes(offset()));
167
    __ ldr(temp(), r0);
168
    Label L;
169
    __ cbnz(temp(), L);
170
    __ mov(r0, zr);
171
    __ bind(L);
172
    static_assert(sizeof(jobject) == wordSize, "");
173
    __ str(r0, Address(to(), next_stack_offset(sizeof(jobject))));
174
  }
175
}
176

177
void InterpreterRuntime::SignatureHandlerGenerator::generate(uint64_t fingerprint) {
178
  // generate code to handle arguments
179
  iterate(fingerprint);
180

181
  // return result handler
182
  __ lea(r0, ExternalAddress(Interpreter::result_handler(method()->result_type())));
183
  __ ret(lr);
184

185
  __ flush();
186
}
187

188

189
// Implementation of SignatureHandlerLibrary
190

191
void SignatureHandlerLibrary::pd_set_handler(address handler) {}
192

193

194
class SlowSignatureHandler
195
  : public NativeSignatureIterator {
196
 private:
197
  address   _from;
198
  char*     _to;
199
  intptr_t* _int_args;
200
  intptr_t* _fp_args;
201
  intptr_t* _fp_identifiers;
202
  unsigned int _num_reg_int_args;
203
  unsigned int _num_reg_fp_args;
204

205
  intptr_t* single_slot_addr() {
206
    intptr_t* from_addr = (intptr_t*)(_from+Interpreter::local_offset_in_bytes(0));
207
    _from -= Interpreter::stackElementSize;
208
    return from_addr;
209
  }
210

211
  intptr_t* double_slot_addr() {
212
    intptr_t* from_addr = (intptr_t*)(_from+Interpreter::local_offset_in_bytes(1));
213
    _from -= 2*Interpreter::stackElementSize;
214
    return from_addr;
215
  }
216

217
  int pass_gpr(intptr_t value) {
218
    if (_num_reg_int_args < Argument::n_int_register_parameters_c-1) {
219
      *_int_args++ = value;
220
      return _num_reg_int_args++;
221
    }
222
    return -1;
223
  }
224

225
  int pass_fpr(intptr_t value) {
226
    if (_num_reg_fp_args < Argument::n_float_register_parameters_c) {
227
      *_fp_args++ = value;
228
      return _num_reg_fp_args++;
229
    }
230
    return -1;
231
  }
232

233
  template<typename T>
234
  void pass_stack(T value) {
235
    MACOS_ONLY(_to = align_up(_to, sizeof(value)));
236
    *(T *)_to = value;
237
    _to += NOT_MACOS(wordSize) MACOS_ONLY(sizeof(value));
238
  }
239

240
  virtual void pass_byte() {
241
    jbyte value = *(jbyte*)single_slot_addr();
242
    if (pass_gpr(value) < 0) {
243
      pass_stack<>(value);
244
    }
245
  }
246

247
  virtual void pass_short() {
248
    jshort value = *(jshort*)single_slot_addr();
249
    if (pass_gpr(value) < 0) {
250
      pass_stack<>(value);
251
    }
252
  }
253

254
  virtual void pass_int() {
255
    jint value = *(jint*)single_slot_addr();
256
    if (pass_gpr(value) < 0) {
257
      pass_stack<>(value);
258
    }
259
  }
260

261
  virtual void pass_long() {
262
    intptr_t value = *double_slot_addr();
263
    if (pass_gpr(value) < 0) {
264
      pass_stack<>(value);
265
    }
266
  }
267

268
  virtual void pass_object() {
269
    intptr_t* addr = single_slot_addr();
270
    intptr_t value = *addr == 0 ? (intptr_t)0 : (intptr_t)addr;
271
    if (pass_gpr(value) < 0) {
272
      pass_stack<>(value);
273
    }
274
  }
275

276
  virtual void pass_float() {
277
    jint value = *(jint*)single_slot_addr();
278
    if (pass_fpr(value) < 0) {
279
      pass_stack<>(value);
280
    }
281
  }
282

283
  virtual void pass_double() {
284
    intptr_t value = *double_slot_addr();
285
    int arg = pass_fpr(value);
286
    if (0 <= arg) {
287
      *_fp_identifiers |= (1ull << arg); // mark as double
288
    } else {
289
      pass_stack<>(value);
290
    }
291
  }
292

293
 public:
294
  SlowSignatureHandler(const methodHandle& method, address from, intptr_t* to)
295
    : NativeSignatureIterator(method)
296
  {
297
    _from = from;
298
    _to   = (char *)to;
299

300
    _int_args = to - (method->is_static() ? 16 : 17);
301
    _fp_args =  to - 8;
302
    _fp_identifiers = to - 9;
303
    *(int*) _fp_identifiers = 0;
304
    _num_reg_int_args = (method->is_static() ? 1 : 0);
305
    _num_reg_fp_args = 0;
306
  }
307

308
};
309

310

311
JRT_ENTRY(address,
312
          InterpreterRuntime::slow_signature_handler(JavaThread* current,
313
                                                     Method* method,
314
                                                     intptr_t* from,
315
                                                     intptr_t* to))
316
  methodHandle m(current, (Method*)method);
317
  assert(m->is_native(), "sanity check");
318

319
  // handle arguments
320
  SlowSignatureHandler ssh(m, (address)from, to);
321
  ssh.iterate((uint64_t)CONST64(-1));
322

323
  // return result handler
324
  return Interpreter::result_handler(m->result_type());
325
JRT_END
326

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

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

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

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