Fix a couple of places to check for instrumented entry points

There are a couple of places where we missed the check for instrumented
entry points:
- In resoultion stubs, when we get the code to execute we need to check
  if we need an instrumentation entry point. Resolution stubs could
  suspend so it is possible that we instrumented after resolution stub
  started executing.
- When undeoptimizing a method, though the method itself is
  undeoptimized we may still need instrumentation entry points.
  Instrumentation entry points are also required to deoptimize the
  caller.

Bug: 222479430
Test: art/test.py
Change-Id: Id520b5f6ff47fddee67e2bf8d3396d6d9db7fff6
diff --git a/runtime/entrypoints/quick/quick_trampoline_entrypoints.cc b/runtime/entrypoints/quick/quick_trampoline_entrypoints.cc
index e54126f..2086fa2 100644
--- a/runtime/entrypoints/quick/quick_trampoline_entrypoints.cc
+++ b/runtime/entrypoints/quick/quick_trampoline_entrypoints.cc
@@ -1391,7 +1391,10 @@
     }
     if (success) {
       instrumentation::Instrumentation* instrumentation = Runtime::Current()->GetInstrumentation();
-      code = instrumentation->GetCodeForInvoke(called);
+      // Check if we need instrumented code here. Since resolution stubs could suspend, it is
+      // possible that we instrumented the entry points after we started executing the resolution
+      // stub.
+      code = instrumentation->GetMaybeInstrumentedCodeForInvoke(called);
     } else {
       DCHECK(called_class->IsErroneous());
       DCHECK(self->IsExceptionPending());
diff --git a/runtime/instrumentation.cc b/runtime/instrumentation.cc
index 7da959a..1e328a3 100644
--- a/runtime/instrumentation.cc
+++ b/runtime/instrumentation.cc
@@ -1184,22 +1184,25 @@
         << " is not deoptimized";
   }
 
-  // Restore code and possibly stack only if we did not deoptimize everything.
-  if (!InterpreterStubsInstalled()) {
-    // Restore its code or resolution trampoline.
-    if (InterpretOnly(method)) {
-      UpdateEntryPoints(method, GetQuickToInterpreterBridge());
-    } else if (NeedsClinitCheckBeforeCall(method) &&
-               !method->GetDeclaringClass()->IsVisiblyInitialized()) {
-      UpdateEntryPoints(method, GetQuickResolutionStub());
-    } else {
-      UpdateEntryPoints(method, GetOptimizedCodeFor(method));
-    }
+  // If interpreter stubs are still needed nothing to do.
+  if (InterpreterStubsInstalled()) {
+    return;
+  }
 
-    // If there is no deoptimized method left, we can restore the stack of each thread.
-    if (!EntryExitStubsInstalled()) {
-      MaybeRestoreInstrumentationStack();
-    }
+  // We are not using interpreter stubs for deoptimization. Restore the code of the method.
+  // We still retain interpreter bridge if we need it for other reasons.
+  if (InterpretOnly(method)) {
+    UpdateEntryPoints(method, GetQuickToInterpreterBridge());
+  } else if (NeedsClinitCheckBeforeCall(method) &&
+             !method->GetDeclaringClass()->IsVisiblyInitialized()) {
+    UpdateEntryPoints(method, GetQuickResolutionStub());
+  } else {
+    UpdateEntryPoints(method, GetMaybeInstrumentedCodeForInvoke(method));
+  }
+
+  // If there is no deoptimized method left, we can restore the stack of each thread.
+  if (!EntryExitStubsInstalled()) {
+    MaybeRestoreInstrumentationStack();
   }
 }
 
@@ -1287,6 +1290,16 @@
   return GetOptimizedCodeFor(method);
 }
 
+const void* Instrumentation::GetMaybeInstrumentedCodeForInvoke(ArtMethod* method) {
+  // This is called by resolution trampolines and that should never be getting proxy methods.
+  DCHECK(!method->IsProxyMethod()) << method->PrettyMethod();
+  const void* code = GetCodeForInvoke(method);
+  if (EntryExitStubsInstalled() && CodeNeedsEntryExitStub(code, method)) {
+    return GetQuickInstrumentationEntryPoint();
+  }
+  return code;
+}
+
 void Instrumentation::MethodEnterEventImpl(Thread* thread, ArtMethod* method) const {
   DCHECK(!method->IsRuntimeMethod());
   if (HasMethodEntryListeners()) {
diff --git a/runtime/instrumentation.h b/runtime/instrumentation.h
index 34f08e7..b163109 100644
--- a/runtime/instrumentation.h
+++ b/runtime/instrumentation.h
@@ -309,6 +309,13 @@
   // Return the code that we can execute for an invoke including from the JIT.
   const void* GetCodeForInvoke(ArtMethod* method) REQUIRES_SHARED(Locks::mutator_lock_);
 
+  // Return the code that we can execute considering the current instrumentation level.
+  // If interpreter stubs are installed return interpreter bridge. If the entry exit stubs
+  // are installed return an instrumentation entry point. Otherwise, return the code that
+  // can be executed including from the JIT.
+  const void* GetMaybeInstrumentedCodeForInvoke(ArtMethod* method)
+      REQUIRES_SHARED(Locks::mutator_lock_);
+
   void ForceInterpretOnly() {
     forced_interpret_only_ = true;
   }