< prev index next >

src/hotspot/share/c1/c1_LIR.hpp

Print this page
@@ -315,10 +315,11 @@
        case T_BYTE:
        case T_SHORT:
        case T_INT:
        case T_ADDRESS:
        case T_OBJECT:
+       case T_INLINE_TYPE:
        case T_ARRAY:
        case T_METADATA:
          return single_size;
          break;
  

@@ -465,10 +466,11 @@
    case T_INT:      return LIR_OprDesc::int_type;
    case T_LONG:     return LIR_OprDesc::long_type;
    case T_FLOAT:    return LIR_OprDesc::float_type;
    case T_DOUBLE:   return LIR_OprDesc::double_type;
    case T_OBJECT:
+   case T_INLINE_TYPE:
    case T_ARRAY:    return LIR_OprDesc::object_type;
    case T_ADDRESS:  return LIR_OprDesc::address_type;
    case T_METADATA: return LIR_OprDesc::metadata_type;
    case T_ILLEGAL:  // fall through
    default: ShouldNotReachHere(); return LIR_OprDesc::unknown_type;

@@ -655,10 +657,11 @@
      }
  
      LIR_Opr res;
      switch (type) {
        case T_OBJECT: // fall through
+       case T_INLINE_TYPE: // fall through
        case T_ARRAY:
          res = (LIR_Opr)(intptr_t)((index << LIR_OprDesc::data_shift)  |
                                              LIR_OprDesc::object_type  |
                                              LIR_OprDesc::cpu_register |
                                              LIR_OprDesc::single_size  |

@@ -760,10 +763,11 @@
    // the index is platform independent; a double stack useing indeces 2 and 3 has always
    // index 2.
    static LIR_Opr stack(int index, BasicType type) {
      LIR_Opr res;
      switch (type) {
+       case T_INLINE_TYPE: // fall through
        case T_OBJECT: // fall through
        case T_ARRAY:
          res = (LIR_Opr)(intptr_t)((index << LIR_OprDesc::data_shift) |
                                    LIR_OprDesc::object_type           |
                                    LIR_OprDesc::stack_value           |

@@ -873,13 +877,17 @@
  class      LIR_OpRTCall;
  class    LIR_OpArrayCopy;
  class    LIR_OpUpdateCRC32;
  class    LIR_OpLock;
  class    LIR_OpTypeCheck;
+ class    LIR_OpFlattenedArrayCheck;
+ class    LIR_OpNullFreeArrayCheck;
+ class    LIR_OpSubstitutabilityCheck;
  class    LIR_OpCompareAndSwap;
  class    LIR_OpProfileCall;
  class    LIR_OpProfileType;
+ class    LIR_OpProfileInlineType;
  #ifdef ASSERT
  class    LIR_OpAssert;
  #endif
  
  // LIR operation codes

@@ -900,10 +908,11 @@
        , lir_membar_storestore
        , lir_membar_loadstore
        , lir_membar_storeload
        , lir_get_thread
        , lir_on_spin_wait
+       , lir_check_orig_pc
    , end_op0
    , begin_op1
        , lir_fxch
        , lir_fld
        , lir_push

@@ -976,18 +985,28 @@
    , begin_opTypeCheck
      , lir_instanceof
      , lir_checkcast
      , lir_store_check
    , end_opTypeCheck
+   , begin_opFlattenedArrayCheck
+     , lir_flattened_array_check
+   , end_opFlattenedArrayCheck
+   , begin_opNullFreeArrayCheck
+     , lir_null_free_array_check
+   , end_opNullFreeArrayCheck
+   , begin_opSubstitutabilityCheck
+     , lir_substitutability_check
+   , end_opSubstitutabilityCheck
    , begin_opCompareAndSwap
      , lir_cas_long
      , lir_cas_obj
      , lir_cas_int
    , end_opCompareAndSwap
    , begin_opMDOProfile
      , lir_profile_call
      , lir_profile_type
+     , lir_profile_inline_type
    , end_opMDOProfile
    , begin_opAssert
      , lir_assert
    , end_opAssert
  };

@@ -1126,13 +1145,17 @@
    virtual LIR_Op2* as_Op2() { return NULL; }
    virtual LIR_Op3* as_Op3() { return NULL; }
    virtual LIR_OpArrayCopy* as_OpArrayCopy() { return NULL; }
    virtual LIR_OpUpdateCRC32* as_OpUpdateCRC32() { return NULL; }
    virtual LIR_OpTypeCheck* as_OpTypeCheck() { return NULL; }
+   virtual LIR_OpFlattenedArrayCheck* as_OpFlattenedArrayCheck() { return NULL; }
+   virtual LIR_OpNullFreeArrayCheck* as_OpNullFreeArrayCheck() { return NULL; }
+   virtual LIR_OpSubstitutabilityCheck* as_OpSubstitutabilityCheck() { return NULL; }
    virtual LIR_OpCompareAndSwap* as_OpCompareAndSwap() { return NULL; }
    virtual LIR_OpProfileCall* as_OpProfileCall() { return NULL; }
    virtual LIR_OpProfileType* as_OpProfileType() { return NULL; }
+   virtual LIR_OpProfileInlineType* as_OpProfileInlineType() { return NULL; }
  #ifdef ASSERT
    virtual LIR_OpAssert* as_OpAssert() { return NULL; }
  #endif
  
    virtual void verify() const {}

@@ -1201,10 +1224,12 @@
    }
  
    virtual void emit_code(LIR_Assembler* masm);
    virtual LIR_OpJavaCall* as_OpJavaCall() { return this; }
    virtual void print_instr(outputStream* out) const PRODUCT_RETURN;
+ 
+   bool maybe_return_as_fields(ciInlineKlass** vk = NULL) const;
  };
  
  // --------------------------------------------------
  // LIR_OpLabel
  // --------------------------------------------------

@@ -1252,11 +1277,14 @@
      type_check             = 1 << 7,
      overlapping            = 1 << 8,
      unaligned              = 1 << 9,
      src_objarray           = 1 << 10,
      dst_objarray           = 1 << 11,
-     all_flags              = (1 << 12) - 1
+     always_slow_path       = 1 << 12,
+     src_inlinetype_check   = 1 << 13,
+     dst_inlinetype_check   = 1 << 14,
+     all_flags              = (1 << 15) - 1
    };
  
    LIR_OpArrayCopy(LIR_Opr src, LIR_Opr src_pos, LIR_Opr dst, LIR_Opr dst_pos, LIR_Opr length, LIR_Opr tmp,
                    ciArrayKlass* expected_type, int flags, CodeEmitInfo* info);
  

@@ -1554,15 +1582,16 @@
    CodeEmitInfo* _info_for_exception;
    CodeStub*     _stub;
    ciMethod*     _profiled_method;
    int           _profiled_bci;
    bool          _should_profile;
+   bool          _need_null_check;
  
  public:
    LIR_OpTypeCheck(LIR_Code code, LIR_Opr result, LIR_Opr object, ciKlass* klass,
                    LIR_Opr tmp1, LIR_Opr tmp2, LIR_Opr tmp3, bool fast_check,
-                   CodeEmitInfo* info_for_exception, CodeEmitInfo* info_for_patch, CodeStub* stub);
+                   CodeEmitInfo* info_for_exception, CodeEmitInfo* info_for_patch, CodeStub* stub, bool need_null_check = true);
    LIR_OpTypeCheck(LIR_Code code, LIR_Opr object, LIR_Opr array,
                    LIR_Opr tmp1, LIR_Opr tmp2, LIR_Opr tmp3, CodeEmitInfo* info_for_exception);
  
    LIR_Opr object() const                         { return _object;         }
    LIR_Opr array() const                          { assert(code() == lir_store_check, "not valid"); return _array;         }

@@ -1580,17 +1609,93 @@
    void set_profiled_bci(int bci)                 { _profiled_bci = bci;       }
    void set_should_profile(bool b)                { _should_profile = b;       }
    ciMethod* profiled_method() const              { return _profiled_method;   }
    int       profiled_bci() const                 { return _profiled_bci;      }
    bool      should_profile() const               { return _should_profile;    }
- 
+   bool      need_null_check() const              { return _need_null_check;   }
    virtual bool is_patching() { return _info_for_patch != NULL; }
    virtual void emit_code(LIR_Assembler* masm);
    virtual LIR_OpTypeCheck* as_OpTypeCheck() { return this; }
    void print_instr(outputStream* out) const PRODUCT_RETURN;
  };
  
+ // LIR_OpFlattenedArrayCheck
+ class LIR_OpFlattenedArrayCheck: public LIR_Op {
+  friend class LIR_OpVisitState;
+ 
+  private:
+   LIR_Opr       _array;
+   LIR_Opr       _value;
+   LIR_Opr       _tmp;
+   CodeStub*     _stub;
+ public:
+   LIR_OpFlattenedArrayCheck(LIR_Opr array, LIR_Opr value, LIR_Opr tmp, CodeStub* stub);
+   LIR_Opr array() const                          { return _array;         }
+   LIR_Opr value() const                          { return _value;         }
+   LIR_Opr tmp() const                            { return _tmp;           }
+   CodeStub* stub() const                         { return _stub;          }
+ 
+   virtual void emit_code(LIR_Assembler* masm);
+   virtual LIR_OpFlattenedArrayCheck* as_OpFlattenedArrayCheck() { return this; }
+   virtual void print_instr(outputStream* out) const PRODUCT_RETURN;
+ };
+ 
+ // LIR_OpNullFreeArrayCheck
+ class LIR_OpNullFreeArrayCheck: public LIR_Op {
+  friend class LIR_OpVisitState;
+ 
+  private:
+   LIR_Opr       _array;
+   LIR_Opr       _tmp;
+ public:
+   LIR_OpNullFreeArrayCheck(LIR_Opr array, LIR_Opr tmp);
+   LIR_Opr array() const                          { return _array;         }
+   LIR_Opr tmp() const                            { return _tmp;           }
+ 
+   virtual void emit_code(LIR_Assembler* masm);
+   virtual LIR_OpNullFreeArrayCheck* as_OpNullFreeArrayCheck() { return this; }
+   virtual void print_instr(outputStream* out) const PRODUCT_RETURN;
+ };
+ 
+ class LIR_OpSubstitutabilityCheck: public LIR_Op {
+  friend class LIR_OpVisitState;
+ 
+  private:
+   LIR_Opr       _left;
+   LIR_Opr       _right;
+   LIR_Opr       _equal_result;
+   LIR_Opr       _not_equal_result;
+   LIR_Opr       _tmp1;
+   LIR_Opr       _tmp2;
+   ciKlass*      _left_klass;
+   ciKlass*      _right_klass;
+   LIR_Opr       _left_klass_op;
+   LIR_Opr       _right_klass_op;
+   CodeStub*     _stub;
+ public:
+   LIR_OpSubstitutabilityCheck(LIR_Opr result, LIR_Opr left, LIR_Opr right, LIR_Opr equal_result, LIR_Opr not_equal_result,
+                               LIR_Opr tmp1, LIR_Opr tmp2,
+                               ciKlass* left_klass, ciKlass* right_klass, LIR_Opr left_klass_op, LIR_Opr right_klass_op,
+                               CodeEmitInfo* info, CodeStub* stub);
+ 
+   LIR_Opr left() const             { return _left; }
+   LIR_Opr right() const            { return _right; }
+   LIR_Opr equal_result() const     { return _equal_result; }
+   LIR_Opr not_equal_result() const { return _not_equal_result; }
+   LIR_Opr tmp1() const             { return _tmp1; }
+   LIR_Opr tmp2() const             { return _tmp2; }
+   ciKlass* left_klass() const      { return _left_klass; }
+   ciKlass* right_klass() const     { return _right_klass; }
+   LIR_Opr left_klass_op() const    { return _left_klass_op; }
+   LIR_Opr right_klass_op() const   { return _right_klass_op; }
+   CodeStub* stub() const           { return _stub; }
+ 
+   virtual void emit_code(LIR_Assembler* masm);
+   virtual LIR_OpSubstitutabilityCheck* as_OpSubstitutabilityCheck() { return this; }
+   virtual void print_instr(outputStream* out) const PRODUCT_RETURN;
+ };
+ 
  // LIR_Op2
  class LIR_Op2: public LIR_Op {
   friend class LIR_OpVisitState;
  
    int  _fpu_stack_size; // for sin/cos implementation on Intel

@@ -1779,24 +1884,27 @@
    LIR_Opr _hdr;
    LIR_Opr _obj;
    LIR_Opr _lock;
    LIR_Opr _scratch;
    CodeStub* _stub;
+   CodeStub* _throw_imse_stub;
   public:
-   LIR_OpLock(LIR_Code code, LIR_Opr hdr, LIR_Opr obj, LIR_Opr lock, LIR_Opr scratch, CodeStub* stub, CodeEmitInfo* info)
+   LIR_OpLock(LIR_Code code, LIR_Opr hdr, LIR_Opr obj, LIR_Opr lock, LIR_Opr scratch, CodeStub* stub, CodeEmitInfo* info, CodeStub* throw_imse_stub=NULL)
      : LIR_Op(code, LIR_OprFact::illegalOpr, info)
      , _hdr(hdr)
      , _obj(obj)
      , _lock(lock)
      , _scratch(scratch)
-     , _stub(stub)                      {}
+     , _stub(stub)
+     , _throw_imse_stub(throw_imse_stub)                    {}
  
    LIR_Opr hdr_opr() const                        { return _hdr; }
    LIR_Opr obj_opr() const                        { return _obj; }
    LIR_Opr lock_opr() const                       { return _lock; }
    LIR_Opr scratch_opr() const                    { return _scratch; }
    CodeStub* stub() const                         { return _stub; }
+   CodeStub* throw_imse_stub() const              { return _throw_imse_stub; }
  
    virtual void emit_code(LIR_Assembler* masm);
    virtual LIR_OpLock* as_OpLock() { return this; }
    void print_instr(outputStream* out) const PRODUCT_RETURN;
  };

@@ -1959,10 +2067,42 @@
    virtual void emit_code(LIR_Assembler* masm);
    virtual LIR_OpProfileType* as_OpProfileType() { return this; }
    virtual void print_instr(outputStream* out) const PRODUCT_RETURN;
  };
  
+ // LIR_OpProfileInlineType
+ class LIR_OpProfileInlineType : public LIR_Op {
+  friend class LIR_OpVisitState;
+ 
+  private:
+   LIR_Opr      _mdp;
+   LIR_Opr      _obj;
+   int          _flag;
+   LIR_Opr      _tmp;
+   bool         _not_null;      // true if we know statically that _obj cannot be null
+ 
+  public:
+   // Destroys recv
+   LIR_OpProfileInlineType(LIR_Opr mdp, LIR_Opr obj, int flag, LIR_Opr tmp, bool not_null)
+     : LIR_Op(lir_profile_inline_type, LIR_OprFact::illegalOpr, NULL)  // no result, no info
+     , _mdp(mdp)
+     , _obj(obj)
+     , _flag(flag)
+     , _tmp(tmp)
+     , _not_null(not_null) { }
+ 
+   LIR_Opr      mdp()              const             { return _mdp;              }
+   LIR_Opr      obj()              const             { return _obj;              }
+   int          flag()             const             { return _flag;             }
+   LIR_Opr      tmp()              const             { return _tmp;              }
+   bool         not_null()         const             { return _not_null;         }
+ 
+   virtual void emit_code(LIR_Assembler* masm);
+   virtual LIR_OpProfileInlineType* as_OpProfileInlineType() { return this; }
+   virtual void print_instr(outputStream* out) const PRODUCT_RETURN;
+ };
+ 
  class LIR_InsertionBuffer;
  
  //--------------------------------LIR_List---------------------------------------------------
  // Maintains a list of LIR instructions (one instance of LIR_List per basic block)
  // The LIR instructions are appended by the LIR_List class itself;

@@ -2216,32 +2356,41 @@
      append(new LIR_OpRTCall(routine, tmp, result, arguments, info));
    }
  
    void load_stack_address_monitor(int monitor_ix, LIR_Opr dst)  { append(new LIR_Op1(lir_monaddr, LIR_OprFact::intConst(monitor_ix), dst)); }
    void unlock_object(LIR_Opr hdr, LIR_Opr obj, LIR_Opr lock, LIR_Opr scratch, CodeStub* stub);
-   void lock_object(LIR_Opr hdr, LIR_Opr obj, LIR_Opr lock, LIR_Opr scratch, CodeStub* stub, CodeEmitInfo* info);
+   void lock_object(LIR_Opr hdr, LIR_Opr obj, LIR_Opr lock, LIR_Opr scratch, CodeStub* stub, CodeEmitInfo* info, CodeStub* throw_imse_stub=NULL);
  
    void breakpoint()                                                  { append(new LIR_Op0(lir_breakpoint)); }
  
    void arraycopy(LIR_Opr src, LIR_Opr src_pos, LIR_Opr dst, LIR_Opr dst_pos, LIR_Opr length, LIR_Opr tmp, ciArrayKlass* expected_type, int flags, CodeEmitInfo* info) { append(new LIR_OpArrayCopy(src, src_pos, dst, dst_pos, length, tmp, expected_type, flags, info)); }
  
    void update_crc32(LIR_Opr crc, LIR_Opr val, LIR_Opr res)  { append(new LIR_OpUpdateCRC32(crc, val, res)); }
  
    void instanceof(LIR_Opr result, LIR_Opr object, ciKlass* klass, LIR_Opr tmp1, LIR_Opr tmp2, LIR_Opr tmp3, bool fast_check, CodeEmitInfo* info_for_patch, ciMethod* profiled_method, int profiled_bci);
    void store_check(LIR_Opr object, LIR_Opr array, LIR_Opr tmp1, LIR_Opr tmp2, LIR_Opr tmp3, CodeEmitInfo* info_for_exception, ciMethod* profiled_method, int profiled_bci);
+   void check_flattened_array(LIR_Opr array, LIR_Opr value, LIR_Opr tmp, CodeStub* stub);
+   void check_null_free_array(LIR_Opr array, LIR_Opr tmp);
+   void substitutability_check(LIR_Opr result, LIR_Opr left, LIR_Opr right, LIR_Opr equal_result, LIR_Opr not_equal_result,
+                               LIR_Opr tmp1, LIR_Opr tmp2,
+                               ciKlass* left_klass, ciKlass* right_klass, LIR_Opr left_klass_op, LIR_Opr right_klass_op,
+                               CodeEmitInfo* info, CodeStub* stub);
  
    void checkcast (LIR_Opr result, LIR_Opr object, ciKlass* klass,
                    LIR_Opr tmp1, LIR_Opr tmp2, LIR_Opr tmp3, bool fast_check,
                    CodeEmitInfo* info_for_exception, CodeEmitInfo* info_for_patch, CodeStub* stub,
-                   ciMethod* profiled_method, int profiled_bci);
+                   ciMethod* profiled_method, int profiled_bci, bool is_null_free);
    // MethodData* profiling
    void profile_call(ciMethod* method, int bci, ciMethod* callee, LIR_Opr mdo, LIR_Opr recv, LIR_Opr t1, ciKlass* cha_klass) {
      append(new LIR_OpProfileCall(method, bci, callee, mdo, recv, t1, cha_klass));
    }
    void profile_type(LIR_Address* mdp, LIR_Opr obj, ciKlass* exact_klass, intptr_t current_klass, LIR_Opr tmp, bool not_null, bool no_conflict) {
      append(new LIR_OpProfileType(LIR_OprFact::address(mdp), obj, exact_klass, current_klass, tmp, not_null, no_conflict));
    }
+   void profile_inline_type(LIR_Address* mdp, LIR_Opr obj, int flag, LIR_Opr tmp, bool not_null) {
+     append(new LIR_OpProfileInlineType(LIR_OprFact::address(mdp), obj, flag, tmp, not_null));
+   }
  
    void xadd(LIR_Opr src, LIR_Opr add, LIR_Opr res, LIR_Opr tmp) { append(new LIR_Op2(lir_xadd, src, add, res, tmp)); }
    void xchg(LIR_Opr src, LIR_Opr set, LIR_Opr res, LIR_Opr tmp) { append(new LIR_Op2(lir_xchg, src, set, res, tmp)); }
  #ifdef ASSERT
    void lir_assert(LIR_Condition condition, LIR_Opr opr1, LIR_Opr opr2, const char* msg, bool halt) { append(new LIR_OpAssert(condition, opr1, opr2, msg, halt)); }
< prev index next >