Minor nterp improvements.

Do not resolve primitive field types for iput*, sput*
before updating the interpreter cache.

Introduce and use `ArtMethod::IsStringConstructor(),
a convenience helper function where we  avoid a read
barrier for checking if the declaring class is the
`String` class.

Change one `CHECK_LE()` to `DCHECK_LE()`.

Test: testrunner.py --host --interpreter
Change-Id: I17b0409cee5321e0ca389f053da1f767d2913d08
diff --git a/runtime/interpreter/mterp/nterp.cc b/runtime/interpreter/mterp/nterp.cc
index 2498319..a652d62 100644
--- a/runtime/interpreter/mterp/nterp.cc
+++ b/runtime/interpreter/mterp/nterp.cc
@@ -293,7 +293,7 @@
   Instruction::Code opcode = inst->Opcode();
   DCHECK(IsUint<8>(static_cast<std::underlying_type_t<Instruction::Code>>(opcode)));
   uint8_t raw_invoke_type = kOpcodeInvokeTypes[opcode];
-  CHECK_LE(raw_invoke_type, kMaxInvokeType);
+  DCHECK_LE(raw_invoke_type, kMaxInvokeType);
   InvokeType invoke_type = static_cast<InvokeType>(raw_invoke_type);
 
   // In release mode, this is just a simple load.
@@ -341,9 +341,7 @@
     }
     UpdateCache(self, dex_pc_ptr, result);
     return result;
-  } else if (resolved_method->GetDeclaringClass()->IsStringClass()
-             && !resolved_method->IsStatic()
-             && resolved_method->IsConstructor()) {
+  } else if (resolved_method->IsStringConstructor()) {
     CHECK_NE(invoke_type, kSuper);
     resolved_method = WellKnownClasses::StringInitToStringFactory(resolved_method);
     // Or the result with 1 to notify to nterp this is a string init method. We
@@ -369,14 +367,14 @@
   const Instruction* inst = Instruction::At(dex_pc_ptr);
   uint16_t field_index = inst->VRegB_21c();
   ClassLinker* const class_linker = Runtime::Current()->GetClassLinker();
-  bool is_put = IsInstructionSPut(inst->Opcode());
+  Instruction::Code opcode = inst->Opcode();
   ArtField* resolved_field = ResolveFieldWithAccessChecks(
       self,
       class_linker,
       field_index,
       caller,
-      /* is_static */ true,
-      is_put,
+      /*is_static=*/ true,
+      /*is_put=*/ IsInstructionSPut(opcode),
       resolve_field_type);
 
   if (resolved_field == nullptr) {
@@ -399,11 +397,13 @@
     // check for it.
     return reinterpret_cast<size_t>(resolved_field) | 1;
   } else {
-    // Try to resolve the field type even if we were not requested to. Only if
-    // the field type is successfully resolved can we update the cache. If we
+    // For sput-object, try to resolve the field type even if we were not requested to.
+    // Only if the field type is successfully resolved can we update the cache. If we
     // fail to resolve the type, we clear the exception to keep interpreter
     // semantics of not throwing when null is stored.
-    if (is_put && resolve_field_type == 0 && resolved_field->ResolveType() == nullptr) {
+    if (opcode == Instruction::SPUT_OBJECT &&
+        resolve_field_type == 0 &&
+        resolved_field->ResolveType() == nullptr) {
       DCHECK(self->IsExceptionPending());
       self->ClearException();
     } else {
@@ -422,14 +422,14 @@
   const Instruction* inst = Instruction::At(dex_pc_ptr);
   uint16_t field_index = inst->VRegC_22c();
   ClassLinker* const class_linker = Runtime::Current()->GetClassLinker();
-  bool is_put = IsInstructionIPut(inst->Opcode());
+  Instruction::Code opcode = inst->Opcode();
   ArtField* resolved_field = ResolveFieldWithAccessChecks(
       self,
       class_linker,
       field_index,
       caller,
-      /* is_static */ false,
-      is_put,
+      /*is_static=*/ false,
+      /*is_put=*/ IsInstructionIPut(opcode),
       resolve_field_type);
   if (resolved_field == nullptr) {
     DCHECK(self->IsExceptionPending());
@@ -440,11 +440,13 @@
     // of volatile.
     return -resolved_field->GetOffset().Uint32Value();
   }
-  // Try to resolve the field type even if we were not requested to. Only if
-  // the field type is successfully resolved can we update the cache. If we
+  // For iput-object, try to resolve the field type even if we were not requested to.
+  // Only if the field type is successfully resolved can we update the cache. If we
   // fail to resolve the type, we clear the exception to keep interpreter
   // semantics of not throwing when null is stored.
-  if (is_put && resolve_field_type == 0 && resolved_field->ResolveType() == nullptr) {
+  if (opcode == Instruction::IPUT_OBJECT &&
+      resolve_field_type == 0 &&
+      resolved_field->ResolveType() == nullptr) {
     DCHECK(self->IsExceptionPending());
     self->ClearException();
   } else {