Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mobile
Path: blob/master/src/hotspot/share/c1/c1_CodeStubs.hpp
40930 views
1
/*
2
* Copyright (c) 1999, 2020, 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
#ifndef SHARE_C1_C1_CODESTUBS_HPP
26
#define SHARE_C1_C1_CODESTUBS_HPP
27
28
#include "c1/c1_FrameMap.hpp"
29
#include "c1/c1_IR.hpp"
30
#include "c1/c1_Instruction.hpp"
31
#include "c1/c1_LIR.hpp"
32
#include "c1/c1_Runtime1.hpp"
33
#include "code/nativeInst.hpp"
34
#include "utilities/growableArray.hpp"
35
#include "utilities/macros.hpp"
36
37
class CodeEmitInfo;
38
class LIR_Assembler;
39
class LIR_OpVisitState;
40
41
// CodeStubs are little 'out-of-line' pieces of code that
42
// usually handle slow cases of operations. All code stubs
43
// are collected and code is emitted at the end of the
44
// nmethod.
45
46
class CodeStub: public CompilationResourceObj {
47
protected:
48
Label _entry; // label at the stub entry point
49
Label _continuation; // label where stub continues, if any
50
51
public:
52
CodeStub() {}
53
54
// code generation
55
void assert_no_unbound_labels() { assert(!_entry.is_unbound() && !_continuation.is_unbound(), "unbound label"); }
56
virtual void emit_code(LIR_Assembler* e) = 0;
57
virtual CodeEmitInfo* info() const { return NULL; }
58
virtual bool is_exception_throw_stub() const { return false; }
59
virtual bool is_range_check_stub() const { return false; }
60
virtual bool is_divbyzero_stub() const { return false; }
61
virtual bool is_simple_exception_stub() const { return false; }
62
#ifndef PRODUCT
63
virtual void print_name(outputStream* out) const = 0;
64
#endif
65
66
// label access
67
Label* entry() { return &_entry; }
68
Label* continuation() { return &_continuation; }
69
// for LIR
70
virtual void visit(LIR_OpVisitState* visit) {
71
#ifndef PRODUCT
72
if (LIRTracePeephole && Verbose) {
73
tty->print("no visitor for ");
74
print_name(tty);
75
tty->cr();
76
}
77
#endif
78
}
79
};
80
81
class CodeStubList: public GrowableArray<CodeStub*> {
82
public:
83
CodeStubList(): GrowableArray<CodeStub*>() {}
84
85
void append(CodeStub* stub) {
86
if (!contains(stub)) {
87
GrowableArray<CodeStub*>::append(stub);
88
}
89
}
90
};
91
92
class C1SafepointPollStub: public CodeStub {
93
private:
94
uintptr_t _safepoint_offset;
95
96
public:
97
C1SafepointPollStub() :
98
_safepoint_offset(0) {
99
}
100
101
uintptr_t safepoint_offset() { return _safepoint_offset; }
102
void set_safepoint_offset(uintptr_t safepoint_offset) { _safepoint_offset = safepoint_offset; }
103
104
virtual void emit_code(LIR_Assembler* e);
105
virtual void visit(LIR_OpVisitState* visitor) {
106
// don't pass in the code emit info since it's processed in the fast path
107
visitor->do_slow_case();
108
}
109
#ifndef PRODUCT
110
virtual void print_name(outputStream* out) const { out->print("C1SafepointPollStub"); }
111
#endif // PRODUCT
112
};
113
114
class CounterOverflowStub: public CodeStub {
115
private:
116
CodeEmitInfo* _info;
117
int _bci;
118
LIR_Opr _method;
119
120
public:
121
CounterOverflowStub(CodeEmitInfo* info, int bci, LIR_Opr method) : _info(info), _bci(bci), _method(method) {
122
}
123
124
virtual void emit_code(LIR_Assembler* e);
125
126
virtual void visit(LIR_OpVisitState* visitor) {
127
visitor->do_slow_case(_info);
128
visitor->do_input(_method);
129
}
130
131
#ifndef PRODUCT
132
virtual void print_name(outputStream* out) const { out->print("CounterOverflowStub"); }
133
#endif // PRODUCT
134
135
};
136
137
class ConversionStub: public CodeStub {
138
private:
139
Bytecodes::Code _bytecode;
140
LIR_Opr _input;
141
LIR_Opr _result;
142
143
static float float_zero;
144
static double double_zero;
145
public:
146
ConversionStub(Bytecodes::Code bytecode, LIR_Opr input, LIR_Opr result)
147
: _bytecode(bytecode), _input(input), _result(result) {
148
NOT_IA32( ShouldNotReachHere(); ) // used only on x86-32
149
}
150
151
Bytecodes::Code bytecode() { return _bytecode; }
152
LIR_Opr input() { return _input; }
153
LIR_Opr result() { return _result; }
154
155
virtual void emit_code(LIR_Assembler* e);
156
virtual void visit(LIR_OpVisitState* visitor) {
157
visitor->do_slow_case();
158
visitor->do_input(_input);
159
visitor->do_output(_result);
160
}
161
#ifndef PRODUCT
162
virtual void print_name(outputStream* out) const { out->print("ConversionStub"); }
163
#endif // PRODUCT
164
};
165
166
167
// Throws ArrayIndexOutOfBoundsException by default but can be
168
// configured to throw IndexOutOfBoundsException in constructor
169
class RangeCheckStub: public CodeStub {
170
private:
171
CodeEmitInfo* _info;
172
LIR_Opr _index;
173
LIR_Opr _array;
174
bool _throw_index_out_of_bounds_exception;
175
176
public:
177
// For ArrayIndexOutOfBoundsException.
178
RangeCheckStub(CodeEmitInfo* info, LIR_Opr index, LIR_Opr array);
179
// For IndexOutOfBoundsException.
180
RangeCheckStub(CodeEmitInfo* info, LIR_Opr index);
181
virtual void emit_code(LIR_Assembler* e);
182
virtual CodeEmitInfo* info() const { return _info; }
183
virtual bool is_exception_throw_stub() const { return true; }
184
virtual bool is_range_check_stub() const { return true; }
185
virtual void visit(LIR_OpVisitState* visitor) {
186
visitor->do_slow_case(_info);
187
visitor->do_input(_index);
188
if (_array) { visitor->do_input(_array); }
189
}
190
#ifndef PRODUCT
191
virtual void print_name(outputStream* out) const { out->print("RangeCheckStub"); }
192
#endif // PRODUCT
193
};
194
195
// stub used when predicate fails and deoptimization is needed
196
class PredicateFailedStub: public CodeStub {
197
private:
198
CodeEmitInfo* _info;
199
200
public:
201
PredicateFailedStub(CodeEmitInfo* info);
202
virtual void emit_code(LIR_Assembler* e);
203
virtual CodeEmitInfo* info() const { return _info; }
204
virtual void visit(LIR_OpVisitState* visitor) {
205
visitor->do_slow_case(_info);
206
}
207
#ifndef PRODUCT
208
virtual void print_name(outputStream* out) const { out->print("PredicateFailedStub"); }
209
#endif // PRODUCT
210
};
211
212
class DivByZeroStub: public CodeStub {
213
private:
214
CodeEmitInfo* _info;
215
int _offset;
216
217
public:
218
DivByZeroStub(CodeEmitInfo* info)
219
: _info(info), _offset(-1) {
220
}
221
DivByZeroStub(int offset, CodeEmitInfo* info)
222
: _info(info), _offset(offset) {
223
}
224
virtual void emit_code(LIR_Assembler* e);
225
virtual CodeEmitInfo* info() const { return _info; }
226
virtual bool is_exception_throw_stub() const { return true; }
227
virtual bool is_divbyzero_stub() const { return true; }
228
virtual void visit(LIR_OpVisitState* visitor) {
229
visitor->do_slow_case(_info);
230
}
231
#ifndef PRODUCT
232
virtual void print_name(outputStream* out) const { out->print("DivByZeroStub"); }
233
#endif // PRODUCT
234
};
235
236
237
class ImplicitNullCheckStub: public CodeStub {
238
private:
239
CodeEmitInfo* _info;
240
int _offset;
241
242
public:
243
ImplicitNullCheckStub(int offset, CodeEmitInfo* info)
244
: _info(info), _offset(offset) {
245
}
246
virtual void emit_code(LIR_Assembler* e);
247
virtual CodeEmitInfo* info() const { return _info; }
248
virtual bool is_exception_throw_stub() const { return true; }
249
virtual void visit(LIR_OpVisitState* visitor) {
250
visitor->do_slow_case(_info);
251
}
252
#ifndef PRODUCT
253
virtual void print_name(outputStream* out) const { out->print("ImplicitNullCheckStub"); }
254
#endif // PRODUCT
255
};
256
257
258
class NewInstanceStub: public CodeStub {
259
private:
260
ciInstanceKlass* _klass;
261
LIR_Opr _klass_reg;
262
LIR_Opr _result;
263
CodeEmitInfo* _info;
264
Runtime1::StubID _stub_id;
265
266
public:
267
NewInstanceStub(LIR_Opr klass_reg, LIR_Opr result, ciInstanceKlass* klass, CodeEmitInfo* info, Runtime1::StubID stub_id);
268
virtual void emit_code(LIR_Assembler* e);
269
virtual CodeEmitInfo* info() const { return _info; }
270
virtual void visit(LIR_OpVisitState* visitor) {
271
visitor->do_slow_case(_info);
272
visitor->do_input(_klass_reg);
273
visitor->do_output(_result);
274
}
275
#ifndef PRODUCT
276
virtual void print_name(outputStream* out) const { out->print("NewInstanceStub"); }
277
#endif // PRODUCT
278
};
279
280
281
class NewTypeArrayStub: public CodeStub {
282
private:
283
LIR_Opr _klass_reg;
284
LIR_Opr _length;
285
LIR_Opr _result;
286
CodeEmitInfo* _info;
287
288
public:
289
NewTypeArrayStub(LIR_Opr klass_reg, LIR_Opr length, LIR_Opr result, CodeEmitInfo* info);
290
virtual void emit_code(LIR_Assembler* e);
291
virtual CodeEmitInfo* info() const { return _info; }
292
virtual void visit(LIR_OpVisitState* visitor) {
293
visitor->do_slow_case(_info);
294
visitor->do_input(_klass_reg);
295
visitor->do_input(_length);
296
assert(_result->is_valid(), "must be valid"); visitor->do_output(_result);
297
}
298
#ifndef PRODUCT
299
virtual void print_name(outputStream* out) const { out->print("NewTypeArrayStub"); }
300
#endif // PRODUCT
301
};
302
303
304
class NewObjectArrayStub: public CodeStub {
305
private:
306
LIR_Opr _klass_reg;
307
LIR_Opr _length;
308
LIR_Opr _result;
309
CodeEmitInfo* _info;
310
311
public:
312
NewObjectArrayStub(LIR_Opr klass_reg, LIR_Opr length, LIR_Opr result, CodeEmitInfo* info);
313
virtual void emit_code(LIR_Assembler* e);
314
virtual CodeEmitInfo* info() const { return _info; }
315
virtual void visit(LIR_OpVisitState* visitor) {
316
visitor->do_slow_case(_info);
317
visitor->do_input(_klass_reg);
318
visitor->do_input(_length);
319
assert(_result->is_valid(), "must be valid"); visitor->do_output(_result);
320
}
321
#ifndef PRODUCT
322
virtual void print_name(outputStream* out) const { out->print("NewObjectArrayStub"); }
323
#endif // PRODUCT
324
};
325
326
327
class MonitorAccessStub: public CodeStub {
328
protected:
329
LIR_Opr _obj_reg;
330
LIR_Opr _lock_reg;
331
332
public:
333
MonitorAccessStub(LIR_Opr obj_reg, LIR_Opr lock_reg) {
334
_obj_reg = obj_reg;
335
_lock_reg = lock_reg;
336
}
337
338
#ifndef PRODUCT
339
virtual void print_name(outputStream* out) const { out->print("MonitorAccessStub"); }
340
#endif // PRODUCT
341
};
342
343
344
class MonitorEnterStub: public MonitorAccessStub {
345
private:
346
CodeEmitInfo* _info;
347
348
public:
349
MonitorEnterStub(LIR_Opr obj_reg, LIR_Opr lock_reg, CodeEmitInfo* info);
350
351
virtual void emit_code(LIR_Assembler* e);
352
virtual CodeEmitInfo* info() const { return _info; }
353
virtual void visit(LIR_OpVisitState* visitor) {
354
visitor->do_input(_obj_reg);
355
visitor->do_input(_lock_reg);
356
visitor->do_slow_case(_info);
357
}
358
#ifndef PRODUCT
359
virtual void print_name(outputStream* out) const { out->print("MonitorEnterStub"); }
360
#endif // PRODUCT
361
};
362
363
364
class MonitorExitStub: public MonitorAccessStub {
365
private:
366
bool _compute_lock;
367
int _monitor_ix;
368
369
public:
370
MonitorExitStub(LIR_Opr lock_reg, bool compute_lock, int monitor_ix)
371
: MonitorAccessStub(LIR_OprFact::illegalOpr, lock_reg),
372
_compute_lock(compute_lock), _monitor_ix(monitor_ix) { }
373
virtual void emit_code(LIR_Assembler* e);
374
virtual void visit(LIR_OpVisitState* visitor) {
375
assert(_obj_reg->is_illegal(), "unused");
376
if (_compute_lock) {
377
visitor->do_temp(_lock_reg);
378
} else {
379
visitor->do_input(_lock_reg);
380
}
381
}
382
#ifndef PRODUCT
383
virtual void print_name(outputStream* out) const { out->print("MonitorExitStub"); }
384
#endif // PRODUCT
385
};
386
387
388
class PatchingStub: public CodeStub {
389
public:
390
enum PatchID {
391
access_field_id,
392
load_klass_id,
393
load_mirror_id,
394
load_appendix_id
395
};
396
enum constants {
397
patch_info_size = 3
398
};
399
private:
400
PatchID _id;
401
address _pc_start;
402
int _bytes_to_copy;
403
Label _patched_code_entry;
404
Label _patch_site_entry;
405
Label _patch_site_continuation;
406
Register _obj;
407
CodeEmitInfo* _info;
408
int _index; // index of the patchable oop or Klass* in nmethod or metadata table if needed
409
static int _patch_info_offset;
410
411
void align_patch_site(MacroAssembler* masm);
412
413
public:
414
static int patch_info_offset() { return _patch_info_offset; }
415
416
PatchingStub(MacroAssembler* masm, PatchID id, int index = -1):
417
_id(id)
418
, _info(NULL)
419
, _index(index) {
420
// force alignment of patch sites so we
421
// can guarantee atomic writes to the patch site.
422
align_patch_site(masm);
423
_pc_start = masm->pc();
424
masm->bind(_patch_site_entry);
425
}
426
427
void install(MacroAssembler* masm, LIR_PatchCode patch_code, Register obj, CodeEmitInfo* info) {
428
_info = info;
429
_obj = obj;
430
masm->bind(_patch_site_continuation);
431
_bytes_to_copy = masm->pc() - pc_start();
432
if (_id == PatchingStub::access_field_id) {
433
// embed a fixed offset to handle long patches which need to be offset by a word.
434
// the patching code will just add the field offset field to this offset so
435
// that we can reference either the high or low word of a double word field.
436
int field_offset = 0;
437
switch (patch_code) {
438
case lir_patch_low: field_offset = lo_word_offset_in_bytes; break;
439
case lir_patch_high: field_offset = hi_word_offset_in_bytes; break;
440
case lir_patch_normal: field_offset = 0; break;
441
default: ShouldNotReachHere();
442
}
443
NativeMovRegMem* n_move = nativeMovRegMem_at(pc_start());
444
n_move->set_offset(field_offset);
445
// Copy will never get executed, so only copy the part which is required for patching.
446
_bytes_to_copy = MAX2(n_move->num_bytes_to_end_of_patch(), (int)NativeGeneralJump::instruction_size);
447
} else if (_id == load_klass_id || _id == load_mirror_id || _id == load_appendix_id) {
448
assert(_obj != noreg, "must have register object for load_klass/load_mirror");
449
#ifdef ASSERT
450
// verify that we're pointing at a NativeMovConstReg
451
nativeMovConstReg_at(pc_start());
452
#endif
453
} else {
454
ShouldNotReachHere();
455
}
456
assert(_bytes_to_copy <= (masm->pc() - pc_start()), "not enough bytes");
457
}
458
459
address pc_start() const { return _pc_start; }
460
PatchID id() const { return _id; }
461
462
virtual void emit_code(LIR_Assembler* e);
463
virtual CodeEmitInfo* info() const { return _info; }
464
virtual void visit(LIR_OpVisitState* visitor) {
465
visitor->do_slow_case(_info);
466
}
467
#ifndef PRODUCT
468
virtual void print_name(outputStream* out) const { out->print("PatchingStub"); }
469
#endif // PRODUCT
470
};
471
472
473
//------------------------------------------------------------------------------
474
// DeoptimizeStub
475
//
476
class DeoptimizeStub : public CodeStub {
477
private:
478
CodeEmitInfo* _info;
479
jint _trap_request;
480
481
public:
482
DeoptimizeStub(CodeEmitInfo* info, Deoptimization::DeoptReason reason, Deoptimization::DeoptAction action) :
483
_info(new CodeEmitInfo(info)), _trap_request(Deoptimization::make_trap_request(reason, action)) {}
484
485
virtual void emit_code(LIR_Assembler* e);
486
virtual CodeEmitInfo* info() const { return _info; }
487
virtual bool is_exception_throw_stub() const { return true; }
488
virtual void visit(LIR_OpVisitState* visitor) {
489
visitor->do_slow_case(_info);
490
}
491
#ifndef PRODUCT
492
virtual void print_name(outputStream* out) const { out->print("DeoptimizeStub"); }
493
#endif // PRODUCT
494
};
495
496
497
class SimpleExceptionStub: public CodeStub {
498
private:
499
LIR_Opr _obj;
500
Runtime1::StubID _stub;
501
CodeEmitInfo* _info;
502
503
public:
504
SimpleExceptionStub(Runtime1::StubID stub, LIR_Opr obj, CodeEmitInfo* info):
505
_obj(obj), _stub(stub), _info(info) {
506
}
507
508
void set_obj(LIR_Opr obj) {
509
_obj = obj;
510
}
511
512
virtual void emit_code(LIR_Assembler* e);
513
virtual CodeEmitInfo* info() const { return _info; }
514
virtual bool is_exception_throw_stub() const { return true; }
515
virtual bool is_simple_exception_stub() const { return true; }
516
virtual void visit(LIR_OpVisitState* visitor) {
517
if (_obj->is_valid()) visitor->do_input(_obj);
518
visitor->do_slow_case(_info);
519
}
520
#ifndef PRODUCT
521
virtual void print_name(outputStream* out) const { out->print("SimpleExceptionStub"); }
522
#endif // PRODUCT
523
};
524
525
526
527
class ArrayStoreExceptionStub: public SimpleExceptionStub {
528
private:
529
CodeEmitInfo* _info;
530
531
public:
532
ArrayStoreExceptionStub(LIR_Opr obj, CodeEmitInfo* info): SimpleExceptionStub(Runtime1::throw_array_store_exception_id, obj, info) {}
533
#ifndef PRODUCT
534
virtual void print_name(outputStream* out) const { out->print("ArrayStoreExceptionStub"); }
535
#endif // PRODUCT
536
};
537
538
539
class ArrayCopyStub: public CodeStub {
540
private:
541
LIR_OpArrayCopy* _op;
542
543
public:
544
ArrayCopyStub(LIR_OpArrayCopy* op): _op(op) { }
545
546
LIR_Opr src() const { return _op->src(); }
547
LIR_Opr src_pos() const { return _op->src_pos(); }
548
LIR_Opr dst() const { return _op->dst(); }
549
LIR_Opr dst_pos() const { return _op->dst_pos(); }
550
LIR_Opr length() const { return _op->length(); }
551
LIR_Opr tmp() const { return _op->tmp(); }
552
553
virtual void emit_code(LIR_Assembler* e);
554
virtual CodeEmitInfo* info() const { return _op->info(); }
555
virtual void visit(LIR_OpVisitState* visitor) {
556
// don't pass in the code emit info since it's processed in the fast path
557
visitor->do_slow_case();
558
}
559
#ifndef PRODUCT
560
virtual void print_name(outputStream* out) const { out->print("ArrayCopyStub"); }
561
#endif // PRODUCT
562
};
563
564
#endif // SHARE_C1_C1_CODESTUBS_HPP
565
566