--- old/src/hotspot/share/ci/ciType.hpp 2019-03-11 14:25:30.758355645 +0100 +++ new/src/hotspot/share/ci/ciType.hpp 2019-03-11 14:25:30.506355648 +0100 @@ -29,12 +29,13 @@ // ciType // -// This class represents either a class (T_OBJECT), array (T_ARRAY), -// or one of the primitive types such as T_INT. +// This class represents either a class (T_OBJECT), value (T_VALUETYPE), +// array (T_ARRAY), or one of the primitive types such as T_INT. class ciType : public ciMetadata { CI_PACKAGE_ACCESS friend class ciKlass; friend class ciReturnAddress; + friend class ciWrapper; private: BasicType _basic_type; @@ -67,7 +68,7 @@ ciKlass* box_klass(); // Returns true if this is not a klass or array (i.e., not a reference type). - bool is_primitive_type() const { return basic_type() != T_OBJECT && basic_type() != T_ARRAY; } + bool is_primitive_type() const { return basic_type() != T_OBJECT && basic_type() != T_ARRAY && basic_type() != T_VALUETYPE; } int size() const { return type2size[basic_type()]; } bool is_void() const { return basic_type() == T_VOID; } bool is_one_word() const { return size() == 1; } @@ -77,6 +78,9 @@ bool is_type() const { return true; } bool is_classless() const { return is_primitive_type(); } + virtual ciType* unwrap() { return this; } + virtual bool is_never_null() const { return false; } + const char* name(); virtual void print_name_on(outputStream* st); void print_name() { @@ -112,4 +116,38 @@ static ciReturnAddress* make(int bci); }; +// ciWrapper +// +// This class wraps another type to carry additional information like nullability. +// Should only be instantiated and used by ciTypeFlow and ciSignature. +class ciWrapper : public ciType { + CI_PACKAGE_ACCESS + +private: + ciType* _type; + bool _never_null; + + ciWrapper(ciType* type, bool never_null) : ciType(type->basic_type()) { + assert(type->is_valuetype(), "should only be used for value types"); + _type = type; + _never_null = never_null; + } + + const char* type_string() { return "ciWrapper"; } + + void print_impl(outputStream* st) { _type->print_impl(st); } + +public: + bool equals(ciMetadata* obj) const { + return obj->is_wrapper() && + obj->as_wrapper()->unwrap()->equals(_type) && + obj->as_wrapper()->is_never_null() == _never_null; + } + + bool is_wrapper() const { return true; } + + ciType* unwrap() { return _type; } + bool is_never_null() const { return _never_null; } +}; + #endif // SHARE_CI_CITYPE_HPP