Clean up after verifier changes wrt. conflict/undefined reg.
Remove unused path in RegType::Merge() and compare undefined
type as pointers. Reduce the number of edges to merge in
b_22331663.smali to just those that we really want to test.
Bug: 22331663
Change-Id: I16b83c4c97fd40be9dd246ef13ccda6e924eef60
diff --git a/runtime/verifier/reg_type.cc b/runtime/verifier/reg_type.cc
index 1435607..9c52819 100644
--- a/runtime/verifier/reg_type.cc
+++ b/runtime/verifier/reg_type.cc
@@ -583,24 +583,20 @@
const RegType& RegType::Merge(const RegType& incoming_type, RegTypeCache* reg_types) const {
DCHECK(!Equals(incoming_type)); // Trivial equality handled by caller
- // Perform pointer equality tests for conflict to avoid virtual method dispatch.
+ // Perform pointer equality tests for undefined and conflict to avoid virtual method dispatch.
+ const UndefinedType& undefined = reg_types->Undefined();
const ConflictType& conflict = reg_types->Conflict();
- if (IsUndefined() || incoming_type.IsUndefined()) {
+ DCHECK_EQ(this == &undefined, IsUndefined());
+ DCHECK_EQ(&incoming_type == &undefined, incoming_type.IsUndefined());
+ DCHECK_EQ(this == &conflict, IsConflict());
+ DCHECK_EQ(&incoming_type == &conflict, incoming_type.IsConflict());
+ if (this == &undefined || &incoming_type == &undefined) {
// There is a difference between undefined and conflict. Conflicts may be copied around, but
// not used. Undefined registers must not be copied. So any merge with undefined should return
// undefined.
- if (IsUndefined()) {
- return *this;
- }
- return incoming_type;
- } else if (this == &conflict) {
- DCHECK(IsConflict());
- return *this; // Conflict MERGE * => Conflict
- } else if (&incoming_type == &conflict) {
- DCHECK(incoming_type.IsConflict());
- return incoming_type; // * MERGE Conflict => Conflict
- } else if (IsUndefined() || incoming_type.IsUndefined()) {
- return conflict; // Unknown MERGE * => Conflict
+ return undefined;
+ } else if (this == &conflict || &incoming_type == &conflict) {
+ return conflict; // (Conflict MERGE *) or (* MERGE Conflict) => Conflict
} else if (IsConstant() && incoming_type.IsConstant()) {
const ConstantType& type1 = *down_cast<const ConstantType*>(this);
const ConstantType& type2 = *down_cast<const ConstantType*>(&incoming_type);
diff --git a/test/800-smali/smali/b_22331663.smali b/test/800-smali/smali/b_22331663.smali
index 057fc7f..bae75c2 100644
--- a/test/800-smali/smali/b_22331663.smali
+++ b/test/800-smali/smali/b_22331663.smali
@@ -4,29 +4,29 @@
.method public static run(Z)V
.registers 6
- # Make v4 defined, just use null.
- const v4, 0
+ if-eqz v5, :if_eqz_target
- if-eqz v5, :Label2
-
-:Label1
# Construct a java.lang.Object completely, and throw a new exception.
new-instance v4, Ljava/lang/Object;
invoke-direct {v4}, Ljava/lang/Object;-><init>()V
new-instance v3, Ljava/lang/RuntimeException;
invoke-direct {v3}, Ljava/lang/RuntimeException;-><init>()V
+:throw1_begin
throw v3
+:throw1_end
-:Label2
+:if_eqz_target
# Allocate a java.lang.Object (do not initialize), and throw a new exception.
new-instance v4, Ljava/lang/Object;
new-instance v3, Ljava/lang/RuntimeException;
invoke-direct {v3}, Ljava/lang/RuntimeException;-><init>()V
+:throw2_begin
throw v3
+:throw2_end
-:Label3
+:catch_entry
# Catch handler. Here we had to merge the uninitialized with the initialized reference,
# which creates a conflict. Copy the conflict, and then return. This should not make the
# verifier fail the method.
@@ -34,5 +34,6 @@
return-void
-.catchall {:Label1 .. :Label3} :Label3
+.catchall {:throw1_begin .. :throw1_end} :catch_entry
+.catchall {:throw2_begin .. :throw2_end} :catch_entry
.end method