Move verification of primitive type puts into helper method.

Change-Id: Ia40d9f85303a52e20ca57acf13a0cfc8a9922024
diff --git a/runtime/verifier/method_verifier.cc b/runtime/verifier/method_verifier.cc
index 9fb3b07..95fda9d 100644
--- a/runtime/verifier/method_verifier.cc
+++ b/runtime/verifier/method_verifier.cc
@@ -3299,6 +3299,43 @@
   }
 }
 
+void MethodVerifier::VerifyPrimitivePut(const RegType& target_type, const RegType& insn_type,
+                                        const uint32_t vregA) {
+  // Primitive assignability rules are weaker than regular assignability rules.
+  bool instruction_compatible;
+  bool value_compatible;
+  const RegType& value_type = work_line_->GetRegisterType(vregA);
+  if (target_type.IsIntegralTypes()) {
+    instruction_compatible = insn_type.IsIntegralTypes();
+    value_compatible = value_type.IsIntegralTypes();
+  } else if (target_type.IsFloat()) {
+    instruction_compatible = insn_type.IsInteger();  // no put-float, so expect put-int
+    value_compatible = value_type.IsFloatTypes();
+  } else if (target_type.IsLong()) {
+    instruction_compatible = insn_type.IsLong();
+    value_compatible = value_type.IsLongTypes();
+  } else if (target_type.IsDouble()) {
+    instruction_compatible = insn_type.IsLong();  // no put-double, so expect put-long
+    value_compatible = value_type.IsDoubleTypes();
+  } else {
+    instruction_compatible = false;  // reference with primitive store
+    value_compatible = false;  // unused
+  }
+  if (!instruction_compatible) {
+    // This is a global failure rather than a class change failure as the instructions and
+    // the descriptors for the type should have been consistent within the same file at
+    // compile time.
+    Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "put insn has type '" << insn_type
+        << "' but expected type '" << target_type << "'";
+    return;
+  }
+  if (!value_compatible) {
+    Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "unexpected value in v" << vregA
+        << " of type " << value_type << " but expected " << target_type << " for put";
+    return;
+  }
+}
+
 void MethodVerifier::VerifyAPut(const Instruction* inst,
                              const RegType& insn_type, bool is_primitive) {
   const RegType& index_type = work_line_->GetRegisterType(inst->VRegC_23x());
@@ -3313,45 +3350,9 @@
       Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "not array type " << array_type << " with aput";
     } else {
       const RegType& component_type = reg_types_.GetComponentType(array_type, class_loader_);
+      const uint32_t vregA = inst->VRegA_23x();
       if (is_primitive) {
-        // Primitive array assignability rules are weaker than regular assignability rules.
-        bool instruction_compatible;
-        bool value_compatible;
-        const RegType& value_type = work_line_->GetRegisterType(inst->VRegA_23x());
-        if (component_type.IsNonZeroReferenceTypes()) {
-          Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "reference array type " << array_type
-              << " source for category 1 aput";
-          return;
-        } else if (component_type.IsIntegralTypes()) {
-          instruction_compatible = insn_type.IsIntegralTypes();
-          value_compatible = value_type.IsIntegralTypes();
-        } else if (component_type.IsFloat()) {
-          instruction_compatible = insn_type.IsInteger();  // no aput-float, so expect aput-int
-          value_compatible = value_type.IsFloatTypes();
-        } else if (component_type.IsLong()) {
-          instruction_compatible = insn_type.IsLong();
-          value_compatible = value_type.IsLongTypes();
-        } else if (component_type.IsDouble()) {
-          instruction_compatible = insn_type.IsLong();  // no aput-double, so expect aput-long
-          value_compatible = value_type.IsDoubleTypes();
-        } else {
-          instruction_compatible = false;  // reference array with primitive store
-          value_compatible = false;  // unused
-        }
-        if (!instruction_compatible) {
-          // This is a global failure rather than a class change failure as the instructions and
-          // the descriptors for the type should have been consistent within the same file at
-          // compile time
-          Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "expected array to be of type '" << insn_type
-                                            << "' but found type '" << component_type
-                                            << "' in aput";
-          return;
-        }
-        if (!value_compatible) {
-          Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "unexpected value in v" << inst->VRegA_23x()
-              << " of type " << value_type << " but expected " << component_type << " for aput";
-          return;
-        }
+        VerifyPrimitivePut(component_type, insn_type, vregA);
       } else {
         if (!component_type.IsReferenceTypes()) {
           Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "primitive array type " << array_type
@@ -3360,7 +3361,7 @@
           // The instruction agrees with the type of array, confirm the value to be stored does too
           // Note: we use the instruction type (rather than the component type) for aput-object as
           // incompatible classes will be caught at runtime as an array store exception
-          work_line_->VerifyRegisterType(inst->VRegA_23x(), insn_type);
+          work_line_->VerifyRegisterType(vregA, insn_type);
         }
       }
     }
@@ -3551,43 +3552,7 @@
   }
   const uint32_t vregA = (is_static) ? inst->VRegA_21c() : inst->VRegA_22c();
   if (is_primitive) {
-    // Primitive field assignability rules are weaker than regular assignability rules
-    bool instruction_compatible;
-    bool value_compatible;
-    const RegType& value_type = work_line_->GetRegisterType(vregA);
-    if (field_type.IsIntegralTypes()) {
-      instruction_compatible = insn_type.IsIntegralTypes();
-      value_compatible = value_type.IsIntegralTypes();
-    } else if (field_type.IsFloat()) {
-      instruction_compatible = insn_type.IsInteger();  // no [is]put-float, so expect [is]put-int
-      value_compatible = value_type.IsFloatTypes();
-    } else if (field_type.IsLong()) {
-      instruction_compatible = insn_type.IsLong();
-      value_compatible = value_type.IsLongTypes();
-    } else if (field_type.IsDouble()) {
-      instruction_compatible = insn_type.IsLong();  // no [is]put-double, so expect [is]put-long
-      value_compatible = value_type.IsDoubleTypes();
-    } else {
-      instruction_compatible = false;  // reference field with primitive store
-      value_compatible = false;  // unused
-    }
-    if (!instruction_compatible) {
-      // This is a global failure rather than a class change failure as the instructions and
-      // the descriptors for the type should have been consistent within the same file at
-      // compile time
-      Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "expected field " << PrettyField(field)
-                                        << " to be of type '" << insn_type
-                                        << "' but found type '" << field_type
-                                        << "' in put";
-      return;
-    }
-    if (!value_compatible) {
-      Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "unexpected value in v" << vregA
-          << " of type " << value_type
-          << " but expected " << field_type
-          << " for store to " << PrettyField(field) << " in put";
-      return;
-    }
+    VerifyPrimitivePut(field_type, insn_type, vregA);
   } else {
     if (!insn_type.IsAssignableFrom(field_type)) {
       Fail(VERIFY_ERROR_BAD_CLASS_SOFT) << "expected field " << PrettyField(field)
diff --git a/runtime/verifier/method_verifier.h b/runtime/verifier/method_verifier.h
index 3f98a00..ed64307 100644
--- a/runtime/verifier/method_verifier.h
+++ b/runtime/verifier/method_verifier.h
@@ -476,6 +476,10 @@
   void VerifyNewArray(const Instruction* inst, bool is_filled, bool is_range)
       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
 
+  // Helper to perform verification on puts of primitive type.
+  void VerifyPrimitivePut(const RegType& target_type, const RegType& insn_type,
+                          const uint32_t vregA) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+
   // Perform verification of an aget instruction. The destination register's type will be set to
   // be that of component type of the array unless the array type is unknown, in which case a
   // bottom type inferred from the type of instruction is used. is_primitive is false for an