Revert "Use InitializeMethodsCode when we need to reinitialize a method entrypoint."

This reverts commit 82e525a4f5f08a72ea1b6907c0a10dacb77a8a87.

Reason for revert: Fails a test

Change-Id: Iab83b543b99fb6f6d5d9be22cd10d4eb88312d4b
diff --git a/compiler/common_compiler_test.cc b/compiler/common_compiler_test.cc
index bbb2016..1b69f2a 100644
--- a/compiler/common_compiler_test.cc
+++ b/compiler/common_compiler_test.cc
@@ -149,18 +149,20 @@
 void CommonCompilerTestImpl::MakeExecutable(ArtMethod* method,
                                             const CompiledMethod* compiled_method) {
   CHECK(method != nullptr);
-  const void* method_code = nullptr;
   // If the code size is 0 it means the method was skipped due to profile guided compilation.
   if (compiled_method != nullptr && compiled_method->GetQuickCode().size() != 0u) {
     const void* code_ptr = MakeExecutable(compiled_method->GetQuickCode(),
                                           compiled_method->GetVmapTable(),
                                           compiled_method->GetInstructionSet());
-    method_code =
+    const void* method_code =
         CompiledMethod::CodePointer(code_ptr, compiled_method->GetInstructionSet());
     LOG(INFO) << "MakeExecutable " << method->PrettyMethod() << " code=" << method_code;
+    method->SetEntryPointFromQuickCompiledCode(method_code);
+  } else {
+    // No code? You must mean to go into the interpreter.
+    // Or the generic JNI...
+    GetClassLinker()->SetEntryPointsToInterpreter(method);
   }
-  Runtime::Current()->GetInstrumentation()->InitializeMethodsCode(
-      method, /*aot_code=*/ method_code);
 }
 
 void CommonCompilerTestImpl::SetUp() {
diff --git a/openjdkjvmti/events.cc b/openjdkjvmti/events.cc
index a6425af..c69ee7b 100644
--- a/openjdkjvmti/events.cc
+++ b/openjdkjvmti/events.cc
@@ -1260,7 +1260,7 @@
           continue;
         } else if (!runtime_->GetClassLinker()->IsQuickToInterpreterBridge(code) &&
                    !runtime_->IsAsyncDeoptimizeable(reinterpret_cast<uintptr_t>(code))) {
-          runtime_->GetInstrumentation()->InitializeMethodsCode(&m, /*aot_code=*/ nullptr);
+          runtime_->GetInstrumentation()->UpdateMethodsCodeToInterpreterEntryPoint(&m);
         }
       }
       return true;
diff --git a/openjdkjvmti/ti_redefine.cc b/openjdkjvmti/ti_redefine.cc
index c234bd4..37a61d3 100644
--- a/openjdkjvmti/ti_redefine.cc
+++ b/openjdkjvmti/ti_redefine.cc
@@ -2116,7 +2116,7 @@
   }
   // Finish setting up methods.
   linked_class->VisitMethods([&](art::ArtMethod* m) REQUIRES_SHARED(art::Locks::mutator_lock_) {
-    driver_->runtime_->GetInstrumentation()->InitializeMethodsCode(m, /* aot_code= */ nullptr);
+    linker->SetEntryPointsToInterpreter(m);
     m->SetNotIntrinsic();
     DCHECK(m->IsCopied() || m->GetDeclaringClass() == linked_class.Get())
         << m->PrettyMethod()
@@ -2543,7 +2543,7 @@
     CHECK(method_id != nullptr);
     uint32_t dex_method_idx = dex_file_->GetIndexForMethodId(*method_id);
     method.SetDexMethodIndex(dex_method_idx);
-    driver_->runtime_->GetInstrumentation()->InitializeMethodsCode(&method, /*aot_code=*/ nullptr);
+    linker->SetEntryPointsToInterpreter(&method);
     if (method.HasCodeItem()) {
       method.SetCodeItem(
           dex_file_->GetCodeItem(dex_file_->FindCodeItemOffset(class_def, dex_method_idx)),
diff --git a/runtime/class_linker.cc b/runtime/class_linker.cc
index 62dd4d2..d2ab81e 100644
--- a/runtime/class_linker.cc
+++ b/runtime/class_linker.cc
@@ -201,6 +201,22 @@
   self->AssertPendingException();
 }
 
+static void ChangeInterpreterBridgeToNterp(ArtMethod* method, ClassLinker* class_linker)
+    REQUIRES_SHARED(Locks::mutator_lock_) {
+  Runtime* runtime = Runtime::Current();
+  if (class_linker->IsQuickToInterpreterBridge(method->GetEntryPointFromQuickCompiledCode()) &&
+      CanMethodUseNterp(method)) {
+    if (method->GetDeclaringClass()->IsVisiblyInitialized() ||
+        !NeedsClinitCheckBeforeCall(method)) {
+      runtime->GetInstrumentation()->UpdateMethodsCode(method, interpreter::GetNterpEntryPoint());
+    } else {
+      // Put the resolution stub, which will initialize the class and then
+      // call the method with nterp.
+      runtime->GetInstrumentation()->UpdateMethodsCode(method, GetQuickResolutionStub());
+    }
+  }
+}
+
 static void UpdateClassAfterVerification(Handle<mirror::Class> klass,
                                          PointerSize pointer_size,
                                          verifier::FailureKind failure_kind)
@@ -215,9 +231,7 @@
   // to methods that currently use the switch interpreter.
   if (interpreter::CanRuntimeUseNterp()) {
     for (ArtMethod& m : klass->GetMethods(pointer_size)) {
-      if (class_linker->IsQuickToInterpreterBridge(m.GetEntryPointFromQuickCompiledCode())) {
-        runtime->GetInstrumentation()->InitializeMethodsCode(&m, /*aot_code=*/nullptr);
-      }
+      ChangeInterpreterBridgeToNterp(&m, class_linker);
     }
   }
 }
@@ -1959,11 +1973,10 @@
         // reset it with the runtime value.
         method.ResetCounter(hotness_threshold);
       }
+      // Set image methods' entry point that point to the interpreter bridge to the
+      // nterp entry point.
       if (method.GetEntryPointFromQuickCompiledCode() == nterp_trampoline_) {
         if (can_use_nterp) {
-          // Set image methods' entry point that point to the nterp trampoline to the
-          // nterp entry point. This allows taking the fast path when doing a
-          // nterp->nterp call.
           DCHECK(!NeedsClinitCheckBeforeCall(&method) ||
                  method.GetDeclaringClass()->IsVisiblyInitialized());
           method.SetEntryPointFromQuickCompiledCode(interpreter::GetNterpEntryPoint());
@@ -3340,7 +3353,6 @@
     return;
   }
 
-  instrumentation::Instrumentation* instrumentation = runtime->GetInstrumentation();
   // Link the code of methods skipped by LinkCode.
   for (size_t method_index = 0; method_index < num_direct_methods; ++method_index) {
     ArtMethod* method = klass->GetDirectMethod(method_index, pointer_size);
@@ -3348,6 +3360,7 @@
       // Only update static methods.
       continue;
     }
+    instrumentation::Instrumentation* instrumentation = runtime->GetInstrumentation();
     instrumentation->UpdateMethodsCode(method, instrumentation->GetCodeForInvoke(method));
   }
   // Ignore virtual methods on the iterator.
@@ -9643,6 +9656,14 @@
   return GetQuickGenericJniStub();
 }
 
+void ClassLinker::SetEntryPointsToInterpreter(ArtMethod* method) const {
+  if (!method->IsNative()) {
+    method->SetEntryPointFromQuickCompiledCode(GetQuickToInterpreterBridge());
+  } else {
+    method->SetEntryPointFromQuickCompiledCode(GetQuickGenericJniStub());
+  }
+}
+
 void ClassLinker::SetEntryPointsForObsoleteMethod(ArtMethod* method) const {
   DCHECK(method->IsObsolete());
   // We cannot mess with the entrypoints of native methods because they are used to determine how
diff --git a/runtime/class_linker.h b/runtime/class_linker.h
index 7ba62f4..b0c02e5 100644
--- a/runtime/class_linker.h
+++ b/runtime/class_linker.h
@@ -620,6 +620,10 @@
     return intern_table_;
   }
 
+  // Set the entrypoints up for method to the enter the interpreter.
+  void SetEntryPointsToInterpreter(ArtMethod* method) const
+      REQUIRES_SHARED(Locks::mutator_lock_);
+
   // Set the entrypoints up for an obsolete method.
   void SetEntryPointsForObsoleteMethod(ArtMethod* method) const
       REQUIRES_SHARED(Locks::mutator_lock_);
diff --git a/runtime/common_runtime_test.cc b/runtime/common_runtime_test.cc
index 6ff4f1a..f949759 100644
--- a/runtime/common_runtime_test.cc
+++ b/runtime/common_runtime_test.cc
@@ -400,7 +400,7 @@
 void CommonRuntimeTestImpl::MakeInterpreted(ObjPtr<mirror::Class> klass) {
   PointerSize pointer_size = class_linker_->GetImagePointerSize();
   for (ArtMethod& method : klass->GetMethods(pointer_size)) {
-    Runtime::Current()->GetInstrumentation()->InitializeMethodsCode(&method, /*aot_code=*/ nullptr);
+    class_linker_->SetEntryPointsToInterpreter(&method);
   }
 }
 
diff --git a/runtime/entrypoints/quick/quick_trampoline_entrypoints.cc b/runtime/entrypoints/quick/quick_trampoline_entrypoints.cc
index 926d534..027bda5 100644
--- a/runtime/entrypoints/quick/quick_trampoline_entrypoints.cc
+++ b/runtime/entrypoints/quick/quick_trampoline_entrypoints.cc
@@ -1052,7 +1052,7 @@
          !jit->GetCodeCache()->ContainsPc(result))
       << method->PrettyMethod() << " code will jump to possibly cleaned up jit code!";
 
-  bool interpreter_entry = Runtime::Current()->GetClassLinker()->IsQuickToInterpreterBridge(result);
+  bool interpreter_entry = (result == GetQuickToInterpreterBridge());
   bool is_static = method->IsStatic();
   uint32_t shorty_len;
   const char* shorty =
diff --git a/runtime/instrumentation.cc b/runtime/instrumentation.cc
index 65123ff..71d48ee 100644
--- a/runtime/instrumentation.cc
+++ b/runtime/instrumentation.cc
@@ -375,7 +375,7 @@
   }
 
   // Special case if we need an initialization check.
-  if (NeedsClinitCheckBeforeCall(method) && !method->GetDeclaringClass()->IsVisiblyInitialized()) {
+  if (NeedsClinitCheckBeforeCall(method)) {
     // If we have code but the method needs a class initialization check before calling
     // that code, install the resolution stub that will perform the check.
     // It will be replaced by the proper entry point by ClassLinker::FixupStaticTrampolines
@@ -397,17 +397,10 @@
     return;
   }
 
-  // We check if the class is verified as we need the slow interpreter for lock verification.
-  // If the class is not verified, This will be updated in
-  // ClassLinker::UpdateClassAfterVerification.
-  if (interpreter::CanRuntimeUseNterp() &&
-      CanMethodUseNterp(method) &&
-      method->GetDeclaringClass()->IsVerified()) {
-    UpdateEntryPoints(method, interpreter::GetNterpEntryPoint());
-    return;
-  }
-
   // Use default entrypoints.
+  // Note we cannot use the nterp entrypoint because we do not know if the
+  // method will need the slow interpreter for lock verification. This will
+  // be updated in ClassLinker::UpdateClassAfterVerification.
   UpdateEntryPoints(
       method, method->IsNative() ? GetQuickGenericJniStub() : GetQuickToInterpreterBridge());
 }
@@ -1107,6 +1100,19 @@
   UpdateMethodsCodeImpl(method, new_code);
 }
 
+void Instrumentation::UpdateMethodsCodeToInterpreterEntryPoint(ArtMethod* method) {
+  UpdateMethodsCodeImpl(method, GetQuickToInterpreterBridge());
+}
+
+void Instrumentation::UpdateMethodsCodeForJavaDebuggable(ArtMethod* method,
+                                                         const void* new_code) {
+  // When the runtime is set to Java debuggable, we may update the entry points of
+  // all methods of a class to the interpreter bridge. A method's declaring class
+  // might not be in resolved state yet in that case, so we bypass the DCHECK in
+  // UpdateMethodsCode.
+  UpdateMethodsCodeImpl(method, new_code);
+}
+
 bool Instrumentation::AddDeoptimizedMethod(ArtMethod* method) {
   if (IsDeoptimizedMethod(method)) {
     // Already in the map. Return.
diff --git a/runtime/instrumentation.h b/runtime/instrumentation.h
index d4cb85b..276d1ca 100644
--- a/runtime/instrumentation.h
+++ b/runtime/instrumentation.h
@@ -312,6 +312,14 @@
   void UpdateNativeMethodsCodeToJitCode(ArtMethod* method, const void* new_code)
       REQUIRES_SHARED(Locks::mutator_lock_) REQUIRES(!GetDeoptimizedMethodsLock());
 
+  // Update the code of a method to the interpreter respecting any installed stubs from debugger.
+  void UpdateMethodsCodeToInterpreterEntryPoint(ArtMethod* method)
+      REQUIRES_SHARED(Locks::mutator_lock_) REQUIRES(!GetDeoptimizedMethodsLock());
+
+  // Update the code of a method respecting any installed stubs from debugger.
+  void UpdateMethodsCodeForJavaDebuggable(ArtMethod* method, const void* new_code)
+      REQUIRES_SHARED(Locks::mutator_lock_) REQUIRES(!GetDeoptimizedMethodsLock());
+
   // Return the code that we can execute for an invoke including from the JIT.
   const void* GetCodeForInvoke(ArtMethod* method) REQUIRES_SHARED(Locks::mutator_lock_);
 
diff --git a/runtime/jit/jit_code_cache.cc b/runtime/jit/jit_code_cache.cc
index 34ddfc4..8b91f9e 100644
--- a/runtime/jit/jit_code_cache.cc
+++ b/runtime/jit/jit_code_cache.cc
@@ -793,7 +793,8 @@
   }
 
   ClearMethodCounter(method, /* was_warm= */ false);
-  Runtime::Current()->GetInstrumentation()->InitializeMethodsCode(method, /*aot_code=*/ nullptr);
+  Runtime::Current()->GetInstrumentation()->UpdateMethodsCode(
+      method, GetQuickToInterpreterBridge());
   VLOG(jit)
       << "JIT removed (osr=" << std::boolalpha << osr << std::noboolalpha << ") "
       << ArtMethod::PrettyMethod(method) << "@" << method
@@ -1317,8 +1318,7 @@
               OatQuickMethodHeader::FromEntryPoint(entry_point);
           if (CodeInfo::IsBaseline(method_header->GetOptimizedCodeInfoPtr())) {
             info->GetMethod()->ResetCounter(warmup_threshold);
-            Runtime::Current()->GetInstrumentation()->InitializeMethodsCode(
-                info->GetMethod(), /*aot_code=*/ nullptr);
+            info->GetMethod()->SetEntryPointFromQuickCompiledCode(GetQuickToInterpreterBridge());
           }
         }
       }
@@ -1744,7 +1744,7 @@
     if (meth->IsObsolete()) {
       linker->SetEntryPointsForObsoleteMethod(meth);
     } else {
-      Runtime::Current()->GetInstrumentation()->InitializeMethodsCode(meth, /*aot_code=*/ nullptr);
+      linker->SetEntryPointsToInterpreter(meth);
     }
   }
   saved_compiled_methods_map_.clear();
@@ -1761,7 +1761,8 @@
   if (method_entrypoint == header->GetEntryPoint()) {
     // The entrypoint is the one to invalidate, so we just update it to the interpreter entry point
     // and clear the counter to get the method Jitted again.
-    Runtime::Current()->GetInstrumentation()->InitializeMethodsCode(method, /*aot_code=*/ nullptr);
+    Runtime::Current()->GetInstrumentation()->UpdateMethodsCode(
+        method, GetQuickToInterpreterBridge());
     ClearMethodCounter(method, /*was_warm=*/ true);
   } else {
     MutexLock mu(Thread::Current(), *Locks::jit_lock_);
diff --git a/runtime/quick_exception_handler.cc b/runtime/quick_exception_handler.cc
index c372248..ac5065b 100644
--- a/runtime/quick_exception_handler.cc
+++ b/runtime/quick_exception_handler.cc
@@ -606,8 +606,9 @@
     Runtime::Current()->GetJit()->GetCodeCache()->InvalidateCompiledCodeFor(
         deopt_method, visitor.GetSingleFrameDeoptQuickMethodHeader());
   } else {
-    Runtime::Current()->GetInstrumentation()->InitializeMethodsCode(
-        deopt_method, /*aot_code=*/ nullptr);
+    // Transfer the code to interpreter.
+    Runtime::Current()->GetInstrumentation()->UpdateMethodsCode(
+        deopt_method, GetQuickToInterpreterBridge());
   }
 
   PrepareForLongJumpToInvokeStubOrInterpreterBridge();
diff --git a/runtime/runtime.cc b/runtime/runtime.cc
index afa8504..54e9d38 100644
--- a/runtime/runtime.cc
+++ b/runtime/runtime.cc
@@ -3095,21 +3095,21 @@
       if (Runtime::Current()->GetHeap()->IsInBootImageOatFile(code) &&
           !m.IsNative() &&
           !m.IsProxyMethod()) {
-        instrumentation_->InitializeMethodsCode(&m, /*aot_code=*/ nullptr);
+        instrumentation_->UpdateMethodsCodeForJavaDebuggable(&m, GetQuickToInterpreterBridge());
       }
 
       if (Runtime::Current()->GetJit() != nullptr &&
           Runtime::Current()->GetJit()->GetCodeCache()->IsInZygoteExecSpace(code) &&
           !m.IsNative()) {
         DCHECK(!m.IsProxyMethod());
-        instrumentation_->InitializeMethodsCode(&m, /*aot_code=*/ nullptr);
+        instrumentation_->UpdateMethodsCodeForJavaDebuggable(&m, GetQuickToInterpreterBridge());
       }
 
       if (m.IsPreCompiled()) {
         // Precompilation is incompatible with debuggable, so clear the flag
         // and update the entrypoint in case it has been compiled.
         m.ClearPreCompiled();
-        instrumentation_->InitializeMethodsCode(&m, /*aot_code=*/ nullptr);
+        instrumentation_->UpdateMethodsCodeForJavaDebuggable(&m, GetQuickToInterpreterBridge());
       }
     }
     return true;
diff --git a/runtime/runtime_callbacks_test.cc b/runtime/runtime_callbacks_test.cc
index 7f64721..7619750 100644
--- a/runtime/runtime_callbacks_test.cc
+++ b/runtime/runtime_callbacks_test.cc
@@ -80,7 +80,7 @@
     PointerSize pointer_size = class_linker_->GetImagePointerSize();
     for (auto& m : klass->GetMethods(pointer_size)) {
       if (!m.IsAbstract()) {
-        Runtime::Current()->GetInstrumentation()->InitializeMethodsCode(&m, /*aot_code=*/ nullptr);
+        class_linker_->SetEntryPointsToInterpreter(&m);
       }
     }
   }