Fix 084-class-init

Don't update the code and direct methods table for classes that are
still initializing as a 2nd thread may need to wait for class
initialization.
Fix the return value of EnsureInitialized when the class initializer
throws an exception.

Change-Id: I571d983f1a4025b5bcdd51b817d252ef131a6e97
diff --git a/src/runtime_support.cc b/src/runtime_support.cc
index 1a6d2e6..696ef70 100644
--- a/src/runtime_support.cc
+++ b/src/runtime_support.cc
@@ -408,12 +408,18 @@
   Method* called = linker->ResolveMethod(method_idx, *caller_sp, true);
   if (LIKELY(!thread->IsExceptionPending())) {
     if (LIKELY(called->IsDirect())) {
-      // Update CodeAndDirectMethod table
-      Method* caller = *caller_sp;
-      DexCache* dex_cache = caller->GetDeclaringClass()->GetDexCache();
-      dex_cache->GetCodeAndDirectMethods()->SetResolvedDirectMethod(method_idx, called);
-      // We got this far, ensure that the declaring class is initialized
-      linker->EnsureInitialized(called->GetDeclaringClass(), true);
+      // Ensure that the called method's class is initialized
+      Class* called_class = called->GetDeclaringClass();
+      linker->EnsureInitialized(called_class, true);
+      if (LIKELY(called_class->IsInitialized())) {
+        // Update CodeAndDirectMethod table and avoid the trampoline when we know the called class
+        // is initialized (see test 084-class-init SlowInit)
+        Method* caller = *caller_sp;
+        DexCache* dex_cache = caller->GetDeclaringClass()->GetDexCache();
+        dex_cache->GetCodeAndDirectMethods()->SetResolvedDirectMethod(method_idx, called);
+        // We got this far, ensure that the declaring class is initialized
+        linker->EnsureInitialized(called->GetDeclaringClass(), true);
+      }
     } else {
       // Direct method has been made virtual
       thread->ThrowNewExceptionF("Ljava/lang/IncompatibleClassChangeError;",
@@ -430,7 +436,7 @@
     thread->ClearException();
   } else {
     // Expect class to at least be initializing
-    CHECK(called->GetDeclaringClass()->IsInitializing());
+    DCHECK(called->GetDeclaringClass()->IsInitializing());
     // Set up entry into main method
     regs[0] = reinterpret_cast<uintptr_t>(called);
     code = const_cast<void*>(called->GetCode());