< prev index next >

src/hotspot/share/c1/c1_Instruction.hpp

Print this page

        

@@ -70,10 +70,11 @@
 class   OsrEntry;
 class   ExceptionObject;
 class   StateSplit;
 class     Invoke;
 class     NewInstance;
+class     NewValueTypeInstance;
 class     NewArray;
 class       NewTypeArray;
 class       NewObjectArray;
 class       NewMultiArray;
 class     TypeCheck;

@@ -175,10 +176,11 @@
   virtual void do_Convert        (Convert*         x) = 0;
   virtual void do_NullCheck      (NullCheck*       x) = 0;
   virtual void do_TypeCast       (TypeCast*        x) = 0;
   virtual void do_Invoke         (Invoke*          x) = 0;
   virtual void do_NewInstance    (NewInstance*     x) = 0;
+  virtual void do_NewValueTypeInstance(NewValueTypeInstance* x) = 0;
   virtual void do_NewTypeArray   (NewTypeArray*    x) = 0;
   virtual void do_NewObjectArray (NewObjectArray*  x) = 0;
   virtual void do_NewMultiArray  (NewMultiArray*   x) = 0;
   virtual void do_CheckCast      (CheckCast*       x) = 0;
   virtual void do_InstanceOf     (InstanceOf*      x) = 0;

@@ -355,10 +357,11 @@
 
   static const int no_bci = -99;
 
   enum InstructionFlag {
     NeedsNullCheckFlag = 0,
+    NeverNullFlag,          // For "Q" signatures
     CanTrapFlag,
     DirectCompareFlag,
     IsEliminatedFlag,
     IsSafepointFlag,
     IsStaticFlag,

@@ -449,10 +452,12 @@
   Instruction* subst()                           { return _subst == NULL ? this : _subst->subst(); }
   LIR_Opr operand() const                        { return _operand; }
 
   void set_needs_null_check(bool f)              { set_flag(NeedsNullCheckFlag, f); }
   bool needs_null_check() const                  { return check_flag(NeedsNullCheckFlag); }
+  void set_never_null(bool f)                    { set_flag(NeverNullFlag, f); }
+  bool is_never_null() const                     { return check_flag(NeverNullFlag); }
   bool is_linked() const                         { return check_flag(IsLinkedInBlockFlag); }
   bool can_be_linked()                           { return as_Local() == NULL && as_Phi() == NULL; }
 
   bool has_uses() const                          { return use_count() > 0; }
   ValueStack* state_before() const               { return _state_before; }

@@ -501,10 +506,15 @@
     set_next(i);
     i->set_next(n);
     return _next;
   }
 
+  bool is_flattened_array() const;             // FIXME -- remove it
+
+  bool is_loaded_flattened_array() const;
+  bool maybe_flattened_array();
+
   Instruction *insert_after_same_bci(Instruction *i) {
 #ifndef PRODUCT
     i->set_printable_bci(printable_bci());
 #endif
     return insert_after(i);

@@ -548,10 +558,11 @@
   virtual NullCheck*        as_NullCheck()       { return NULL; }
   virtual OsrEntry*         as_OsrEntry()        { return NULL; }
   virtual StateSplit*       as_StateSplit()      { return NULL; }
   virtual Invoke*           as_Invoke()          { return NULL; }
   virtual NewInstance*      as_NewInstance()     { return NULL; }
+  virtual NewValueTypeInstance* as_NewValueTypeInstance() { return NULL; }
   virtual NewArray*         as_NewArray()        { return NULL; }
   virtual NewTypeArray*     as_NewTypeArray()    { return NULL; }
   virtual NewObjectArray*   as_NewObjectArray()  { return NULL; }
   virtual NewMultiArray*    as_NewMultiArray()   { return NULL; }
   virtual TypeCheck*        as_TypeCheck()       { return NULL; }

@@ -642,24 +653,34 @@
 
 LEAF(Phi, Instruction)
  private:
   int         _pf_flags; // the flags of the phi function
   int         _index;    // to value on operand stack (index < 0) or to local
+  ciType*     _exact_type; // currently is set only for flattened arrays, NULL otherwise.
  public:
   // creation
-  Phi(ValueType* type, BlockBegin* b, int index)
+  Phi(ValueType* type, BlockBegin* b, int index, ciType* exact_type)
   : Instruction(type->base())
   , _pf_flags(0)
   , _index(index)
+  , _exact_type(exact_type)
   {
     _block = b;
     NOT_PRODUCT(set_printable_bci(Value(b)->printable_bci()));
     if (type->is_illegal()) {
       make_illegal();
     }
   }
 
+  virtual ciType* exact_type() const {
+    return _exact_type;
+  }
+
+  virtual ciType* declared_type() const {
+    return _exact_type;
+  }
+
   // flags
   enum Flag {
     no_flag         = 0,
     visited         = 1 << 0,
     cannot_simplify = 1 << 1

@@ -701,16 +722,17 @@
   int      _java_index;                          // the local index within the method to which the local belongs
   bool     _is_receiver;                         // if local variable holds the receiver: "this" for non-static methods
   ciType*  _declared_type;
  public:
   // creation
-  Local(ciType* declared, ValueType* type, int index, bool receiver)
+  Local(ciType* declared, ValueType* type, int index, bool receiver, bool never_null)
     : Instruction(type)
     , _java_index(index)
     , _is_receiver(receiver)
     , _declared_type(declared)
   {
+    set_never_null(never_null);
     NOT_PRODUCT(set_printable_bci(-1));
   }
 
   // accessors
   int java_index() const                         { return _java_index; }

@@ -823,21 +845,28 @@
   virtual void input_values_do(ValueVisitor* f)   { f->visit(&_obj); }
 };
 
 
 LEAF(LoadField, AccessField)
+  ciValueKlass* _value_klass;
+  Value _default_value;
  public:
   // creation
   LoadField(Value obj, int offset, ciField* field, bool is_static,
-            ValueStack* state_before, bool needs_patching)
+            ValueStack* state_before, bool needs_patching,
+            ciValueKlass* value_klass = NULL, Value default_value = NULL )
   : AccessField(obj, offset, field, is_static, state_before, needs_patching)
+  , _value_klass(value_klass), _default_value(default_value)
   {}
 
   ciType* declared_type() const;
 
   // generic
   HASHING2(LoadField, !needs_patching() && !field()->is_volatile(), obj()->subst(), offset())  // cannot be eliminated if needs patching or if volatile
+
+  ciValueKlass* value_klass() const { return _value_klass;}
+  Value default_value() const { return _default_value; }
 };
 
 
 LEAF(StoreField, AccessField)
  private:

@@ -945,10 +974,11 @@
 
 
 LEAF(LoadIndexed, AccessIndexed)
  private:
   NullCheck*  _explicit_null_check;              // For explicit null check elimination
+  NewValueTypeInstance* _vt;
 
  public:
   // creation
   LoadIndexed(Value array, Value index, Value length, BasicType elt_type, ValueStack* state_before, bool mismatched = false)
   : AccessIndexed(array, index, length, elt_type, state_before, mismatched)

@@ -962,10 +992,13 @@
   void set_explicit_null_check(NullCheck* check) { _explicit_null_check = check; }
 
   ciType* exact_type() const;
   ciType* declared_type() const;
 
+  NewValueTypeInstance* vt() { return _vt; }
+  void set_vt(NewValueTypeInstance* vt) { _vt = vt; }
+
   // generic
   HASHING2(LoadIndexed, true, array()->subst(), index()->subst())
 };
 
 

@@ -1000,10 +1033,12 @@
   void set_profiled_method(ciMethod* method)         { _profiled_method = method;   }
   void set_profiled_bci(int bci)                     { _profiled_bci = bci;         }
   bool      should_profile() const                   { return check_flag(ProfileMDOFlag); }
   ciMethod* profiled_method() const                  { return _profiled_method;     }
   int       profiled_bci() const                     { return _profiled_bci;        }
+  // Flattened array support
+  bool is_exact_flattened_array_store() const;
   // generic
   virtual void input_values_do(ValueVisitor* f)   { AccessIndexed::input_values_do(f); f->visit(&_value); }
 };
 
 

@@ -1252,11 +1287,11 @@
   ciMethod*       _target;
 
  public:
   // creation
   Invoke(Bytecodes::Code code, ValueType* result_type, Value recv, Values* args,
-         int vtable_index, ciMethod* target, ValueStack* state_before);
+         int vtable_index, ciMethod* target, ValueStack* state_before, bool never_null);
 
   // accessors
   Bytecodes::Code code() const                   { return _code; }
   Value receiver() const                         { return _recv; }
   bool has_receiver() const                      { return receiver() != NULL; }

@@ -1313,10 +1348,47 @@
   virtual bool can_trap() const                  { return true; }
   ciType* exact_type() const;
   ciType* declared_type() const;
 };
 
+LEAF(NewValueTypeInstance, StateSplit)
+  bool _is_unresolved;
+  ciValueKlass* _klass;
+  Value _depends_on;      // Link to instance on with withfield was called on
+
+public:
+
+  // Default creation, always allocated for now
+  NewValueTypeInstance(ciValueKlass* klass, ValueStack* state_before, bool is_unresolved, Value depends_on = NULL)
+  : StateSplit(instanceType, state_before)
+   , _is_unresolved(is_unresolved)
+   , _klass(klass)
+  {
+    if (depends_on == NULL) {
+      _depends_on = this;
+    } else {
+      _depends_on = depends_on;
+    }
+    set_never_null(true);
+  }
+
+  // accessors
+  bool is_unresolved() const                     { return _is_unresolved; }
+  Value depends_on();
+
+  ciValueKlass* klass() const { return _klass; }
+
+  virtual bool needs_exception_state() const     { return false; }
+
+  // generic
+  virtual bool can_trap() const                  { return true; }
+  ciType* exact_type() const;
+  ciType* declared_type() const;
+
+  // Only done in LIR Generator -> map everything to object
+  void set_to_object_type() { set_type(instanceType); }
+};
 
 BASE(NewArray, StateSplit)
  private:
   Value       _length;
 

@@ -1399,10 +1471,12 @@
     // get updated, and the value must not be traversed twice. Was bug
     // - kbr 4/10/2001
     StateSplit::input_values_do(f);
     for (int i = 0; i < _dims->length(); i++) f->visit(_dims->adr_at(i));
   }
+
+  ciType* exact_type() const;
 };
 
 
 BASE(TypeCheck, StateSplit)
  private:

@@ -1445,12 +1519,14 @@
 
 
 LEAF(CheckCast, TypeCheck)
  public:
   // creation
-  CheckCast(ciKlass* klass, Value obj, ValueStack* state_before)
-  : TypeCheck(klass, obj, objectType, state_before) {}
+  CheckCast(ciKlass* klass, Value obj, ValueStack* state_before, bool never_null = false)
+  : TypeCheck(klass, obj, objectType, state_before) {
+    set_never_null(never_null);
+  }
 
   void set_incompatible_class_change_check() {
     set_flag(ThrowIncompatibleClassChangeErrorFlag, true);
   }
   bool is_incompatible_class_change_check() const {

@@ -1504,18 +1580,23 @@
   virtual void input_values_do(ValueVisitor* f)   { StateSplit::input_values_do(f); f->visit(&_obj); }
 };
 
 
 LEAF(MonitorEnter, AccessMonitor)
+  bool _maybe_valuetype;
  public:
   // creation
-  MonitorEnter(Value obj, int monitor_no, ValueStack* state_before)
+  MonitorEnter(Value obj, int monitor_no, ValueStack* state_before, bool maybe_valuetype)
   : AccessMonitor(obj, monitor_no, state_before)
+  , _maybe_valuetype(maybe_valuetype)
   {
     ASSERT_VALUES
   }
 
+  // accessors
+  bool maybe_valuetype() const                   { return _maybe_valuetype; }
+
   // generic
   virtual bool can_trap() const                  { return true; }
 };
 
 
< prev index next >