8150102: C1 should fold arraylength for constant/trusted arrays
Reviewed-by: vlivanov, kvn
--- a/hotspot/src/share/vm/c1/c1_Canonicalizer.cpp Wed Feb 17 10:59:04 2016 +0100
+++ b/hotspot/src/share/vm/c1/c1_Canonicalizer.cpp Fri Feb 19 11:16:38 2016 +0300
@@ -222,29 +222,31 @@
}
void Canonicalizer::do_ArrayLength (ArrayLength* x) {
- NewArray* array = x->array()->as_NewArray();
- if (array != NULL && array->length() != NULL) {
- Constant* length = array->length()->as_Constant();
- if (length != NULL) {
- // do not use the Constant itself, but create a new Constant
- // with same value Otherwise a Constant is live over multiple
- // blocks without being registered in a state array.
+ NewArray* na;
+ Constant* ct;
+
+ if ((na = x->array()->as_NewArray()) != NULL) {
+ // New arrays might have the known length.
+ // Do not use the Constant itself, but create a new Constant
+ // with same value Otherwise a Constant is live over multiple
+ // blocks without being registered in a state array.
+ Constant* length;
+ if (na->length() != NULL &&
+ (length = na->length()->as_Constant()) != NULL) {
assert(length->type()->as_IntConstant() != NULL, "array length must be integer");
set_constant(length->type()->as_IntConstant()->value());
}
+
+ } else if ((ct = x->array()->as_Constant()) != NULL) {
+ // Constant arrays have constant lengths.
+ set_constant(ct->type()->as_ArrayConstant()->value()->length());
+
+#ifdef ASSERT
} else {
LoadField* lf = x->array()->as_LoadField();
- if (lf != NULL) {
- ciField* field = lf->field();
- if (field->is_constant() && field->is_static()) {
- // final static field
- ciObject* c = field->constant_value().as_object();
- if (c->is_array()) {
- ciArray* array = (ciArray*) c;
- set_constant(array->length());
- }
- }
- }
+ bool is_static_constant = (lf != NULL) && lf->field()->is_constant() && lf->field()->is_static();
+ assert(!is_static_constant, "Constant field loads are folded during parsing");
+#endif // ASSERT
}
}