< prev index next >

src/hotspot/share/c1/c1_ValueStack.cpp

Print this page

@@ -170,26 +170,51 @@
 int ValueStack::unlock() {
   _locks.pop();
   return total_locks_size();
 }
 
+// When we merge two object slots, we usually lose the type information.
+// However, for aaload/aastore to work with flattened arrays, we need to preserve
+// the type info (because the aaload/aastore bytecode themselves don't carry the
+// type info).
+ciType* ValueStack::merge_if_flattened_array_types(Value existing_value, Value new_value) {
+  assert(new_value != NULL, "must be");
+  assert(existing_value != new_value, "must be");
+
+  if (existing_value == NULL) {
+    if (new_value->is_flattened_array()) {
+      return new_value->exact_type();
+    } else {
+      return NULL;
+    }
+  }
+
+  if (existing_value->is_flattened_array() && new_value->is_flattened_array()) {
+    // The merged block should be able to access this value as a flattened array.
+    assert(existing_value->exact_type() == new_value->exact_type(), "must be guaranteed by verifier");
+    return existing_value->exact_type();
+  } else {
+    // The merged block cannot access value as a flattened array without first doing a type cast.
+    return NULL;
+  }
+}
 
-void ValueStack::setup_phi_for_stack(BlockBegin* b, int index) {
+void ValueStack::setup_phi_for_stack(BlockBegin* b, int index, Value existing_value, Value new_value) {
   assert(stack_at(index)->as_Phi() == NULL || stack_at(index)->as_Phi()->block() != b, "phi function already created");
 
   ValueType* t = stack_at(index)->type();
-  Value phi = new Phi(t, b, -index - 1);
+  Value phi = new Phi(t, b, -index - 1, merge_if_flattened_array_types(existing_value, new_value));
   _stack.at_put(index, phi);
 
   assert(!t->is_double_word() || _stack.at(index + 1) == NULL, "hi-word of doubleword value must be NULL");
 }
 
-void ValueStack::setup_phi_for_local(BlockBegin* b, int index) {
+void ValueStack::setup_phi_for_local(BlockBegin* b, int index, Value existing_value, Value new_value) {
   assert(local_at(index)->as_Phi() == NULL || local_at(index)->as_Phi()->block() != b, "phi function already created");
 
   ValueType* t = local_at(index)->type();
-  Value phi = new Phi(t, b, index);
+  Value phi = new Phi(t, b, index, merge_if_flattened_array_types(existing_value, new_value));
   store_local(index, phi);
 }
 
 #ifndef PRODUCT
 
< prev index next >