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/class_linker.cc b/src/class_linker.cc
index b18b31f..3c0c345 100644
--- a/src/class_linker.cc
+++ b/src/class_linker.cc
@@ -45,6 +45,7 @@
 #if defined(ART_USE_LLVM_COMPILER)
 #include "compiler_llvm/runtime_support_llvm.h"
 #endif
+#include "scoped_jni_thread_state.h"
 #include "ScopedLocalRef.h"
 #include "space.h"
 #include "stack_indirect_reference_table.h"
@@ -1116,7 +1117,7 @@
   return FindClass(descriptor, NULL);
 }
 
-Class* ClassLinker::FindClass(const char* descriptor, const ClassLoader* class_loader) {
+Class* ClassLinker::FindClass(const char* descriptor, ClassLoader* class_loader) {
   DCHECK_NE(*descriptor, '\0') << "descriptor is empty string";
   Thread* self = Thread::Current();
   DCHECK(self != NULL);
@@ -1159,19 +1160,24 @@
     }
 
   } else {
+    ScopedJniThreadState ts(self->GetJniEnv());
+    ScopedLocalRef<jobject> class_loader_object(ts.Env(),
+                                                ts.AddLocalReference<jobject>(class_loader));
     std::string class_name_string(DescriptorToDot(descriptor));
-    ScopedThreadStateChange tsc(self, kNative);
-    JNIEnv* env = self->GetJniEnv();
-    ScopedLocalRef<jobject> class_name_object(env, env->NewStringUTF(class_name_string.c_str()));
-    if (class_name_object.get() == NULL) {
-      return NULL;
+    ScopedLocalRef<jobject> result(ts.Env(), NULL);
+    {
+      ScopedThreadStateChange tsc(self, kNative);
+      ScopedLocalRef<jobject> class_name_object(ts.Env(),
+                                                ts.Env()->NewStringUTF(class_name_string.c_str()));
+      if (class_name_object.get() == NULL) {
+        return NULL;
+      }
+      CHECK(class_loader_object.get() != NULL);
+      result.reset(ts.Env()->CallObjectMethod(class_loader_object.get(),
+                                              WellKnownClasses::java_lang_ClassLoader_loadClass,
+                                              class_name_object.get()));
     }
-    ScopedLocalRef<jobject> class_loader_object(env, AddLocalReference<jobject>(env, class_loader));
-    CHECK(class_loader_object.get() != NULL);
-    ScopedLocalRef<jobject> result(env, env->CallObjectMethod(class_loader_object.get(),
-                                                              WellKnownClasses::java_lang_ClassLoader_loadClass,
-                                                              class_name_object.get()));
-    if (env->ExceptionCheck()) {
+    if (ts.Env()->ExceptionCheck()) {
       // If the ClassLoader threw, pass that exception up.
       return NULL;
     } else if (result.get() == NULL) {
@@ -1181,7 +1187,7 @@
       return NULL;
     } else {
       // success, return Class*
-      return Decode<Class*>(env, result.get());
+      return ts.Decode<Class*>(result.get());
     }
   }
 
@@ -1190,7 +1196,7 @@
 }
 
 Class* ClassLinker::DefineClass(const StringPiece& descriptor,
-                                const ClassLoader* class_loader,
+                                ClassLoader* class_loader,
                                 const DexFile& dex_file,
                                 const DexFile::ClassDef& dex_class_def) {
   SirtRef<Class> klass(NULL);
@@ -1453,7 +1459,7 @@
 void ClassLinker::LoadClass(const DexFile& dex_file,
                             const DexFile::ClassDef& dex_class_def,
                             SirtRef<Class>& klass,
-                            const ClassLoader* class_loader) {
+                            ClassLoader* class_loader) {
   CHECK(klass.get() != NULL);
   CHECK(klass->GetDexCache() != NULL);
   CHECK_EQ(Class::kStatusNotReady, klass->GetStatus());
@@ -1707,7 +1713,7 @@
 // array class; that always comes from the base element class.
 //
 // Returns NULL with an exception raised on failure.
-Class* ClassLinker::CreateArrayClass(const std::string& descriptor, const ClassLoader* class_loader) {
+Class* ClassLinker::CreateArrayClass(const std::string& descriptor, ClassLoader* class_loader) {
   CHECK_EQ('[', descriptor[0]);
 
   // Identify the underlying component type
@@ -2657,7 +2663,7 @@
 
 void ClassLinker::ConstructFieldMap(const DexFile& dex_file, const DexFile::ClassDef& dex_class_def,
                                     Class* c, SafeMap<uint32_t, Field*>& field_map) {
-  const ClassLoader* cl = c->GetClassLoader();
+  ClassLoader* cl = c->GetClassLoader();
   const byte* class_data = dex_file.GetClassData(dex_class_def);
   ClassDataItemIterator it(dex_file, class_data);
   for (size_t i = 0; it.HasNextStaticField(); i++, it.Next()) {
@@ -3342,7 +3348,7 @@
 Class* ClassLinker::ResolveType(const DexFile& dex_file,
                                 uint16_t type_idx,
                                 DexCache* dex_cache,
-                                const ClassLoader* class_loader) {
+                                ClassLoader* class_loader) {
   DCHECK(dex_cache != NULL);
   Class* resolved = dex_cache->GetResolvedType(type_idx);
   if (resolved == NULL) {
@@ -3369,7 +3375,7 @@
 Method* ClassLinker::ResolveMethod(const DexFile& dex_file,
                                    uint32_t method_idx,
                                    DexCache* dex_cache,
-                                   const ClassLoader* class_loader,
+                                   ClassLoader* class_loader,
                                    bool is_direct) {
   DCHECK(dex_cache != NULL);
   Method* resolved = dex_cache->GetResolvedMethod(method_idx);
@@ -3419,7 +3425,7 @@
 Field* ClassLinker::ResolveField(const DexFile& dex_file,
                                  uint32_t field_idx,
                                  DexCache* dex_cache,
-                                 const ClassLoader* class_loader,
+                                 ClassLoader* class_loader,
                                  bool is_static) {
   DCHECK(dex_cache != NULL);
   Field* resolved = dex_cache->GetResolvedField(field_idx);
@@ -3459,7 +3465,7 @@
 Field* ClassLinker::ResolveFieldJLS(const DexFile& dex_file,
                                     uint32_t field_idx,
                                     DexCache* dex_cache,
-                                    const ClassLoader* class_loader) {
+                                    ClassLoader* class_loader) {
   DCHECK(dex_cache != NULL);
   Field* resolved = dex_cache->GetResolvedField(field_idx);
   if (resolved != NULL) {