Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mobile
Path: blob/master/src/hotspot/share/interpreter/templateInterpreterGenerator.cpp
40949 views
1
/*
2
* Copyright (c) 1997, 2021, 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 "compiler/disassembler.hpp"
27
#include "interpreter/interpreter.hpp"
28
#include "interpreter/interpreterRuntime.hpp"
29
#include "interpreter/interp_masm.hpp"
30
#include "interpreter/templateInterpreter.hpp"
31
#include "interpreter/templateInterpreterGenerator.hpp"
32
#include "interpreter/templateTable.hpp"
33
#include "oops/methodData.hpp"
34
35
#define __ Disassembler::hook<InterpreterMacroAssembler>(__FILE__, __LINE__, _masm)->
36
37
TemplateInterpreterGenerator::TemplateInterpreterGenerator(StubQueue* _code): AbstractInterpreterGenerator(_code) {
38
_unimplemented_bytecode = NULL;
39
_illegal_bytecode_sequence = NULL;
40
generate_all();
41
}
42
43
static const BasicType types[Interpreter::number_of_result_handlers] = {
44
T_BOOLEAN,
45
T_CHAR ,
46
T_BYTE ,
47
T_SHORT ,
48
T_INT ,
49
T_LONG ,
50
T_VOID ,
51
T_FLOAT ,
52
T_DOUBLE ,
53
T_OBJECT
54
};
55
56
void TemplateInterpreterGenerator::generate_all() {
57
{ CodeletMark cm(_masm, "slow signature handler");
58
AbstractInterpreter::_slow_signature_handler = generate_slow_signature_handler();
59
}
60
61
{ CodeletMark cm(_masm, "error exits");
62
_unimplemented_bytecode = generate_error_exit("unimplemented bytecode");
63
_illegal_bytecode_sequence = generate_error_exit("illegal bytecode sequence - method not verified");
64
}
65
66
#ifndef PRODUCT
67
if (TraceBytecodes) {
68
CodeletMark cm(_masm, "bytecode tracing support");
69
Interpreter::_trace_code =
70
EntryPoint(
71
generate_trace_code(atos),
72
generate_trace_code(itos),
73
generate_trace_code(ltos),
74
generate_trace_code(ftos),
75
generate_trace_code(dtos),
76
generate_trace_code(vtos)
77
);
78
}
79
#endif // !PRODUCT
80
81
{ CodeletMark cm(_masm, "return entry points");
82
Interpreter::_return_entry[0] = EntryPoint();
83
for (int i = 1; i < Interpreter::number_of_return_entries; i++) {
84
Interpreter::_return_entry[i] =
85
EntryPoint(
86
generate_return_entry_for(atos, i, sizeof(u2)),
87
generate_return_entry_for(itos, i, sizeof(u2)),
88
generate_return_entry_for(ltos, i, sizeof(u2)),
89
generate_return_entry_for(ftos, i, sizeof(u2)),
90
generate_return_entry_for(dtos, i, sizeof(u2)),
91
generate_return_entry_for(vtos, i, sizeof(u2))
92
);
93
}
94
}
95
96
{ CodeletMark cm(_masm, "invoke return entry points");
97
// These states are in order specified in TosState, except btos/ztos/ctos/stos which
98
// are the same as itos since there is no top of stack optimization for these types
99
const TosState states[] = {ilgl, ilgl, ilgl, ilgl, itos, ltos, ftos, dtos, atos, vtos, ilgl};
100
const int invoke_length = Bytecodes::length_for(Bytecodes::_invokestatic);
101
const int invokeinterface_length = Bytecodes::length_for(Bytecodes::_invokeinterface);
102
const int invokedynamic_length = Bytecodes::length_for(Bytecodes::_invokedynamic);
103
104
assert(invoke_length >= 0 && invoke_length < Interpreter::number_of_return_entries, "invariant");
105
assert(invokeinterface_length >= 0 && invokeinterface_length < Interpreter::number_of_return_entries, "invariant");
106
107
for (int i = itos; i < Interpreter::number_of_return_addrs; i++) {
108
TosState state = states[i];
109
assert(state != ilgl, "states array is wrong above");
110
111
// Reuse generated entry points
112
Interpreter::_invoke_return_entry[i] = Interpreter::_return_entry[invoke_length].entry(state);
113
Interpreter::_invokeinterface_return_entry[i] = Interpreter::_return_entry[invokeinterface_length].entry(state);
114
115
Interpreter::_invokedynamic_return_entry[i] = generate_return_entry_for(state, invokedynamic_length, sizeof(u4));
116
}
117
118
// set itos entry points for btos/ztos/ctos/stos
119
for (int i = 0; i < itos; i++) {
120
Interpreter::_invoke_return_entry[i] = Interpreter::_invoke_return_entry[itos];
121
Interpreter::_invokeinterface_return_entry[i] = Interpreter::_invokeinterface_return_entry[itos];
122
Interpreter::_invokedynamic_return_entry[i] = Interpreter::_invokedynamic_return_entry[itos];
123
}
124
}
125
126
{ CodeletMark cm(_masm, "earlyret entry points");
127
Interpreter::_earlyret_entry =
128
EntryPoint(
129
generate_earlyret_entry_for(atos),
130
generate_earlyret_entry_for(itos),
131
generate_earlyret_entry_for(ltos),
132
generate_earlyret_entry_for(ftos),
133
generate_earlyret_entry_for(dtos),
134
generate_earlyret_entry_for(vtos)
135
);
136
}
137
138
{ CodeletMark cm(_masm, "result handlers for native calls");
139
// The various result converter stublets.
140
int is_generated[Interpreter::number_of_result_handlers];
141
memset(is_generated, 0, sizeof(is_generated));
142
143
for (int i = 0; i < Interpreter::number_of_result_handlers; i++) {
144
BasicType type = types[i];
145
if (!is_generated[Interpreter::BasicType_as_index(type)]++) {
146
Interpreter::_native_abi_to_tosca[Interpreter::BasicType_as_index(type)] = generate_result_handler_for(type);
147
}
148
}
149
}
150
151
152
{ CodeletMark cm(_masm, "safepoint entry points");
153
Interpreter::_safept_entry =
154
EntryPoint(
155
generate_safept_entry_for(atos, CAST_FROM_FN_PTR(address, InterpreterRuntime::at_safepoint)),
156
generate_safept_entry_for(itos, CAST_FROM_FN_PTR(address, InterpreterRuntime::at_safepoint)),
157
generate_safept_entry_for(ltos, CAST_FROM_FN_PTR(address, InterpreterRuntime::at_safepoint)),
158
generate_safept_entry_for(ftos, CAST_FROM_FN_PTR(address, InterpreterRuntime::at_safepoint)),
159
generate_safept_entry_for(dtos, CAST_FROM_FN_PTR(address, InterpreterRuntime::at_safepoint)),
160
generate_safept_entry_for(vtos, CAST_FROM_FN_PTR(address, InterpreterRuntime::at_safepoint))
161
);
162
}
163
164
{ CodeletMark cm(_masm, "exception handling");
165
// (Note: this is not safepoint safe because thread may return to compiled code)
166
generate_throw_exception();
167
}
168
169
{ CodeletMark cm(_masm, "throw exception entrypoints");
170
Interpreter::_throw_ArrayIndexOutOfBoundsException_entry = generate_ArrayIndexOutOfBounds_handler();
171
Interpreter::_throw_ArrayStoreException_entry = generate_klass_exception_handler("java/lang/ArrayStoreException");
172
Interpreter::_throw_ArithmeticException_entry = generate_exception_handler("java/lang/ArithmeticException", "/ by zero");
173
Interpreter::_throw_ClassCastException_entry = generate_ClassCastException_handler();
174
Interpreter::_throw_NullPointerException_entry = generate_exception_handler("java/lang/NullPointerException", NULL);
175
Interpreter::_throw_StackOverflowError_entry = generate_StackOverflowError_handler();
176
}
177
178
179
180
#define method_entry(kind) \
181
{ CodeletMark cm(_masm, "method entry point (kind = " #kind ")"); \
182
Interpreter::_entry_table[Interpreter::kind] = generate_method_entry(Interpreter::kind); \
183
}
184
185
// all non-native method kinds
186
method_entry(zerolocals)
187
method_entry(zerolocals_synchronized)
188
method_entry(empty)
189
method_entry(getter)
190
method_entry(setter)
191
method_entry(abstract)
192
method_entry(java_lang_math_sin )
193
method_entry(java_lang_math_cos )
194
method_entry(java_lang_math_tan )
195
method_entry(java_lang_math_abs )
196
method_entry(java_lang_math_sqrt )
197
method_entry(java_lang_math_log )
198
method_entry(java_lang_math_log10)
199
method_entry(java_lang_math_exp )
200
method_entry(java_lang_math_pow )
201
method_entry(java_lang_math_fmaF )
202
method_entry(java_lang_math_fmaD )
203
method_entry(java_lang_ref_reference_get)
204
205
AbstractInterpreter::initialize_method_handle_entries();
206
207
// all native method kinds (must be one contiguous block)
208
Interpreter::_native_entry_begin = Interpreter::code()->code_end();
209
method_entry(native)
210
method_entry(native_synchronized)
211
Interpreter::_native_entry_end = Interpreter::code()->code_end();
212
213
method_entry(java_util_zip_CRC32_update)
214
method_entry(java_util_zip_CRC32_updateBytes)
215
method_entry(java_util_zip_CRC32_updateByteBuffer)
216
method_entry(java_util_zip_CRC32C_updateBytes)
217
method_entry(java_util_zip_CRC32C_updateDirectByteBuffer)
218
219
method_entry(java_lang_Float_intBitsToFloat);
220
method_entry(java_lang_Float_floatToRawIntBits);
221
method_entry(java_lang_Double_longBitsToDouble);
222
method_entry(java_lang_Double_doubleToRawLongBits);
223
224
#undef method_entry
225
226
// Bytecodes
227
set_entry_points_for_all_bytes();
228
229
// installation of code in other places in the runtime
230
// (ExcutableCodeManager calls not needed to copy the entries)
231
set_safepoints_for_all_bytes();
232
233
{ CodeletMark cm(_masm, "deoptimization entry points");
234
Interpreter::_deopt_entry[0] = EntryPoint();
235
Interpreter::_deopt_entry[0].set_entry(vtos, generate_deopt_entry_for(vtos, 0));
236
for (int i = 1; i < Interpreter::number_of_deopt_entries; i++) {
237
Interpreter::_deopt_entry[i] =
238
EntryPoint(
239
generate_deopt_entry_for(atos, i),
240
generate_deopt_entry_for(itos, i),
241
generate_deopt_entry_for(ltos, i),
242
generate_deopt_entry_for(ftos, i),
243
generate_deopt_entry_for(dtos, i),
244
generate_deopt_entry_for(vtos, i)
245
);
246
}
247
address return_continuation = Interpreter::_normal_table.entry(Bytecodes::_return).entry(vtos);
248
vmassert(return_continuation != NULL, "return entry not generated yet");
249
Interpreter::_deopt_reexecute_return_entry = generate_deopt_entry_for(vtos, 0, return_continuation);
250
}
251
252
}
253
254
//------------------------------------------------------------------------------------------------------------------------
255
256
address TemplateInterpreterGenerator::generate_error_exit(const char* msg) {
257
address entry = __ pc();
258
__ stop(msg);
259
return entry;
260
}
261
262
263
//------------------------------------------------------------------------------------------------------------------------
264
265
void TemplateInterpreterGenerator::set_entry_points_for_all_bytes() {
266
for (int i = 0; i < DispatchTable::length; i++) {
267
Bytecodes::Code code = (Bytecodes::Code)i;
268
if (Bytecodes::is_defined(code)) {
269
set_entry_points(code);
270
} else {
271
set_unimplemented(i);
272
}
273
}
274
}
275
276
277
void TemplateInterpreterGenerator::set_safepoints_for_all_bytes() {
278
for (int i = 0; i < DispatchTable::length; i++) {
279
Bytecodes::Code code = (Bytecodes::Code)i;
280
if (Bytecodes::is_defined(code)) Interpreter::_safept_table.set_entry(code, Interpreter::_safept_entry);
281
}
282
}
283
284
285
void TemplateInterpreterGenerator::set_unimplemented(int i) {
286
address e = _unimplemented_bytecode;
287
EntryPoint entry(e, e, e, e, e, e, e, e, e, e);
288
Interpreter::_normal_table.set_entry(i, entry);
289
Interpreter::_wentry_point[i] = _unimplemented_bytecode;
290
}
291
292
293
void TemplateInterpreterGenerator::set_entry_points(Bytecodes::Code code) {
294
CodeletMark cm(_masm, Bytecodes::name(code), code);
295
// initialize entry points
296
assert(_unimplemented_bytecode != NULL, "should have been generated before");
297
assert(_illegal_bytecode_sequence != NULL, "should have been generated before");
298
address bep = _illegal_bytecode_sequence;
299
address zep = _illegal_bytecode_sequence;
300
address cep = _illegal_bytecode_sequence;
301
address sep = _illegal_bytecode_sequence;
302
address aep = _illegal_bytecode_sequence;
303
address iep = _illegal_bytecode_sequence;
304
address lep = _illegal_bytecode_sequence;
305
address fep = _illegal_bytecode_sequence;
306
address dep = _illegal_bytecode_sequence;
307
address vep = _unimplemented_bytecode;
308
address wep = _unimplemented_bytecode;
309
// code for short & wide version of bytecode
310
if (Bytecodes::is_defined(code)) {
311
Template* t = TemplateTable::template_for(code);
312
assert(t->is_valid(), "just checking");
313
set_short_entry_points(t, bep, cep, sep, aep, iep, lep, fep, dep, vep);
314
}
315
if (Bytecodes::wide_is_defined(code)) {
316
Template* t = TemplateTable::template_for_wide(code);
317
assert(t->is_valid(), "just checking");
318
set_wide_entry_point(t, wep);
319
}
320
// set entry points
321
EntryPoint entry(bep, zep, cep, sep, aep, iep, lep, fep, dep, vep);
322
Interpreter::_normal_table.set_entry(code, entry);
323
Interpreter::_wentry_point[code] = wep;
324
}
325
326
327
void TemplateInterpreterGenerator::set_wide_entry_point(Template* t, address& wep) {
328
assert(t->is_valid(), "template must exist");
329
assert(t->tos_in() == vtos, "only vtos tos_in supported for wide instructions");
330
wep = __ pc(); generate_and_dispatch(t);
331
}
332
333
334
void TemplateInterpreterGenerator::set_short_entry_points(Template* t, address& bep, address& cep, address& sep, address& aep, address& iep, address& lep, address& fep, address& dep, address& vep) {
335
assert(t->is_valid(), "template must exist");
336
switch (t->tos_in()) {
337
case btos:
338
case ztos:
339
case ctos:
340
case stos:
341
ShouldNotReachHere(); // btos/ctos/stos should use itos.
342
break;
343
case atos: vep = __ pc(); __ pop(atos); aep = __ pc(); generate_and_dispatch(t); break;
344
case itos: vep = __ pc(); __ pop(itos); iep = __ pc(); generate_and_dispatch(t); break;
345
case ltos: vep = __ pc(); __ pop(ltos); lep = __ pc(); generate_and_dispatch(t); break;
346
case ftos: vep = __ pc(); __ pop(ftos); fep = __ pc(); generate_and_dispatch(t); break;
347
case dtos: vep = __ pc(); __ pop(dtos); dep = __ pc(); generate_and_dispatch(t); break;
348
case vtos: set_vtos_entry_points(t, bep, cep, sep, aep, iep, lep, fep, dep, vep); break;
349
default : ShouldNotReachHere(); break;
350
}
351
}
352
353
354
//------------------------------------------------------------------------------------------------------------------------
355
356
void TemplateInterpreterGenerator::generate_and_dispatch(Template* t, TosState tos_out) {
357
if (PrintBytecodeHistogram) histogram_bytecode(t);
358
#ifndef PRODUCT
359
// debugging code
360
if (CountBytecodes || TraceBytecodes || StopInterpreterAt > 0) count_bytecode();
361
if (PrintBytecodePairHistogram) histogram_bytecode_pair(t);
362
if (TraceBytecodes) trace_bytecode(t);
363
if (StopInterpreterAt > 0) stop_interpreter_at();
364
__ verify_FPU(1, t->tos_in());
365
#endif // !PRODUCT
366
int step = 0;
367
if (!t->does_dispatch()) {
368
step = t->is_wide() ? Bytecodes::wide_length_for(t->bytecode()) : Bytecodes::length_for(t->bytecode());
369
if (tos_out == ilgl) tos_out = t->tos_out();
370
// compute bytecode size
371
assert(step > 0, "just checkin'");
372
// setup stuff for dispatching next bytecode
373
if (ProfileInterpreter && VerifyDataPointer
374
&& MethodData::bytecode_has_profile(t->bytecode())) {
375
__ verify_method_data_pointer();
376
}
377
__ dispatch_prolog(tos_out, step);
378
}
379
// generate template
380
t->generate(_masm);
381
// advance
382
if (t->does_dispatch()) {
383
#ifdef ASSERT
384
// make sure execution doesn't go beyond this point if code is broken
385
__ should_not_reach_here();
386
#endif // ASSERT
387
} else {
388
// dispatch to next bytecode
389
__ dispatch_epilog(tos_out, step);
390
}
391
}
392
393
// Generate method entries
394
address TemplateInterpreterGenerator::generate_method_entry(
395
AbstractInterpreter::MethodKind kind) {
396
// determine code generation flags
397
bool native = false;
398
bool synchronized = false;
399
address entry_point = NULL;
400
401
switch (kind) {
402
case Interpreter::zerolocals : break;
403
case Interpreter::zerolocals_synchronized: synchronized = true; break;
404
case Interpreter::native : native = true; break;
405
case Interpreter::native_synchronized : native = true; synchronized = true; break;
406
case Interpreter::empty : break;
407
case Interpreter::getter : break;
408
case Interpreter::setter : break;
409
case Interpreter::abstract : entry_point = generate_abstract_entry(); break;
410
411
case Interpreter::java_lang_math_sin : // fall thru
412
case Interpreter::java_lang_math_cos : // fall thru
413
case Interpreter::java_lang_math_tan : // fall thru
414
case Interpreter::java_lang_math_abs : // fall thru
415
case Interpreter::java_lang_math_log : // fall thru
416
case Interpreter::java_lang_math_log10 : // fall thru
417
case Interpreter::java_lang_math_sqrt : // fall thru
418
case Interpreter::java_lang_math_pow : // fall thru
419
case Interpreter::java_lang_math_exp : // fall thru
420
case Interpreter::java_lang_math_fmaD : // fall thru
421
case Interpreter::java_lang_math_fmaF : entry_point = generate_math_entry(kind); break;
422
case Interpreter::java_lang_ref_reference_get
423
: entry_point = generate_Reference_get_entry(); break;
424
case Interpreter::java_util_zip_CRC32_update
425
: native = true; entry_point = generate_CRC32_update_entry(); break;
426
case Interpreter::java_util_zip_CRC32_updateBytes
427
: // fall thru
428
case Interpreter::java_util_zip_CRC32_updateByteBuffer
429
: native = true; entry_point = generate_CRC32_updateBytes_entry(kind); break;
430
case Interpreter::java_util_zip_CRC32C_updateBytes
431
: // fall thru
432
case Interpreter::java_util_zip_CRC32C_updateDirectByteBuffer
433
: entry_point = generate_CRC32C_updateBytes_entry(kind); break;
434
#ifdef IA32
435
// On x86_32 platforms, a special entry is generated for the following four methods.
436
// On other platforms the normal entry is used to enter these methods.
437
case Interpreter::java_lang_Float_intBitsToFloat
438
: native = true; entry_point = generate_Float_intBitsToFloat_entry(); break;
439
case Interpreter::java_lang_Float_floatToRawIntBits
440
: native = true; entry_point = generate_Float_floatToRawIntBits_entry(); break;
441
case Interpreter::java_lang_Double_longBitsToDouble
442
: native = true; entry_point = generate_Double_longBitsToDouble_entry(); break;
443
case Interpreter::java_lang_Double_doubleToRawLongBits
444
: native = true; entry_point = generate_Double_doubleToRawLongBits_entry(); break;
445
#else
446
case Interpreter::java_lang_Float_intBitsToFloat:
447
case Interpreter::java_lang_Float_floatToRawIntBits:
448
case Interpreter::java_lang_Double_longBitsToDouble:
449
case Interpreter::java_lang_Double_doubleToRawLongBits:
450
native = true;
451
break;
452
#endif // !IA32
453
default:
454
fatal("unexpected method kind: %d", kind);
455
break;
456
}
457
458
if (entry_point) {
459
return entry_point;
460
}
461
462
// We expect the normal and native entry points to be generated first so we can reuse them.
463
if (native) {
464
entry_point = Interpreter::entry_for_kind(synchronized ? Interpreter::native_synchronized : Interpreter::native);
465
if (entry_point == NULL) {
466
entry_point = generate_native_entry(synchronized);
467
}
468
} else {
469
entry_point = Interpreter::entry_for_kind(synchronized ? Interpreter::zerolocals_synchronized : Interpreter::zerolocals);
470
if (entry_point == NULL) {
471
entry_point = generate_normal_entry(synchronized);
472
}
473
}
474
475
return entry_point;
476
}
477
478