50 #ifndef PRODUCT
51 extern int explicit_null_checks_inserted,
52 explicit_null_checks_elided;
53 #endif
54
55 //---------------------------------array_load----------------------------------
56 void Parse::array_load(BasicType bt) {
57 const Type* elemtype = Type::TOP;
58 Node* adr = array_addressing(bt, 0, &elemtype);
59 if (stopped()) return; // guaranteed null or range check
60
61 Node* idx = pop();
62 Node* ary = pop();
63
64 // Handle value type arrays
65 const TypeOopPtr* elemptr = elemtype->make_oopptr();
66 const TypeAryPtr* ary_t = _gvn.type(ary)->is_aryptr();
67 if (elemtype->isa_valuetype() != NULL) {
68 // Load from flattened value type array
69 ciValueKlass* vk = elemtype->is_valuetype()->value_klass();
70 ValueTypeNode* vt = ValueTypeNode::make_from_flattened(this, vk, ary, adr);
71 push(vt);
72 return;
73 } else if (elemptr != NULL && elemptr->is_valuetypeptr()) {
74 // Load from non-flattened value type array (elements can never be null)
75 bt = T_VALUETYPE;
76 assert(elemptr->meet(TypePtr::NULL_PTR) != elemptr, "value type array elements should never be null");
77 } else if (ValueArrayFlatten && elemptr != NULL && elemptr->can_be_value_type() &&
78 !ary_t->klass_is_exact()) {
79 // Cannot statically determine if array is flattened, emit runtime check
80 IdealKit ideal(this);
81 IdealVariable res(ideal);
82 ideal.declarations_done();
83 Node* kls = load_object_klass(ary);
84 Node* tag = load_lh_array_tag(kls);
85 ideal.if_then(tag, BoolTest::ne, intcon(Klass::_lh_array_tag_vt_value)); {
86 // non flattened
87 sync_kit(ideal);
88 const TypeAryPtr* adr_type = TypeAryPtr::get_array_body_type(bt);
89 elemtype = ary_t->elem()->make_oopptr();
90 Node* ld = access_load_at(ary, adr, adr_type, elemtype, bt,
137
138 ideal.sync_kit(this);
139 ideal.set(res, alloc_obj);
140 } ideal.end_if();
141 sync_kit(ideal);
142 push_node(bt, ideal.value(res));
143 return;
144 }
145
146 if (elemtype == TypeInt::BOOL) {
147 bt = T_BOOLEAN;
148 } else if (bt == T_OBJECT) {
149 elemtype = ary_t->elem()->make_oopptr();
150 }
151
152 const TypeAryPtr* adr_type = TypeAryPtr::get_array_body_type(bt);
153 Node* ld = access_load_at(ary, adr, adr_type, elemtype, bt,
154 IN_HEAP | IS_ARRAY | C2_CONTROL_DEPENDENT_LOAD);
155 if (bt == T_VALUETYPE) {
156 // Loading a non-flattened (but flattenable) value type from an array
157 assert(!gvn().type(ld)->is_ptr()->maybe_null(), "value type array elements should never be null");
158 ld = ValueTypeNode::make_from_oop(this, ld, elemptr->value_klass());
159 }
160
161 push_node(bt, ld);
162 }
163
164
165 //--------------------------------array_store----------------------------------
166 void Parse::array_store(BasicType bt) {
167 const Type* elemtype = Type::TOP;
168 Node* adr = array_addressing(bt, type2size[bt], &elemtype);
169 if (stopped()) return; // guaranteed null or range check
170 Node* cast_val = NULL;
171 if (bt == T_OBJECT) {
172 cast_val = array_store_check();
173 if (stopped()) return;
174 }
175 Node* val = pop_node(bt); // Value to store
176 Node* idx = pop(); // Index in the array
177 Node* ary = pop(); // The array itself
178
179 const TypeAryPtr* ary_t = _gvn.type(ary)->is_aryptr();
180 if (bt == T_OBJECT) {
181 const TypeOopPtr* elemptr = elemtype->make_oopptr();
182 const Type* val_t = _gvn.type(val);
183 if (elemtype->isa_valuetype() != NULL) {
184 // Store to flattened value type array
185 if (!val->is_ValueType() && val_t == TypePtr::NULL_PTR) {
186 // Can not store null into a value type array
187 inc_sp(3);
188 uncommon_trap(Deoptimization::Reason_null_check, Deoptimization::Action_none);
189 return;
190 }
191 cast_val->as_ValueType()->store_flattened(this, ary, adr);
192 return;
193 } else if (elemptr->is_valuetypeptr()) {
194 // Store to non-flattened value type array
195 if (!val->is_ValueType() && val_t == TypePtr::NULL_PTR) {
196 // Can not store null into a value type array
197 inc_sp(3);
198 uncommon_trap(Deoptimization::Reason_null_check, Deoptimization::Action_none);
199 return;
200 }
201 } else if (elemptr->can_be_value_type() && !ary_t->klass_is_exact() &&
202 (val->is_ValueType() || val_t == TypePtr::NULL_PTR || val_t->is_oopptr()->can_be_value_type())) {
203 if (ValueArrayFlatten) {
204 IdealKit ideal(this);
205 Node* kls = load_object_klass(ary);
206 Node* layout_val = load_lh_array_tag(kls);
207 ideal.if_then(layout_val, BoolTest::ne, intcon(Klass::_lh_array_tag_vt_value)); {
208 // non flattened
209 sync_kit(ideal);
210
211 if (!val->is_ValueType() && TypePtr::NULL_PTR->higher_equal(val_t)) {
212 gen_value_type_array_guard(ary, val, 3);
213 }
214
215 const TypeAryPtr* adr_type = TypeAryPtr::get_array_body_type(bt);
216 elemtype = ary_t->elem()->make_oopptr();
217 access_store_at(control(), ary, adr, adr_type, val, elemtype, bt, MO_UNORDERED | IN_HEAP | IS_ARRAY);
218 ideal.sync_kit(this);
219 } ideal.else_(); {
220 // flattened
221 // Object/interface array must be flattened, cast it
222 if (val->is_ValueType()) {
223 sync_kit(ideal);
224 const TypeValueType* vt = _gvn.type(val)->is_valuetype();
225 ciArrayKlass* array_klass = ciArrayKlass::make(vt->value_klass());
226 const TypeAryPtr* arytype = TypeOopPtr::make_from_klass(array_klass)->isa_aryptr();
227 ary = _gvn.transform(new CheckCastPPNode(control(), ary, arytype));
228 adr = array_element_address(ary, idx, T_OBJECT, arytype->size(), control());
229 val->as_ValueType()->store_flattened(this, ary, adr);
230 ideal.sync_kit(this);
231 } else {
232 if (TypePtr::NULL_PTR->higher_equal(val_t)) {
233 sync_kit(ideal);
234 Node* null_ctl = top();
235 val = null_check_oop(val, &null_ctl);
236 {
237 assert(null_ctl != top(), "expected to possibly be null");
238 PreserveJVMState pjvms(this);
239 set_control(null_ctl);
240 inc_sp(3);
241 uncommon_trap(Deoptimization::Reason_null_check, Deoptimization::Action_none);
242 }
243 ideal.sync_kit(this);
244 }
245
246 if (!ideal.ctrl()->is_top()) {
247 ideal.make_leaf_call(OptoRuntime::store_unknown_value_Type(),
248 CAST_FROM_FN_PTR(address, OptoRuntime::store_unknown_value),
249 "store_unknown_value",
250 val, ary, idx);
251 }
252 }
253 } ideal.end_if();
254 sync_kit(ideal);
255 return;
256 } else {
257 if (!val->is_ValueType() && TypePtr::NULL_PTR->higher_equal(val_t)) {
258 gen_value_type_array_guard(ary, val, 3);
259 }
260 }
261 }
262 }
|
50 #ifndef PRODUCT
51 extern int explicit_null_checks_inserted,
52 explicit_null_checks_elided;
53 #endif
54
55 //---------------------------------array_load----------------------------------
56 void Parse::array_load(BasicType bt) {
57 const Type* elemtype = Type::TOP;
58 Node* adr = array_addressing(bt, 0, &elemtype);
59 if (stopped()) return; // guaranteed null or range check
60
61 Node* idx = pop();
62 Node* ary = pop();
63
64 // Handle value type arrays
65 const TypeOopPtr* elemptr = elemtype->make_oopptr();
66 const TypeAryPtr* ary_t = _gvn.type(ary)->is_aryptr();
67 if (elemtype->isa_valuetype() != NULL) {
68 // Load from flattened value type array
69 ciValueKlass* vk = elemtype->is_valuetype()->value_klass();
70 Node* vt = ValueTypeNode::make_from_flattened(this, vk, ary, adr);
71 push(vt);
72 return;
73 } else if (elemptr != NULL && elemptr->is_valuetypeptr()) {
74 // Load from non-flattened value type array (elements can never be null)
75 bt = T_VALUETYPE;
76 assert(elemptr->meet(TypePtr::NULL_PTR) != elemptr, "value type array elements should never be null");
77 } else if (ValueArrayFlatten && elemptr != NULL && elemptr->can_be_value_type() &&
78 !ary_t->klass_is_exact()) {
79 // Cannot statically determine if array is flattened, emit runtime check
80 IdealKit ideal(this);
81 IdealVariable res(ideal);
82 ideal.declarations_done();
83 Node* kls = load_object_klass(ary);
84 Node* tag = load_lh_array_tag(kls);
85 ideal.if_then(tag, BoolTest::ne, intcon(Klass::_lh_array_tag_vt_value)); {
86 // non flattened
87 sync_kit(ideal);
88 const TypeAryPtr* adr_type = TypeAryPtr::get_array_body_type(bt);
89 elemtype = ary_t->elem()->make_oopptr();
90 Node* ld = access_load_at(ary, adr, adr_type, elemtype, bt,
137
138 ideal.sync_kit(this);
139 ideal.set(res, alloc_obj);
140 } ideal.end_if();
141 sync_kit(ideal);
142 push_node(bt, ideal.value(res));
143 return;
144 }
145
146 if (elemtype == TypeInt::BOOL) {
147 bt = T_BOOLEAN;
148 } else if (bt == T_OBJECT) {
149 elemtype = ary_t->elem()->make_oopptr();
150 }
151
152 const TypeAryPtr* adr_type = TypeAryPtr::get_array_body_type(bt);
153 Node* ld = access_load_at(ary, adr, adr_type, elemtype, bt,
154 IN_HEAP | IS_ARRAY | C2_CONTROL_DEPENDENT_LOAD);
155 if (bt == T_VALUETYPE) {
156 // Loading a non-flattened (but flattenable) value type from an array
157 assert(!gvn().type(ld)->maybe_null(), "value type array elements should never be null");
158 if (elemptr->value_klass()->is_scalarizable()) {
159 ld = ValueTypeNode::make_from_oop(this, ld, elemptr->value_klass());
160 }
161 }
162
163 push_node(bt, ld);
164 }
165
166
167 //--------------------------------array_store----------------------------------
168 void Parse::array_store(BasicType bt) {
169 const Type* elemtype = Type::TOP;
170 Node* adr = array_addressing(bt, type2size[bt], &elemtype);
171 if (stopped()) return; // guaranteed null or range check
172 Node* cast_val = NULL;
173 if (bt == T_OBJECT) {
174 cast_val = array_store_check();
175 if (stopped()) return;
176 }
177 Node* val = pop_node(bt); // Value to store
178 Node* idx = pop(); // Index in the array
179 Node* ary = pop(); // The array itself
180
181 const TypeAryPtr* ary_t = _gvn.type(ary)->is_aryptr();
182 if (bt == T_OBJECT) {
183 const TypeOopPtr* elemptr = elemtype->make_oopptr();
184 const Type* val_t = _gvn.type(val);
185 if (elemtype->isa_valuetype() != NULL) {
186 // Store to flattened value type array
187 val_t = _gvn.type(cast_val);
188 if (!cast_val->is_ValueType()) {
189 if (val_t->maybe_null()) {
190 // Can not store null into a value type array
191 assert(val_t == TypePtr::NULL_PTR, "Anything other than null?");
192 inc_sp(3);
193 uncommon_trap(Deoptimization::Reason_null_check, Deoptimization::Action_none);
194 return;
195 }
196 assert(!val_t->maybe_null(), "should never be null");
197 cast_val = ValueTypeNode::make_from_oop(this, cast_val, elemtype->is_valuetype()->value_klass());
198 }
199 cast_val->as_ValueType()->store_flattened(this, ary, adr);
200 return;
201 } else if (elemptr->is_valuetypeptr()) {
202 // Store to non-flattened value type array
203 val_t = _gvn.type(cast_val);
204 if (!cast_val->is_ValueType() && val_t->maybe_null()) {
205 // Can not store null into a value type array
206 assert(val_t == TypePtr::NULL_PTR, "Anything other than null?");
207 inc_sp(3);
208 uncommon_trap(Deoptimization::Reason_null_check, Deoptimization::Action_none);
209 return;
210 }
211 } else if (elemptr->can_be_value_type() && !ary_t->klass_is_exact() &&
212 (val->is_ValueType() || val_t == TypePtr::NULL_PTR || val_t->is_oopptr()->can_be_value_type())) {
213 if (ValueArrayFlatten) {
214 IdealKit ideal(this);
215 Node* kls = load_object_klass(ary);
216 Node* layout_val = load_lh_array_tag(kls);
217 ideal.if_then(layout_val, BoolTest::ne, intcon(Klass::_lh_array_tag_vt_value)); {
218 // non flattened
219 sync_kit(ideal);
220
221 if (!val->is_ValueType() && TypePtr::NULL_PTR->higher_equal(val_t)) {
222 gen_value_type_array_guard(ary, val, 3);
223 }
224
225 const TypeAryPtr* adr_type = TypeAryPtr::get_array_body_type(bt);
226 elemtype = ary_t->elem()->make_oopptr();
227 access_store_at(control(), ary, adr, adr_type, val, elemtype, bt, MO_UNORDERED | IN_HEAP | IS_ARRAY);
228 ideal.sync_kit(this);
229 } ideal.else_(); {
230 // flattened
231 // Object/interface array must be flattened, cast it
232 if (val->is_ValueType()) {
233 sync_kit(ideal);
234 const TypeValueType* vt = _gvn.type(val)->is_valuetype();
235 ciArrayKlass* array_klass = ciArrayKlass::make(vt->value_klass());
236 const TypeAryPtr* arytype = TypeOopPtr::make_from_klass(array_klass)->isa_aryptr();
237 ary = _gvn.transform(new CheckCastPPNode(control(), ary, arytype));
238 adr = array_element_address(ary, idx, T_OBJECT, arytype->size(), control());
239 val->as_ValueType()->store_flattened(this, ary, adr);
240 ideal.sync_kit(this);
241 } else {
242 if (TypePtr::NULL_PTR->higher_equal(val_t)) {
243 sync_kit(ideal);
244 inc_sp(3);
245 val = filter_null(val);
246 dec_sp(3);
247 ideal.sync_kit(this);
248 }
249
250 if (!ideal.ctrl()->is_top()) {
251 ideal.make_leaf_call(OptoRuntime::store_unknown_value_Type(),
252 CAST_FROM_FN_PTR(address, OptoRuntime::store_unknown_value),
253 "store_unknown_value",
254 val, ary, idx);
255 }
256 }
257 } ideal.end_if();
258 sync_kit(ideal);
259 return;
260 } else {
261 if (!val->is_ValueType() && TypePtr::NULL_PTR->higher_equal(val_t)) {
262 gen_value_type_array_guard(ary, val, 3);
263 }
264 }
265 }
266 }
|