Fast JNI support.

Use a modifier to signal a native method is a fast JNI method. If the
modifier is set then don't perform runnable transitions.

Change-Id: I7835b4d837bfdd1cb8e2d54b919c0d5e6cf90499
diff --git a/runtime/native/dalvik_system_DexFile.cc b/runtime/native/dalvik_system_DexFile.cc
index 823013a..4e17b79 100644
--- a/runtime/native/dalvik_system_DexFile.cc
+++ b/runtime/native/dalvik_system_DexFile.cc
@@ -95,7 +95,6 @@
     return 0;
   }
   ScopedObjectAccess soa(env);
-
   uint32_t dex_location_checksum;
   if (!DexFile::GetChecksum(dex_location, &dex_location_checksum)) {
     LOG(WARNING) << "Failed to compute checksum: " << dex_location;
@@ -123,9 +122,10 @@
   return static_cast<jint>(reinterpret_cast<uintptr_t>(dex_file));
 }
 
-static const DexFile* toDexFile(int dex_file_address) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
+static const DexFile* toDexFile(int dex_file_address, JNIEnv* env) {
   const DexFile* dex_file = reinterpret_cast<const DexFile*>(static_cast<uintptr_t>(dex_file_address));
-  if (dex_file == NULL) {
+  if (UNLIKELY(dex_file == nullptr)) {
+    ScopedObjectAccess soa(env);
     ThrowNullPointerException(NULL, "dex_file == null");
   }
   return dex_file;
@@ -133,11 +133,8 @@
 
 static void DexFile_closeDexFile(JNIEnv* env, jclass, jint cookie) {
   const DexFile* dex_file;
-  {
-    ScopedObjectAccess soa(env);
-    dex_file = toDexFile(cookie);
-  }
-  if (dex_file == NULL) {
+  dex_file = toDexFile(cookie, env);
+  if (dex_file == nullptr) {
     return;
   }
   if (Runtime::Current()->GetClassLinker()->IsDexFileRegistered(*dex_file)) {
@@ -148,8 +145,7 @@
 
 static jclass DexFile_defineClassNative(JNIEnv* env, jclass, jstring javaName, jobject javaLoader,
                                         jint cookie) {
-  ScopedObjectAccess soa(env);
-  const DexFile* dex_file = toDexFile(cookie);
+  const DexFile* dex_file = toDexFile(cookie, env);
   if (dex_file == NULL) {
     VLOG(class_linker) << "Failed to find dex_file";
     return NULL;
@@ -165,6 +161,7 @@
     VLOG(class_linker) << "Failed to find dex_class_def";
     return NULL;
   }
+  ScopedObjectAccess soa(env);
   ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
   class_linker->RegisterDexFile(*dex_file);
   mirror::ClassLoader* class_loader = soa.Decode<mirror::ClassLoader*>(javaLoader);
@@ -176,12 +173,9 @@
 
 static jobjectArray DexFile_getClassNameList(JNIEnv* env, jclass, jint cookie) {
   const DexFile* dex_file;
-  {
-    ScopedObjectAccess soa(env);
-    dex_file = toDexFile(cookie);
-  }
-  if (dex_file == NULL) {
-    return NULL;
+  dex_file = toDexFile(cookie, env);
+  if (dex_file == nullptr) {
+    return nullptr;
   }
 
   std::vector<std::string> class_names;