Increase use of ScopedJniThreadState.

Move the routines for changing Object* to jobject and vice-versa
(AddLocalReference and Decode) to ScopedJniThreadState to enforce use of
Object*s in the Runnable thread state. In the Runnable thread state
suspension is necessary before GC can take place.

Reduce use of const ClassLoader* as the code bottoms out in FindClass
and with a field assignment where the const is cast away (ie if we're
not going to enforce the const-ness we shouldn't pretend it is).

Refactor the Thread::Attach API so that we're not handling raw Objects on
unattached threads.

Remove some unreachable code.

Change-Id: I0fa969f49ee6a8f10752af74a6b0e04d46b4cd97
diff --git a/src/oat/runtime/support_proxy.cc b/src/oat/runtime/support_proxy.cc
index 37cacb4..83d2265 100644
--- a/src/oat/runtime/support_proxy.cc
+++ b/src/oat/runtime/support_proxy.cc
@@ -18,6 +18,7 @@
 #include "object_utils.h"
 #include "reflection.h"
 #include "runtime_support.h"
+#include "scoped_jni_thread_state.h"
 #include "thread.h"
 #include "well_known_classes.h"
 
@@ -50,10 +51,11 @@
   DCHECK_EQ(proxy_method->GetFrameSizeInBytes(), FRAME_SIZE_IN_BYTES);
   // Start new JNI local reference state
   JNIEnvExt* env = self->GetJniEnv();
+  ScopedJniThreadState ts(env);
   ScopedJniEnvLocalRefState env_state(env);
   // Create local ref. copies of proxy method and the receiver
-  jobject rcvr_jobj = AddLocalReference<jobject>(env, receiver);
-  jobject proxy_method_jobj = AddLocalReference<jobject>(env, proxy_method);
+  jobject rcvr_jobj = ts.AddLocalReference<jobject>(receiver);
+  jobject proxy_method_jobj = ts.AddLocalReference<jobject>(proxy_method);
 
   // Placing into local references incoming arguments from the caller's register arguments,
   // replacing original Object* with jobject
@@ -72,7 +74,7 @@
   while (cur_arg < args_in_regs && param_index < num_params) {
     if (proxy_mh.IsParamAReference(param_index)) {
       Object* obj = *reinterpret_cast<Object**>(stack_args + (cur_arg * kPointerSize));
-      jobject jobj = AddLocalReference<jobject>(env, obj);
+      jobject jobj = ts.AddLocalReference<jobject>(obj);
       *reinterpret_cast<jobject*>(stack_args + (cur_arg * kPointerSize)) = jobj;
     }
     cur_arg = cur_arg + (proxy_mh.IsParamALongOrDouble(param_index) ? 2 : 1);
@@ -83,7 +85,7 @@
   while (param_index < num_params) {
     if (proxy_mh.IsParamAReference(param_index)) {
       Object* obj = *reinterpret_cast<Object**>(stack_args + (cur_arg * kPointerSize));
-      jobject jobj = AddLocalReference<jobject>(env, obj);
+      jobject jobj = ts.AddLocalReference<jobject>(obj);
       *reinterpret_cast<jobject*>(stack_args + (cur_arg * kPointerSize)) = jobj;
     }
     cur_arg = cur_arg + (proxy_mh.IsParamALongOrDouble(param_index) ? 2 : 1);
@@ -102,13 +104,13 @@
       CHECK(self->IsExceptionPending());
       return;
     }
-    args_jobj[2].l = AddLocalReference<jobjectArray>(env, args);
+    args_jobj[2].l = ts.AddLocalReference<jobjectArray>(args);
   }
   // Convert proxy method into expected interface method
   Method* interface_method = proxy_method->FindOverriddenMethod();
   DCHECK(interface_method != NULL);
   DCHECK(!interface_method->IsProxyMethod()) << PrettyMethod(interface_method);
-  args_jobj[1].l = AddLocalReference<jobject>(env, interface_method);
+  args_jobj[1].l = ts.AddLocalReference<jobject>(interface_method);
   // Box arguments
   cur_arg = 0;  // reset stack location to read to start
   // reset index, will index into param type array which doesn't include the receiver
diff --git a/src/oat/runtime/support_stubs.cc b/src/oat/runtime/support_stubs.cc
index 522ccf2..3f6bc8f 100644
--- a/src/oat/runtime/support_stubs.cc
+++ b/src/oat/runtime/support_stubs.cc
@@ -23,6 +23,7 @@
 #if defined(ART_USE_LLVM_COMPILER)
 #include "nth_caller_visitor.h"
 #endif
+#include "scoped_jni_thread_state.h"
 
 // Architecture specific assembler helper to deliver exception.
 extern "C" void art_deliver_exception_from_code(void*);
@@ -81,6 +82,7 @@
   FinishCalleeSaveFrameSetup(thread, sp, Runtime::kRefsAndArgs);
   // Start new JNI local reference state
   JNIEnvExt* env = thread->GetJniEnv();
+  ScopedJniThreadState ts(env);
   ScopedJniEnvLocalRefState env_state(env);
 
   // Compute details about the called method (avoid GCs)
@@ -145,7 +147,7 @@
       // If we thought we had fewer than 3 arguments in registers, account for the receiver
       args_in_regs++;
     }
-    AddLocalReference<jobject>(env, obj);
+    ts.AddLocalReference<jobject>(obj);
   }
   size_t shorty_index = 1;  // skip return value
   // Iterate while arguments and arguments in registers (less 1 from cur_arg which is offset to skip
@@ -155,7 +157,7 @@
     shorty_index++;
     if (c == 'L') {
       Object* obj = reinterpret_cast<Object*>(regs[cur_arg]);
-      AddLocalReference<jobject>(env, obj);
+      ts.AddLocalReference<jobject>(obj);
     }
     cur_arg = cur_arg + (c == 'J' || c == 'D' ? 2 : 1);
   }
@@ -166,7 +168,7 @@
     shorty_index++;
     if (c == 'L') {
       Object* obj = reinterpret_cast<Object*>(regs[cur_arg]);
-      AddLocalReference<jobject>(env, obj);
+      ts.AddLocalReference<jobject>(obj);
     }
     cur_arg = cur_arg + (c == 'J' || c == 'D' ? 2 : 1);
   }