Revert^2 "Ensure that methods requiring interpreter entrypoint always have it."

The code in test 067-preemptive-unpark is able to cause a method to
have a null entrypoint. This is a valid (though rare) state. The check
we had did not account for it and failed. Made the DCHECK explicitly
allow for null entrypoints.

This makes the check consistent with the code around lines 363 and 398
lower in the function.

This reverts commit c971f6e06a43e70a2d86cb4b3ad0e13a9ae9a06c.

Reason for revert: fixed issue causing test 067 and others to fail.

Test: ./test.py --host -j50
Test: ./test/testrunner/testrunner.py -j50 -t 067-preemptive-unpark

Bug: 62821960

Change-Id: I537e05fd52fa4c8859d4102ac9475cacd75d7437
diff --git a/runtime/art_method.cc b/runtime/art_method.cc
index 96468bb..ef4c3f3 100644
--- a/runtime/art_method.cc
+++ b/runtime/art_method.cc
@@ -319,6 +319,22 @@
     self->AssertThreadSuspensionIsAllowable();
     CHECK_EQ(kRunnable, self->GetState());
     CHECK_STREQ(GetInterfaceMethodIfProxy(kRuntimePointerSize)->GetShorty(), shorty);
+
+    if (!IsNative() &&
+        !IsObsolete() &&
+        !IsProxyMethod() &&
+        IsInvokable() &&
+        ClassLinker::ShouldUseInterpreterEntrypoint(this, GetEntryPointFromQuickCompiledCode())) {
+      ClassLinker* cl = Runtime::Current()->GetClassLinker();
+      const void* entry_point = GetEntryPointFromQuickCompiledCode();
+      DCHECK(cl->IsQuickToInterpreterBridge(entry_point) ||
+             cl->IsQuickResolutionStub(entry_point) ||
+             entry_point == GetQuickInstrumentationEntryPoint() ||
+             entry_point == nullptr)
+          << PrettyMethod() << " is expected to be interpreted but has an unexpected entrypoint."
+          << " The entrypoint is " << entry_point << " (incorrect) oat entrypoint would be "
+          << GetOatMethodQuickCode(cl->GetImagePointerSize());
+    }
   }
 
   // Push a transition back into managed code onto the linked list in thread.
diff --git a/runtime/class_linker.cc b/runtime/class_linker.cc
index 8776542..c487808 100644
--- a/runtime/class_linker.cc
+++ b/runtime/class_linker.cc
@@ -1296,22 +1296,32 @@
             }
             for (ArtMethod& m : klass->GetDirectMethods(kRuntimePointerSize)) {
               const void* code = m.GetEntryPointFromQuickCompiledCode();
-              const void* oat_code = m.IsInvokable() ? class_linker->GetQuickOatCodeFor(&m) : code;
-              if (!class_linker->IsQuickResolutionStub(code) &&
-                  !class_linker->IsQuickGenericJniStub(code) &&
+              if (!m.IsProxyMethod() &&
+                  !m.IsNative() &&
+                  !class_linker->IsQuickResolutionStub(code) &&
                   !class_linker->IsQuickToInterpreterBridge(code) &&
-                  !m.IsNative()) {
-                DCHECK_EQ(code, oat_code) << m.PrettyMethod();
+                  m.IsInvokable()) {
+                // Since this is just a sanity check it's okay to get the oat code here regardless
+                // of whether it's usable.
+                const void* oat_code = m.GetOatMethodQuickCode(class_linker->GetImagePointerSize());
+                if (oat_code != nullptr) {
+                  DCHECK_EQ(code, oat_code) << m.PrettyMethod();
+                }
               }
             }
             for (ArtMethod& m : klass->GetVirtualMethods(kRuntimePointerSize)) {
               const void* code = m.GetEntryPointFromQuickCompiledCode();
-              const void* oat_code = m.IsInvokable() ? class_linker->GetQuickOatCodeFor(&m) : code;
-              if (!class_linker->IsQuickResolutionStub(code) &&
-                  !class_linker->IsQuickGenericJniStub(code) &&
+              if (!m.IsProxyMethod() &&
+                  !m.IsNative() &&
+                  !class_linker->IsQuickResolutionStub(code) &&
                   !class_linker->IsQuickToInterpreterBridge(code) &&
-                  !m.IsNative()) {
-                DCHECK_EQ(code, oat_code) << m.PrettyMethod();
+                  m.IsInvokable()) {
+                // Since this is just a sanity check it's okay to get the oat code here regardless
+                // of whether it's usable.
+                const void* oat_code = m.GetOatMethodQuickCode(class_linker->GetImagePointerSize());
+                if (oat_code != nullptr) {
+                  DCHECK_EQ(code, oat_code) << m.PrettyMethod();
+                }
               }
             }
           }
@@ -2899,21 +2909,25 @@
                                          image_pointer_size_);
 }
 
-// Special case to get oat code without overwriting a trampoline.
-const void* ClassLinker::GetQuickOatCodeFor(ArtMethod* method) {
+const void* ClassLinker::GetQuickEntrypointFor(ArtMethod* method) {
   CHECK(method->IsInvokable()) << method->PrettyMethod();
   if (method->IsProxyMethod()) {
     return GetQuickProxyInvokeHandler();
   }
-  auto* code = method->GetOatMethodQuickCode(GetImagePointerSize());
-  if (code != nullptr) {
-    return code;
+  const void* oat_code = method->GetOatMethodQuickCode(GetImagePointerSize());
+  if (oat_code == nullptr) {
+    // We need either the generic jni or interpreter bridge.
+    if (method->IsNative()) {
+      return GetQuickGenericJniStub();
+    } else {
+      return GetQuickToInterpreterBridge();
+    }
+  } else if (ClassLinker::ShouldUseInterpreterEntrypoint(method, oat_code)) {
+    // We have oat code but we cannot use it for some reason.
+    return GetQuickToInterpreterBridge();
+  } else {
+    return oat_code;
   }
-  if (method->IsNative()) {
-    // No code and native? Use generic trampoline.
-    return GetQuickGenericJniStub();
-  }
-  return GetQuickToInterpreterBridge();
 }
 
 bool ClassLinker::ShouldUseInterpreterEntrypoint(ArtMethod* method, const void* quick_code) {
diff --git a/runtime/class_linker.h b/runtime/class_linker.h
index 3e3425f..62804e7 100644
--- a/runtime/class_linker.h
+++ b/runtime/class_linker.h
@@ -498,9 +498,8 @@
   std::string GetDescriptorForProxy(ObjPtr<mirror::Class> proxy_class)
       REQUIRES_SHARED(Locks::mutator_lock_);
 
-  // Get the oat code for a method when its class isn't yet initialized.
-  const void* GetQuickOatCodeFor(ArtMethod* method)
-      REQUIRES_SHARED(Locks::mutator_lock_);
+  // Get the correct entrypoint for a method as far as the class-linker is concerned.
+  const void* GetQuickEntrypointFor(ArtMethod* method) REQUIRES_SHARED(Locks::mutator_lock_);
 
   pid_t GetClassesLockOwner();  // For SignalCatcher.
   pid_t GetDexLockOwner();  // For SignalCatcher.
diff --git a/runtime/entrypoints/quick/quick_trampoline_entrypoints.cc b/runtime/entrypoints/quick/quick_trampoline_entrypoints.cc
index f727690..a32c717 100644
--- a/runtime/entrypoints/quick/quick_trampoline_entrypoints.cc
+++ b/runtime/entrypoints/quick/quick_trampoline_entrypoints.cc
@@ -1294,9 +1294,9 @@
         // with the interpreter.
         code = GetQuickToInterpreterBridge();
       } else if (invoke_type == kStatic) {
-        // Class is still initializing, go to oat and grab code (trampoline must be left in place
-        // until class is initialized to stop races between threads).
-        code = linker->GetQuickOatCodeFor(called);
+        // Class is still initializing. The entrypoint contains the trampoline, so we cannot return
+        // it. Instead, ask the class linker what is the actual code that needs to be invoked.
+        code = linker->GetQuickEntrypointFor(called);
       } else {
         // No trampoline for non-static methods.
         code = called->GetEntryPointFromQuickCompiledCode();
diff --git a/runtime/instrumentation.cc b/runtime/instrumentation.cc
index 4524448..2a1f219 100644
--- a/runtime/instrumentation.cc
+++ b/runtime/instrumentation.cc
@@ -167,7 +167,7 @@
       if (NeedDebugVersionFor(method)) {
         new_quick_code = GetQuickToInterpreterBridge();
       } else {
-        new_quick_code = class_linker->GetQuickOatCodeFor(method);
+        new_quick_code = class_linker->GetQuickEntrypointFor(method);
       }
     } else {
       new_quick_code = GetQuickResolutionStub();
@@ -188,7 +188,7 @@
         } else if (entry_exit_stubs_installed_) {
           new_quick_code = GetQuickInstrumentationEntryPoint();
         } else {
-          new_quick_code = class_linker->GetQuickOatCodeFor(method);
+          new_quick_code = class_linker->GetQuickEntrypointFor(method);
         }
       } else {
         new_quick_code = GetQuickResolutionStub();
@@ -877,7 +877,7 @@
     } else {
       const void* quick_code = NeedDebugVersionFor(method)
           ? GetQuickToInterpreterBridge()
-          : class_linker->GetQuickOatCodeFor(method);
+          : class_linker->GetQuickEntrypointFor(method);
       UpdateEntrypoints(method, quick_code);
     }
 
@@ -971,7 +971,7 @@
       return code;
     }
   }
-  return class_linker->GetQuickOatCodeFor(method);
+  return class_linker->GetQuickEntrypointFor(method);
 }
 
 void Instrumentation::MethodEnterEventImpl(Thread* thread,