--- old/src/hotspot/share/opto/type.hpp 2019-09-11 16:33:09.000000000 +0200 +++ new/src/hotspot/share/opto/type.hpp 2019-09-11 16:33:04.000000000 +0200 @@ -1140,44 +1140,56 @@ // Class of Java object pointers, pointing either to non-array Java instances // or to a Klass* (including array klasses). class TypeInstPtr : public TypeOopPtr { - TypeInstPtr(PTR ptr, ciKlass* k, bool xk, ciObject* o, Offset offset, int instance_id, - const TypePtr* speculative, int inline_depth); + TypeInstPtr(PTR ptr, ciKlass* k, bool xk, ciObject* o, Offset offset, + bool is_value, int instance_id, const TypePtr* speculative, + int inline_depth); virtual bool eq( const Type *t ) const; virtual int hash() const; // Type specific hashing ciSymbol* _name; // class name - + bool _flatten_array; + + bool meet_flatten_array(bool other_flatten_array) const { + return (_flatten_array && other_flatten_array) ? true : false; + } + public: ciSymbol* name() const { return _name; } + bool flatten_array() const { + assert(!klass()->is_valuetype() || !klass()->as_value_klass()->flatten_array() || _flatten_array, "incorrect value bit"); + assert(!_flatten_array || can_be_value_type(), "incorrect value bit"); + return _flatten_array; + } bool is_loaded() const { return _klass->is_loaded(); } // Make a pointer to a constant oop. static const TypeInstPtr *make(ciObject* o) { - return make(TypePtr::Constant, o->klass(), true, o, Offset(0), InstanceBot); + return make(TypePtr::Constant, o->klass(), true, o, Offset(0), o->klass()->is_valuetype() && o->klass()->as_value_klass()->flatten_array(), InstanceBot); } // Make a pointer to a constant oop with offset. static const TypeInstPtr* make(ciObject* o, Offset offset) { - return make(TypePtr::Constant, o->klass(), true, o, offset, InstanceBot); + return make(TypePtr::Constant, o->klass(), true, o, offset, o->klass()->is_valuetype() && o->klass()->as_value_klass()->flatten_array(), InstanceBot); } // Make a pointer to some value of type klass. static const TypeInstPtr *make(PTR ptr, ciKlass* klass) { - return make(ptr, klass, false, NULL, Offset(0), InstanceBot); + return make(ptr, klass, false, NULL, Offset(0), klass->is_valuetype() && klass->as_value_klass()->flatten_array(), InstanceBot); } // Make a pointer to some non-polymorphic value of exactly type klass. static const TypeInstPtr *make_exact(PTR ptr, ciKlass* klass) { - return make(ptr, klass, true, NULL, Offset(0), InstanceBot); + return make(ptr, klass, true, NULL, Offset(0), klass->is_valuetype() && klass->as_value_klass()->flatten_array(), InstanceBot); } // Make a pointer to some value of type klass with offset. static const TypeInstPtr *make(PTR ptr, ciKlass* klass, Offset offset) { - return make(ptr, klass, false, NULL, offset, InstanceBot); + return make(ptr, klass, false, NULL, offset, klass->is_valuetype() && klass->as_value_klass()->flatten_array(), InstanceBot); } // Make a pointer to an oop. static const TypeInstPtr* make(PTR ptr, ciKlass* k, bool xk, ciObject* o, Offset offset, + bool flatten_array, int instance_id = InstanceBot, const TypePtr* speculative = NULL, int inline_depth = InlineDepthBottom); @@ -1205,6 +1217,8 @@ virtual const TypePtr* with_inline_depth(int depth) const; virtual const TypePtr* with_instance_id(int instance_id) const; + virtual const TypeInstPtr* cast_to_flatten_array() const; + // the core of the computation of the meet of 2 types virtual const Type *xmeet_helper(const Type *t) const; virtual const TypeInstPtr *xmeet_unloaded( const TypeInstPtr *t ) const; @@ -1400,7 +1414,7 @@ //------------------------------TypeKlassPtr----------------------------------- // Class of Java Klass pointers class TypeKlassPtr : public TypePtr { - TypeKlassPtr(PTR ptr, ciKlass* klass, Offset offset); + TypeKlassPtr(PTR ptr, ciKlass* klass, Offset offset, bool flatten_array); protected: virtual const Type *filter_helper(const Type *kills, bool include_speculative) const; @@ -1414,19 +1428,28 @@ // Does the type exclude subclasses of the klass? (Inexact == polymorphic.) bool _klass_is_exact; + bool _flatten_array; public: ciKlass* klass() const { return _klass; } bool klass_is_exact() const { return _klass_is_exact; } + virtual bool can_be_value_type() const { return EnableValhalla && can_be_value_type_raw(); } + virtual bool can_be_value_type_raw() const { return _klass == NULL || !_klass->is_loaded() || _klass->is_valuetype() || ((_klass->is_java_lang_Object() || _klass->is_interface()) && !klass_is_exact()); } + bool flatten_array() const { + assert(!klass()->is_valuetype() || !klass()->as_value_klass()->flatten_array() || _flatten_array, "incorrect value bit"); + assert(!_flatten_array || can_be_value_type(), "incorrect value bit"); + return _flatten_array; + } + bool is_loaded() const { return klass() != NULL && klass()->is_loaded(); } // ptr to klass 'k' - static const TypeKlassPtr* make(ciKlass* k) { return make( TypePtr::Constant, k, Offset(0)); } + static const TypeKlassPtr* make(ciKlass* k) { return make( TypePtr::Constant, k, Offset(0), k->is_valuetype() && k->as_value_klass()->flatten_array()); } // ptr to klass 'k' with offset - static const TypeKlassPtr* make(ciKlass* k, Offset offset) { return make( TypePtr::Constant, k, offset); } + static const TypeKlassPtr* make(ciKlass* k, Offset offset) { return make( TypePtr::Constant, k, offset, k->is_valuetype() && k->as_value_klass()->flatten_array()); } // ptr to klass 'k' or sub-klass - static const TypeKlassPtr* make(PTR ptr, ciKlass* k, Offset offset); + static const TypeKlassPtr* make(PTR ptr, ciKlass* k, Offset offset, bool flatten_array); virtual const Type *cast_to_ptr_type(PTR ptr) const;