src/share/vm/c1/c1_CodeStubs.hpp

Mon, 24 Jan 2011 13:34:18 -0800

author
never
date
Mon, 24 Jan 2011 13:34:18 -0800
changeset 2488
e4fee0bdaa85
parent 2314
f95d63e2154a
child 2781
e1162778c1c8
permissions
-rw-r--r--

7008809: should report the class in ArrayStoreExceptions from compiled code
Reviewed-by: iveresov, twisti

     1 /*
     2  * Copyright (c) 1999, 2011, 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"
    35 class CodeEmitInfo;
    36 class LIR_Assembler;
    37 class LIR_OpVisitState;
    39 // CodeStubs are little 'out-of-line' pieces of code that
    40 // usually handle slow cases of operations. All code stubs
    41 // are collected and code is emitted at the end of the
    42 // nmethod.
    44 class CodeStub: public CompilationResourceObj {
    45  protected:
    46   Label _entry;                                  // label at the stub entry point
    47   Label _continuation;                           // label where stub continues, if any
    49  public:
    50   CodeStub() {}
    52   // code generation
    53   void assert_no_unbound_labels()                { assert(!_entry.is_unbound() && !_continuation.is_unbound(), "unbound label"); }
    54   virtual void emit_code(LIR_Assembler* e) = 0;
    55   virtual CodeEmitInfo* info() const             { return NULL; }
    56   virtual bool is_exception_throw_stub() const   { return false; }
    57   virtual bool is_range_check_stub() const       { return false; }
    58   virtual bool is_divbyzero_stub() const         { return false; }
    59 #ifndef PRODUCT
    60   virtual void print_name(outputStream* out) const = 0;
    61 #endif
    63   // label access
    64   Label* entry()                                 { return &_entry; }
    65   Label* continuation()                          { return &_continuation; }
    66   // for LIR
    67   virtual void visit(LIR_OpVisitState* visit) {
    68 #ifndef PRODUCT
    69     if (LIRTracePeephole && Verbose) {
    70       tty->print("no visitor for ");
    71       print_name(tty);
    72       tty->cr();
    73     }
    74 #endif
    75   }
    76 };
    79 define_array(CodeStubArray, CodeStub*)
    80 define_stack(_CodeStubList, CodeStubArray)
    82 class CodeStubList: public _CodeStubList {
    83  public:
    84   CodeStubList(): _CodeStubList() {}
    86   void append(CodeStub* stub) {
    87     if (!contains(stub)) {
    88       _CodeStubList::append(stub);
    89     }
    90   }
    91 };
    93 class CounterOverflowStub: public CodeStub {
    94  private:
    95   CodeEmitInfo* _info;
    96   int           _bci;
    97   LIR_Opr       _method;
    99 public:
   100   CounterOverflowStub(CodeEmitInfo* info, int bci, LIR_Opr method) :  _info(info), _bci(bci), _method(method) {
   101   }
   103   virtual void emit_code(LIR_Assembler* e);
   105   virtual void visit(LIR_OpVisitState* visitor) {
   106     visitor->do_slow_case(_info);
   107     visitor->do_input(_method);
   108   }
   110 #ifndef PRODUCT
   111   virtual void print_name(outputStream* out) const { out->print("CounterOverflowStub"); }
   112 #endif // PRODUCT
   114 };
   116 class ConversionStub: public CodeStub {
   117  private:
   118   Bytecodes::Code _bytecode;
   119   LIR_Opr         _input;
   120   LIR_Opr         _result;
   122   static float float_zero;
   123   static double double_zero;
   124  public:
   125   ConversionStub(Bytecodes::Code bytecode, LIR_Opr input, LIR_Opr result)
   126     : _bytecode(bytecode), _input(input), _result(result) {
   127   }
   129   Bytecodes::Code bytecode() { return _bytecode; }
   130   LIR_Opr         input()    { return _input; }
   131   LIR_Opr         result()   { return _result; }
   133   virtual void emit_code(LIR_Assembler* e);
   134   virtual void visit(LIR_OpVisitState* visitor) {
   135     visitor->do_slow_case();
   136     visitor->do_input(_input);
   137     visitor->do_output(_result);
   138   }
   139 #ifndef PRODUCT
   140   virtual void print_name(outputStream* out) const { out->print("ConversionStub"); }
   141 #endif // PRODUCT
   142 };
   145 // Throws ArrayIndexOutOfBoundsException by default but can be
   146 // configured to throw IndexOutOfBoundsException in constructor
   147 class RangeCheckStub: public CodeStub {
   148  private:
   149   CodeEmitInfo* _info;
   150   LIR_Opr       _index;
   151   bool          _throw_index_out_of_bounds_exception;
   153  public:
   154   RangeCheckStub(CodeEmitInfo* info, LIR_Opr index, bool throw_index_out_of_bounds_exception = false);
   155   virtual void emit_code(LIR_Assembler* e);
   156   virtual CodeEmitInfo* info() const             { return _info; }
   157   virtual bool is_exception_throw_stub() const   { return true; }
   158   virtual bool is_range_check_stub() const       { return true; }
   159   virtual void visit(LIR_OpVisitState* visitor) {
   160     visitor->do_slow_case(_info);
   161     visitor->do_input(_index);
   162   }
   163 #ifndef PRODUCT
   164   virtual void print_name(outputStream* out) const { out->print("RangeCheckStub"); }
   165 #endif // PRODUCT
   166 };
   169 class DivByZeroStub: public CodeStub {
   170  private:
   171   CodeEmitInfo* _info;
   172   int           _offset;
   174  public:
   175   DivByZeroStub(CodeEmitInfo* info)
   176     : _info(info), _offset(-1) {
   177   }
   178   DivByZeroStub(int offset, CodeEmitInfo* info)
   179     : _info(info), _offset(offset) {
   180   }
   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_divbyzero_stub() const         { return true; }
   185   virtual void visit(LIR_OpVisitState* visitor) {
   186     visitor->do_slow_case(_info);
   187   }
   188 #ifndef PRODUCT
   189   virtual void print_name(outputStream* out) const { out->print("DivByZeroStub"); }
   190 #endif // PRODUCT
   191 };
   194 class ImplicitNullCheckStub: public CodeStub {
   195  private:
   196   CodeEmitInfo* _info;
   197   int           _offset;
   199  public:
   200   ImplicitNullCheckStub(int offset, CodeEmitInfo* info)
   201     : _offset(offset), _info(info) {
   202   }
   203   virtual void emit_code(LIR_Assembler* e);
   204   virtual CodeEmitInfo* info() const             { return _info; }
   205   virtual bool is_exception_throw_stub() const   { return true; }
   206   virtual void visit(LIR_OpVisitState* visitor) {
   207     visitor->do_slow_case(_info);
   208   }
   209 #ifndef PRODUCT
   210   virtual void print_name(outputStream* out) const { out->print("ImplicitNullCheckStub"); }
   211 #endif // PRODUCT
   212 };
   215 class NewInstanceStub: public CodeStub {
   216  private:
   217   ciInstanceKlass* _klass;
   218   LIR_Opr          _klass_reg;
   219   LIR_Opr          _result;
   220   CodeEmitInfo*    _info;
   221   Runtime1::StubID _stub_id;
   223  public:
   224   NewInstanceStub(LIR_Opr klass_reg, LIR_Opr result, ciInstanceKlass* klass, CodeEmitInfo* info, Runtime1::StubID stub_id);
   225   virtual void emit_code(LIR_Assembler* e);
   226   virtual CodeEmitInfo* info() const             { return _info; }
   227   virtual void visit(LIR_OpVisitState* visitor) {
   228     visitor->do_slow_case(_info);
   229     visitor->do_input(_klass_reg);
   230     visitor->do_output(_result);
   231   }
   232 #ifndef PRODUCT
   233   virtual void print_name(outputStream* out) const { out->print("NewInstanceStub"); }
   234 #endif // PRODUCT
   235 };
   238 class NewTypeArrayStub: public CodeStub {
   239  private:
   240   LIR_Opr       _klass_reg;
   241   LIR_Opr       _length;
   242   LIR_Opr       _result;
   243   CodeEmitInfo* _info;
   245  public:
   246   NewTypeArrayStub(LIR_Opr klass_reg, LIR_Opr length, LIR_Opr result, CodeEmitInfo* info);
   247   virtual void emit_code(LIR_Assembler* e);
   248   virtual CodeEmitInfo* info() const             { return _info; }
   249   virtual void visit(LIR_OpVisitState* visitor) {
   250     visitor->do_slow_case(_info);
   251     visitor->do_input(_klass_reg);
   252     visitor->do_input(_length);
   253     assert(_result->is_valid(), "must be valid"); visitor->do_output(_result);
   254   }
   255 #ifndef PRODUCT
   256   virtual void print_name(outputStream* out) const { out->print("NewTypeArrayStub"); }
   257 #endif // PRODUCT
   258 };
   261 class NewObjectArrayStub: public CodeStub {
   262  private:
   263   LIR_Opr        _klass_reg;
   264   LIR_Opr        _length;
   265   LIR_Opr        _result;
   266   CodeEmitInfo*  _info;
   268  public:
   269   NewObjectArrayStub(LIR_Opr klass_reg, LIR_Opr length, LIR_Opr result, CodeEmitInfo* info);
   270   virtual void emit_code(LIR_Assembler* e);
   271   virtual CodeEmitInfo* info() const             { return _info; }
   272   virtual void visit(LIR_OpVisitState* visitor) {
   273     visitor->do_slow_case(_info);
   274     visitor->do_input(_klass_reg);
   275     visitor->do_input(_length);
   276     assert(_result->is_valid(), "must be valid"); visitor->do_output(_result);
   277   }
   278 #ifndef PRODUCT
   279   virtual void print_name(outputStream* out) const { out->print("NewObjectArrayStub"); }
   280 #endif // PRODUCT
   281 };
   284 class MonitorAccessStub: public CodeStub {
   285  protected:
   286   LIR_Opr _obj_reg;
   287   LIR_Opr _lock_reg;
   289  public:
   290   MonitorAccessStub(LIR_Opr obj_reg, LIR_Opr lock_reg) {
   291     _obj_reg  = obj_reg;
   292     _lock_reg  = lock_reg;
   293   }
   295 #ifndef PRODUCT
   296   virtual void print_name(outputStream* out) const { out->print("MonitorAccessStub"); }
   297 #endif // PRODUCT
   298 };
   301 class MonitorEnterStub: public MonitorAccessStub {
   302  private:
   303   CodeEmitInfo* _info;
   305  public:
   306   MonitorEnterStub(LIR_Opr obj_reg, LIR_Opr lock_reg, CodeEmitInfo* info);
   308   virtual void emit_code(LIR_Assembler* e);
   309   virtual CodeEmitInfo* info() const             { return _info; }
   310   virtual void visit(LIR_OpVisitState* visitor) {
   311     visitor->do_input(_obj_reg);
   312     visitor->do_input(_lock_reg);
   313     visitor->do_slow_case(_info);
   314   }
   315 #ifndef PRODUCT
   316   virtual void print_name(outputStream* out) const { out->print("MonitorEnterStub"); }
   317 #endif // PRODUCT
   318 };
   321 class MonitorExitStub: public MonitorAccessStub {
   322  private:
   323   bool _compute_lock;
   324   int  _monitor_ix;
   326  public:
   327   MonitorExitStub(LIR_Opr lock_reg, bool compute_lock, int monitor_ix)
   328     : MonitorAccessStub(LIR_OprFact::illegalOpr, lock_reg),
   329       _compute_lock(compute_lock), _monitor_ix(monitor_ix) { }
   330   virtual void emit_code(LIR_Assembler* e);
   331   virtual void visit(LIR_OpVisitState* visitor) {
   332     assert(_obj_reg->is_illegal(), "unused");
   333     if (_compute_lock) {
   334       visitor->do_temp(_lock_reg);
   335     } else {
   336       visitor->do_input(_lock_reg);
   337     }
   338   }
   339 #ifndef PRODUCT
   340   virtual void print_name(outputStream* out) const { out->print("MonitorExitStub"); }
   341 #endif // PRODUCT
   342 };
   345 class PatchingStub: public CodeStub {
   346  public:
   347   enum PatchID {
   348     access_field_id,
   349     load_klass_id
   350   };
   351   enum constants {
   352     patch_info_size = 3
   353   };
   354  private:
   355   PatchID       _id;
   356   address       _pc_start;
   357   int           _bytes_to_copy;
   358   Label         _patched_code_entry;
   359   Label         _patch_site_entry;
   360   Label         _patch_site_continuation;
   361   Register      _obj;
   362   CodeEmitInfo* _info;
   363   int           _oop_index;  // index of the patchable oop in nmethod oop table if needed
   364   static int    _patch_info_offset;
   366   void align_patch_site(MacroAssembler* masm);
   368  public:
   369   static int patch_info_offset() { return _patch_info_offset; }
   371   PatchingStub(MacroAssembler* masm, PatchID id, int oop_index = -1):
   372       _id(id)
   373     , _info(NULL)
   374     , _oop_index(oop_index) {
   375     if (os::is_MP()) {
   376       // force alignment of patch sites on MP hardware so we
   377       // can guarantee atomic writes to the patch site.
   378       align_patch_site(masm);
   379     }
   380     _pc_start = masm->pc();
   381     masm->bind(_patch_site_entry);
   382   }
   384   void install(MacroAssembler* masm, LIR_PatchCode patch_code, Register obj, CodeEmitInfo* info) {
   385     _info = info;
   386     _obj = obj;
   387     masm->bind(_patch_site_continuation);
   388     _bytes_to_copy = masm->pc() - pc_start();
   389     if (_id == PatchingStub::access_field_id) {
   390       // embed a fixed offset to handle long patches which need to be offset by a word.
   391       // the patching code will just add the field offset field to this offset so
   392       // that we can refernce either the high or low word of a double word field.
   393       int field_offset = 0;
   394       switch (patch_code) {
   395       case lir_patch_low:         field_offset = lo_word_offset_in_bytes; break;
   396       case lir_patch_high:        field_offset = hi_word_offset_in_bytes; break;
   397       case lir_patch_normal:      field_offset = 0;                       break;
   398       default: ShouldNotReachHere();
   399       }
   400       NativeMovRegMem* n_move = nativeMovRegMem_at(pc_start());
   401       n_move->set_offset(field_offset);
   402     } else if (_id == load_klass_id) {
   403       assert(_obj != noreg, "must have register object for load_klass");
   404 #ifdef ASSERT
   405       // verify that we're pointing at a NativeMovConstReg
   406       nativeMovConstReg_at(pc_start());
   407 #endif
   408     } else {
   409       ShouldNotReachHere();
   410     }
   411     assert(_bytes_to_copy <= (masm->pc() - pc_start()), "not enough bytes");
   412   }
   414   address pc_start() const                       { return _pc_start; }
   415   PatchID id() const                             { return _id; }
   417   virtual void emit_code(LIR_Assembler* e);
   418   virtual CodeEmitInfo* info() const             { return _info; }
   419   virtual void visit(LIR_OpVisitState* visitor) {
   420     visitor->do_slow_case(_info);
   421   }
   422 #ifndef PRODUCT
   423   virtual void print_name(outputStream* out) const { out->print("PatchingStub"); }
   424 #endif // PRODUCT
   425 };
   428 //------------------------------------------------------------------------------
   429 // DeoptimizeStub
   430 //
   431 class DeoptimizeStub : public CodeStub {
   432 private:
   433   CodeEmitInfo* _info;
   435 public:
   436   DeoptimizeStub(CodeEmitInfo* info) : _info(new CodeEmitInfo(info)) {}
   438   virtual void emit_code(LIR_Assembler* e);
   439   virtual CodeEmitInfo* info() const           { return _info; }
   440   virtual bool is_exception_throw_stub() const { return true; }
   441   virtual void visit(LIR_OpVisitState* visitor) {
   442     visitor->do_slow_case(_info);
   443   }
   444 #ifndef PRODUCT
   445   virtual void print_name(outputStream* out) const { out->print("DeoptimizeStub"); }
   446 #endif // PRODUCT
   447 };
   450 class SimpleExceptionStub: public CodeStub {
   451  private:
   452   LIR_Opr          _obj;
   453   Runtime1::StubID _stub;
   454   CodeEmitInfo*    _info;
   456  public:
   457   SimpleExceptionStub(Runtime1::StubID stub, LIR_Opr obj, CodeEmitInfo* info):
   458     _obj(obj), _info(info), _stub(stub) {
   459   }
   461   void set_obj(LIR_Opr obj) {
   462     _obj = obj;
   463   }
   465   virtual void emit_code(LIR_Assembler* e);
   466   virtual CodeEmitInfo* info() const             { return _info; }
   467   virtual bool is_exception_throw_stub() const   { return true; }
   468   virtual void visit(LIR_OpVisitState* visitor) {
   469     if (_obj->is_valid()) visitor->do_input(_obj);
   470     visitor->do_slow_case(_info);
   471   }
   472 #ifndef PRODUCT
   473   virtual void print_name(outputStream* out) const { out->print("SimpleExceptionStub"); }
   474 #endif // PRODUCT
   475 };
   479 class ArrayStoreExceptionStub: public SimpleExceptionStub {
   480  private:
   481   CodeEmitInfo* _info;
   483  public:
   484   ArrayStoreExceptionStub(LIR_Opr obj, CodeEmitInfo* info): SimpleExceptionStub(Runtime1::throw_array_store_exception_id, obj, info) {}
   485 #ifndef PRODUCT
   486   virtual void print_name(outputStream* out) const { out->print("ArrayStoreExceptionStub"); }
   487 #endif // PRODUCT
   488 };
   491 class ArrayCopyStub: public CodeStub {
   492  private:
   493   LIR_OpArrayCopy* _op;
   495  public:
   496   ArrayCopyStub(LIR_OpArrayCopy* op): _op(op) { }
   498   LIR_Opr src() const                         { return _op->src(); }
   499   LIR_Opr src_pos() const                     { return _op->src_pos(); }
   500   LIR_Opr dst() const                         { return _op->dst(); }
   501   LIR_Opr dst_pos() const                     { return _op->dst_pos(); }
   502   LIR_Opr length() const                      { return _op->length(); }
   503   LIR_Opr tmp() const                         { return _op->tmp(); }
   505   virtual void emit_code(LIR_Assembler* e);
   506   virtual CodeEmitInfo* info() const          { return _op->info(); }
   507   virtual void visit(LIR_OpVisitState* visitor) {
   508     // don't pass in the code emit info since it's processed in the fast path
   509     visitor->do_slow_case();
   510   }
   511 #ifndef PRODUCT
   512   virtual void print_name(outputStream* out) const { out->print("ArrayCopyStub"); }
   513 #endif // PRODUCT
   514 };
   516 //////////////////////////////////////////////////////////////////////////////////////////
   517 #ifndef SERIALGC
   519 // Code stubs for Garbage-First barriers.
   520 class G1PreBarrierStub: public CodeStub {
   521  private:
   522   LIR_Opr _addr;
   523   LIR_Opr _pre_val;
   524   LIR_PatchCode _patch_code;
   525   CodeEmitInfo* _info;
   527  public:
   528   // pre_val (a temporary register) must be a register;
   529   // addr (the address of the field to be read) must be a LIR_Address
   530   G1PreBarrierStub(LIR_Opr addr, LIR_Opr pre_val, LIR_PatchCode patch_code, CodeEmitInfo* info) :
   531     _addr(addr), _pre_val(pre_val), _patch_code(patch_code), _info(info)
   532   {
   533     assert(_pre_val->is_register(), "should be temporary register");
   534     assert(_addr->is_address(), "should be the address of the field");
   535   }
   537   LIR_Opr addr() const { return _addr; }
   538   LIR_Opr pre_val() const { return _pre_val; }
   539   LIR_PatchCode patch_code() const { return _patch_code; }
   540   CodeEmitInfo* info() const { return _info; }
   542   virtual void emit_code(LIR_Assembler* e);
   543   virtual void visit(LIR_OpVisitState* visitor) {
   544     // don't pass in the code emit info since it's processed in the fast
   545     // path
   546     if (_info != NULL)
   547       visitor->do_slow_case(_info);
   548     else
   549       visitor->do_slow_case();
   550     visitor->do_input(_addr);
   551     visitor->do_temp(_pre_val);
   552   }
   553 #ifndef PRODUCT
   554   virtual void print_name(outputStream* out) const { out->print("G1PreBarrierStub"); }
   555 #endif // PRODUCT
   556 };
   558 class G1PostBarrierStub: public CodeStub {
   559  private:
   560   LIR_Opr _addr;
   561   LIR_Opr _new_val;
   563   static jbyte* _byte_map_base;
   564   static jbyte* byte_map_base_slow();
   565   static jbyte* byte_map_base() {
   566     if (_byte_map_base == NULL) {
   567       _byte_map_base = byte_map_base_slow();
   568     }
   569     return _byte_map_base;
   570   }
   572  public:
   573   // addr (the address of the object head) and new_val must be registers.
   574   G1PostBarrierStub(LIR_Opr addr, LIR_Opr new_val): _addr(addr), _new_val(new_val) { }
   576   LIR_Opr addr() const { return _addr; }
   577   LIR_Opr new_val() const { return _new_val; }
   579   virtual void emit_code(LIR_Assembler* e);
   580   virtual void visit(LIR_OpVisitState* visitor) {
   581     // don't pass in the code emit info since it's processed in the fast path
   582     visitor->do_slow_case();
   583     visitor->do_input(_addr);
   584     visitor->do_input(_new_val);
   585   }
   586 #ifndef PRODUCT
   587   virtual void print_name(outputStream* out) const { out->print("G1PostBarrierStub"); }
   588 #endif // PRODUCT
   589 };
   591 #endif // SERIALGC
   592 //////////////////////////////////////////////////////////////////////////////////////////
   594 #endif // SHARE_VM_C1_C1_CODESTUBS_HPP

mercurial