OSDN Git Service

Make Release(JNI_COMMIT) faster
authorAndy McFadden <fadden@android.com>
Wed, 9 Feb 2011 00:24:34 +0000 (16:24 -0800)
committerAndy McFadden <fadden@android.com>
Wed, 9 Feb 2011 00:24:34 +0000 (16:24 -0800)
The Release<primitive>ArrayElements and ReleasePrimitiveArrayCritical
calls take a "mode" argument.  If you pass in JNI_COMMIT, the storage
isn't actually released; instead, the buffer contents are flushed to
the backing storage.  If the VM has handed you a pointer to the raw
data rather than a copy, the call is a no-op.

In its present incarnation, it's a no-op that changes the thread state,
adding overhead and the possibility of suspension.  This change moves
the test for JNI_COMMIT outside the enter/exit macros.

Bug 3430203

Change-Id: I8426647ee02b2336c5c90146028fc207cfbacc3a

vm/Jni.c

index a416b13..88f84ac 100644 (file)
--- a/vm/Jni.c
+++ b/vm/Jni.c
@@ -3205,13 +3205,13 @@ NEW_PRIMITIVE_ARRAY(jdoubleArray, Double, 'D');
         _ctype##Array jarr, _ctype* elems, jint mode)                       \
     {                                                                       \
         UNUSED_PARAMETER(elems);                                            \
-        JNI_ENTER();                                                        \
         if (mode != JNI_COMMIT) {                                           \
+            JNI_ENTER();                                                    \
             ArrayObject* arrayObj =                                         \
                 (ArrayObject*) dvmDecodeIndirectRef(env, jarr);             \
             unpinPrimitiveArray(arrayObj);                                  \
+            JNI_EXIT();                                                     \
         }                                                                   \
-        JNI_EXIT();                                                         \
     }
 
 static void throwArrayRegionOutOfBounds(ArrayObject* arrayObj, jsize start,
@@ -3466,12 +3466,12 @@ static void* GetPrimitiveArrayCritical(JNIEnv* env, jarray jarr,
 static void ReleasePrimitiveArrayCritical(JNIEnv* env, jarray jarr,
     void* carray, jint mode)
 {
-    JNI_ENTER();
     if (mode != JNI_COMMIT) {
+        JNI_ENTER();
         ArrayObject* arrayObj = (ArrayObject*) dvmDecodeIndirectRef(env, jarr);
         unpinPrimitiveArray(arrayObj);
+        JNI_EXIT();
     }
-    JNI_EXIT();
 }
 
 /*