Don't push handle scope for critical native generic JNI

Leaving a stale handle scope causes problems for the GC the next
time roots are visited. At this point the stack will have other
contents and the GC will attempt to mark many invalid roots.

Bug: 31933313

Test: non preopt eng build booting.
Test: test-art-host

(cherry picked from commit 92879f9bbcfc034660ed1ff5ef741d7f2bcb116f)

Change-Id: I7d57964ccd2b59a05bb06f67062f646362ce1204
diff --git a/runtime/entrypoints/quick/quick_trampoline_entrypoints.cc b/runtime/entrypoints/quick/quick_trampoline_entrypoints.cc
index 81513ee..126e26c 100644
--- a/runtime/entrypoints/quick/quick_trampoline_entrypoints.cc
+++ b/runtime/entrypoints/quick/quick_trampoline_entrypoints.cc
@@ -1866,6 +1866,10 @@
       }
     }
 
+    bool CriticalNative() const {
+      return critical_native_;
+    }
+
    private:
     HandleScope* handle_scope_;
     size_t cur_entry_;
@@ -1939,8 +1943,10 @@
 void BuildGenericJniFrameVisitor::FinalizeHandleScope(Thread* self) {
   // Clear out rest of the scope.
   jni_call_.ResetRemainingScopeSlots();
-  // Install HandleScope.
-  self->PushHandleScope(handle_scope_);
+  if (!jni_call_.CriticalNative()) {
+    // Install HandleScope.
+    self->PushHandleScope(handle_scope_);
+  }
 }
 
 #if defined(__arm__) || defined(__aarch64__)