src/share/vm/c1/c1_CodeStubs.hpp

Wed, 23 Jan 2013 13:02:39 -0500

author
jprovino
date
Wed, 23 Jan 2013 13:02:39 -0500
changeset 4542
db9981fd3124
parent 4037
da91efe96a93
child 4860
46f6f063b272
permissions
-rw-r--r--

8005915: Unify SERIALGC and INCLUDE_ALTERNATE_GCS
Summary: Rename INCLUDE_ALTERNATE_GCS to INCLUDE_ALL_GCS and replace SERIALGC with INCLUDE_ALL_GCS.
Reviewed-by: coleenp, stefank

     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 };
   170 class DivByZeroStub: public CodeStub {
   171  private:
   172   CodeEmitInfo* _info;
   173   int           _offset;
   175  public:
   176   DivByZeroStub(CodeEmitInfo* info)
   177     : _info(info), _offset(-1) {
   178   }
   179   DivByZeroStub(int offset, CodeEmitInfo* info)
   180     : _info(info), _offset(offset) {
   181   }
   182   virtual void emit_code(LIR_Assembler* e);
   183   virtual CodeEmitInfo* info() const             { return _info; }
   184   virtual bool is_exception_throw_stub() const   { return true; }
   185   virtual bool is_divbyzero_stub() const         { return true; }
   186   virtual void visit(LIR_OpVisitState* visitor) {
   187     visitor->do_slow_case(_info);
   188   }
   189 #ifndef PRODUCT
   190   virtual void print_name(outputStream* out) const { out->print("DivByZeroStub"); }
   191 #endif // PRODUCT
   192 };
   195 class ImplicitNullCheckStub: public CodeStub {
   196  private:
   197   CodeEmitInfo* _info;
   198   int           _offset;
   200  public:
   201   ImplicitNullCheckStub(int offset, CodeEmitInfo* info)
   202     : _offset(offset), _info(info) {
   203   }
   204   virtual void emit_code(LIR_Assembler* e);
   205   virtual CodeEmitInfo* info() const             { return _info; }
   206   virtual bool is_exception_throw_stub() const   { return true; }
   207   virtual void visit(LIR_OpVisitState* visitor) {
   208     visitor->do_slow_case(_info);
   209   }
   210 #ifndef PRODUCT
   211   virtual void print_name(outputStream* out) const { out->print("ImplicitNullCheckStub"); }
   212 #endif // PRODUCT
   213 };
   216 class NewInstanceStub: public CodeStub {
   217  private:
   218   ciInstanceKlass* _klass;
   219   LIR_Opr          _klass_reg;
   220   LIR_Opr          _result;
   221   CodeEmitInfo*    _info;
   222   Runtime1::StubID _stub_id;
   224  public:
   225   NewInstanceStub(LIR_Opr klass_reg, LIR_Opr result, ciInstanceKlass* klass, CodeEmitInfo* info, Runtime1::StubID stub_id);
   226   virtual void emit_code(LIR_Assembler* e);
   227   virtual CodeEmitInfo* info() const             { return _info; }
   228   virtual void visit(LIR_OpVisitState* visitor) {
   229     visitor->do_slow_case(_info);
   230     visitor->do_input(_klass_reg);
   231     visitor->do_output(_result);
   232   }
   233 #ifndef PRODUCT
   234   virtual void print_name(outputStream* out) const { out->print("NewInstanceStub"); }
   235 #endif // PRODUCT
   236 };
   239 class NewTypeArrayStub: public CodeStub {
   240  private:
   241   LIR_Opr       _klass_reg;
   242   LIR_Opr       _length;
   243   LIR_Opr       _result;
   244   CodeEmitInfo* _info;
   246  public:
   247   NewTypeArrayStub(LIR_Opr klass_reg, LIR_Opr length, LIR_Opr result, CodeEmitInfo* info);
   248   virtual void emit_code(LIR_Assembler* e);
   249   virtual CodeEmitInfo* info() const             { return _info; }
   250   virtual void visit(LIR_OpVisitState* visitor) {
   251     visitor->do_slow_case(_info);
   252     visitor->do_input(_klass_reg);
   253     visitor->do_input(_length);
   254     assert(_result->is_valid(), "must be valid"); visitor->do_output(_result);
   255   }
   256 #ifndef PRODUCT
   257   virtual void print_name(outputStream* out) const { out->print("NewTypeArrayStub"); }
   258 #endif // PRODUCT
   259 };
   262 class NewObjectArrayStub: public CodeStub {
   263  private:
   264   LIR_Opr        _klass_reg;
   265   LIR_Opr        _length;
   266   LIR_Opr        _result;
   267   CodeEmitInfo*  _info;
   269  public:
   270   NewObjectArrayStub(LIR_Opr klass_reg, LIR_Opr length, LIR_Opr result, CodeEmitInfo* info);
   271   virtual void emit_code(LIR_Assembler* e);
   272   virtual CodeEmitInfo* info() const             { return _info; }
   273   virtual void visit(LIR_OpVisitState* visitor) {
   274     visitor->do_slow_case(_info);
   275     visitor->do_input(_klass_reg);
   276     visitor->do_input(_length);
   277     assert(_result->is_valid(), "must be valid"); visitor->do_output(_result);
   278   }
   279 #ifndef PRODUCT
   280   virtual void print_name(outputStream* out) const { out->print("NewObjectArrayStub"); }
   281 #endif // PRODUCT
   282 };
   285 class MonitorAccessStub: public CodeStub {
   286  protected:
   287   LIR_Opr _obj_reg;
   288   LIR_Opr _lock_reg;
   290  public:
   291   MonitorAccessStub(LIR_Opr obj_reg, LIR_Opr lock_reg) {
   292     _obj_reg  = obj_reg;
   293     _lock_reg  = lock_reg;
   294   }
   296 #ifndef PRODUCT
   297   virtual void print_name(outputStream* out) const { out->print("MonitorAccessStub"); }
   298 #endif // PRODUCT
   299 };
   302 class MonitorEnterStub: public MonitorAccessStub {
   303  private:
   304   CodeEmitInfo* _info;
   306  public:
   307   MonitorEnterStub(LIR_Opr obj_reg, LIR_Opr lock_reg, CodeEmitInfo* info);
   309   virtual void emit_code(LIR_Assembler* e);
   310   virtual CodeEmitInfo* info() const             { return _info; }
   311   virtual void visit(LIR_OpVisitState* visitor) {
   312     visitor->do_input(_obj_reg);
   313     visitor->do_input(_lock_reg);
   314     visitor->do_slow_case(_info);
   315   }
   316 #ifndef PRODUCT
   317   virtual void print_name(outputStream* out) const { out->print("MonitorEnterStub"); }
   318 #endif // PRODUCT
   319 };
   322 class MonitorExitStub: public MonitorAccessStub {
   323  private:
   324   bool _compute_lock;
   325   int  _monitor_ix;
   327  public:
   328   MonitorExitStub(LIR_Opr lock_reg, bool compute_lock, int monitor_ix)
   329     : MonitorAccessStub(LIR_OprFact::illegalOpr, lock_reg),
   330       _compute_lock(compute_lock), _monitor_ix(monitor_ix) { }
   331   virtual void emit_code(LIR_Assembler* e);
   332   virtual void visit(LIR_OpVisitState* visitor) {
   333     assert(_obj_reg->is_illegal(), "unused");
   334     if (_compute_lock) {
   335       visitor->do_temp(_lock_reg);
   336     } else {
   337       visitor->do_input(_lock_reg);
   338     }
   339   }
   340 #ifndef PRODUCT
   341   virtual void print_name(outputStream* out) const { out->print("MonitorExitStub"); }
   342 #endif // PRODUCT
   343 };
   346 class PatchingStub: public CodeStub {
   347  public:
   348   enum PatchID {
   349     access_field_id,
   350     load_klass_id,
   351     load_mirror_id
   352   };
   353   enum constants {
   354     patch_info_size = 3
   355   };
   356  private:
   357   PatchID       _id;
   358   address       _pc_start;
   359   int           _bytes_to_copy;
   360   Label         _patched_code_entry;
   361   Label         _patch_site_entry;
   362   Label         _patch_site_continuation;
   363   Register      _obj;
   364   CodeEmitInfo* _info;
   365   int           _index;  // index of the patchable oop or Klass* in nmethod oop or metadata table if needed
   366   static int    _patch_info_offset;
   368   void align_patch_site(MacroAssembler* masm);
   370  public:
   371   static int patch_info_offset() { return _patch_info_offset; }
   373   PatchingStub(MacroAssembler* masm, PatchID id, int index = -1):
   374       _id(id)
   375     , _info(NULL)
   376     , _index(index) {
   377     if (os::is_MP()) {
   378       // force alignment of patch sites on MP hardware so we
   379       // can guarantee atomic writes to the patch site.
   380       align_patch_site(masm);
   381     }
   382     _pc_start = masm->pc();
   383     masm->bind(_patch_site_entry);
   384   }
   386   void install(MacroAssembler* masm, LIR_PatchCode patch_code, Register obj, CodeEmitInfo* info) {
   387     _info = info;
   388     _obj = obj;
   389     masm->bind(_patch_site_continuation);
   390     _bytes_to_copy = masm->pc() - pc_start();
   391     if (_id == PatchingStub::access_field_id) {
   392       // embed a fixed offset to handle long patches which need to be offset by a word.
   393       // the patching code will just add the field offset field to this offset so
   394       // that we can refernce either the high or low word of a double word field.
   395       int field_offset = 0;
   396       switch (patch_code) {
   397       case lir_patch_low:         field_offset = lo_word_offset_in_bytes; break;
   398       case lir_patch_high:        field_offset = hi_word_offset_in_bytes; break;
   399       case lir_patch_normal:      field_offset = 0;                       break;
   400       default: ShouldNotReachHere();
   401       }
   402       NativeMovRegMem* n_move = nativeMovRegMem_at(pc_start());
   403       n_move->set_offset(field_offset);
   404     } else if (_id == load_klass_id || _id == load_mirror_id) {
   405       assert(_obj != noreg, "must have register object for load_klass/load_mirror");
   406 #ifdef ASSERT
   407       // verify that we're pointing at a NativeMovConstReg
   408       nativeMovConstReg_at(pc_start());
   409 #endif
   410     } else {
   411       ShouldNotReachHere();
   412     }
   413     assert(_bytes_to_copy <= (masm->pc() - pc_start()), "not enough bytes");
   414   }
   416   address pc_start() const                       { return _pc_start; }
   417   PatchID id() const                             { return _id; }
   419   virtual void emit_code(LIR_Assembler* e);
   420   virtual CodeEmitInfo* info() const             { return _info; }
   421   virtual void visit(LIR_OpVisitState* visitor) {
   422     visitor->do_slow_case(_info);
   423   }
   424 #ifndef PRODUCT
   425   virtual void print_name(outputStream* out) const { out->print("PatchingStub"); }
   426 #endif // PRODUCT
   427 };
   430 //------------------------------------------------------------------------------
   431 // DeoptimizeStub
   432 //
   433 class DeoptimizeStub : public CodeStub {
   434 private:
   435   CodeEmitInfo* _info;
   437 public:
   438   DeoptimizeStub(CodeEmitInfo* info) : _info(new CodeEmitInfo(info)) {}
   440   virtual void emit_code(LIR_Assembler* e);
   441   virtual CodeEmitInfo* info() const           { return _info; }
   442   virtual bool is_exception_throw_stub() const { return true; }
   443   virtual void visit(LIR_OpVisitState* visitor) {
   444     visitor->do_slow_case(_info);
   445   }
   446 #ifndef PRODUCT
   447   virtual void print_name(outputStream* out) const { out->print("DeoptimizeStub"); }
   448 #endif // PRODUCT
   449 };
   452 class SimpleExceptionStub: public CodeStub {
   453  private:
   454   LIR_Opr          _obj;
   455   Runtime1::StubID _stub;
   456   CodeEmitInfo*    _info;
   458  public:
   459   SimpleExceptionStub(Runtime1::StubID stub, LIR_Opr obj, CodeEmitInfo* info):
   460     _obj(obj), _info(info), _stub(stub) {
   461   }
   463   void set_obj(LIR_Opr obj) {
   464     _obj = obj;
   465   }
   467   virtual void emit_code(LIR_Assembler* e);
   468   virtual CodeEmitInfo* info() const             { return _info; }
   469   virtual bool is_exception_throw_stub() const   { return true; }
   470   virtual void visit(LIR_OpVisitState* visitor) {
   471     if (_obj->is_valid()) visitor->do_input(_obj);
   472     visitor->do_slow_case(_info);
   473   }
   474 #ifndef PRODUCT
   475   virtual void print_name(outputStream* out) const { out->print("SimpleExceptionStub"); }
   476 #endif // PRODUCT
   477 };
   481 class ArrayStoreExceptionStub: public SimpleExceptionStub {
   482  private:
   483   CodeEmitInfo* _info;
   485  public:
   486   ArrayStoreExceptionStub(LIR_Opr obj, CodeEmitInfo* info): SimpleExceptionStub(Runtime1::throw_array_store_exception_id, obj, info) {}
   487 #ifndef PRODUCT
   488   virtual void print_name(outputStream* out) const { out->print("ArrayStoreExceptionStub"); }
   489 #endif // PRODUCT
   490 };
   493 class ArrayCopyStub: public CodeStub {
   494  private:
   495   LIR_OpArrayCopy* _op;
   497  public:
   498   ArrayCopyStub(LIR_OpArrayCopy* op): _op(op) { }
   500   LIR_Opr src() const                         { return _op->src(); }
   501   LIR_Opr src_pos() const                     { return _op->src_pos(); }
   502   LIR_Opr dst() const                         { return _op->dst(); }
   503   LIR_Opr dst_pos() const                     { return _op->dst_pos(); }
   504   LIR_Opr length() const                      { return _op->length(); }
   505   LIR_Opr tmp() const                         { return _op->tmp(); }
   507   virtual void emit_code(LIR_Assembler* e);
   508   virtual CodeEmitInfo* info() const          { return _op->info(); }
   509   virtual void visit(LIR_OpVisitState* visitor) {
   510     // don't pass in the code emit info since it's processed in the fast path
   511     visitor->do_slow_case();
   512   }
   513 #ifndef PRODUCT
   514   virtual void print_name(outputStream* out) const { out->print("ArrayCopyStub"); }
   515 #endif // PRODUCT
   516 };
   518 //////////////////////////////////////////////////////////////////////////////////////////
   519 #if INCLUDE_ALL_GCS
   521 // Code stubs for Garbage-First barriers.
   522 class G1PreBarrierStub: public CodeStub {
   523  private:
   524   bool _do_load;
   525   LIR_Opr _addr;
   526   LIR_Opr _pre_val;
   527   LIR_PatchCode _patch_code;
   528   CodeEmitInfo* _info;
   530  public:
   531   // Version that _does_ generate a load of the previous value from addr.
   532   // addr (the address of the field to be read) must be a LIR_Address
   533   // pre_val (a temporary register) must be a register;
   534   G1PreBarrierStub(LIR_Opr addr, LIR_Opr pre_val, LIR_PatchCode patch_code, CodeEmitInfo* info) :
   535     _addr(addr), _pre_val(pre_val), _do_load(true),
   536     _patch_code(patch_code), _info(info)
   537   {
   538     assert(_pre_val->is_register(), "should be temporary register");
   539     assert(_addr->is_address(), "should be the address of the field");
   540   }
   542   // Version that _does not_ generate load of the previous value; the
   543   // previous value is assumed to have already been loaded into pre_val.
   544   G1PreBarrierStub(LIR_Opr pre_val) :
   545     _addr(LIR_OprFact::illegalOpr), _pre_val(pre_val), _do_load(false),
   546     _patch_code(lir_patch_none), _info(NULL)
   547   {
   548     assert(_pre_val->is_register(), "should be a register");
   549   }
   551   LIR_Opr addr() const { return _addr; }
   552   LIR_Opr pre_val() const { return _pre_val; }
   553   LIR_PatchCode patch_code() const { return _patch_code; }
   554   CodeEmitInfo* info() const { return _info; }
   555   bool do_load() const { return _do_load; }
   557   virtual void emit_code(LIR_Assembler* e);
   558   virtual void visit(LIR_OpVisitState* visitor) {
   559     if (_do_load) {
   560       // don't pass in the code emit info since it's processed in the fast
   561       // path
   562       if (_info != NULL)
   563         visitor->do_slow_case(_info);
   564       else
   565         visitor->do_slow_case();
   567       visitor->do_input(_addr);
   568       visitor->do_temp(_pre_val);
   569     } else {
   570       visitor->do_slow_case();
   571       visitor->do_input(_pre_val);
   572     }
   573   }
   574 #ifndef PRODUCT
   575   virtual void print_name(outputStream* out) const { out->print("G1PreBarrierStub"); }
   576 #endif // PRODUCT
   577 };
   579 class G1PostBarrierStub: public CodeStub {
   580  private:
   581   LIR_Opr _addr;
   582   LIR_Opr _new_val;
   584   static jbyte* _byte_map_base;
   585   static jbyte* byte_map_base_slow();
   586   static jbyte* byte_map_base() {
   587     if (_byte_map_base == NULL) {
   588       _byte_map_base = byte_map_base_slow();
   589     }
   590     return _byte_map_base;
   591   }
   593  public:
   594   // addr (the address of the object head) and new_val must be registers.
   595   G1PostBarrierStub(LIR_Opr addr, LIR_Opr new_val): _addr(addr), _new_val(new_val) { }
   597   LIR_Opr addr() const { return _addr; }
   598   LIR_Opr new_val() const { return _new_val; }
   600   virtual void emit_code(LIR_Assembler* e);
   601   virtual void visit(LIR_OpVisitState* visitor) {
   602     // don't pass in the code emit info since it's processed in the fast path
   603     visitor->do_slow_case();
   604     visitor->do_input(_addr);
   605     visitor->do_input(_new_val);
   606   }
   607 #ifndef PRODUCT
   608   virtual void print_name(outputStream* out) const { out->print("G1PostBarrierStub"); }
   609 #endif // PRODUCT
   610 };
   612 #endif // INCLUDE_ALL_GCS
   613 //////////////////////////////////////////////////////////////////////////////////////////
   615 #endif // SHARE_VM_C1_C1_CODESTUBS_HPP

mercurial