29 #include "opto/connode.hpp"
30
31 class GraphKit;
32
33 class ValueTypeBaseNode : public TypeNode {
34 protected:
35 ValueTypeBaseNode(const Type* t, int nb_fields)
36 : TypeNode(t, nb_fields) {
37 init_class_id(Class_ValueTypeBase);
38 Compile::current()->add_value_type(this);
39 }
40
41 enum { Control, // Control input
42 Oop, // Oop of TypeInstPtr
43 Values // Nodes corresponding to values of the value type's fields.
44 // Nodes are connected in increasing order of the index of the field they correspond to.
45 };
46
47 virtual const TypeInstPtr* value_ptr() const = 0;
48 // Get the klass defining the field layout of the value type
49 virtual ciValueKlass* value_klass() const = 0;
50
51 int make_scalar_in_safepoint(PhaseIterGVN* igvn, Unique_Node_List& worklist, SafePointNode* sfpt);
52
53 const TypePtr* field_adr_type(Node* base, int offset, ciInstanceKlass* holder, DecoratorSet decorators, PhaseGVN& gvn) const;
54
55 public:
56 // Support for control flow merges
57 bool has_phi_inputs(Node* region);
58 ValueTypeBaseNode* clone_with_phis(PhaseGVN* gvn, Node* region);
59 ValueTypeBaseNode* merge_with(PhaseGVN* gvn, const ValueTypeBaseNode* other, int pnum, bool transform);
60 void add_new_path(Node* region);
61
62 // Get oop for heap allocated value type (may be TypePtr::NULL_PTR)
63 Node* get_oop() const { return in(Oop); }
64 void set_oop(Node* oop) { set_req(Oop, oop); }
65
66 // Value type fields
67 uint field_count() const { return req() - Values; }
68 Node* field_value(uint index) const;
69 Node* field_value_by_offset(int offset, bool recursive = false) const;
70 void set_field_value(uint index, Node* value);
71 void set_field_value_by_offset(int offset, Node* value);
72 int field_offset(uint index) const;
73 uint field_index(int offset) const;
74 ciType* field_type(uint index) const;
75 bool field_is_flattened(uint index) const;
76 bool field_is_flattenable(uint index) const;
77
78 // Replace ValueTypeNodes in debug info at safepoints with SafePointScalarObjectNodes
79 void make_scalar_in_safepoints(PhaseIterGVN* igvn);
80
81 // Store the value type as a flattened (headerless) representation
82 void store_flattened(GraphKit* kit, Node* base, Node* ptr, ciInstanceKlass* holder = NULL, int holder_offset = 0, DecoratorSet decorators = IN_HEAP | MO_UNORDERED) const;
83 // Store the field values to memory
84 void store(GraphKit* kit, Node* base, Node* ptr, ciInstanceKlass* holder, int holder_offset = 0, bool deoptimize_on_exception = false, DecoratorSet decorators = IN_HEAP | MO_UNORDERED) const;
85 // Initialize the value type by loading its field values from memory
86 void load(GraphKit* kit, Node* base, Node* ptr, ciInstanceKlass* holder, int holder_offset = 0, DecoratorSet decorators = IN_HEAP | MO_UNORDERED);
87
88 // Allocates the value type (if not yet allocated)
89 ValueTypeBaseNode* allocate(GraphKit* kit, bool deoptimize_on_exception = false);
90 bool is_allocated(PhaseGVN* phase) const;
91
92 void replace_call_results(GraphKit* kit, Node* call, Compile* C);
93 };
94
95 //------------------------------ValueTypeNode-------------------------------------
96 // Node representing a value type in C2 IR
97 class ValueTypeNode : public ValueTypeBaseNode {
98 friend class ValueTypeBaseNode;
99 friend class ValueTypePtrNode;
100 private:
101 ValueTypeNode(ciValueKlass* vk, Node* oop)
102 : ValueTypeBaseNode(TypeValueType::make(vk), Values + vk->nof_declared_nonstatic_fields()) {
103 init_class_id(Class_ValueType);
104 init_req(Oop, oop);
105 }
106
107 // Checks if the value type is loaded from memory and if so returns the oop
108 Node* is_loaded(PhaseGVN* phase, ciValueKlass* vk = NULL, Node* base = NULL, int holder_offset = 0);
109
110 // Checks if the value type fields are all set to default values
111 bool is_default(PhaseGVN& gvn) const;
112
113 const TypeInstPtr* value_ptr() const { return TypeInstPtr::make(TypePtr::BotPTR, value_klass()); }
114 ciValueKlass* value_klass() const { return type()->is_valuetype()->value_klass(); }
115
116 public:
117 // Create uninitialized
118 static ValueTypeNode* make_uninitialized(PhaseGVN& gvn, ciValueKlass* vk);
119 // Create with default field values
120 static ValueTypeNode* make_default(PhaseGVN& gvn, ciValueKlass* vk);
121 // Create and initialize by loading the field values from an oop
122 static ValueTypeNode* make_from_oop(GraphKit* kit, Node* oop, ciValueKlass* vk);
123 // Create and initialize by loading the field values from a flattened field or array
124 static ValueTypeNode* make_from_flattened(GraphKit* kit, ciValueKlass* vk, Node* obj, Node* ptr, ciInstanceKlass* holder = NULL, int holder_offset = 0, DecoratorSet decorators = IN_HEAP | MO_UNORDERED);
125 // Create and initialize with the inputs or outputs of a MultiNode (method entry or call)
126 static ValueTypeNode* make_from_multi(GraphKit* kit, MultiNode* multi, ExtendedSignature& sig, ciValueKlass* vk, uint& base_input, bool in);
127
128 ValueTypeNode* make_larval(GraphKit* kit, bool allocate) const;
129 ValueTypeNode* finish_larval(GraphKit* kit) const;
130
131 // Returns the constant oop of the default value type allocation
132 static Node* default_oop(PhaseGVN& gvn, ciValueKlass* vk);
133
134 // Allocate all non-flattened value type fields
138 return tagged_klass(value_klass(), gvn);
139 }
140 static Node* tagged_klass(ciValueKlass* vk, PhaseGVN& gvn);
141 // Pass value type as fields at a call or return
142 void pass_fields(GraphKit* kit, Node* n, ExtendedSignature& sig, uint& base_input, int base_offset = 0);
143 // Initialize the value type fields with the inputs or outputs of a MultiNode
144 void initialize_fields(GraphKit* kit, MultiNode* multi, ExtendedSignature& sig, uint& base_input, int base_offset, bool in);
145
146 // Allocation optimizations
147 void remove_redundant_allocations(PhaseIterGVN* igvn, PhaseIdealLoop* phase);
148
149 virtual Node* Ideal(PhaseGVN* phase, bool can_reshape);
150 virtual int Opcode() const;
151 };
152
153 //------------------------------ValueTypePtrNode-------------------------------------
154 // Node representing a value type as a pointer in C2 IR
155 class ValueTypePtrNode : public ValueTypeBaseNode {
156 private:
157 const TypeInstPtr* value_ptr() const { return type()->isa_instptr(); }
158 ciValueKlass* value_klass() const { return value_ptr()->value_klass(); }
159
160 ValueTypePtrNode(ciValueKlass* vk, Node* oop)
161 : ValueTypeBaseNode(TypeInstPtr::make(TypePtr::NotNull, vk), Values + vk->nof_declared_nonstatic_fields()) {
162 init_class_id(Class_ValueTypePtr);
163 init_req(Oop, oop);
164 }
165
166 public:
167 // Create and initialize with the values of a ValueTypeNode
168 static ValueTypePtrNode* make_from_value_type(GraphKit* kit, ValueTypeNode* vt, bool deoptimize_on_exception = false);
169 // Create and initialize by loading the field values from an oop
170 static ValueTypePtrNode* make_from_oop(GraphKit* kit, Node* oop);
171
172 virtual int Opcode() const;
173 };
174
175 #endif // SHARE_VM_OPTO_VALUETYPENODE_HPP
|
29 #include "opto/connode.hpp"
30
31 class GraphKit;
32
33 class ValueTypeBaseNode : public TypeNode {
34 protected:
35 ValueTypeBaseNode(const Type* t, int nb_fields)
36 : TypeNode(t, nb_fields) {
37 init_class_id(Class_ValueTypeBase);
38 Compile::current()->add_value_type(this);
39 }
40
41 enum { Control, // Control input
42 Oop, // Oop of TypeInstPtr
43 Values // Nodes corresponding to values of the value type's fields.
44 // Nodes are connected in increasing order of the index of the field they correspond to.
45 };
46
47 virtual const TypeInstPtr* value_ptr() const = 0;
48 // Get the klass defining the field layout of the value type
49 ciValueKlass* value_klass() const { return type()->value_klass(); }
50
51 int make_scalar_in_safepoint(PhaseIterGVN* igvn, Unique_Node_List& worklist, SafePointNode* sfpt);
52
53 const TypePtr* field_adr_type(Node* base, int offset, ciInstanceKlass* holder, DecoratorSet decorators, PhaseGVN& gvn) const;
54
55 public:
56 // Support for control flow merges
57 bool has_phi_inputs(Node* region);
58 ValueTypeBaseNode* clone_with_phis(PhaseGVN* gvn, Node* region);
59 ValueTypeBaseNode* merge_with(PhaseGVN* gvn, const ValueTypeBaseNode* other, int pnum, bool transform);
60 void add_new_path(Node* region);
61
62 // Get oop for heap allocated value type (may be TypePtr::NULL_PTR)
63 Node* get_oop() const { return in(Oop); }
64 void set_oop(Node* oop) { set_req(Oop, oop); }
65
66 // Value type fields
67 uint field_count() const { return req() - Values; }
68 Node* field_value(uint index) const;
69 Node* field_value_by_offset(int offset, bool recursive = false) const;
70 void set_field_value(uint index, Node* value);
71 void set_field_value_by_offset(int offset, Node* value);
72 int field_offset(uint index) const;
73 uint field_index(int offset) const;
74 ciType* field_type(uint index) const;
75 bool field_is_flattened(uint index) const;
76 bool field_is_flattenable(uint index) const;
77
78 // Replace ValueTypeNodes in debug info at safepoints with SafePointScalarObjectNodes
79 void make_scalar_in_safepoints(PhaseIterGVN* igvn);
80
81 // Store the value type as a flattened (headerless) representation
82 void store_flattened(GraphKit* kit, Node* base, Node* ptr, ciInstanceKlass* holder = NULL, int holder_offset = 0, DecoratorSet decorators = IN_HEAP | MO_UNORDERED) const;
83 // Store the field values to memory
84 void store(GraphKit* kit, Node* base, Node* ptr, ciInstanceKlass* holder, int holder_offset = 0, bool deoptimize_on_exception = false, DecoratorSet decorators = IN_HEAP | MO_UNORDERED) const;
85 // Initialize the value type by loading its field values from memory
86 void load(GraphKit* kit, Node* base, Node* ptr, ciInstanceKlass* holder, int holder_offset = 0, DecoratorSet decorators = IN_HEAP | MO_UNORDERED);
87
88 // Allocates the value type (if not yet allocated)
89 ValueTypeBaseNode* allocate(GraphKit* kit, bool deoptimize_on_exception = false, bool safe_for_replace = true);
90 bool is_allocated(PhaseGVN* phase) const;
91
92 void replace_call_results(GraphKit* kit, Node* call, Compile* C);
93 };
94
95 //------------------------------ValueTypeNode-------------------------------------
96 // Node representing a value type in C2 IR
97 class ValueTypeNode : public ValueTypeBaseNode {
98 friend class ValueTypeBaseNode;
99 friend class ValueTypePtrNode;
100 private:
101 ValueTypeNode(ciValueKlass* vk, Node* oop)
102 : ValueTypeBaseNode(TypeValueType::make(vk), Values + vk->nof_declared_nonstatic_fields()) {
103 init_class_id(Class_ValueType);
104 init_req(Oop, oop);
105 }
106
107 // Checks if the value type is loaded from memory and if so returns the oop
108 Node* is_loaded(PhaseGVN* phase, ciValueKlass* vk = NULL, Node* base = NULL, int holder_offset = 0);
109
110 // Checks if the value type fields are all set to default values
111 bool is_default(PhaseGVN& gvn) const;
112
113 const TypeInstPtr* value_ptr() const { return TypeInstPtr::make(TypePtr::BotPTR, value_klass()); }
114
115 public:
116 // Create uninitialized
117 static ValueTypeNode* make_uninitialized(PhaseGVN& gvn, ciValueKlass* vk);
118 // Create with default field values
119 static ValueTypeNode* make_default(PhaseGVN& gvn, ciValueKlass* vk);
120 // Create and initialize by loading the field values from an oop
121 static ValueTypeNode* make_from_oop(GraphKit* kit, Node* oop, ciValueKlass* vk);
122 // Create and initialize by loading the field values from a flattened field or array
123 static ValueTypeNode* make_from_flattened(GraphKit* kit, ciValueKlass* vk, Node* obj, Node* ptr, ciInstanceKlass* holder = NULL, int holder_offset = 0, DecoratorSet decorators = IN_HEAP | MO_UNORDERED);
124 // Create and initialize with the inputs or outputs of a MultiNode (method entry or call)
125 static ValueTypeNode* make_from_multi(GraphKit* kit, MultiNode* multi, ExtendedSignature& sig, ciValueKlass* vk, uint& base_input, bool in);
126
127 ValueTypeNode* make_larval(GraphKit* kit, bool allocate) const;
128 ValueTypeNode* finish_larval(GraphKit* kit) const;
129
130 // Returns the constant oop of the default value type allocation
131 static Node* default_oop(PhaseGVN& gvn, ciValueKlass* vk);
132
133 // Allocate all non-flattened value type fields
137 return tagged_klass(value_klass(), gvn);
138 }
139 static Node* tagged_klass(ciValueKlass* vk, PhaseGVN& gvn);
140 // Pass value type as fields at a call or return
141 void pass_fields(GraphKit* kit, Node* n, ExtendedSignature& sig, uint& base_input, int base_offset = 0);
142 // Initialize the value type fields with the inputs or outputs of a MultiNode
143 void initialize_fields(GraphKit* kit, MultiNode* multi, ExtendedSignature& sig, uint& base_input, int base_offset, bool in);
144
145 // Allocation optimizations
146 void remove_redundant_allocations(PhaseIterGVN* igvn, PhaseIdealLoop* phase);
147
148 virtual Node* Ideal(PhaseGVN* phase, bool can_reshape);
149 virtual int Opcode() const;
150 };
151
152 //------------------------------ValueTypePtrNode-------------------------------------
153 // Node representing a value type as a pointer in C2 IR
154 class ValueTypePtrNode : public ValueTypeBaseNode {
155 private:
156 const TypeInstPtr* value_ptr() const { return type()->isa_instptr(); }
157
158 ValueTypePtrNode(ciValueKlass* vk, Node* oop)
159 : ValueTypeBaseNode(TypeInstPtr::make(TypePtr::NotNull, vk), Values + vk->nof_declared_nonstatic_fields()) {
160 init_class_id(Class_ValueTypePtr);
161 init_req(Oop, oop);
162 }
163
164 public:
165 // Create and initialize with the values of a ValueTypeNode
166 static ValueTypePtrNode* make_from_value_type(GraphKit* kit, ValueTypeNode* vt, bool deoptimize_on_exception = false);
167 // Create and initialize by loading the field values from an oop
168 static ValueTypePtrNode* make_from_oop(GraphKit* kit, Node* oop);
169
170 virtual int Opcode() const;
171 };
172
173 #endif // SHARE_VM_OPTO_VALUETYPENODE_HPP
|