src/share/vm/c1/c1_CodeStubs.hpp

Tue, 18 Jun 2013 12:31:07 -0700

author
johnc
date
Tue, 18 Jun 2013 12:31:07 -0700
changeset 5277
01522ca68fc7
parent 4860
46f6f063b272
child 5628
f98f5d48f511
permissions
-rw-r--r--

8015237: Parallelize string table scanning during strong root processing
Summary: Parallelize the scanning of the intern string table by having each GC worker claim a given number of buckets. Changes were also reviewed by Per Liden <per.liden@oracle.com>.
Reviewed-by: tschatzl, stefank, twisti

     1 /*
     2  * Copyright (c) 1999, 2012, 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  */
    25 #ifndef SHARE_VM_C1_C1_CODESTUBS_HPP
    26 #define SHARE_VM_C1_C1_CODESTUBS_HPP
    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"
    36 class CodeEmitInfo;
    37 class LIR_Assembler;
    38 class LIR_OpVisitState;
    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.
    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
    50  public:
    51   CodeStub() {}
    53   // code generation
    54   void assert_no_unbound_labels()                { assert(!_entry.is_unbound() && !_continuation.is_unbound(), "unbound label"); }
    55   virtual void emit_code(LIR_Assembler* e) = 0;
    56   virtual CodeEmitInfo* info() const             { return NULL; }
    57   virtual bool is_exception_throw_stub() const   { return false; }
    58   virtual bool is_range_check_stub() const       { return false; }
    59   virtual bool is_divbyzero_stub() const         { return false; }
    60 #ifndef PRODUCT
    61   virtual void print_name(outputStream* out) const = 0;
    62 #endif
    64   // label access
    65   Label* entry()                                 { return &_entry; }
    66   Label* continuation()                          { return &_continuation; }
    67   // for LIR
    68   virtual void visit(LIR_OpVisitState* visit) {
    69 #ifndef PRODUCT
    70     if (LIRTracePeephole && Verbose) {
    71       tty->print("no visitor for ");
    72       print_name(tty);
    73       tty->cr();
    74     }
    75 #endif
    76   }
    77 };
    80 define_array(CodeStubArray, CodeStub*)
    81 define_stack(_CodeStubList, CodeStubArray)
    83 class CodeStubList: public _CodeStubList {
    84  public:
    85   CodeStubList(): _CodeStubList() {}
    87   void append(CodeStub* stub) {
    88     if (!contains(stub)) {
    89       _CodeStubList::append(stub);
    90     }
    91   }
    92 };
    94 class CounterOverflowStub: public CodeStub {
    95  private:
    96   CodeEmitInfo* _info;
    97   int           _bci;
    98   LIR_Opr       _method;
   100 public:
   101   CounterOverflowStub(CodeEmitInfo* info, int bci, LIR_Opr method) :  _info(info), _bci(bci), _method(method) {
   102   }
   104   virtual void emit_code(LIR_Assembler* e);
   106   virtual void visit(LIR_OpVisitState* visitor) {
   107     visitor->do_slow_case(_info);
   108     visitor->do_input(_method);
   109   }
   111 #ifndef PRODUCT
   112   virtual void print_name(outputStream* out) const { out->print("CounterOverflowStub"); }
   113 #endif // PRODUCT
   115 };
   117 class ConversionStub: public CodeStub {
   118  private:
   119   Bytecodes::Code _bytecode;
   120   LIR_Opr         _input;
   121   LIR_Opr         _result;
   123   static float float_zero;
   124   static double double_zero;
   125  public:
   126   ConversionStub(Bytecodes::Code bytecode, LIR_Opr input, LIR_Opr result)
   127     : _bytecode(bytecode), _input(input), _result(result) {
   128   }
   130   Bytecodes::Code bytecode() { return _bytecode; }
   131   LIR_Opr         input()    { return _input; }
   132   LIR_Opr         result()   { return _result; }
   134   virtual void emit_code(LIR_Assembler* e);
   135   virtual void visit(LIR_OpVisitState* visitor) {
   136     visitor->do_slow_case();
   137     visitor->do_input(_input);
   138     visitor->do_output(_result);
   139   }
   140 #ifndef PRODUCT
   141   virtual void print_name(outputStream* out) const { out->print("ConversionStub"); }
   142 #endif // PRODUCT
   143 };
   146 // Throws ArrayIndexOutOfBoundsException by default but can be
   147 // configured to throw IndexOutOfBoundsException in constructor
   148 class RangeCheckStub: public CodeStub {
   149  private:
   150   CodeEmitInfo* _info;
   151   LIR_Opr       _index;
   152   bool          _throw_index_out_of_bounds_exception;
   154  public:
   155   RangeCheckStub(CodeEmitInfo* info, LIR_Opr index, bool throw_index_out_of_bounds_exception = false);
   156   virtual void emit_code(LIR_Assembler* e);
   157   virtual CodeEmitInfo* info() const             { return _info; }
   158   virtual bool is_exception_throw_stub() const   { return true; }
   159   virtual bool is_range_check_stub() const       { return true; }
   160   virtual void visit(LIR_OpVisitState* visitor) {
   161     visitor->do_slow_case(_info);
   162     visitor->do_input(_index);
   163   }
   164 #ifndef PRODUCT
   165   virtual void print_name(outputStream* out) const { out->print("RangeCheckStub"); }
   166 #endif // PRODUCT
   167 };
   169 // stub used when predicate fails and deoptimization is needed
   170 class PredicateFailedStub: public CodeStub {
   171  private:
   172   CodeEmitInfo* _info;
   174  public:
   175   PredicateFailedStub(CodeEmitInfo* info);
   176   virtual void emit_code(LIR_Assembler* e);
   177   virtual CodeEmitInfo* info() const             { return _info; }
   178   virtual void visit(LIR_OpVisitState* visitor) {
   179     visitor->do_slow_case(_info);
   180   }
   181 #ifndef PRODUCT
   182   virtual void print_name(outputStream* out) const { out->print("PredicateFailedStub"); }
   183 #endif // PRODUCT
   184 };
   186 class DivByZeroStub: public CodeStub {
   187  private:
   188   CodeEmitInfo* _info;
   189   int           _offset;
   191  public:
   192   DivByZeroStub(CodeEmitInfo* info)
   193     : _info(info), _offset(-1) {
   194   }
   195   DivByZeroStub(int offset, CodeEmitInfo* info)
   196     : _info(info), _offset(offset) {
   197   }
   198   virtual void emit_code(LIR_Assembler* e);
   199   virtual CodeEmitInfo* info() const             { return _info; }
   200   virtual bool is_exception_throw_stub() const   { return true; }
   201   virtual bool is_divbyzero_stub() const         { return true; }
   202   virtual void visit(LIR_OpVisitState* visitor) {
   203     visitor->do_slow_case(_info);
   204   }
   205 #ifndef PRODUCT
   206   virtual void print_name(outputStream* out) const { out->print("DivByZeroStub"); }
   207 #endif // PRODUCT
   208 };
   211 class ImplicitNullCheckStub: public CodeStub {
   212  private:
   213   CodeEmitInfo* _info;
   214   int           _offset;
   216  public:
   217   ImplicitNullCheckStub(int offset, CodeEmitInfo* info)
   218     : _offset(offset), _info(info) {
   219   }
   220   virtual void emit_code(LIR_Assembler* e);
   221   virtual CodeEmitInfo* info() const             { return _info; }
   222   virtual bool is_exception_throw_stub() const   { return true; }
   223   virtual void visit(LIR_OpVisitState* visitor) {
   224     visitor->do_slow_case(_info);
   225   }
   226 #ifndef PRODUCT
   227   virtual void print_name(outputStream* out) const { out->print("ImplicitNullCheckStub"); }
   228 #endif // PRODUCT
   229 };
   232 class NewInstanceStub: public CodeStub {
   233  private:
   234   ciInstanceKlass* _klass;
   235   LIR_Opr          _klass_reg;
   236   LIR_Opr          _result;
   237   CodeEmitInfo*    _info;
   238   Runtime1::StubID _stub_id;
   240  public:
   241   NewInstanceStub(LIR_Opr klass_reg, LIR_Opr result, ciInstanceKlass* klass, CodeEmitInfo* info, Runtime1::StubID stub_id);
   242   virtual void emit_code(LIR_Assembler* e);
   243   virtual CodeEmitInfo* info() const             { return _info; }
   244   virtual void visit(LIR_OpVisitState* visitor) {
   245     visitor->do_slow_case(_info);
   246     visitor->do_input(_klass_reg);
   247     visitor->do_output(_result);
   248   }
   249 #ifndef PRODUCT
   250   virtual void print_name(outputStream* out) const { out->print("NewInstanceStub"); }
   251 #endif // PRODUCT
   252 };
   255 class NewTypeArrayStub: public CodeStub {
   256  private:
   257   LIR_Opr       _klass_reg;
   258   LIR_Opr       _length;
   259   LIR_Opr       _result;
   260   CodeEmitInfo* _info;
   262  public:
   263   NewTypeArrayStub(LIR_Opr klass_reg, LIR_Opr length, LIR_Opr result, CodeEmitInfo* info);
   264   virtual void emit_code(LIR_Assembler* e);
   265   virtual CodeEmitInfo* info() const             { return _info; }
   266   virtual void visit(LIR_OpVisitState* visitor) {
   267     visitor->do_slow_case(_info);
   268     visitor->do_input(_klass_reg);
   269     visitor->do_input(_length);
   270     assert(_result->is_valid(), "must be valid"); visitor->do_output(_result);
   271   }
   272 #ifndef PRODUCT
   273   virtual void print_name(outputStream* out) const { out->print("NewTypeArrayStub"); }
   274 #endif // PRODUCT
   275 };
   278 class NewObjectArrayStub: public CodeStub {
   279  private:
   280   LIR_Opr        _klass_reg;
   281   LIR_Opr        _length;
   282   LIR_Opr        _result;
   283   CodeEmitInfo*  _info;
   285  public:
   286   NewObjectArrayStub(LIR_Opr klass_reg, LIR_Opr length, LIR_Opr result, CodeEmitInfo* info);
   287   virtual void emit_code(LIR_Assembler* e);
   288   virtual CodeEmitInfo* info() const             { return _info; }
   289   virtual void visit(LIR_OpVisitState* visitor) {
   290     visitor->do_slow_case(_info);
   291     visitor->do_input(_klass_reg);
   292     visitor->do_input(_length);
   293     assert(_result->is_valid(), "must be valid"); visitor->do_output(_result);
   294   }
   295 #ifndef PRODUCT
   296   virtual void print_name(outputStream* out) const { out->print("NewObjectArrayStub"); }
   297 #endif // PRODUCT
   298 };
   301 class MonitorAccessStub: public CodeStub {
   302  protected:
   303   LIR_Opr _obj_reg;
   304   LIR_Opr _lock_reg;
   306  public:
   307   MonitorAccessStub(LIR_Opr obj_reg, LIR_Opr lock_reg) {
   308     _obj_reg  = obj_reg;
   309     _lock_reg  = lock_reg;
   310   }
   312 #ifndef PRODUCT
   313   virtual void print_name(outputStream* out) const { out->print("MonitorAccessStub"); }
   314 #endif // PRODUCT
   315 };
   318 class MonitorEnterStub: public MonitorAccessStub {
   319  private:
   320   CodeEmitInfo* _info;
   322  public:
   323   MonitorEnterStub(LIR_Opr obj_reg, LIR_Opr lock_reg, CodeEmitInfo* info);
   325   virtual void emit_code(LIR_Assembler* e);
   326   virtual CodeEmitInfo* info() const             { return _info; }
   327   virtual void visit(LIR_OpVisitState* visitor) {
   328     visitor->do_input(_obj_reg);
   329     visitor->do_input(_lock_reg);
   330     visitor->do_slow_case(_info);
   331   }
   332 #ifndef PRODUCT
   333   virtual void print_name(outputStream* out) const { out->print("MonitorEnterStub"); }
   334 #endif // PRODUCT
   335 };
   338 class MonitorExitStub: public MonitorAccessStub {
   339  private:
   340   bool _compute_lock;
   341   int  _monitor_ix;
   343  public:
   344   MonitorExitStub(LIR_Opr lock_reg, bool compute_lock, int monitor_ix)
   345     : MonitorAccessStub(LIR_OprFact::illegalOpr, lock_reg),
   346       _compute_lock(compute_lock), _monitor_ix(monitor_ix) { }
   347   virtual void emit_code(LIR_Assembler* e);
   348   virtual void visit(LIR_OpVisitState* visitor) {
   349     assert(_obj_reg->is_illegal(), "unused");
   350     if (_compute_lock) {
   351       visitor->do_temp(_lock_reg);
   352     } else {
   353       visitor->do_input(_lock_reg);
   354     }
   355   }
   356 #ifndef PRODUCT
   357   virtual void print_name(outputStream* out) const { out->print("MonitorExitStub"); }
   358 #endif // PRODUCT
   359 };
   362 class PatchingStub: public CodeStub {
   363  public:
   364   enum PatchID {
   365     access_field_id,
   366     load_klass_id,
   367     load_mirror_id
   368   };
   369   enum constants {
   370     patch_info_size = 3
   371   };
   372  private:
   373   PatchID       _id;
   374   address       _pc_start;
   375   int           _bytes_to_copy;
   376   Label         _patched_code_entry;
   377   Label         _patch_site_entry;
   378   Label         _patch_site_continuation;
   379   Register      _obj;
   380   CodeEmitInfo* _info;
   381   int           _index;  // index of the patchable oop or Klass* in nmethod oop or metadata table if needed
   382   static int    _patch_info_offset;
   384   void align_patch_site(MacroAssembler* masm);
   386  public:
   387   static int patch_info_offset() { return _patch_info_offset; }
   389   PatchingStub(MacroAssembler* masm, PatchID id, int index = -1):
   390       _id(id)
   391     , _info(NULL)
   392     , _index(index) {
   393     if (os::is_MP()) {
   394       // force alignment of patch sites on MP hardware so we
   395       // can guarantee atomic writes to the patch site.
   396       align_patch_site(masm);
   397     }
   398     _pc_start = masm->pc();
   399     masm->bind(_patch_site_entry);
   400   }
   402   void install(MacroAssembler* masm, LIR_PatchCode patch_code, Register obj, CodeEmitInfo* info) {
   403     _info = info;
   404     _obj = obj;
   405     masm->bind(_patch_site_continuation);
   406     _bytes_to_copy = masm->pc() - pc_start();
   407     if (_id == PatchingStub::access_field_id) {
   408       // embed a fixed offset to handle long patches which need to be offset by a word.
   409       // the patching code will just add the field offset field to this offset so
   410       // that we can refernce either the high or low word of a double word field.
   411       int field_offset = 0;
   412       switch (patch_code) {
   413       case lir_patch_low:         field_offset = lo_word_offset_in_bytes; break;
   414       case lir_patch_high:        field_offset = hi_word_offset_in_bytes; break;
   415       case lir_patch_normal:      field_offset = 0;                       break;
   416       default: ShouldNotReachHere();
   417       }
   418       NativeMovRegMem* n_move = nativeMovRegMem_at(pc_start());
   419       n_move->set_offset(field_offset);
   420     } else if (_id == load_klass_id || _id == load_mirror_id) {
   421       assert(_obj != noreg, "must have register object for load_klass/load_mirror");
   422 #ifdef ASSERT
   423       // verify that we're pointing at a NativeMovConstReg
   424       nativeMovConstReg_at(pc_start());
   425 #endif
   426     } else {
   427       ShouldNotReachHere();
   428     }
   429     assert(_bytes_to_copy <= (masm->pc() - pc_start()), "not enough bytes");
   430   }
   432   address pc_start() const                       { return _pc_start; }
   433   PatchID id() const                             { return _id; }
   435   virtual void emit_code(LIR_Assembler* e);
   436   virtual CodeEmitInfo* info() const             { return _info; }
   437   virtual void visit(LIR_OpVisitState* visitor) {
   438     visitor->do_slow_case(_info);
   439   }
   440 #ifndef PRODUCT
   441   virtual void print_name(outputStream* out) const { out->print("PatchingStub"); }
   442 #endif // PRODUCT
   443 };
   446 //------------------------------------------------------------------------------
   447 // DeoptimizeStub
   448 //
   449 class DeoptimizeStub : public CodeStub {
   450 private:
   451   CodeEmitInfo* _info;
   453 public:
   454   DeoptimizeStub(CodeEmitInfo* info) : _info(new CodeEmitInfo(info)) {}
   456   virtual void emit_code(LIR_Assembler* e);
   457   virtual CodeEmitInfo* info() const           { return _info; }
   458   virtual bool is_exception_throw_stub() const { return true; }
   459   virtual void visit(LIR_OpVisitState* visitor) {
   460     visitor->do_slow_case(_info);
   461   }
   462 #ifndef PRODUCT
   463   virtual void print_name(outputStream* out) const { out->print("DeoptimizeStub"); }
   464 #endif // PRODUCT
   465 };
   468 class SimpleExceptionStub: public CodeStub {
   469  private:
   470   LIR_Opr          _obj;
   471   Runtime1::StubID _stub;
   472   CodeEmitInfo*    _info;
   474  public:
   475   SimpleExceptionStub(Runtime1::StubID stub, LIR_Opr obj, CodeEmitInfo* info):
   476     _obj(obj), _info(info), _stub(stub) {
   477   }
   479   void set_obj(LIR_Opr obj) {
   480     _obj = obj;
   481   }
   483   virtual void emit_code(LIR_Assembler* e);
   484   virtual CodeEmitInfo* info() const             { return _info; }
   485   virtual bool is_exception_throw_stub() const   { return true; }
   486   virtual void visit(LIR_OpVisitState* visitor) {
   487     if (_obj->is_valid()) visitor->do_input(_obj);
   488     visitor->do_slow_case(_info);
   489   }
   490 #ifndef PRODUCT
   491   virtual void print_name(outputStream* out) const { out->print("SimpleExceptionStub"); }
   492 #endif // PRODUCT
   493 };
   497 class ArrayStoreExceptionStub: public SimpleExceptionStub {
   498  private:
   499   CodeEmitInfo* _info;
   501  public:
   502   ArrayStoreExceptionStub(LIR_Opr obj, CodeEmitInfo* info): SimpleExceptionStub(Runtime1::throw_array_store_exception_id, obj, info) {}
   503 #ifndef PRODUCT
   504   virtual void print_name(outputStream* out) const { out->print("ArrayStoreExceptionStub"); }
   505 #endif // PRODUCT
   506 };
   509 class ArrayCopyStub: public CodeStub {
   510  private:
   511   LIR_OpArrayCopy* _op;
   513  public:
   514   ArrayCopyStub(LIR_OpArrayCopy* op): _op(op) { }
   516   LIR_Opr src() const                         { return _op->src(); }
   517   LIR_Opr src_pos() const                     { return _op->src_pos(); }
   518   LIR_Opr dst() const                         { return _op->dst(); }
   519   LIR_Opr dst_pos() const                     { return _op->dst_pos(); }
   520   LIR_Opr length() const                      { return _op->length(); }
   521   LIR_Opr tmp() const                         { return _op->tmp(); }
   523   virtual void emit_code(LIR_Assembler* e);
   524   virtual CodeEmitInfo* info() const          { return _op->info(); }
   525   virtual void visit(LIR_OpVisitState* visitor) {
   526     // don't pass in the code emit info since it's processed in the fast path
   527     visitor->do_slow_case();
   528   }
   529 #ifndef PRODUCT
   530   virtual void print_name(outputStream* out) const { out->print("ArrayCopyStub"); }
   531 #endif // PRODUCT
   532 };
   534 //////////////////////////////////////////////////////////////////////////////////////////
   535 #if INCLUDE_ALL_GCS
   537 // Code stubs for Garbage-First barriers.
   538 class G1PreBarrierStub: public CodeStub {
   539  private:
   540   bool _do_load;
   541   LIR_Opr _addr;
   542   LIR_Opr _pre_val;
   543   LIR_PatchCode _patch_code;
   544   CodeEmitInfo* _info;
   546  public:
   547   // Version that _does_ generate a load of the previous value from addr.
   548   // addr (the address of the field to be read) must be a LIR_Address
   549   // pre_val (a temporary register) must be a register;
   550   G1PreBarrierStub(LIR_Opr addr, LIR_Opr pre_val, LIR_PatchCode patch_code, CodeEmitInfo* info) :
   551     _addr(addr), _pre_val(pre_val), _do_load(true),
   552     _patch_code(patch_code), _info(info)
   553   {
   554     assert(_pre_val->is_register(), "should be temporary register");
   555     assert(_addr->is_address(), "should be the address of the field");
   556   }
   558   // Version that _does not_ generate load of the previous value; the
   559   // previous value is assumed to have already been loaded into pre_val.
   560   G1PreBarrierStub(LIR_Opr pre_val) :
   561     _addr(LIR_OprFact::illegalOpr), _pre_val(pre_val), _do_load(false),
   562     _patch_code(lir_patch_none), _info(NULL)
   563   {
   564     assert(_pre_val->is_register(), "should be a register");
   565   }
   567   LIR_Opr addr() const { return _addr; }
   568   LIR_Opr pre_val() const { return _pre_val; }
   569   LIR_PatchCode patch_code() const { return _patch_code; }
   570   CodeEmitInfo* info() const { return _info; }
   571   bool do_load() const { return _do_load; }
   573   virtual void emit_code(LIR_Assembler* e);
   574   virtual void visit(LIR_OpVisitState* visitor) {
   575     if (_do_load) {
   576       // don't pass in the code emit info since it's processed in the fast
   577       // path
   578       if (_info != NULL)
   579         visitor->do_slow_case(_info);
   580       else
   581         visitor->do_slow_case();
   583       visitor->do_input(_addr);
   584       visitor->do_temp(_pre_val);
   585     } else {
   586       visitor->do_slow_case();
   587       visitor->do_input(_pre_val);
   588     }
   589   }
   590 #ifndef PRODUCT
   591   virtual void print_name(outputStream* out) const { out->print("G1PreBarrierStub"); }
   592 #endif // PRODUCT
   593 };
   595 class G1PostBarrierStub: public CodeStub {
   596  private:
   597   LIR_Opr _addr;
   598   LIR_Opr _new_val;
   600   static jbyte* _byte_map_base;
   601   static jbyte* byte_map_base_slow();
   602   static jbyte* byte_map_base() {
   603     if (_byte_map_base == NULL) {
   604       _byte_map_base = byte_map_base_slow();
   605     }
   606     return _byte_map_base;
   607   }
   609  public:
   610   // addr (the address of the object head) and new_val must be registers.
   611   G1PostBarrierStub(LIR_Opr addr, LIR_Opr new_val): _addr(addr), _new_val(new_val) { }
   613   LIR_Opr addr() const { return _addr; }
   614   LIR_Opr new_val() const { return _new_val; }
   616   virtual void emit_code(LIR_Assembler* e);
   617   virtual void visit(LIR_OpVisitState* visitor) {
   618     // don't pass in the code emit info since it's processed in the fast path
   619     visitor->do_slow_case();
   620     visitor->do_input(_addr);
   621     visitor->do_input(_new_val);
   622   }
   623 #ifndef PRODUCT
   624   virtual void print_name(outputStream* out) const { out->print("G1PostBarrierStub"); }
   625 #endif // PRODUCT
   626 };
   628 #endif // INCLUDE_ALL_GCS
   629 //////////////////////////////////////////////////////////////////////////////////////////
   631 #endif // SHARE_VM_C1_C1_CODESTUBS_HPP

mercurial