Fix crash on error paths from GenericJNI trampoline.

Test: Added a regression test to 178-app-image-native-method
Test: testrunner.py --host --optimizing -t 178-app-image-native-method
Bug: 181736463
Change-Id: Ib98d6d58ce1fb8287c32f88fda0f83b7e21ef42d
diff --git a/runtime/entrypoints/quick/quick_trampoline_entrypoints.cc b/runtime/entrypoints/quick/quick_trampoline_entrypoints.cc
index 4c67bb9..bc5a10d 100644
--- a/runtime/entrypoints/quick/quick_trampoline_entrypoints.cc
+++ b/runtime/entrypoints/quick/quick_trampoline_entrypoints.cc
@@ -2114,7 +2114,6 @@
       Handle<mirror::Class> h_class(hs.NewHandle(declaring_class));
       if (!runtime->GetClassLinker()->EnsureInitialized(self, h_class, true, true)) {
         DCHECK(Thread::Current()->IsExceptionPending()) << called->PrettyMethod();
-        self->PopHandleScope();
         return nullptr;  // Report error.
       }
     }
@@ -2130,7 +2129,6 @@
       jobject lock = GetGenericJniSynchronizationObject(self, called);
       cookie = JniMethodStartSynchronized(lock, self);
       if (self->IsExceptionPending()) {
-        self->PopHandleScope();
         return nullptr;  // Report error.
       }
     } else {
diff --git a/test/178-app-image-native-method/src/Main.java b/test/178-app-image-native-method/src/Main.java
index a9c6f0a..e6c76ff 100644
--- a/test/178-app-image-native-method/src/Main.java
+++ b/test/178-app-image-native-method/src/Main.java
@@ -51,6 +51,8 @@
     $noinline$opt$testMissingCritical();
     $noinline$opt$testCriticalSignatures();
 
+    $noinline$regressionTestB181736463();
+
     new CriticalClinitCheck();
     sTestCriticalClinitCheckOtherThread.join();
   }
@@ -369,6 +371,15 @@
         254));
   }
 
+  static void $noinline$regressionTestB181736463() {
+    // Regression test for bug 181736463 (GenericJNI crashing when class initializer throws).
+    try {
+      BadClassB181736463.nativeMethodVoid();
+      throw new Error("Unreachable");
+    } catch (B181736463Error expected) {
+    }
+  }
+
   static void initializingCriticalClinitCheck() {
     // Called from CriticalClinitCheck.<clinit>().
     // Test @CriticalNative calls on the initializing thread.
@@ -823,3 +834,17 @@
     Main.initializingCriticalClinitCheck();
   }
 }
+
+class B181736463Error extends Error {
+}
+
+class BadClassB181736463 {
+  static {
+    // Deliberately throw from class initializer.
+    if (true) {
+      throw new B181736463Error();
+    }
+  }
+
+  public static native int nativeMethodVoid();
+}