< 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 >