summaryrefslogtreecommitdiffstats
path: root/libnativehelper
diff options
context:
space:
mode:
authorAndy McFadden <fadden@android.com>2011-02-08 12:07:32 -0800
committerAndy McFadden <fadden@android.com>2011-02-08 15:46:38 -0800
commit37b80052435aab7a419f05eb1121ef294cb6170c (patch)
tree54ba97c72b2a8690a1d2db36de0479ce3ba4e548 /libnativehelper
parent85019f27b4140f86450948f3486a64743d1f8671 (diff)
downloadandroid_dalvik-37b80052435aab7a419f05eb1121ef294cb6170c.tar.gz
android_dalvik-37b80052435aab7a419f05eb1121ef294cb6170c.tar.bz2
android_dalvik-37b80052435aab7a419f05eb1121ef294cb6170c.zip
Added JNI hack to support JNI hack
Some of our graphics code wants to get a pointer, release it, and then continue to use it. The "forcecopy" mode of CheckJNI was designed to find any code that does this. It succeeded. To support the behavior, we provide a JNI helper function that does the dirty work. It passes a magic value into the Get and Release calls that causes "forcecopy" to skip the copy. When forcecopy is not enabled, the values are simply ignored. To avoid any possibility of the function getting published in the NDK, the function is not described in JNIHelp.h. Bug 3409356 Change-Id: Ibd20d12ba6d3d3236ebf5760f7ccaa8c557e3774
Diffstat (limited to 'libnativehelper')
-rw-r--r--libnativehelper/JNIHelp.c36
1 files changed, 36 insertions, 0 deletions
diff --git a/libnativehelper/JNIHelp.c b/libnativehelper/JNIHelp.c
index ededb4c30..e5abc0f5d 100644
--- a/libnativehelper/JNIHelp.c
+++ b/libnativehelper/JNIHelp.c
@@ -21,6 +21,7 @@
#include "JNIHelp.h"
#include "utils/Log.h"
+#include <stdlib.h>
#include <string.h>
#include <assert.h>
@@ -337,3 +338,38 @@ int jniGetFDFromFileDescriptor(JNIEnv* env, jobject fileDescriptor) {
void jniSetFileDescriptorOfFD(JNIEnv* env, jobject fileDescriptor, int value) {
(*env)->SetIntField(env, fileDescriptor, gCachedFields.descriptorField, value);
}
+
+/*
+ * DO NOT USE THIS FUNCTION
+ *
+ * Get a pointer to the elements of a non-movable array.
+ *
+ * The semantics are similar to GetDirectBufferAddress. Specifically, the VM
+ * guarantees that the array will not move, and the caller must ensure that
+ * it does not continue to use the pointer after the object is collected.
+ *
+ * We currently use an illegal sequence that trips up CheckJNI when
+ * the "forcecopy" mode is enabled. We pass in a magic value to work
+ * around the problem.
+ *
+ * Returns NULL if the array is movable.
+ */
+jbyte* jniGetNonMovableArrayElements(JNIEnv* env, jarray arrayObj)
+{
+#define kNoCopyMagic 0xd5aab57f /* also in CheckJni.c */
+
+ /*
+ * Normally the "isCopy" parameter is for a return value only, so the
+ * non-CheckJNI VM will ignore whatever we pass in.
+ */
+ uint32_t noCopy = kNoCopyMagic;
+ jbyte *addr = (*env)->GetByteArrayElements(env, arrayObj,
+ (jboolean*)&noCopy);
+
+ /*
+ * The non-CheckJNI implementation only cares about the array object,
+ * so we can replace the element pointer with the magic value.
+ */
+ (*env)->ReleaseByteArrayElements(env, arrayObj, (jbyte*) kNoCopyMagic, 0);
+ return addr;
+}