Change iftable to never be null

Simplifies code generation by removing a null check. The null case
is rare.

Ritzperf code size: 13107624 -> 13095336

Also addressed comments from previous CL.

Bug: 32577579

Test: test-art-host, run ritzperf both with CC

Change-Id: I2b31e800867112869d7f0643e16c08826296979e
diff --git a/runtime/arch/arm/entrypoints_init_arm.cc b/runtime/arch/arm/entrypoints_init_arm.cc
index 2a12f1d..de72d3a 100644
--- a/runtime/arch/arm/entrypoints_init_arm.cc
+++ b/runtime/arch/arm/entrypoints_init_arm.cc
@@ -86,7 +86,7 @@
   DefaultInitEntryPoints(jpoints, qpoints);
 
   // Cast
-  qpoints->pInstanceofNonTrivial = artInstanceOfFromCode;;
+  qpoints->pInstanceofNonTrivial = artInstanceOfFromCode;
   qpoints->pCheckInstanceOf = art_quick_check_instance_of;
 
   // Math
diff --git a/runtime/class_linker-inl.h b/runtime/class_linker-inl.h
index 350855b..7359243 100644
--- a/runtime/class_linker-inl.h
+++ b/runtime/class_linker-inl.h
@@ -69,7 +69,7 @@
   Thread::PoisonObjectPointersIfDebug();
   ObjPtr<mirror::Class> declaring_class = referrer->GetDeclaringClass();
   // MethodVerifier refuses methods with string_idx out of bounds.
-  DCHECK_LT(string_idx, declaring_class->GetDexFile().NumStringIds());;
+  DCHECK_LT(string_idx, declaring_class->GetDexFile().NumStringIds());
   ObjPtr<mirror::String> string =
         mirror::StringDexCachePair::Lookup(declaring_class->GetDexCacheStrings(),
                                            string_idx,
diff --git a/runtime/class_linker.cc b/runtime/class_linker.cc
index ac5e6aa..65e46c2 100644
--- a/runtime/class_linker.cc
+++ b/runtime/class_linker.cc
@@ -475,6 +475,9 @@
   SetClassRoot(kJavaLangString, java_lang_String.Get());
   SetClassRoot(kJavaLangRefReference, java_lang_ref_Reference.Get());
 
+  // Fill in the empty iftable. Needs to be done after the kObjectArrayClass root is set.
+  java_lang_Object->SetIfTable(AllocIfTable(self, 0));
+
   // Setup the primitive type classes.
   SetClassRoot(kPrimitiveBoolean, CreatePrimitiveClass(self, Primitive::kPrimBoolean));
   SetClassRoot(kPrimitiveByte, CreatePrimitiveClass(self, Primitive::kPrimByte));
@@ -916,13 +919,11 @@
         SanityCheckArtMethod(klass->GetEmbeddedVTableEntry(i, pointer_size), nullptr, image_spaces);
       }
     }
-    auto* iftable = klass->GetIfTable();
-    if (iftable != nullptr) {
-      for (int32_t i = 0; i < klass->GetIfTableCount(); ++i) {
-        if (iftable->GetMethodArrayCount(i) > 0) {
-          SanityCheckArtMethodPointerArray(
-              iftable->GetMethodArray(i), nullptr, pointer_size, image_spaces);
-        }
+    mirror::IfTable* iftable = klass->GetIfTable();
+    for (int32_t i = 0; i < klass->GetIfTableCount(); ++i) {
+      if (iftable->GetMethodArrayCount(i) > 0) {
+        SanityCheckArtMethodPointerArray(
+            iftable->GetMethodArray(i), nullptr, pointer_size, image_spaces);
       }
     }
   }
@@ -3401,7 +3402,8 @@
 }
 
 mirror::Class* ClassLinker::CreatePrimitiveClass(Thread* self, Primitive::Type type) {
-  ObjPtr<mirror::Class> klass = AllocClass(self, mirror::Class::PrimitiveClassSize(image_pointer_size_));
+  ObjPtr<mirror::Class> klass =
+      AllocClass(self, mirror::Class::PrimitiveClassSize(image_pointer_size_));
   if (UNLIKELY(klass == nullptr)) {
     self->AssertPendingOOMException();
     return nullptr;
@@ -3419,10 +3421,12 @@
   ObjectLock<mirror::Class> lock(self, h_class);
   h_class->SetAccessFlags(kAccPublic | kAccFinal | kAccAbstract);
   h_class->SetPrimitiveType(type);
+  h_class->SetIfTable(GetClassRoot(kJavaLangObject)->GetIfTable());
   mirror::Class::SetStatus(h_class, mirror::Class::kStatusInitialized, self);
   const char* descriptor = Primitive::Descriptor(type);
-  ObjPtr<mirror::Class> existing = InsertClass(descriptor, h_class.Get(),
-                                        ComputeModifiedUtf8Hash(descriptor));
+  ObjPtr<mirror::Class> existing = InsertClass(descriptor,
+                                               h_class.Get(),
+                                               ComputeModifiedUtf8Hash(descriptor));
   CHECK(existing == nullptr) << "InitPrimitiveClass(" << type << ") failed";
   return h_class.Get();
 }
@@ -4121,6 +4125,8 @@
   DCHECK_EQ(klass->GetPrimitiveType(), Primitive::kPrimNot);
   klass->SetName(soa.Decode<mirror::String>(name));
   klass->SetDexCache(GetClassRoot(kJavaLangReflectProxy)->GetDexCache());
+  // Object has an empty iftable, copy it for that reason.
+  klass->SetIfTable(GetClassRoot(kJavaLangObject)->GetIfTable());
   mirror::Class::SetStatus(klass, mirror::Class::kStatusIdx, self);
   std::string descriptor(GetDescriptorForProxy(klass.Get()));
   const size_t hash = ComputeModifiedUtf8Hash(descriptor.c_str());
@@ -6381,16 +6387,18 @@
 bool ClassLinker::SetupInterfaceLookupTable(Thread* self, Handle<mirror::Class> klass,
                                             Handle<mirror::ObjectArray<mirror::Class>> interfaces) {
   StackHandleScope<1> hs(self);
-  const size_t super_ifcount =
-      klass->HasSuperClass() ? klass->GetSuperClass()->GetIfTableCount() : 0U;
+  const bool has_superclass = klass->HasSuperClass();
+  const size_t super_ifcount = has_superclass ? klass->GetSuperClass()->GetIfTableCount() : 0U;
   const bool have_interfaces = interfaces.Get() != nullptr;
   const size_t num_interfaces =
       have_interfaces ? interfaces->GetLength() : klass->NumDirectInterfaces();
   if (num_interfaces == 0) {
     if (super_ifcount == 0) {
+      if (LIKELY(has_superclass)) {
+        klass->SetIfTable(klass->GetSuperClass()->GetIfTable());
+      }
       // Class implements no interfaces.
       DCHECK_EQ(klass->GetIfTableCount(), 0);
-      DCHECK(klass->GetIfTable() == nullptr);
       return true;
     }
     // Class implements same interfaces as parent, are any of these not marker interfaces?
@@ -6583,7 +6591,7 @@
   } else {
     // No imt in the super class, need to reconstruct from the iftable.
     ObjPtr<mirror::IfTable> if_table = super_class->GetIfTable();
-    if (if_table != nullptr) {
+    if (if_table->Count() != 0) {
       // Ignore copied methods since we will handle these in LinkInterfaceMethods.
       FillIMTFromIfTable(if_table,
                          unimplemented_method,
diff --git a/runtime/class_linker_test.cc b/runtime/class_linker_test.cc
index ab2d9d0..44590ba 100644
--- a/runtime/class_linker_test.cc
+++ b/runtime/class_linker_test.cc
@@ -101,7 +101,8 @@
     EXPECT_EQ(0U, primitive->NumDirectInterfaces());
     EXPECT_FALSE(primitive->HasVTable());
     EXPECT_EQ(0, primitive->GetIfTableCount());
-    EXPECT_TRUE(primitive->GetIfTable() == nullptr);
+    EXPECT_TRUE(primitive->GetIfTable() != nullptr);
+    EXPECT_EQ(primitive->GetIfTable()->Count(), 0u);
     EXPECT_EQ(kAccPublic | kAccFinal | kAccAbstract, primitive->GetAccessFlags());
   }
 
diff --git a/runtime/class_table.h b/runtime/class_table.h
index bc9eaf4..558c144 100644
--- a/runtime/class_table.h
+++ b/runtime/class_table.h
@@ -48,7 +48,7 @@
     uint32_t operator()(const GcRoot<mirror::Class>& root) const NO_THREAD_SAFETY_ANALYSIS;
     // Same class loader and descriptor.
     bool operator()(const GcRoot<mirror::Class>& a, const GcRoot<mirror::Class>& b) const
-        NO_THREAD_SAFETY_ANALYSIS;;
+        NO_THREAD_SAFETY_ANALYSIS;
     // Same descriptor.
     bool operator()(const GcRoot<mirror::Class>& a, const char* descriptor) const
         NO_THREAD_SAFETY_ANALYSIS;
diff --git a/runtime/gc/space/image_space.cc b/runtime/gc/space/image_space.cc
index 0b602e9..6019540 100644
--- a/runtime/gc/space/image_space.cc
+++ b/runtime/gc/space/image_space.cc
@@ -1002,7 +1002,7 @@
         mirror::IfTable* iftable = as_klass->GetIfTable<kVerifyNone, kWithoutReadBarrier>();
         // Ensure iftable arrays are fixed up since we need GetMethodArray to return the valid
         // contents.
-        if (iftable != nullptr && IsInAppImage(iftable)) {
+        if (IsInAppImage(iftable)) {
           operator()(iftable);
           for (int32_t i = 0, count = iftable->Count(); i < count; ++i) {
             if (iftable->GetMethodArrayCount<kVerifyNone, kWithoutReadBarrier>(i) > 0) {
diff --git a/runtime/interpreter/interpreter_common.cc b/runtime/interpreter/interpreter_common.cc
index cb775cd..8c63a9e 100644
--- a/runtime/interpreter/interpreter_common.cc
+++ b/runtime/interpreter/interpreter_common.cc
@@ -1020,7 +1020,7 @@
   } else {
     DCHECK(!is_range);
     ArtField* field = method_handle->GetTargetField();
-    Primitive::Type field_type = field->GetTypeAsPrimitiveType();;
+    Primitive::Type field_type = field->GetTypeAsPrimitiveType();
 
     switch (handle_kind) {
       case kInstanceGet: {
diff --git a/runtime/interpreter/unstarted_runtime.cc b/runtime/interpreter/unstarted_runtime.cc
index 2257fd6..a5b1038 100644
--- a/runtime/interpreter/unstarted_runtime.cc
+++ b/runtime/interpreter/unstarted_runtime.cc
@@ -424,7 +424,7 @@
 
   std::unique_ptr<ZipArchive> zip_archive(ZipArchive::Open(jar_file.c_str(), error_msg));
   if (zip_archive == nullptr) {
-    return nullptr;;
+    return nullptr;
   }
   std::unique_ptr<ZipEntry> zip_entry(zip_archive->Find(entry_name, error_msg));
   if (zip_entry == nullptr) {
diff --git a/runtime/jit/jit.cc b/runtime/jit/jit.cc
index 4c10063..23a5ddd 100644
--- a/runtime/jit/jit.cc
+++ b/runtime/jit/jit.cc
@@ -114,7 +114,7 @@
   } else {
     jit_options->invoke_transition_weight_ = std::max(
         jit_options->warmup_threshold_ / Jit::kDefaultInvokeTransitionWeightRatio,
-        static_cast<size_t>(1));;
+        static_cast<size_t>(1));
   }
 
   return jit_options;
diff --git a/runtime/mirror/class-inl.h b/runtime/mirror/class-inl.h
index bbdb2af..9a6d60e 100644
--- a/runtime/mirror/class-inl.h
+++ b/runtime/mirror/class-inl.h
@@ -526,18 +526,17 @@
 template<VerifyObjectFlags kVerifyFlags,
          ReadBarrierOption kReadBarrierOption>
 inline IfTable* Class::GetIfTable() {
-  return GetFieldObject<IfTable, kVerifyFlags, kReadBarrierOption>(IfTableOffset());
+  ObjPtr<IfTable> ret = GetFieldObject<IfTable, kVerifyFlags, kReadBarrierOption>(IfTableOffset());
+  DCHECK(ret != nullptr) << PrettyClass(this);
+  return ret.Ptr();
 }
 
 inline int32_t Class::GetIfTableCount() {
-  ObjPtr<IfTable> iftable = GetIfTable();
-  if (iftable == nullptr) {
-    return 0;
-  }
-  return iftable->Count();
+  return GetIfTable()->Count();
 }
 
 inline void Class::SetIfTable(ObjPtr<IfTable> new_iftable) {
+  DCHECK(new_iftable != nullptr) << PrettyClass(this);
   SetFieldObject<false>(IfTableOffset(), new_iftable);
 }
 
diff --git a/runtime/oat.h b/runtime/oat.h
index 3aef707..8c84d42 100644
--- a/runtime/oat.h
+++ b/runtime/oat.h
@@ -32,7 +32,7 @@
 class PACKED(4) OatHeader {
  public:
   static constexpr uint8_t kOatMagic[] = { 'o', 'a', 't', '\n' };
-  static constexpr uint8_t kOatVersion[] = { '0', '9', '1', '\0' };
+  static constexpr uint8_t kOatVersion[] = { '0', '9', '2', '\0' };
 
   static constexpr const char* kImageLocationKey = "image-location";
   static constexpr const char* kDex2OatCmdLineKey = "dex2oat-cmdline";