Make InternalStackTraceToStackTraceElementArray compaction safe.

Added more SOA decodes.

Change-Id: Idbfd546467582a848be91c358c6926a6e472fbff
diff --git a/runtime/thread.cc b/runtime/thread.cc
index 7e79ce1..99a7d1e 100644
--- a/runtime/thread.cc
+++ b/runtime/thread.cc
@@ -1387,24 +1387,23 @@
   // Transition into runnable state to work on Object*/Array*
   ScopedObjectAccess soa(env);
   // Decode the internal stack trace into the depth, method trace and PC trace
-  mirror::ObjectArray<mirror::Object>* method_trace =
-      soa.Decode<mirror::ObjectArray<mirror::Object>*>(internal);
-  int32_t depth = method_trace->GetLength() - 1;
-  mirror::IntArray* pc_trace = down_cast<mirror::IntArray*>(method_trace->Get(depth));
+  int32_t depth = soa.Decode<mirror::ObjectArray<mirror::Object>*>(internal)->GetLength() - 1;
 
   ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
 
   jobjectArray result;
-  mirror::ObjectArray<mirror::StackTraceElement>* java_traces;
+
   if (output_array != NULL) {
     // Reuse the array we were given.
     result = output_array;
-    java_traces = soa.Decode<mirror::ObjectArray<mirror::StackTraceElement>*>(output_array);
     // ...adjusting the number of frames we'll write to not exceed the array length.
-    depth = std::min(depth, java_traces->GetLength());
+    const int32_t traces_length =
+        soa.Decode<mirror::ObjectArray<mirror::StackTraceElement>*>(result)->GetLength();
+    depth = std::min(depth, traces_length);
   } else {
     // Create java_trace array and place in local reference table
-    java_traces = class_linker->AllocStackTraceElementArray(soa.Self(), depth);
+    mirror::ObjectArray<mirror::StackTraceElement>* java_traces =
+        class_linker->AllocStackTraceElementArray(soa.Self(), depth);
     if (java_traces == NULL) {
       return NULL;
     }
@@ -1417,9 +1416,12 @@
 
   MethodHelper mh;
   for (int32_t i = 0; i < depth; ++i) {
+    mirror::ObjectArray<mirror::Object>* method_trace =
+          soa.Decode<mirror::ObjectArray<mirror::Object>*>(internal);
     // Prepare parameters for StackTraceElement(String cls, String method, String file, int line)
     mirror::ArtMethod* method = down_cast<mirror::ArtMethod*>(method_trace->Get(i));
     mh.ChangeMethod(method);
+    mirror::IntArray* pc_trace = down_cast<mirror::IntArray*>(method_trace->Get(depth));
     uint32_t dex_pc = pc_trace->Get(i);
     int32_t line_number = mh.GetLineNumFromDexPC(dex_pc);
     // Allocate element, potentially triggering GC
@@ -1442,8 +1444,9 @@
       return NULL;
     }
     const char* source_file = mh.GetDeclaringClassSourceFile();
-    SirtRef<mirror::String> source_name_object(soa.Self(), mirror::String::AllocFromModifiedUtf8(soa.Self(),
-                                                                                                 source_file));
+    SirtRef<mirror::String> source_name_object(soa.Self(),
+                                               mirror::String::AllocFromModifiedUtf8(soa.Self(),
+                                                                                     source_file));
     mirror::StackTraceElement* obj = mirror::StackTraceElement::Alloc(soa.Self(),
                                                                       class_name_object.get(),
                                                                       method_name_object.get(),
@@ -1452,13 +1455,7 @@
     if (obj == NULL) {
       return NULL;
     }
-#ifdef MOVING_GARBAGE_COLLECTOR
-    // Re-read after potential GC
-    java_traces = Decode<ObjectArray<Object>*>(soa.Env(), result);
-    method_trace = down_cast<ObjectArray<Object>*>(Decode<Object*>(soa.Env(), internal));
-    pc_trace = down_cast<IntArray*>(method_trace->Get(depth));
-#endif
-    java_traces->Set(i, obj);
+    soa.Decode<mirror::ObjectArray<mirror::StackTraceElement>*>(result)->Set(i, obj);
   }
   return result;
 }