1 /*
2  * Copyright (c) 1999, 2016, 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_VM_C1_C1_CODESTUBS_HPP
26 #define SHARE_VM_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 "utilities/array.hpp"
34 #include "utilities/macros.hpp"
35 
36 class CodeEmitInfo;
37 class LIR_Assembler;
38 class LIR_OpVisitState;
39 
40 // CodeStubs are little 'out-of-line' pieces of code that
41 // usually handle slow cases of operations. All code stubs
42 // are collected and code is emitted at the end of the
43 // nmethod.
44 
45 class CodeStub: public CompilationResourceObj {
46  protected:
47   Label _entry;                                  // label at the stub entry point
48   Label _continuation;                           // label where stub continues, if any
49 
50  public:
CodeStub()51   CodeStub() {}
52 
53   // code generation
assert_no_unbound_labels()54   void assert_no_unbound_labels()                { assert(!_entry.is_unbound() && !_continuation.is_unbound(), "unbound label"); }
55   virtual void emit_code(LIR_Assembler* e) = 0;
info() const56   virtual CodeEmitInfo* info() const             { return NULL; }
is_exception_throw_stub() const57   virtual bool is_exception_throw_stub() const   { return false; }
is_range_check_stub() const58   virtual bool is_range_check_stub() const       { return false; }
is_divbyzero_stub() const59   virtual bool is_divbyzero_stub() const         { return false; }
is_simple_exception_stub() const60   virtual bool is_simple_exception_stub() const  { return false; }
61 #ifndef PRODUCT
62   virtual void print_name(outputStream* out) const = 0;
63 #endif
64 
65   // label access
entry()66   Label* entry()                                 { return &_entry; }
continuation()67   Label* continuation()                          { return &_continuation; }
68   // for LIR
visit(LIR_OpVisitState * visit)69   virtual void visit(LIR_OpVisitState* visit) {
70 #ifndef PRODUCT
71     if (LIRTracePeephole && Verbose) {
72       tty->print("no visitor for ");
73       print_name(tty);
74       tty->cr();
75     }
76 #endif
77   }
78 };
79 
80 
81 define_array(CodeStubArray, CodeStub*)
82 define_stack(_CodeStubList, CodeStubArray)
83 
84 class CodeStubList: public _CodeStubList {
85  public:
CodeStubList()86   CodeStubList(): _CodeStubList() {}
87 
append(CodeStub * stub)88   void append(CodeStub* stub) {
89     if (!contains(stub)) {
90       _CodeStubList::append(stub);
91     }
92   }
93 };
94 
95 class CounterOverflowStub: public CodeStub {
96  private:
97   CodeEmitInfo* _info;
98   int           _bci;
99   LIR_Opr       _method;
100 
101 public:
CounterOverflowStub(CodeEmitInfo * info,int bci,LIR_Opr method)102   CounterOverflowStub(CodeEmitInfo* info, int bci, LIR_Opr method) :  _info(info), _bci(bci), _method(method) {
103   }
104 
105   virtual void emit_code(LIR_Assembler* e);
106 
visit(LIR_OpVisitState * visitor)107   virtual void visit(LIR_OpVisitState* visitor) {
108     visitor->do_slow_case(_info);
109     visitor->do_input(_method);
110   }
111 
112 #ifndef PRODUCT
print_name(outputStream * out) const113   virtual void print_name(outputStream* out) const { out->print("CounterOverflowStub"); }
114 #endif // PRODUCT
115 
116 };
117 
118 class ConversionStub: public CodeStub {
119  private:
120   Bytecodes::Code _bytecode;
121   LIR_Opr         _input;
122   LIR_Opr         _result;
123 
124   static float float_zero;
125   static double double_zero;
126  public:
ConversionStub(Bytecodes::Code bytecode,LIR_Opr input,LIR_Opr result)127   ConversionStub(Bytecodes::Code bytecode, LIR_Opr input, LIR_Opr result)
128     : _bytecode(bytecode), _input(input), _result(result) {
129   }
130 
bytecode()131   Bytecodes::Code bytecode() { return _bytecode; }
input()132   LIR_Opr         input()    { return _input; }
result()133   LIR_Opr         result()   { return _result; }
134 
135   virtual void emit_code(LIR_Assembler* e);
visit(LIR_OpVisitState * visitor)136   virtual void visit(LIR_OpVisitState* visitor) {
137     visitor->do_slow_case();
138     visitor->do_input(_input);
139     visitor->do_output(_result);
140   }
141 #ifndef PRODUCT
print_name(outputStream * out) const142   virtual void print_name(outputStream* out) const { out->print("ConversionStub"); }
143 #endif // PRODUCT
144 };
145 
146 
147 // Throws ArrayIndexOutOfBoundsException by default but can be
148 // configured to throw IndexOutOfBoundsException in constructor
149 class RangeCheckStub: public CodeStub {
150  private:
151   CodeEmitInfo* _info;
152   LIR_Opr       _index;
153   bool          _throw_index_out_of_bounds_exception;
154 
155  public:
156   RangeCheckStub(CodeEmitInfo* info, LIR_Opr index, bool throw_index_out_of_bounds_exception = false);
157   virtual void emit_code(LIR_Assembler* e);
info() const158   virtual CodeEmitInfo* info() const             { return _info; }
is_exception_throw_stub() const159   virtual bool is_exception_throw_stub() const   { return true; }
is_range_check_stub() const160   virtual bool is_range_check_stub() const       { return true; }
visit(LIR_OpVisitState * visitor)161   virtual void visit(LIR_OpVisitState* visitor) {
162     visitor->do_slow_case(_info);
163     visitor->do_input(_index);
164   }
165 #ifndef PRODUCT
print_name(outputStream * out) const166   virtual void print_name(outputStream* out) const { out->print("RangeCheckStub"); }
167 #endif // PRODUCT
168 };
169 
170 // stub used when predicate fails and deoptimization is needed
171 class PredicateFailedStub: public CodeStub {
172  private:
173   CodeEmitInfo* _info;
174 
175  public:
176   PredicateFailedStub(CodeEmitInfo* info);
177   virtual void emit_code(LIR_Assembler* e);
info() const178   virtual CodeEmitInfo* info() const             { return _info; }
visit(LIR_OpVisitState * visitor)179   virtual void visit(LIR_OpVisitState* visitor) {
180     visitor->do_slow_case(_info);
181   }
182 #ifndef PRODUCT
print_name(outputStream * out) const183   virtual void print_name(outputStream* out) const { out->print("PredicateFailedStub"); }
184 #endif // PRODUCT
185 };
186 
187 class DivByZeroStub: public CodeStub {
188  private:
189   CodeEmitInfo* _info;
190   int           _offset;
191 
192  public:
DivByZeroStub(CodeEmitInfo * info)193   DivByZeroStub(CodeEmitInfo* info)
194     : _info(info), _offset(-1) {
195   }
DivByZeroStub(int offset,CodeEmitInfo * info)196   DivByZeroStub(int offset, CodeEmitInfo* info)
197     : _info(info), _offset(offset) {
198   }
199   virtual void emit_code(LIR_Assembler* e);
info() const200   virtual CodeEmitInfo* info() const             { return _info; }
is_exception_throw_stub() const201   virtual bool is_exception_throw_stub() const   { return true; }
is_divbyzero_stub() const202   virtual bool is_divbyzero_stub() const         { return true; }
visit(LIR_OpVisitState * visitor)203   virtual void visit(LIR_OpVisitState* visitor) {
204     visitor->do_slow_case(_info);
205   }
206 #ifndef PRODUCT
print_name(outputStream * out) const207   virtual void print_name(outputStream* out) const { out->print("DivByZeroStub"); }
208 #endif // PRODUCT
209 };
210 
211 
212 class ImplicitNullCheckStub: public CodeStub {
213  private:
214   CodeEmitInfo* _info;
215   int           _offset;
216 
217  public:
ImplicitNullCheckStub(int offset,CodeEmitInfo * info)218   ImplicitNullCheckStub(int offset, CodeEmitInfo* info)
219     : _offset(offset), _info(info) {
220   }
221   virtual void emit_code(LIR_Assembler* e);
info() const222   virtual CodeEmitInfo* info() const             { return _info; }
is_exception_throw_stub() const223   virtual bool is_exception_throw_stub() const   { return true; }
visit(LIR_OpVisitState * visitor)224   virtual void visit(LIR_OpVisitState* visitor) {
225     visitor->do_slow_case(_info);
226   }
227 #ifndef PRODUCT
print_name(outputStream * out) const228   virtual void print_name(outputStream* out) const { out->print("ImplicitNullCheckStub"); }
229 #endif // PRODUCT
230 };
231 
232 
233 class NewInstanceStub: public CodeStub {
234  private:
235   ciInstanceKlass* _klass;
236   LIR_Opr          _klass_reg;
237   LIR_Opr          _result;
238   CodeEmitInfo*    _info;
239   Runtime1::StubID _stub_id;
240 
241  public:
242   NewInstanceStub(LIR_Opr klass_reg, LIR_Opr result, ciInstanceKlass* klass, CodeEmitInfo* info, Runtime1::StubID stub_id);
243   virtual void emit_code(LIR_Assembler* e);
info() const244   virtual CodeEmitInfo* info() const             { return _info; }
visit(LIR_OpVisitState * visitor)245   virtual void visit(LIR_OpVisitState* visitor) {
246     visitor->do_slow_case(_info);
247     visitor->do_input(_klass_reg);
248     visitor->do_output(_result);
249   }
250 #ifndef PRODUCT
print_name(outputStream * out) const251   virtual void print_name(outputStream* out) const { out->print("NewInstanceStub"); }
252 #endif // PRODUCT
253 };
254 
255 
256 class NewTypeArrayStub: public CodeStub {
257  private:
258   LIR_Opr       _klass_reg;
259   LIR_Opr       _length;
260   LIR_Opr       _result;
261   CodeEmitInfo* _info;
262 
263  public:
264   NewTypeArrayStub(LIR_Opr klass_reg, LIR_Opr length, LIR_Opr result, CodeEmitInfo* info);
265   virtual void emit_code(LIR_Assembler* e);
info() const266   virtual CodeEmitInfo* info() const             { return _info; }
visit(LIR_OpVisitState * visitor)267   virtual void visit(LIR_OpVisitState* visitor) {
268     visitor->do_slow_case(_info);
269     visitor->do_input(_klass_reg);
270     visitor->do_input(_length);
271     assert(_result->is_valid(), "must be valid"); visitor->do_output(_result);
272   }
273 #ifndef PRODUCT
print_name(outputStream * out) const274   virtual void print_name(outputStream* out) const { out->print("NewTypeArrayStub"); }
275 #endif // PRODUCT
276 };
277 
278 
279 class NewObjectArrayStub: public CodeStub {
280  private:
281   LIR_Opr        _klass_reg;
282   LIR_Opr        _length;
283   LIR_Opr        _result;
284   CodeEmitInfo*  _info;
285 
286  public:
287   NewObjectArrayStub(LIR_Opr klass_reg, LIR_Opr length, LIR_Opr result, CodeEmitInfo* info);
288   virtual void emit_code(LIR_Assembler* e);
info() const289   virtual CodeEmitInfo* info() const             { return _info; }
visit(LIR_OpVisitState * visitor)290   virtual void visit(LIR_OpVisitState* visitor) {
291     visitor->do_slow_case(_info);
292     visitor->do_input(_klass_reg);
293     visitor->do_input(_length);
294     assert(_result->is_valid(), "must be valid"); visitor->do_output(_result);
295   }
296 #ifndef PRODUCT
print_name(outputStream * out) const297   virtual void print_name(outputStream* out) const { out->print("NewObjectArrayStub"); }
298 #endif // PRODUCT
299 };
300 
301 
302 class MonitorAccessStub: public CodeStub {
303  protected:
304   LIR_Opr _obj_reg;
305   LIR_Opr _lock_reg;
306 
307  public:
MonitorAccessStub(LIR_Opr obj_reg,LIR_Opr lock_reg)308   MonitorAccessStub(LIR_Opr obj_reg, LIR_Opr lock_reg) {
309     _obj_reg  = obj_reg;
310     _lock_reg  = lock_reg;
311   }
312 
313 #ifndef PRODUCT
print_name(outputStream * out) const314   virtual void print_name(outputStream* out) const { out->print("MonitorAccessStub"); }
315 #endif // PRODUCT
316 };
317 
318 
319 class MonitorEnterStub: public MonitorAccessStub {
320  private:
321   CodeEmitInfo* _info;
322 
323  public:
324   MonitorEnterStub(LIR_Opr obj_reg, LIR_Opr lock_reg, CodeEmitInfo* info);
325 
326   virtual void emit_code(LIR_Assembler* e);
info() const327   virtual CodeEmitInfo* info() const             { return _info; }
visit(LIR_OpVisitState * visitor)328   virtual void visit(LIR_OpVisitState* visitor) {
329     visitor->do_input(_obj_reg);
330     visitor->do_input(_lock_reg);
331     visitor->do_slow_case(_info);
332   }
333 #ifndef PRODUCT
print_name(outputStream * out) const334   virtual void print_name(outputStream* out) const { out->print("MonitorEnterStub"); }
335 #endif // PRODUCT
336 };
337 
338 
339 class MonitorExitStub: public MonitorAccessStub {
340  private:
341   bool _compute_lock;
342   int  _monitor_ix;
343 
344  public:
MonitorExitStub(LIR_Opr lock_reg,bool compute_lock,int monitor_ix)345   MonitorExitStub(LIR_Opr lock_reg, bool compute_lock, int monitor_ix)
346     : MonitorAccessStub(LIR_OprFact::illegalOpr, lock_reg),
347       _compute_lock(compute_lock), _monitor_ix(monitor_ix) { }
348   virtual void emit_code(LIR_Assembler* e);
visit(LIR_OpVisitState * visitor)349   virtual void visit(LIR_OpVisitState* visitor) {
350     assert(_obj_reg->is_illegal(), "unused");
351     if (_compute_lock) {
352       visitor->do_temp(_lock_reg);
353     } else {
354       visitor->do_input(_lock_reg);
355     }
356   }
357 #ifndef PRODUCT
print_name(outputStream * out) const358   virtual void print_name(outputStream* out) const { out->print("MonitorExitStub"); }
359 #endif // PRODUCT
360 };
361 
362 
363 class PatchingStub: public CodeStub {
364  public:
365   enum PatchID {
366     access_field_id,
367     load_klass_id,
368     load_mirror_id,
369     load_appendix_id
370   };
371   enum constants {
372     patch_info_size = 3
373   };
374  private:
375   PatchID       _id;
376   address       _pc_start;
377   int           _bytes_to_copy;
378   Label         _patched_code_entry;
379   Label         _patch_site_entry;
380   Label         _patch_site_continuation;
381   Register      _obj;
382   CodeEmitInfo* _info;
383   int           _index;  // index of the patchable oop or Klass* in nmethod oop or metadata table if needed
384   static int    _patch_info_offset;
385 
386   void align_patch_site(MacroAssembler* masm);
387 
388  public:
patch_info_offset()389   static int patch_info_offset() { return _patch_info_offset; }
390 
PatchingStub(MacroAssembler * masm,PatchID id,int index=-1)391   PatchingStub(MacroAssembler* masm, PatchID id, int index = -1):
392       _id(id)
393     , _info(NULL)
394     , _index(index) {
395     if (os::is_MP()) {
396       // force alignment of patch sites on MP hardware so we
397       // can guarantee atomic writes to the patch site.
398       align_patch_site(masm);
399     }
400     _pc_start = masm->pc();
401     masm->bind(_patch_site_entry);
402   }
403 
install(MacroAssembler * masm,LIR_PatchCode patch_code,Register obj,CodeEmitInfo * info)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 
pc_start() const434   address pc_start() const                       { return _pc_start; }
id() const435   PatchID id() const                             { return _id; }
436 
437   virtual void emit_code(LIR_Assembler* e);
info() const438   virtual CodeEmitInfo* info() const             { return _info; }
visit(LIR_OpVisitState * visitor)439   virtual void visit(LIR_OpVisitState* visitor) {
440     visitor->do_slow_case(_info);
441   }
442 #ifndef PRODUCT
print_name(outputStream * out) const443   virtual void print_name(outputStream* out) const { out->print("PatchingStub"); }
444 #endif // PRODUCT
445 };
446 
447 
448 //------------------------------------------------------------------------------
449 // DeoptimizeStub
450 //
451 class DeoptimizeStub : public CodeStub {
452 private:
453   CodeEmitInfo* _info;
454 
455 public:
DeoptimizeStub(CodeEmitInfo * info)456   DeoptimizeStub(CodeEmitInfo* info) : _info(new CodeEmitInfo(info)) {}
457 
458   virtual void emit_code(LIR_Assembler* e);
info() const459   virtual CodeEmitInfo* info() const           { return _info; }
is_exception_throw_stub() const460   virtual bool is_exception_throw_stub() const { return true; }
visit(LIR_OpVisitState * visitor)461   virtual void visit(LIR_OpVisitState* visitor) {
462     visitor->do_slow_case(_info);
463   }
464 #ifndef PRODUCT
print_name(outputStream * out) const465   virtual void print_name(outputStream* out) const { out->print("DeoptimizeStub"); }
466 #endif // PRODUCT
467 };
468 
469 
470 class SimpleExceptionStub: public CodeStub {
471  private:
472   LIR_Opr          _obj;
473   Runtime1::StubID _stub;
474   CodeEmitInfo*    _info;
475 
476  public:
SimpleExceptionStub(Runtime1::StubID stub,LIR_Opr obj,CodeEmitInfo * info)477   SimpleExceptionStub(Runtime1::StubID stub, LIR_Opr obj, CodeEmitInfo* info):
478     _obj(obj), _info(info), _stub(stub) {
479   }
480 
set_obj(LIR_Opr obj)481   void set_obj(LIR_Opr obj) {
482     _obj = obj;
483   }
484 
485   virtual void emit_code(LIR_Assembler* e);
info() const486   virtual CodeEmitInfo* info() const             { return _info; }
is_exception_throw_stub() const487   virtual bool is_exception_throw_stub() const   { return true; }
is_simple_exception_stub() const488   virtual bool is_simple_exception_stub() const  { return true; }
visit(LIR_OpVisitState * visitor)489   virtual void visit(LIR_OpVisitState* visitor) {
490     if (_obj->is_valid()) visitor->do_input(_obj);
491     visitor->do_slow_case(_info);
492   }
493 #ifndef PRODUCT
print_name(outputStream * out) const494   virtual void print_name(outputStream* out) const { out->print("SimpleExceptionStub"); }
495 #endif // PRODUCT
496 };
497 
498 
499 
500 class ArrayStoreExceptionStub: public SimpleExceptionStub {
501  private:
502   CodeEmitInfo* _info;
503 
504  public:
ArrayStoreExceptionStub(LIR_Opr obj,CodeEmitInfo * info)505   ArrayStoreExceptionStub(LIR_Opr obj, CodeEmitInfo* info): SimpleExceptionStub(Runtime1::throw_array_store_exception_id, obj, info) {}
506 #ifndef PRODUCT
print_name(outputStream * out) const507   virtual void print_name(outputStream* out) const { out->print("ArrayStoreExceptionStub"); }
508 #endif // PRODUCT
509 };
510 
511 
512 class ArrayCopyStub: public CodeStub {
513  private:
514   LIR_OpArrayCopy* _op;
515 
516  public:
ArrayCopyStub(LIR_OpArrayCopy * op)517   ArrayCopyStub(LIR_OpArrayCopy* op): _op(op) { }
518 
src() const519   LIR_Opr src() const                         { return _op->src(); }
src_pos() const520   LIR_Opr src_pos() const                     { return _op->src_pos(); }
dst() const521   LIR_Opr dst() const                         { return _op->dst(); }
dst_pos() const522   LIR_Opr dst_pos() const                     { return _op->dst_pos(); }
length() const523   LIR_Opr length() const                      { return _op->length(); }
tmp() const524   LIR_Opr tmp() const                         { return _op->tmp(); }
525 
526   virtual void emit_code(LIR_Assembler* e);
info() const527   virtual CodeEmitInfo* info() const          { return _op->info(); }
visit(LIR_OpVisitState * visitor)528   virtual void visit(LIR_OpVisitState* visitor) {
529     // don't pass in the code emit info since it's processed in the fast path
530     visitor->do_slow_case();
531   }
532 #ifndef PRODUCT
print_name(outputStream * out) const533   virtual void print_name(outputStream* out) const { out->print("ArrayCopyStub"); }
534 #endif // PRODUCT
535 };
536 
537 //////////////////////////////////////////////////////////////////////////////////////////
538 #if INCLUDE_ALL_GCS
539 
540 // Code stubs for Garbage-First barriers.
541 class G1PreBarrierStub: public CodeStub {
542  private:
543   bool _do_load;
544   LIR_Opr _addr;
545   LIR_Opr _pre_val;
546   LIR_PatchCode _patch_code;
547   CodeEmitInfo* _info;
548 
549  public:
550   // Version that _does_ generate a load of the previous value from addr.
551   // addr (the address of the field to be read) must be a LIR_Address
552   // pre_val (a temporary register) must be a register;
G1PreBarrierStub(LIR_Opr addr,LIR_Opr pre_val,LIR_PatchCode patch_code,CodeEmitInfo * info)553   G1PreBarrierStub(LIR_Opr addr, LIR_Opr pre_val, LIR_PatchCode patch_code, CodeEmitInfo* info) :
554     _addr(addr), _pre_val(pre_val), _do_load(true),
555     _patch_code(patch_code), _info(info)
556   {
557     assert(_pre_val->is_register(), "should be temporary register");
558     assert(_addr->is_address(), "should be the address of the field");
559   }
560 
561   // Version that _does not_ generate load of the previous value; the
562   // previous value is assumed to have already been loaded into pre_val.
G1PreBarrierStub(LIR_Opr pre_val)563   G1PreBarrierStub(LIR_Opr pre_val) :
564     _addr(LIR_OprFact::illegalOpr), _pre_val(pre_val), _do_load(false),
565     _patch_code(lir_patch_none), _info(NULL)
566   {
567     assert(_pre_val->is_register(), "should be a register");
568   }
569 
addr() const570   LIR_Opr addr() const { return _addr; }
pre_val() const571   LIR_Opr pre_val() const { return _pre_val; }
patch_code() const572   LIR_PatchCode patch_code() const { return _patch_code; }
info() const573   CodeEmitInfo* info() const { return _info; }
do_load() const574   bool do_load() const { return _do_load; }
575 
576   virtual void emit_code(LIR_Assembler* e);
visit(LIR_OpVisitState * visitor)577   virtual void visit(LIR_OpVisitState* visitor) {
578     if (_do_load) {
579       // don't pass in the code emit info since it's processed in the fast
580       // path
581       if (_info != NULL)
582         visitor->do_slow_case(_info);
583       else
584         visitor->do_slow_case();
585 
586       visitor->do_input(_addr);
587       visitor->do_temp(_pre_val);
588     } else {
589       visitor->do_slow_case();
590       visitor->do_input(_pre_val);
591     }
592   }
593 #ifndef PRODUCT
print_name(outputStream * out) const594   virtual void print_name(outputStream* out) const { out->print("G1PreBarrierStub"); }
595 #endif // PRODUCT
596 };
597 
598 class G1PostBarrierStub: public CodeStub {
599  private:
600   LIR_Opr _addr;
601   LIR_Opr _new_val;
602 
603   static jbyte* _byte_map_base;
604   static jbyte* byte_map_base_slow();
byte_map_base()605   static jbyte* byte_map_base() {
606     if (_byte_map_base == NULL) {
607       _byte_map_base = byte_map_base_slow();
608     }
609     return _byte_map_base;
610   }
611 
612  public:
613   // addr (the address of the object head) and new_val must be registers.
G1PostBarrierStub(LIR_Opr addr,LIR_Opr new_val)614   G1PostBarrierStub(LIR_Opr addr, LIR_Opr new_val): _addr(addr), _new_val(new_val) { }
615 
addr() const616   LIR_Opr addr() const { return _addr; }
new_val() const617   LIR_Opr new_val() const { return _new_val; }
618 
619   virtual void emit_code(LIR_Assembler* e);
visit(LIR_OpVisitState * visitor)620   virtual void visit(LIR_OpVisitState* visitor) {
621     // don't pass in the code emit info since it's processed in the fast path
622     visitor->do_slow_case();
623     visitor->do_input(_addr);
624     visitor->do_input(_new_val);
625   }
626 #ifndef PRODUCT
print_name(outputStream * out) const627   virtual void print_name(outputStream* out) const { out->print("G1PostBarrierStub"); }
628 #endif // PRODUCT
629 };
630 
631 #endif // INCLUDE_ALL_GCS
632 //////////////////////////////////////////////////////////////////////////////////////////
633 
634 #endif // SHARE_VM_C1_C1_CODESTUBS_HPP
635