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/interpreter_aarch32.cpp
32285 views
1
/*
2
* Copyright (c) 2003, 2011, 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 "asm/macroAssembler.hpp"
29
#include "interp_masm_aarch32.hpp"
30
#include "interpreter/bytecodeHistogram.hpp"
31
#include "interpreter/interpreter.hpp"
32
#include "interpreter/interpreterGenerator.hpp"
33
#include "interpreter/interpreterRuntime.hpp"
34
#include "interpreter/templateTable.hpp"
35
#include "oops/arrayOop.hpp"
36
#include "oops/method.hpp"
37
#include "oops/methodData.hpp"
38
#include "oops/oop.inline.hpp"
39
#include "prims/jvmtiExport.hpp"
40
#include "prims/jvmtiThreadState.hpp"
41
#include "prims/methodHandles.hpp"
42
#include "runtime/arguments.hpp"
43
#include "runtime/deoptimization.hpp"
44
#include "runtime/frame.inline.hpp"
45
#include "runtime/sharedRuntime.hpp"
46
#include "runtime/stubRoutines.hpp"
47
#include "runtime/synchronizer.hpp"
48
#include "runtime/timer.hpp"
49
#include "runtime/vframeArray.hpp"
50
#include "utilities/debug.hpp"
51
#include "vm_version_aarch32.hpp"
52
#ifdef COMPILER1
53
#include "c1/c1_Runtime1.hpp"
54
#endif
55
56
#define __ _masm->
57
58
59
address AbstractInterpreterGenerator::generate_slow_signature_handler() {
60
address entry = __ pc();
61
62
// The sp should be aligned on entry to the bottom of where the integer args
63
// need to be copied to.
64
65
// rmethod
66
// rlocals
67
// c_rarg3: first stack arg - wordSize
68
69
__ mov(c_rarg3, sp);
70
__ sub(sp, sp, 22 * wordSize);
71
__ str(lr, sp);
72
__ call_VM(noreg,
73
CAST_FROM_FN_PTR(address,
74
InterpreterRuntime::slow_signature_handler),
75
rmethod, rlocals, c_rarg3);
76
77
// r0: result handler
78
79
// Stack layout:
80
// rsp: return address <- sp (lowest addr)
81
// 1 float/double identifiers with the following structure:
82
// 16 bit - 2 bits per word free/in use indication (0==in use)
83
// 8 bits - 1 bit per word, double/float indication (0==double)
84
// 4 integer args (if static first is unused)
85
// 8 double args (defined by ARM calling convention spec)
86
// stack args <- sp (on entry)
87
// garbage
88
// expression stack bottom
89
// bcp (NULL)
90
// ...
91
// If this changes, update interpreterRt_aarch32.cpp slowpath!
92
93
// Restore LR
94
__ ldr(lr, sp);
95
96
#ifdef HARD_FLOAT_CC
97
// Do FP first so we can use c_rarg3 as temp
98
__ ldr(c_rarg3, Address(sp, wordSize)); // float/double identifiers
99
100
{
101
Label fp_done;
102
// each iteration covers either single double register or up to 2 float registers
103
for (int i = 0; i < Argument::n_float_register_parameters_c; i++) {
104
Label d, done;
105
106
__ tst(c_rarg3, 1 << i+16);
107
__ b(d, __ EQ);
108
__ tst(c_rarg3, 1 << i*2);
109
__ b(fp_done, __ NE);
110
__ vldr_f32(as_FloatRegister(i*2), Address(sp, (6 + 2 * i) * wordSize));
111
__ tst(c_rarg3, 1 << i*2+1);
112
__ vldr_f32(as_FloatRegister(i*2+1), Address(sp, (7 + 2 * i) * wordSize), __ EQ);
113
__ b(done);
114
__ bind(d);
115
__ vldr_f64(as_DoubleFloatRegister(i), Address(sp, (6 + 2 * i) * wordSize));
116
__ bind(done);
117
}
118
__ bind(fp_done);
119
}
120
#endif // HARD_FLOAT_CC
121
122
// c_rarg0 contains the result from the call of
123
// InterpreterRuntime::slow_signature_handler so we don't touch it
124
// here. It will be loaded with the JNIEnv* later.
125
__ ldr(c_rarg1, Address(sp, 2 * wordSize));
126
__ ldrd(c_rarg2, c_rarg3, Address(sp, 3 * wordSize));
127
128
__ add(sp, sp, 22 * wordSize);
129
__ b(lr);
130
131
return entry;
132
}
133
134
135
//
136
// Various method entries
137
//
138
139
address InterpreterGenerator::generate_math_entry(AbstractInterpreter::MethodKind kind) {
140
// rmethod: Method*
141
// r4: sender sp
142
// sp: args
143
144
//if (!InlineIntrinsics) return NULL; // Generate a vanilla entry
145
// FIXME currently ignoring this flag and inlining anyway
146
147
// These don't need a safepoint check because they aren't virtually
148
// callable. We won't enter these intrinsics from compiled code.
149
// If in the future we added an intrinsic which was virtually callable
150
// we'd have to worry about how to safepoint so that this code is used.
151
152
// mathematical functions inlined by compiler
153
// (interpreter must provide identical implementation
154
// in order to avoid monotonicity bugs when switching
155
// from interpreter to compiler in the middle of some
156
// computation)
157
//
158
// stack:
159
// [ arg ] <-- sp
160
// [ arg ]
161
// retaddr in lr
162
163
address entry_point = NULL;
164
Register continuation = lr;
165
bool transcendental_entry = false;
166
167
switch (kind) {
168
case Interpreter::java_lang_math_abs:
169
entry_point = __ pc();
170
if(hasFPU()) {
171
__ vldr_f64(d0, Address(sp));
172
__ vabs_f64(d0, d0);
173
} else {
174
__ ldrd(r0, Address(sp));
175
transcendental_entry = true;
176
}
177
break;
178
case Interpreter::java_lang_math_sqrt:
179
entry_point = __ pc();
180
if(hasFPU()) {
181
__ vldr_f64(d0, Address(sp));
182
__ vsqrt_f64(d0, d0);
183
} else {
184
__ ldrd(r0, Address(sp));
185
transcendental_entry = true;
186
}
187
break;
188
case Interpreter::java_lang_math_sin :
189
case Interpreter::java_lang_math_cos :
190
case Interpreter::java_lang_math_tan :
191
case Interpreter::java_lang_math_log :
192
case Interpreter::java_lang_math_log10 :
193
case Interpreter::java_lang_math_exp :
194
entry_point = __ pc();
195
transcendental_entry = true;
196
#ifndef HARD_FLOAT_CC
197
__ ldrd(r0, Address(sp));
198
#else
199
__ vldr_f64(d0, Address(sp));
200
#endif //HARD_FLOAT_CC
201
break;
202
case Interpreter::java_lang_math_pow :
203
entry_point = __ pc();
204
transcendental_entry = true;
205
#ifndef HARD_FLOAT_CC
206
__ ldrd(r0, Address(sp, 2*Interpreter::stackElementSize));
207
__ ldrd(r2, Address(sp));
208
#else
209
__ vldr_f64(d0, Address(sp, 2*Interpreter::stackElementSize));
210
__ vldr_f64(d1, Address(sp));
211
#endif //HARD_FLOAT_CC
212
break;
213
default:
214
ShouldNotReachHere();
215
}
216
217
__ mov(sp, r4);
218
if(transcendental_entry) {
219
__ mov(r4, lr);
220
continuation = r4;
221
generate_transcendental_entry(kind);
222
#ifndef HARD_FLOAT_CC
223
if(hasFPU()) {
224
__ vmov_f64(d0, r0, r1);
225
}
226
#endif
227
}
228
229
if (entry_point) {
230
__ b(continuation);
231
}
232
233
return entry_point;
234
}
235
236
// double trigonometrics and transcendentals
237
// static jdouble dsin(jdouble x);
238
// static jdouble dcos(jdouble x);
239
// static jdouble dtan(jdouble x);
240
// static jdouble dlog(jdouble x);
241
// static jdouble dlog10(jdouble x);
242
// static jdouble dexp(jdouble x);
243
// static jdouble dpow(jdouble x, jdouble y);
244
245
void InterpreterGenerator::generate_transcendental_entry(AbstractInterpreter::MethodKind kind) {
246
address fn;
247
switch (kind) {
248
#ifdef __SOFTFP__
249
case Interpreter::java_lang_math_abs:
250
fn = CAST_FROM_FN_PTR(address, SharedRuntime::dabs);
251
break;
252
case Interpreter::java_lang_math_sqrt:
253
fn = CAST_FROM_FN_PTR(address, SharedRuntime::dsqrt);
254
break;
255
#endif //__SOFTFP__
256
case Interpreter::java_lang_math_sin :
257
fn = CAST_FROM_FN_PTR(address, SharedRuntime::dsin);
258
break;
259
case Interpreter::java_lang_math_cos :
260
fn = CAST_FROM_FN_PTR(address, SharedRuntime::dcos);
261
break;
262
case Interpreter::java_lang_math_tan :
263
fn = CAST_FROM_FN_PTR(address, SharedRuntime::dtan);
264
break;
265
case Interpreter::java_lang_math_log :
266
fn = CAST_FROM_FN_PTR(address, SharedRuntime::dlog);
267
break;
268
case Interpreter::java_lang_math_log10 :
269
fn = CAST_FROM_FN_PTR(address, SharedRuntime::dlog10);
270
break;
271
case Interpreter::java_lang_math_exp :
272
fn = CAST_FROM_FN_PTR(address, SharedRuntime::dexp);
273
break;
274
case Interpreter::java_lang_math_pow :
275
fn = CAST_FROM_FN_PTR(address, SharedRuntime::dpow);
276
break;
277
default:
278
ShouldNotReachHere();
279
}
280
__ align_stack();
281
__ mov(rscratch1, fn);
282
__ bl(rscratch1);
283
}
284
285
// Jump into normal path for accessor and empty entry to jump to normal entry
286
// The "fast" optimization don't update compilation count therefore can disable inlining
287
// for these functions that should be inlined.
288
address InterpreterGenerator::generate_jump_to_normal_entry(void) {
289
address entry_point = __ pc();
290
291
assert(Interpreter::entry_for_kind(Interpreter::zerolocals) != NULL, "should already be generated");
292
__ b(Interpreter::entry_for_kind(Interpreter::zerolocals));
293
return entry_point;
294
}
295
296
// Abstract method entry
297
// Attempt to execute abstract method. Throw exception
298
address InterpreterGenerator::generate_abstract_entry(void) {
299
// rmethod: Method*
300
// r13: sender SP
301
302
address entry_point = __ pc();
303
304
// abstract method entry
305
306
// pop return address, reset last_sp to NULL
307
__ empty_expression_stack();
308
__ restore_bcp(); // bcp must be correct for exception handler (was destroyed)
309
__ restore_locals(); // make sure locals pointer is correct as well (was destroyed)
310
311
// throw exception
312
__ call_VM(noreg, CAST_FROM_FN_PTR(address,
313
InterpreterRuntime::throw_AbstractMethodError));
314
// the call_VM checks for exception, so we should never return here.
315
__ should_not_reach_here();
316
317
return entry_point;
318
}
319
320
321
void Deoptimization::unwind_callee_save_values(frame* f, vframeArray* vframe_array) {
322
323
// This code is sort of the equivalent of C2IAdapter::setup_stack_frame back in
324
// the days we had adapter frames. When we deoptimize a situation where a
325
// compiled caller calls a compiled caller will have registers it expects
326
// to survive the call to the callee. If we deoptimize the callee the only
327
// way we can restore these registers is to have the oldest interpreter
328
// frame that we create restore these values. That is what this routine
329
// will accomplish.
330
331
// At the moment we have modified c2 to not have any callee save registers
332
// so this problem does not exist and this routine is just a place holder.
333
334
assert(f->is_interpreted_frame(), "must be interpreted");
335
}
336
337