Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/openjdk-multiarch-jdk8u
Path: blob/aarch64-shenandoah-jdk8u272-b10/hotspot/src/cpu/aarch32/vm/interpreterRT_aarch32.cpp
32285 views
1
/*
2
* Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
3
* Copyright (c) 2014, Red Hat Inc. All rights reserved.
4
* Copyright (c) 2015, Linaro Ltd. 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 "interpreter/interpreter.hpp"
29
#include "interpreter/interpreterRuntime.hpp"
30
#include "memory/allocation.inline.hpp"
31
#include "memory/universe.inline.hpp"
32
#include "oops/method.hpp"
33
#include "oops/oop.inline.hpp"
34
#include "runtime/handles.inline.hpp"
35
#include "runtime/icache.hpp"
36
#include "runtime/interfaceSupport.hpp"
37
#include "runtime/signature.hpp"
38
39
#define __ _masm->
40
41
/*#define print_copy(name, off) \
42
__ mov(rscratch1, (address)name);\
43
__ mov(rscratch2, off);\
44
__ reg_printf("%s copied from offset %p + %d\n", rscratch1, from(), rscratch2);*/
45
46
#define print_copy(name, off)
47
48
// Implementation of SignatureHandlerGenerator
49
Register InterpreterRuntime::SignatureHandlerGenerator::from() { return rlocals; }
50
Register InterpreterRuntime::SignatureHandlerGenerator::to() { return r4; }
51
Register InterpreterRuntime::SignatureHandlerGenerator::temp() { return rscratch1; }
52
53
void InterpreterRuntime::SignatureHandlerGenerator::pass_int() {
54
print_copy(__FUNCTION__, Interpreter::local_offset_in_bytes(offset()));
55
const Address src(from(), Interpreter::local_offset_in_bytes(offset()));
56
57
switch (_num_int_args) {
58
case 0:
59
__ ldr(c_rarg1, src);
60
_num_int_args++;
61
break;
62
case 1:
63
__ ldr(c_rarg2, src);
64
_num_int_args++;
65
break;
66
case 2:
67
__ ldr(c_rarg3, src);
68
_num_int_args++;
69
break;
70
default:
71
__ ldr(r0, src);
72
__ str(r0, Address(to(), _stack_offset));
73
_stack_offset += wordSize;
74
_num_int_args++;
75
break;
76
}
77
}
78
79
void InterpreterRuntime::SignatureHandlerGenerator::pass_long() {
80
print_copy(__FUNCTION__, Interpreter::local_offset_in_bytes(offset() + 1));
81
const Address src(from(), Interpreter::local_offset_in_bytes(offset() + 1));
82
// Needs to be aligned to even registers. Means also won't be split across
83
// registers and stack.
84
85
switch (_num_int_args) {
86
case 0:
87
case 1:
88
__ ldrd(c_rarg2, c_rarg3, src);
89
_num_int_args = 3; // force next args onto stack
90
break;
91
default:
92
__ ldrd(r0, temp(), src);
93
_stack_offset = (_stack_offset + 7) & ~7; // Align on 8-byte boundary
94
__ strd(r0, temp(), Address(to(), _stack_offset));
95
_stack_offset += 2 * wordSize;
96
_num_int_args += 2;
97
break;
98
}
99
}
100
101
#ifdef HARD_FLOAT_CC
102
void InterpreterRuntime::SignatureHandlerGenerator::pass_float() {
103
print_copy(__FUNCTION__, Interpreter::local_offset_in_bytes(offset()));
104
const Address src(from(), Interpreter::local_offset_in_bytes(offset()));
105
106
if (_fp_arg_mask & ((1 << Argument::n_float_register_parameters_c*2)-1)) {
107
unsigned index = __builtin_ctz(_fp_arg_mask);
108
__ vldr_f32(as_FloatRegister(index), src);
109
_fp_arg_mask &= ~(1 << index);
110
_next_double_dex += (~index) & 1;
111
} else {
112
__ ldr(r0, src);
113
__ str(r0, Address(to(), _stack_offset));
114
_stack_offset += wordSize;
115
}
116
}
117
118
void InterpreterRuntime::SignatureHandlerGenerator::pass_double() {
119
print_copy(__FUNCTION__, Interpreter::local_offset_in_bytes(offset() + 1));
120
const Address src(from(), Interpreter::local_offset_in_bytes(offset() + 1));
121
122
if (_next_double_dex < Argument::n_float_register_parameters_c) {
123
_fp_arg_mask &= ~((3 << _next_double_dex*2) | ((1 << _next_double_dex+16)));
124
__ vldr_f64(as_DoubleFloatRegister(_next_double_dex++), src);
125
} else {
126
// make future floats allocate on stack too
127
_fp_arg_mask &= ~((1 << Argument::n_float_register_parameters_c*2)-1);
128
129
__ ldrd(r0, temp(), src);
130
_stack_offset = (_stack_offset + 7) & ~7;
131
__ strd(r0, temp(), Address(to(), _stack_offset));
132
_stack_offset += 2 * wordSize;
133
}
134
}
135
#else
136
// Just pass them in integer registers and on the stack as we would
137
// any other argument
138
void InterpreterRuntime::SignatureHandlerGenerator::pass_float() {
139
pass_int();
140
}
141
142
void InterpreterRuntime::SignatureHandlerGenerator::pass_double() {
143
pass_long();
144
}
145
#endif //HARD_FLOAT_CC
146
147
void InterpreterRuntime::SignatureHandlerGenerator::pass_object() {
148
print_copy(__FUNCTION__, Interpreter::local_offset_in_bytes(offset()));
149
150
switch (_num_int_args) {
151
case 0:
152
assert(offset() == 0, "argument register 1 can only be (non-null) receiver");
153
__ add(c_rarg1, from(), Interpreter::local_offset_in_bytes(offset()));
154
_num_int_args++;
155
break;
156
case 1:
157
{
158
__ add(r0, from(), Interpreter::local_offset_in_bytes(offset()));
159
__ mov(c_rarg2, 0);
160
__ ldr(temp(), r0);
161
Label L;
162
__ cbz(temp(), L);
163
__ mov(c_rarg2, r0);
164
__ bind(L);
165
_num_int_args++;
166
break;
167
}
168
case 2:
169
{
170
__ add(r0, from(), Interpreter::local_offset_in_bytes(offset()));
171
__ mov(c_rarg3, 0);
172
__ ldr(temp(), r0);
173
Label L;
174
__ cbz(temp(), L);
175
__ mov(c_rarg3, r0);
176
__ bind(L);
177
_num_int_args++;
178
break;
179
}
180
default:
181
{
182
__ add(r0, from(), Interpreter::local_offset_in_bytes(offset()));
183
__ ldr(temp(), r0);
184
Label L;
185
__ cbnz(temp(), L);
186
__ mov(r0, 0);
187
__ bind(L);
188
__ str(r0, Address(to(), _stack_offset));
189
_stack_offset += wordSize;
190
_num_int_args++;
191
break;
192
}
193
}
194
}
195
196
void InterpreterRuntime::SignatureHandlerGenerator::generate(uint64_t fingerprint) {
197
// generate code to handle arguments
198
iterate(fingerprint);
199
200
// return result handler
201
__ lea(r0, ExternalAddress(Interpreter::result_handler(method()->result_type())));
202
__ b(lr);
203
204
__ flush();
205
}
206
207
208
// Implementation of SignatureHandlerLibrary
209
210
void SignatureHandlerLibrary::pd_set_handler(address handler) {}
211
212
213
class SlowSignatureHandler : public NativeSignatureIterator {
214
private:
215
address _from;
216
intptr_t* _to;
217
intptr_t* _int_args;
218
intptr_t* _fp_args;
219
intptr_t* _fp_identifiers;
220
221
int _num_int_reg_args;
222
int _next_double_dex;
223
224
virtual void pass_int()
225
{
226
jint from_obj = *(jint *)(_from+Interpreter::local_offset_in_bytes(0));
227
_from -= Interpreter::stackElementSize;
228
229
if (_num_int_reg_args < Argument::n_int_register_parameters_c-1) {
230
*_int_args++ = from_obj;
231
_num_int_reg_args++;
232
} else {
233
*_to++ = from_obj;
234
}
235
}
236
237
virtual void pass_long()
238
{
239
intptr_t high_obj = *(intptr_t*)(_from+Interpreter::local_offset_in_bytes(0));
240
intptr_t low_obj = *(intptr_t*)(_from+Interpreter::local_offset_in_bytes(1));
241
_from -= 2*Interpreter::stackElementSize;
242
243
if (_num_int_reg_args < Argument::n_int_register_parameters_c-2) {
244
// Passing longs. As c_rarg0 is always reserved for jni_env we could only
245
// possibly stash a long in r3:r2 due to alignment so we can only enter here
246
// with either zero or one parameters.
247
// Align to two
248
_int_args += 1 - _num_int_reg_args; // 0 or 1
249
*_int_args++ = low_obj;
250
*_int_args++ = high_obj;
251
_num_int_reg_args = 3;
252
} else {
253
_to = (intptr_t*)(((intptr_t)_to + 7) & ~7); // Align to eight bytes
254
*_to++ = low_obj;
255
*_to++ = high_obj;
256
_num_int_reg_args = 3;
257
}
258
}
259
260
virtual void pass_object()
261
{
262
intptr_t *from_addr = (intptr_t*)(_from + Interpreter::local_offset_in_bytes(0));
263
_from -= Interpreter::stackElementSize;
264
265
if (_num_int_reg_args < Argument::n_int_register_parameters_c-1) {
266
*_int_args++ = (*from_addr == 0) ? NULL : (intptr_t)from_addr;
267
_num_int_reg_args++;
268
} else {
269
*_to++ = (*from_addr == 0) ? NULL : (intptr_t) from_addr;
270
}
271
}
272
#ifdef HARD_FLOAT_CC
273
virtual void pass_float()
274
{
275
jint from_obj = *(jint*)(_from+Interpreter::local_offset_in_bytes(0));
276
_from -= Interpreter::stackElementSize;
277
278
if ((*_fp_identifiers) & 0xffff) {
279
unsigned index = __builtin_ctz(*_fp_identifiers);
280
_fp_args[index] = from_obj;
281
*_fp_identifiers ^= 1 << index;
282
_next_double_dex += (~index) & 1;
283
} else {
284
*_to++ = from_obj;
285
}
286
}
287
288
virtual void pass_double()
289
{
290
intptr_t high_obj = *(intptr_t*)(_from+Interpreter::local_offset_in_bytes(0));
291
intptr_t low_obj = *(intptr_t*)(_from+Interpreter::local_offset_in_bytes(1));
292
_from -= 2*Interpreter::stackElementSize;
293
294
if (_next_double_dex < Argument::n_float_register_parameters_c) {
295
//We can allocate to a register.
296
int index = _next_double_dex++;
297
*_fp_identifiers &= ~((3 << index*2) | (1 << index+16));
298
_fp_args[index*2] = low_obj;
299
_fp_args[index*2 + 1] = high_obj;
300
} else {
301
*_fp_identifiers &= ~0xffff; // make future floats allocate on stack too
302
_to = (intptr_t*)(((intptr_t)_to + 7) & ~7); // Align to eight bytes
303
*_to++ = low_obj;
304
*_to++ = high_obj;
305
}
306
}
307
#else
308
virtual void pass_float() { pass_int(); }
309
virtual void pass_double() { pass_long(); }
310
#endif // HARD_FLOAT_CC
311
312
public:
313
SlowSignatureHandler(methodHandle method, address from, intptr_t* to)
314
: NativeSignatureIterator(method)
315
{
316
_from = from;
317
_to = to;
318
// See layout in interpreter_aarch32.cpp
319
_int_args = to - (method->is_static() ? 19 : 20);
320
_fp_args = to - 16; //each slot is for a double
321
_fp_identifiers = to - 21;
322
*_fp_identifiers = (1 <<(Argument::n_float_register_parameters_c * 3)) - 1;
323
324
_num_int_reg_args = (method->is_static() ? 1 : 0);
325
_next_double_dex = 0;
326
}
327
};
328
329
330
IRT_ENTRY(address,
331
InterpreterRuntime::slow_signature_handler(JavaThread* thread,
332
Method* method,
333
intptr_t* from,
334
intptr_t* to))
335
methodHandle m(thread, (Method*)method);
336
assert(m->is_native(), "sanity check");
337
338
// handle arguments
339
SlowSignatureHandler ssh(m, (address)from, to);
340
ssh.iterate(UCONST64(-1));
341
342
// return result handler
343
return Interpreter::result_handler(m->result_type());
344
IRT_END
345
346