ART: Refactor VMStack code

Make GetThreadStack generic wrt/ a function being called to generate the
stack. In preparation for new code.

Bug: 70538431
Test: m test-art-host
Change-Id: I7e2b6583b28ad89bc645acdc9549f2f0a25ea055
diff --git a/runtime/native/dalvik_system_VMStack.cc b/runtime/native/dalvik_system_VMStack.cc
index a88563d..3e8040b 100644
--- a/runtime/native/dalvik_system_VMStack.cc
+++ b/runtime/native/dalvik_system_VMStack.cc
@@ -16,6 +16,8 @@
 
 #include "dalvik_system_VMStack.h"
 
+#include <type_traits>
+
 #include "nativehelper/jni_macros.h"
 
 #include "art_method-inl.h"
@@ -32,12 +34,17 @@
 
 namespace art {
 
-static jobject GetThreadStack(const ScopedFastNativeObjectAccess& soa, jobject peer)
+template <typename T,
+          typename ResultT =
+              typename std::result_of<T(Thread*, const ScopedFastNativeObjectAccess&)>::type>
+static ResultT GetThreadStack(const ScopedFastNativeObjectAccess& soa,
+                              jobject peer,
+                              T fn)
     REQUIRES_SHARED(Locks::mutator_lock_) {
-  jobject trace = nullptr;
+  ResultT trace = nullptr;
   ObjPtr<mirror::Object> decoded_peer = soa.Decode<mirror::Object>(peer);
   if (decoded_peer == soa.Self()->GetPeer()) {
-    trace = soa.Self()->CreateInternalStackTrace<false>(soa);
+    trace = fn(soa.Self(), soa);
   } else {
     // Never allow suspending the heap task thread since it may deadlock if allocations are
     // required for the stack trace.
@@ -59,7 +66,7 @@
       // Must be runnable to create returned array.
       {
         ScopedObjectAccess soa2(soa.Self());
-        trace = thread->CreateInternalStackTrace<false>(soa);
+        trace = fn(thread, soa);
       }
       // Restart suspended thread.
       bool resumed = thread_list->Resume(thread, SuspendReason::kInternal);
@@ -75,7 +82,11 @@
 static jint VMStack_fillStackTraceElements(JNIEnv* env, jclass, jobject javaThread,
                                            jobjectArray javaSteArray) {
   ScopedFastNativeObjectAccess soa(env);
-  jobject trace = GetThreadStack(soa, javaThread);
+  auto fn = [](Thread* thread, const ScopedFastNativeObjectAccess& soaa)
+      REQUIRES_SHARED(Locks::mutator_lock_) -> jobject {
+    return thread->CreateInternalStackTrace<false>(soaa);
+  };
+  jobject trace = GetThreadStack(soa, javaThread, fn);
   if (trace == nullptr) {
     return 0;
   }
@@ -138,7 +149,11 @@
 
 static jobjectArray VMStack_getThreadStackTrace(JNIEnv* env, jclass, jobject javaThread) {
   ScopedFastNativeObjectAccess soa(env);
-  jobject trace = GetThreadStack(soa, javaThread);
+  auto fn = [](Thread* thread, const ScopedFastNativeObjectAccess& soaa)
+     REQUIRES_SHARED(Locks::mutator_lock_) -> jobject {
+    return thread->CreateInternalStackTrace<false>(soaa);
+  };
+  jobject trace = GetThreadStack(soa, javaThread, fn);
   if (trace == nullptr) {
     return nullptr;
   }