1/*
2 * Copyright (c) 1999, 2019, 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
37class CodeEmitInfo;
38class LIR_Assembler;
39class 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
46class 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
81class 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
92class CounterOverflowStub: public CodeStub {
93 private:
94 CodeEmitInfo* _info;
95 int _bci;
96 LIR_Opr _method;
97
98public:
99 CounterOverflowStub(CodeEmitInfo* info, int bci, LIR_Opr method) : _info(info), _bci(bci), _method(method) {
100 }
101
102 virtual void emit_code(LIR_Assembler* e);
103
104 virtual void visit(LIR_OpVisitState* visitor) {
105 visitor->do_slow_case(_info);
106 visitor->do_input(_method);
107 }
108
109#ifndef PRODUCT
110 virtual void print_name(outputStream* out) const { out->print("CounterOverflowStub"); }
111#endif // PRODUCT
112
113};
114
115class ConversionStub: public CodeStub {
116 private:
117 Bytecodes::Code _bytecode;
118 LIR_Opr _input;
119 LIR_Opr _result;
120
121 static float float_zero;
122 static double double_zero;
123 public:
124 ConversionStub(Bytecodes::Code bytecode, LIR_Opr input, LIR_Opr result)
125 : _bytecode(bytecode), _input(input), _result(result) {
126 }
127
128 Bytecodes::Code bytecode() { return _bytecode; }
129 LIR_Opr input() { return _input; }
130 LIR_Opr result() { return _result; }
131
132 virtual void emit_code(LIR_Assembler* e);
133 virtual void visit(LIR_OpVisitState* visitor) {
134 visitor->do_slow_case();
135 visitor->do_input(_input);
136 visitor->do_output(_result);
137 }
138#ifndef PRODUCT
139 virtual void print_name(outputStream* out) const { out->print("ConversionStub"); }
140#endif // PRODUCT
141};
142
143
144// Throws ArrayIndexOutOfBoundsException by default but can be
145// configured to throw IndexOutOfBoundsException in constructor
146class RangeCheckStub: public CodeStub {
147 private:
148 CodeEmitInfo* _info;
149 LIR_Opr _index;
150 LIR_Opr _array;
151 bool _throw_index_out_of_bounds_exception;
152
153 public:
154 // For ArrayIndexOutOfBoundsException.
155 RangeCheckStub(CodeEmitInfo* info, LIR_Opr index, LIR_Opr array);
156 // For IndexOutOfBoundsException.
157 RangeCheckStub(CodeEmitInfo* info, LIR_Opr index);
158 virtual void emit_code(LIR_Assembler* e);
159 virtual CodeEmitInfo* info() const { return _info; }
160 virtual bool is_exception_throw_stub() const { return true; }
161 virtual bool is_range_check_stub() const { return true; }
162 virtual void visit(LIR_OpVisitState* visitor) {
163 visitor->do_slow_case(_info);
164 visitor->do_input(_index);
165 if (_array) { visitor->do_input(_array); }
166 }
167#ifndef PRODUCT
168 virtual void print_name(outputStream* out) const { out->print("RangeCheckStub"); }
169#endif // PRODUCT
170};
171
172// stub used when predicate fails and deoptimization is needed
173class PredicateFailedStub: public CodeStub {
174 private:
175 CodeEmitInfo* _info;
176
177 public:
178 PredicateFailedStub(CodeEmitInfo* info);
179 virtual void emit_code(LIR_Assembler* e);
180 virtual CodeEmitInfo* info() const { return _info; }
181 virtual void visit(LIR_OpVisitState* visitor) {
182 visitor->do_slow_case(_info);
183 }
184#ifndef PRODUCT
185 virtual void print_name(outputStream* out) const { out->print("PredicateFailedStub"); }
186#endif // PRODUCT
187};
188
189class DivByZeroStub: public CodeStub {
190 private:
191 CodeEmitInfo* _info;
192 int _offset;
193
194 public:
195 DivByZeroStub(CodeEmitInfo* info)
196 : _info(info), _offset(-1) {
197 }
198 DivByZeroStub(int offset, CodeEmitInfo* info)
199 : _info(info), _offset(offset) {
200 }
201 virtual void emit_code(LIR_Assembler* e);
202 virtual CodeEmitInfo* info() const { return _info; }
203 virtual bool is_exception_throw_stub() const { return true; }
204 virtual bool is_divbyzero_stub() const { return true; }
205 virtual void visit(LIR_OpVisitState* visitor) {
206 visitor->do_slow_case(_info);
207 }
208#ifndef PRODUCT
209 virtual void print_name(outputStream* out) const { out->print("DivByZeroStub"); }
210#endif // PRODUCT
211};
212
213
214class ImplicitNullCheckStub: public CodeStub {
215 private:
216 CodeEmitInfo* _info;
217 int _offset;
218
219 public:
220 ImplicitNullCheckStub(int offset, CodeEmitInfo* info)
221 : _info(info), _offset(offset) {
222 }
223 virtual void emit_code(LIR_Assembler* e);
224 virtual CodeEmitInfo* info() const { return _info; }
225 virtual bool is_exception_throw_stub() const { return true; }
226 virtual void visit(LIR_OpVisitState* visitor) {
227 visitor->do_slow_case(_info);
228 }
229#ifndef PRODUCT
230 virtual void print_name(outputStream* out) const { out->print("ImplicitNullCheckStub"); }
231#endif // PRODUCT
232};
233
234
235class NewInstanceStub: public CodeStub {
236 private:
237 ciInstanceKlass* _klass;
238 LIR_Opr _klass_reg;
239 LIR_Opr _result;
240 CodeEmitInfo* _info;
241 Runtime1::StubID _stub_id;
242
243 public:
244 NewInstanceStub(LIR_Opr klass_reg, LIR_Opr result, ciInstanceKlass* klass, CodeEmitInfo* info, Runtime1::StubID stub_id);
245 virtual void emit_code(LIR_Assembler* e);
246 virtual CodeEmitInfo* info() const { return _info; }
247 virtual void visit(LIR_OpVisitState* visitor) {
248 visitor->do_slow_case(_info);
249 visitor->do_input(_klass_reg);
250 visitor->do_output(_result);
251 }
252#ifndef PRODUCT
253 virtual void print_name(outputStream* out) const { out->print("NewInstanceStub"); }
254#endif // PRODUCT
255};
256
257
258class NewTypeArrayStub: public CodeStub {
259 private:
260 LIR_Opr _klass_reg;
261 LIR_Opr _length;
262 LIR_Opr _result;
263 CodeEmitInfo* _info;
264
265 public:
266 NewTypeArrayStub(LIR_Opr klass_reg, LIR_Opr length, LIR_Opr result, CodeEmitInfo* info);
267 virtual void emit_code(LIR_Assembler* e);
268 virtual CodeEmitInfo* info() const { return _info; }
269 virtual void visit(LIR_OpVisitState* visitor) {
270 visitor->do_slow_case(_info);
271 visitor->do_input(_klass_reg);
272 visitor->do_input(_length);
273 assert(_result->is_valid(), "must be valid"); visitor->do_output(_result);
274 }
275#ifndef PRODUCT
276 virtual void print_name(outputStream* out) const { out->print("NewTypeArrayStub"); }
277#endif // PRODUCT
278};
279
280
281class NewObjectArrayStub: public CodeStub {
282 private:
283 LIR_Opr _klass_reg;
284 LIR_Opr _length;
285 LIR_Opr _result;
286 CodeEmitInfo* _info;
287
288 public:
289 NewObjectArrayStub(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("NewObjectArrayStub"); }
300#endif // PRODUCT
301};
302
303
304class MonitorAccessStub: public CodeStub {
305 protected:
306 LIR_Opr _obj_reg;
307 LIR_Opr _lock_reg;
308
309 public:
310 MonitorAccessStub(LIR_Opr obj_reg, LIR_Opr lock_reg) {
311 _obj_reg = obj_reg;
312 _lock_reg = lock_reg;
313 }
314
315#ifndef PRODUCT
316 virtual void print_name(outputStream* out) const { out->print("MonitorAccessStub"); }
317#endif // PRODUCT
318};
319
320
321class MonitorEnterStub: public MonitorAccessStub {
322 private:
323 CodeEmitInfo* _info;
324
325 public:
326 MonitorEnterStub(LIR_Opr obj_reg, LIR_Opr lock_reg, CodeEmitInfo* info);
327
328 virtual void emit_code(LIR_Assembler* e);
329 virtual CodeEmitInfo* info() const { return _info; }
330 virtual void visit(LIR_OpVisitState* visitor) {
331 visitor->do_input(_obj_reg);
332 visitor->do_input(_lock_reg);
333 visitor->do_slow_case(_info);
334 }
335#ifndef PRODUCT
336 virtual void print_name(outputStream* out) const { out->print("MonitorEnterStub"); }
337#endif // PRODUCT
338};
339
340
341class MonitorExitStub: public MonitorAccessStub {
342 private:
343 bool _compute_lock;
344 int _monitor_ix;
345
346 public:
347 MonitorExitStub(LIR_Opr lock_reg, bool compute_lock, int monitor_ix)
348 : MonitorAccessStub(LIR_OprFact::illegalOpr, lock_reg),
349 _compute_lock(compute_lock), _monitor_ix(monitor_ix) { }
350 virtual void emit_code(LIR_Assembler* e);
351 virtual void visit(LIR_OpVisitState* visitor) {
352 assert(_obj_reg->is_illegal(), "unused");
353 if (_compute_lock) {
354 visitor->do_temp(_lock_reg);
355 } else {
356 visitor->do_input(_lock_reg);
357 }
358 }
359#ifndef PRODUCT
360 virtual void print_name(outputStream* out) const { out->print("MonitorExitStub"); }
361#endif // PRODUCT
362};
363
364
365class PatchingStub: public CodeStub {
366 public:
367 enum PatchID {
368 access_field_id,
369 load_klass_id,
370 load_mirror_id,
371 load_appendix_id
372 };
373 enum constants {
374 patch_info_size = 3
375 };
376 private:
377 PatchID _id;
378 address _pc_start;
379 int _bytes_to_copy;
380 Label _patched_code_entry;
381 Label _patch_site_entry;
382 Label _patch_site_continuation;
383 Register _obj;
384 CodeEmitInfo* _info;
385 int _index; // index of the patchable oop or Klass* in nmethod oop or metadata table if needed
386 static int _patch_info_offset;
387
388 void align_patch_site(MacroAssembler* masm);
389
390 public:
391 static int patch_info_offset() { return _patch_info_offset; }
392
393 PatchingStub(MacroAssembler* masm, PatchID id, int index = -1):
394 _id(id)
395 , _info(NULL)
396 , _index(index) {
397 // force alignment of patch sites so we
398 // can guarantee atomic writes to the patch site.
399 align_patch_site(masm);
400 _pc_start = masm->pc();
401 masm->bind(_patch_site_entry);
402 }
403
404 void install(MacroAssembler* masm, LIR_PatchCode patch_code, Register obj, CodeEmitInfo* info) {
405 _info = info;
406 _obj = obj;
407 masm->bind(_patch_site_continuation);
408 _bytes_to_copy = masm->pc() - pc_start();
409 if (_id == PatchingStub::access_field_id) {
410 // embed a fixed offset to handle long patches which need to be offset by a word.
411 // the patching code will just add the field offset field to this offset so
412 // that we can refernce either the high or low word of a double word field.
413 int field_offset = 0;
414 switch (patch_code) {
415 case lir_patch_low: field_offset = lo_word_offset_in_bytes; break;
416 case lir_patch_high: field_offset = hi_word_offset_in_bytes; break;
417 case lir_patch_normal: field_offset = 0; break;
418 default: ShouldNotReachHere();
419 }
420 NativeMovRegMem* n_move = nativeMovRegMem_at(pc_start());
421 n_move->set_offset(field_offset);
422 } else if (_id == load_klass_id || _id == load_mirror_id || _id == load_appendix_id) {
423 assert(_obj != noreg, "must have register object for load_klass/load_mirror");
424#ifdef ASSERT
425 // verify that we're pointing at a NativeMovConstReg
426 nativeMovConstReg_at(pc_start());
427#endif
428 } else {
429 ShouldNotReachHere();
430 }
431 assert(_bytes_to_copy <= (masm->pc() - pc_start()), "not enough bytes");
432 }
433
434 address pc_start() const { return _pc_start; }
435 PatchID id() const { return _id; }
436
437 virtual void emit_code(LIR_Assembler* e);
438 virtual CodeEmitInfo* info() const { return _info; }
439 virtual void visit(LIR_OpVisitState* visitor) {
440 visitor->do_slow_case(_info);
441 }
442#ifndef PRODUCT
443 virtual void print_name(outputStream* out) const { out->print("PatchingStub"); }
444#endif // PRODUCT
445};
446
447
448//------------------------------------------------------------------------------
449// DeoptimizeStub
450//
451class DeoptimizeStub : public CodeStub {
452private:
453 CodeEmitInfo* _info;
454 jint _trap_request;
455
456public:
457 DeoptimizeStub(CodeEmitInfo* info, Deoptimization::DeoptReason reason, Deoptimization::DeoptAction action) :
458 _info(new CodeEmitInfo(info)), _trap_request(Deoptimization::make_trap_request(reason, action)) {}
459
460 virtual void emit_code(LIR_Assembler* e);
461 virtual CodeEmitInfo* info() const { return _info; }
462 virtual bool is_exception_throw_stub() const { return true; }
463 virtual void visit(LIR_OpVisitState* visitor) {
464 visitor->do_slow_case(_info);
465 }
466#ifndef PRODUCT
467 virtual void print_name(outputStream* out) const { out->print("DeoptimizeStub"); }
468#endif // PRODUCT
469};
470
471
472class SimpleExceptionStub: public CodeStub {
473 private:
474 LIR_Opr _obj;
475 Runtime1::StubID _stub;
476 CodeEmitInfo* _info;
477
478 public:
479 SimpleExceptionStub(Runtime1::StubID stub, LIR_Opr obj, CodeEmitInfo* info):
480 _obj(obj), _stub(stub), _info(info) {
481 }
482
483 void set_obj(LIR_Opr obj) {
484 _obj = obj;
485 }
486
487 virtual void emit_code(LIR_Assembler* e);
488 virtual CodeEmitInfo* info() const { return _info; }
489 virtual bool is_exception_throw_stub() const { return true; }
490 virtual bool is_simple_exception_stub() const { return true; }
491 virtual void visit(LIR_OpVisitState* visitor) {
492 if (_obj->is_valid()) visitor->do_input(_obj);
493 visitor->do_slow_case(_info);
494 }
495#ifndef PRODUCT
496 virtual void print_name(outputStream* out) const { out->print("SimpleExceptionStub"); }
497#endif // PRODUCT
498};
499
500
501
502class ArrayStoreExceptionStub: public SimpleExceptionStub {
503 private:
504 CodeEmitInfo* _info;
505
506 public:
507 ArrayStoreExceptionStub(LIR_Opr obj, CodeEmitInfo* info): SimpleExceptionStub(Runtime1::throw_array_store_exception_id, obj, info) {}
508#ifndef PRODUCT
509 virtual void print_name(outputStream* out) const { out->print("ArrayStoreExceptionStub"); }
510#endif // PRODUCT
511};
512
513
514class ArrayCopyStub: public CodeStub {
515 private:
516 LIR_OpArrayCopy* _op;
517
518 public:
519 ArrayCopyStub(LIR_OpArrayCopy* op): _op(op) { }
520
521 LIR_Opr src() const { return _op->src(); }
522 LIR_Opr src_pos() const { return _op->src_pos(); }
523 LIR_Opr dst() const { return _op->dst(); }
524 LIR_Opr dst_pos() const { return _op->dst_pos(); }
525 LIR_Opr length() const { return _op->length(); }
526 LIR_Opr tmp() const { return _op->tmp(); }
527
528 virtual void emit_code(LIR_Assembler* e);
529 virtual CodeEmitInfo* info() const { return _op->info(); }
530 virtual void visit(LIR_OpVisitState* visitor) {
531 // don't pass in the code emit info since it's processed in the fast path
532 visitor->do_slow_case();
533 }
534#ifndef PRODUCT
535 virtual void print_name(outputStream* out) const { out->print("ArrayCopyStub"); }
536#endif // PRODUCT
537};
538
539#endif // SHARE_C1_C1_CODESTUBS_HPP
540