240
241 } else if ((ct = x->array()->as_Constant()) != NULL) {
242 // Constant arrays have constant lengths.
243 ArrayConstant* cnst = ct->type()->as_ArrayConstant();
244 if (cnst != NULL) {
245 set_constant(cnst->value()->length());
246 }
247
248 } else if ((lf = x->array()->as_LoadField()) != NULL) {
249 ciField* field = lf->field();
250 if (field->is_constant() && field->is_static()) {
251 assert(PatchALot || ScavengeRootsInCode < 2, "Constant field loads are folded during parsing");
252 ciObject* c = field->constant_value().as_object();
253 if (!c->is_null_object()) {
254 set_constant(c->as_array()->length());
255 }
256 }
257 }
258 }
259
260 void Canonicalizer::do_LoadIndexed (LoadIndexed* x) {}
261 void Canonicalizer::do_StoreIndexed (StoreIndexed* x) {
262 // If a value is going to be stored into a field or array some of
263 // the conversions emitted by javac are unneeded because the fields
264 // are packed to their natural size.
265 Convert* conv = x->value()->as_Convert();
266 if (conv) {
267 Value value = NULL;
268 BasicType type = x->elt_type();
269 switch (conv->op()) {
270 case Bytecodes::_i2b: if (type == T_BYTE) value = conv->value(); break;
271 case Bytecodes::_i2s: if (type == T_SHORT || type == T_BYTE) value = conv->value(); break;
272 case Bytecodes::_i2c: if (type == T_CHAR || type == T_BYTE) value = conv->value(); break;
273 }
274 // limit this optimization to current block
275 if (value != NULL && in_current_block(conv)) {
276 set_canonical(new StoreIndexed(x->array(), x->index(), x->length(),
277 x->elt_type(), value, x->state_before()));
278 return;
279 }
280 }
|
240
241 } else if ((ct = x->array()->as_Constant()) != NULL) {
242 // Constant arrays have constant lengths.
243 ArrayConstant* cnst = ct->type()->as_ArrayConstant();
244 if (cnst != NULL) {
245 set_constant(cnst->value()->length());
246 }
247
248 } else if ((lf = x->array()->as_LoadField()) != NULL) {
249 ciField* field = lf->field();
250 if (field->is_constant() && field->is_static()) {
251 assert(PatchALot || ScavengeRootsInCode < 2, "Constant field loads are folded during parsing");
252 ciObject* c = field->constant_value().as_object();
253 if (!c->is_null_object()) {
254 set_constant(c->as_array()->length());
255 }
256 }
257 }
258 }
259
260 void Canonicalizer::do_LoadIndexed (LoadIndexed* x) {
261 StableArrayConstant* array = x->array()->type()->as_StableArrayConstant();
262 IntConstant* index = x->index()->type()->as_IntConstant();
263
264 assert(array == NULL || FoldStableValues, "not enabled");
265
266 // Constant fold loads from stable arrays.
267 if (array != NULL && index != NULL) {
268 jint idx = index->value();
269 if (idx < 0 || idx >= array->value()->length()) {
270 // Leave the load as is. The range check will handle it.
271 return;
272 }
273
274 ciConstant field_val = array->value()->element_value(idx);
275 if (!field_val.is_null_or_zero()) {
276 jint dimension = array->dimension();
277 assert(dimension <= array->value()->array_type()->dimension(), "inconsistent info");
278 ValueType* value = NULL;
279 if (dimension > 1) {
280 // Preserve information about the dimension for the element.
281 assert(field_val.as_object()->is_array(), "not an array");
282 value = new StableArrayConstant(field_val.as_object()->as_array(), dimension - 1);
283 } else {
284 assert(dimension == 1, "sanity");
285 value = as_ValueType(field_val);
286 }
287 set_canonical(new Constant(value));
288 }
289 }
290 }
291
292 void Canonicalizer::do_StoreIndexed (StoreIndexed* x) {
293 // If a value is going to be stored into a field or array some of
294 // the conversions emitted by javac are unneeded because the fields
295 // are packed to their natural size.
296 Convert* conv = x->value()->as_Convert();
297 if (conv) {
298 Value value = NULL;
299 BasicType type = x->elt_type();
300 switch (conv->op()) {
301 case Bytecodes::_i2b: if (type == T_BYTE) value = conv->value(); break;
302 case Bytecodes::_i2s: if (type == T_SHORT || type == T_BYTE) value = conv->value(); break;
303 case Bytecodes::_i2c: if (type == T_CHAR || type == T_BYTE) value = conv->value(); break;
304 }
305 // limit this optimization to current block
306 if (value != NULL && in_current_block(conv)) {
307 set_canonical(new StoreIndexed(x->array(), x->index(), x->length(),
308 x->elt_type(), value, x->state_before()));
309 return;
310 }
311 }
|