--- old/src/share/vm/opto/valuetypenode.hpp 2017-07-10 18:12:11.422366453 +0200 +++ new/src/share/vm/opto/valuetypenode.hpp 2017-07-10 18:12:06.493388530 +0200 @@ -30,35 +30,71 @@ class GraphKit; +class ValueTypeBaseNode : public TypeNode { +protected: + ValueTypeBaseNode(const Type* t, int nb_fields) + : TypeNode(t, nb_fields) { + init_class_id(Class_ValueTypeBase); + } + + enum { Control, // Control input + Oop, // Oop of TypeValueTypePtr + Values // Nodes corresponding to values of the value type's fields. + // Nodes are connected in increasing order of the index of the field + // they correspond to. Field indeces are defined in ciValueKlass::_field_index_map. + }; + + virtual const TypeValueTypePtr* value_type_ptr() const = 0; + // Get the klass defining the field layout of the value type + virtual ciValueKlass* value_klass() const = 0; + int make_scalar_in_safepoint(SafePointNode* sfpt, Node* root, PhaseGVN* gvn); +public: + // Support for control flow merges + bool has_phi_inputs(Node* region); + ValueTypeBaseNode* clone_with_phis(PhaseGVN* gvn, Node* region); + ValueTypeBaseNode* merge_with(PhaseGVN* gvn, const ValueTypeBaseNode* other, int pnum, bool transform); + + // Get oop for heap allocated value type (may be TypePtr::NULL_PTR) + Node* get_oop() const { return in(Oop); } + void set_oop(Node* oop) { set_req(Oop, oop); } + + // Value type fields + uint field_count() const { return req() - Values; } + Node* field_value(uint index) const; + Node* field_value_by_offset(int offset, bool recursive = false) const; + void set_field_value(uint index, Node* value); + int field_offset(uint index) const; + ciType* field_type(uint index) const; + + // Replace ValueTypeNodes in debug info at safepoints with SafePointScalarObjectNodes + void make_scalar_in_safepoints(Node* root, PhaseGVN* gvn); +}; + //------------------------------ValueTypeNode------------------------------------- // Node representing a value type in C2 IR -class ValueTypeNode : public TypeNode { +class ValueTypeNode : public ValueTypeBaseNode { + friend class ValueTypeBaseNode; private: ValueTypeNode(const TypeValueType* t, Node* oop) - : TypeNode(t, Values + t->value_klass()->nof_declared_nonstatic_fields()) { + : ValueTypeBaseNode(t, Values + t->value_klass()->nof_declared_nonstatic_fields()) { init_class_id(Class_ValueType); init_req(Oop, oop); } ValueTypeNode(const TypeValueType* t, Node* oop, int field_count) - : TypeNode(t, Values + field_count) { + : ValueTypeBaseNode(t, Values + field_count) { init_class_id(Class_ValueType); init_req(Oop, oop); } - // Get the klass defining the field layout of the value type - ciValueKlass* value_klass() const { return type()->is_valuetype()->value_klass(); } // Initialize the value type by loading its field values from memory void load(PhaseGVN& gvn, Node* mem, Node* base, Node* ptr, ciInstanceKlass* holder, int holder_offset = 0); // Checks if the value type is loaded from memory and if so returns the oop Node* is_loaded(PhaseGVN* phase, const TypeValueType* t, Node* base = NULL, int holder_offset = 0); - enum { Control, // Control input - Oop, // Oop of TypeValueTypePtr - Values // Nodes corresponding to values of the value type's fields. - // Nodes are connected in increasing order of the index of the field - // they correspond to. Field indeces are defined in ciValueKlass::_field_index_map. - }; + const TypeValueTypePtr* value_type_ptr() const { return TypeValueTypePtr::make(bottom_type()->isa_valuetype()); } + // Get the klass defining the field layout of the value type + ciValueKlass* value_klass() const { return type()->is_valuetype()->value_klass(); } public: // Create a new ValueTypeNode with uninitialized values @@ -70,33 +106,16 @@ // Create a new ValueTypeNode and load its values from a flattened value type field or array static Node* make(PhaseGVN& gvn, ciValueKlass* vk, Node* mem, Node* obj, Node* ptr, ciInstanceKlass* holder = NULL, int holder_offset = 0); - // Support for control flow merges - ValueTypeNode* clone_with_phis(PhaseGVN* gvn, Node* region); - bool has_phi_inputs(Node* region); - ValueTypeNode* merge_with(PhaseGVN* gvn, const ValueTypeNode* other, int pnum, bool transform); // Store the value type as a flattened (headerless) representation void store_flattened(GraphKit* kit, Node* base, Node* ptr, ciInstanceKlass* holder = NULL, int holder_offset = 0) const; // Store the field values to memory void store(GraphKit* kit, Node* base, Node* ptr, ciInstanceKlass* holder, int holder_offset = 0) const; - // Get oop for heap allocated value type (may be TypePtr::NULL_PTR) - Node* get_oop() const { return in(Oop); } - void set_oop(Node* oop) { set_req(Oop, oop); } // Allocates the value type (if not yet allocated) and returns the oop Node* allocate(GraphKit* kit); bool is_allocated(PhaseGVN* phase) const; - // Value type fields - uint field_count() const { return req() - Values; } - Node* field_value(uint index) const; - Node* field_value_by_offset(int offset, bool recursive = false) const; - void set_field_value(uint index, Node* value); - int field_offset(uint index) const; - ciType* field_type(uint index) const; - - // Replace ValueTypeNodes in debug info at safepoints with SafePointScalarObjectNodes - void make_scalar_in_safepoints(Compile* C); void pass_klass(Node* n, uint pos, const GraphKit& kit); uint pass_fields(Node* call, int base_input, const GraphKit& kit, ciValueKlass* base_vk = NULL, int base_offset = 0); void replace_call_results(Node* call, Compile* C); @@ -112,4 +131,25 @@ #endif }; +//------------------------------ValueTypeNode------------------------------------- +// Node representing a value type as a pointer in C2 IR +class ValueTypePtrNode : public ValueTypeBaseNode { +private: + ciValueKlass* value_klass() const { return type()->is_valuetypeptr()->value_type()->value_klass(); } + const TypeValueTypePtr* value_type_ptr() const { return bottom_type()->isa_valuetypeptr(); } +public: + + ValueTypePtrNode(ValueTypeNode* vt, Node* oop, Compile* C) + : ValueTypeBaseNode(TypeValueTypePtr::make(vt->type()->is_valuetype())->cast_to_ptr_type(TypePtr::NotNull), vt->req()) { + init_class_id(Class_ValueTypePtr); + for (uint i = Oop+1; i < vt->req(); i++) { + init_req(i, vt->in(i)); + } + init_req(Oop, oop); + C->add_value_type_ptr(this); + } + + virtual int Opcode() const; +}; + #endif // SHARE_VM_OPTO_VALUETYPENODE_HPP