diff options
| author | Andy McFadden <fadden@android.com> | 2011-02-08 12:07:32 -0800 |
|---|---|---|
| committer | Andy McFadden <fadden@android.com> | 2011-02-08 15:46:38 -0800 |
| commit | 37b80052435aab7a419f05eb1121ef294cb6170c (patch) | |
| tree | 54ba97c72b2a8690a1d2db36de0479ce3ba4e548 /libnativehelper | |
| parent | 85019f27b4140f86450948f3486a64743d1f8671 (diff) | |
| download | android_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.c | 36 |
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; +} |
