< prev index next >

src/share/vm/c1/c1_Canonicalizer.cpp

Print this page

        

@@ -220,33 +220,43 @@
   }
 
 }
 
 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
+  NewArray*  na;
+  LoadField* lf;
+  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 {
-    LoadField* lf = x->array()->as_LoadField();
-    if (lf != NULL) {
+
+  } else if ((lf = x->array()->as_LoadField()) != NULL) {
+    // Arrays loaded from static final fields have statically known
+    // length. Many static final loads can come in Constant form,
+    // that are handled below.
       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());
         }
       }
-    }
+
+  } else if ((ct = x->array()->as_Constant()) != NULL) {
+    // Constant arrays have constant lengths.
+    set_constant(ct->type()->as_ArrayConstant()->value()->length());
   }
 }
 
 void Canonicalizer::do_LoadIndexed    (LoadIndexed*     x) {}
 void Canonicalizer::do_StoreIndexed   (StoreIndexed*    x) {
< prev index next >