aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorOrion Hodson <oth@google.com>2019-02-22 16:41:10 +0000
committerOrion Hodson <oth@google.com>2019-04-11 16:53:46 +0100
commitbcc2b6fda49e42add4715882231215b2b3ada9d0 (patch)
tree9345e8f3e6e5eef59d8ec9ccc29cafda6a8c5a4d
parent99b0113fdcb2abb2c0f7043d21b9ccfaae8c78d1 (diff)
downloadlibnativehelper-android-10.0.0_r22.tar.gz
Bug: 124338141 Test: Boot and observe no core platform api warnings from opengl (cherry picked from commit f5480bdcdd27e492a9858599664c74e16a46a961) Change-Id: I4680418398f0708c26c0124b418a2ccb1094a038 Merged-In: I6db85f6084dd620e08568dbdeea0d10efb20a84f
-rw-r--r--JNIHelp.cpp37
-rw-r--r--JniConstants.cpp113
-rw-r--r--JniConstants.h30
-rw-r--r--include/nativehelper/JNIHelp.h60
-rw-r--r--libnativehelper.map.txt4
5 files changed, 240 insertions, 4 deletions
diff --git a/JNIHelp.cpp b/JNIHelp.cpp
index 867488b..8432f7a 100644
--- a/JNIHelp.cpp
+++ b/JNIHelp.cpp
@@ -355,6 +355,43 @@ MODULE_API jlong jniGetOwnerIdFromFileDescriptor(C_JNIEnv* env, jobject fileDesc
return e->GetLongField(fileDescriptor, JniConstants::GetFileDescriptorOwnerIdField(e));
}
+MODULE_API jarray jniGetNioBufferBaseArray(C_JNIEnv* env, jobject nioBuffer) {
+ JNIEnv* e = reinterpret_cast<JNIEnv*>(env);
+ jclass nioAccessClass = JniConstants::GetNioAccessClass(e);
+ jmethodID getBaseArrayMethod = JniConstants::GetNioAccessGetBaseArrayMethod(e);
+ jobject object = e->CallStaticObjectMethod(nioAccessClass, getBaseArrayMethod, nioBuffer);
+ return static_cast<jarray>(object);
+}
+
+MODULE_API int jniGetNioBufferBaseArrayOffset(C_JNIEnv* env, jobject nioBuffer) {
+ JNIEnv* e = reinterpret_cast<JNIEnv*>(env);
+ jclass nioAccessClass = JniConstants::GetNioAccessClass(e);
+ jmethodID getBaseArrayOffsetMethod = JniConstants::GetNioAccessGetBaseArrayOffsetMethod(e);
+ return e->CallStaticIntMethod(nioAccessClass, getBaseArrayOffsetMethod, nioBuffer);
+}
+
+MODULE_API jlong jniGetNioBufferPointer(C_JNIEnv* env, jobject nioBuffer) {
+ JNIEnv* e = reinterpret_cast<JNIEnv*>(env);
+ jlong baseAddress = e->GetLongField(nioBuffer, JniConstants::GetNioBufferAddressField(e));
+ if (baseAddress != 0) {
+ const int position = e->GetIntField(nioBuffer, JniConstants::GetNioBufferPositionField(e));
+ const int shift =
+ e->GetIntField(nioBuffer, JniConstants::GetNioBufferElementSizeShiftField(e));
+ baseAddress += position << shift;
+ }
+ return baseAddress;
+}
+
+MODULE_API jlong jniGetNioBufferFields(C_JNIEnv* env, jobject nioBuffer,
+ jint* position, jint* limit, jint* elementSizeShift) {
+ JNIEnv* e = reinterpret_cast<JNIEnv*>(env);
+ *position = e->GetIntField(nioBuffer, JniConstants::GetNioBufferPositionField(e));
+ *limit = e->GetIntField(nioBuffer, JniConstants::GetNioBufferLimitField(e));
+ *elementSizeShift =
+ e->GetIntField(nioBuffer, JniConstants::GetNioBufferElementSizeShiftField(e));
+ return e->GetLongField(nioBuffer, JniConstants::GetNioBufferAddressField(e));
+}
+
MODULE_API jobject jniGetReferent(C_JNIEnv* env, jobject ref) {
JNIEnv* e = reinterpret_cast<JNIEnv*>(env);
return e->CallObjectMethod(ref, JniConstants::GetReferenceGetMethod(e));
diff --git a/JniConstants.cpp b/JniConstants.cpp
index 3a0de9d..6d6ce79 100644
--- a/JniConstants.cpp
+++ b/JniConstants.cpp
@@ -42,6 +42,8 @@ std::atomic<bool> g_class_refs_initialized(false);
// retrieve one of these classes.
jclass g_file_descriptor_class = nullptr; // java.io.FileDescriptor
+jclass g_nio_access_class = nullptr; // java.nio.Access
+jclass g_nio_buffer_class = nullptr; // java.nio.Buffer
jclass g_reference_class = nullptr; // java.lang.ref.Reference
jclass g_string_class = nullptr; // java.lang.String
@@ -70,6 +72,14 @@ jclass g_string_class = nullptr; // java.lang.String
jfieldID g_file_descriptor_descriptor_field = nullptr; // java.io.FileDescriptor.descriptor
jfieldID g_file_descriptor_owner_id_field = nullptr; // java.io.FileDescriptor.ownerId
jmethodID g_file_descriptor_init_method = nullptr; // void java.io.FileDescriptor.<init>()
+jmethodID g_nio_access_get_base_array_method = nullptr; // Object java.nio.NIOAccess.getBaseArray()
+jmethodID g_nio_access_get_base_array_offset_method = nullptr; // Object java.nio.NIOAccess.getBaseArray()
+jfieldID g_nio_buffer_address_field = nullptr; // long java.nio.Buffer.address
+jfieldID g_nio_buffer_element_size_shift_field = nullptr; // int java.nio.Buffer._elementSizeShift
+jfieldID g_nio_buffer_limit_field = nullptr; // int java.nio.Buffer.limit
+jfieldID g_nio_buffer_position_field = nullptr; // int java.nio.Buffer.position
+jmethodID g_nio_buffer_array_method = nullptr; // Object java.nio.Buffer.array()
+jmethodID g_nio_buffer_array_offset_method = nullptr; // int java.nio.Buffer.arrayOffset()
jmethodID g_reference_get_method = nullptr; // Object java.lang.ref.Reference.get()
jclass FindClass(JNIEnv* env, const char* name) {
@@ -90,16 +100,32 @@ jmethodID FindMethod(JNIEnv* env, jclass klass, const char* name, const char* si
return result;
}
+jmethodID FindStaticMethod(JNIEnv* env, jclass klass, const char* name, const char* signature) {
+ jmethodID result = env->GetStaticMethodID(klass, name, signature);
+ ALOG_ALWAYS_FATAL_IF(result == nullptr, "failed to find static method '%s%s'", name, signature);
+ return result;
+}
+
} // namespace
-jclass JniConstants::GetReferenceClass(JNIEnv* env) {
+jclass JniConstants::GetFileDescriptorClass(JNIEnv* env) {
EnsureClassReferencesInitialized(env);
- return g_reference_class;
+ return g_file_descriptor_class;
}
-jclass JniConstants::GetFileDescriptorClass(JNIEnv* env) {
+jclass JniConstants::GetNioAccessClass(JNIEnv* env) {
EnsureClassReferencesInitialized(env);
- return g_file_descriptor_class;
+ return g_nio_access_class;
+}
+
+jclass JniConstants::GetNioBufferClass(JNIEnv* env) {
+ EnsureClassReferencesInitialized(env);
+ return g_nio_buffer_class;
+}
+
+jclass JniConstants::GetReferenceClass(JNIEnv* env) {
+ EnsureClassReferencesInitialized(env);
+ return g_reference_class;
}
jclass JniConstants::GetStringClass(JNIEnv* env) {
@@ -131,6 +157,73 @@ jmethodID JniConstants::GetFileDescriptorInitMethod(JNIEnv* env) {
return g_file_descriptor_init_method;
}
+jmethodID JniConstants::GetNioAccessGetBaseArrayMethod(JNIEnv* env) {
+ if (g_nio_access_get_base_array_method == nullptr) {
+ jclass klass = GetNioAccessClass(env);
+ g_nio_access_get_base_array_method =
+ FindStaticMethod(env, klass, "getBaseArray",
+ "(Ljava/nio/Buffer;)Ljava/lang/Object;");
+ }
+ return g_nio_access_get_base_array_method;
+}
+
+jmethodID JniConstants::GetNioAccessGetBaseArrayOffsetMethod(JNIEnv* env) {
+ if (g_nio_access_get_base_array_offset_method == nullptr) {
+ jclass klass = GetNioAccessClass(env);
+ g_nio_access_get_base_array_offset_method =
+ FindStaticMethod(env, klass, "getBaseArrayOffset", "(Ljava/nio/Buffer;)I");
+ }
+ return g_nio_access_get_base_array_offset_method;
+}
+
+jfieldID JniConstants::GetNioBufferAddressField(JNIEnv* env) {
+ if (g_nio_buffer_address_field == nullptr) {
+ jclass klass = GetNioBufferClass(env);
+ g_nio_buffer_address_field = FindField(env, klass, "address", "J");
+ }
+ return g_nio_buffer_address_field;
+}
+
+jfieldID JniConstants::GetNioBufferElementSizeShiftField(JNIEnv* env) {
+ if (g_nio_buffer_element_size_shift_field == nullptr) {
+ jclass klass = GetNioBufferClass(env);
+ g_nio_buffer_element_size_shift_field = FindField(env, klass, "_elementSizeShift", "I");
+ }
+ return g_nio_buffer_element_size_shift_field;
+}
+
+jfieldID JniConstants::GetNioBufferLimitField(JNIEnv* env) {
+ if (g_nio_buffer_limit_field == nullptr) {
+ jclass klass = GetNioBufferClass(env);
+ g_nio_buffer_limit_field = FindField(env, klass, "limit", "I");
+ }
+ return g_nio_buffer_limit_field;
+}
+
+jfieldID JniConstants::GetNioBufferPositionField(JNIEnv* env) {
+ if (g_nio_buffer_position_field == nullptr) {
+ jclass klass = GetNioBufferClass(env);
+ g_nio_buffer_position_field = FindField(env, klass, "position", "I");
+ }
+ return g_nio_buffer_position_field;
+}
+
+jmethodID JniConstants::GetNioBufferArrayMethod(JNIEnv* env) {
+ if (g_nio_buffer_array_method == nullptr) {
+ jclass klass = GetNioBufferClass(env);
+ g_nio_buffer_array_method = FindMethod(env, klass, "array", "()Ljava/lang/Object;");
+ }
+ return g_nio_buffer_array_method;
+}
+
+jmethodID JniConstants::GetNioBufferArrayOffsetMethod(JNIEnv* env) {
+ if (g_nio_buffer_array_offset_method == nullptr) {
+ jclass klass = GetNioBufferClass(env);
+ g_nio_buffer_array_offset_method = FindMethod(env, klass, "arrayOffset", "()I");
+ }
+ return g_nio_buffer_array_offset_method;
+}
+
jmethodID JniConstants::GetReferenceGetMethod(JNIEnv* env) {
if (g_reference_get_method == nullptr) {
jclass klass = GetReferenceClass(env);
@@ -156,6 +249,8 @@ void JniConstants::EnsureClassReferencesInitialized(JNIEnv* env) {
// are not references and races only have trivial performance
// consequences.
g_file_descriptor_class = FindClass(env, "java/io/FileDescriptor");
+ g_nio_access_class = FindClass(env, "java/nio/NIOAccess");
+ g_nio_buffer_class = FindClass(env, "java/nio/Buffer");
g_reference_class = FindClass(env, "java/lang/ref/Reference");
g_string_class = FindClass(env, "java/lang/String");
g_class_refs_initialized.store(true, std::memory_order_release);
@@ -175,6 +270,16 @@ void JniConstants::Uninitialize() {
g_file_descriptor_descriptor_field = nullptr;
g_file_descriptor_owner_id_field = nullptr;
g_file_descriptor_init_method = nullptr;
+ g_nio_access_class = nullptr;
+ g_nio_access_get_base_array_method = nullptr;
+ g_nio_access_get_base_array_offset_method = nullptr;
+ g_nio_buffer_class = nullptr;
+ g_nio_buffer_address_field = nullptr;
+ g_nio_buffer_element_size_shift_field = nullptr;
+ g_nio_buffer_limit_field = nullptr;
+ g_nio_buffer_position_field = nullptr;
+ g_nio_buffer_array_method = nullptr;
+ g_nio_buffer_array_offset_method = nullptr;
g_reference_class = nullptr;
g_reference_get_method = nullptr;
g_string_class = nullptr;
diff --git a/JniConstants.h b/JniConstants.h
index 617cf43..b2d03be 100644
--- a/JniConstants.h
+++ b/JniConstants.h
@@ -31,6 +31,36 @@ struct JniConstants {
// void java.io.FileDescriptor.<init>().
static jmethodID GetFileDescriptorInitMethod(JNIEnv* env);
+ // Global reference to java.nio.NIOAccess.
+ static jclass GetNioAccessClass(JNIEnv* env);
+
+ // Object java.nio.NIOAccess.getBaseArray(Buffer);
+ static jmethodID GetNioAccessGetBaseArrayMethod(JNIEnv* env);
+
+ // int java.nio.NIOAccess.getBaseArrayOffset(Buffer);
+ static jmethodID GetNioAccessGetBaseArrayOffsetMethod(JNIEnv* env);
+
+ // Global reference to java.nio.Buffer.
+ static jclass GetNioBufferClass(JNIEnv* env);
+
+ // long java.nio.Buffer.address
+ static jfieldID GetNioBufferAddressField(JNIEnv* env);
+
+ // int java.nio.Buffer._elementSizeShift
+ static jfieldID GetNioBufferElementSizeShiftField(JNIEnv* env);
+
+ // int java.nio.Buffer.limit;
+ static jfieldID GetNioBufferLimitField(JNIEnv* env);
+
+ // int java.nio.Buffer.position;
+ static jfieldID GetNioBufferPositionField(JNIEnv* env);
+
+ // Object java.nio.Buffer.array()
+ static jmethodID GetNioBufferArrayMethod(JNIEnv* env);
+
+ // int java.nio.Buffer.arrayOffset()
+ static jmethodID GetNioBufferArrayOffsetMethod(JNIEnv* env);
+
// Global reference to java.lang.ref.Reference.
static jclass GetReferenceClass(JNIEnv* env);
diff --git a/include/nativehelper/JNIHelp.h b/include/nativehelper/JNIHelp.h
index 3076678..bab5dd5 100644
--- a/include/nativehelper/JNIHelp.h
+++ b/include/nativehelper/JNIHelp.h
@@ -122,6 +122,48 @@ MODULE_API void jniSetFileDescriptorOfFD(C_JNIEnv* env,
MODULE_API jlong jniGetOwnerIdFromFileDescriptor(C_JNIEnv* env, jobject fileDescriptor);
/*
+ * Gets the managed heap array backing a java.nio.Buffer instance.
+ *
+ * Returns nullptr if there is no array backing.
+ *
+ * This method performs a JNI call to java.nio.NIOAccess.getBaseArray().
+ */
+MODULE_API jarray jniGetNioBufferBaseArray(C_JNIEnv* env, jobject nioBuffer);
+
+/*
+ * Gets the offset in bytes from the start of the managed heap array backing the buffer.
+ *
+ * Returns 0 if there is no array backing.
+ *
+ * This method performs a JNI call to java.nio.NIOAccess.getBaseArrayOffset().
+ */
+MODULE_API jint jniGetNioBufferBaseArrayOffset(C_JNIEnv* env, jobject nioBuffer);
+
+/*
+ * Gets field information from a java.nio.Buffer instance.
+ *
+ * Reads the |position|, |limit|, and |elementSizeShift| fields from the buffer instance.
+ *
+ * Returns the |address| field of the java.nio.Buffer instance which is only valid (non-zero) when
+ * the buffer is backed by a direct buffer.
+ */
+MODULE_API jlong jniGetNioBufferFields(C_JNIEnv* env,
+ jobject nioBuffer,
+ /*out*/jint* position,
+ /*out*/jint* limit,
+ /*out*/jint* elementSizeShift);
+
+/*
+ * Gets the current position from a java.nio.Buffer as a pointer to memory in a fixed buffer.
+ *
+ * Returns 0 if |nioBuffer| is not backed by a direct buffer.
+ *
+ * This method reads the |address|, |position|, and |elementSizeShift| fields from the
+ * java.nio.Buffer instance to calculate the pointer address for the current position.
+ */
+MODULE_API jlong jniGetNioBufferPointer(C_JNIEnv* env, jobject nioBuffer);
+
+/*
* Returns the reference from a java.lang.ref.Reference.
*/
MODULE_API jobject jniGetReferent(C_JNIEnv* env, jobject ref);
@@ -196,6 +238,24 @@ inline jlong jniGetOwnerIdFromFileDescriptor(JNIEnv* env, jobject fileDescriptor
return jniGetOwnerIdFromFileDescriptor(&env->functions, fileDescriptor);
}
+inline jarray jniGetNioBufferBaseArray(JNIEnv* env, jobject nioBuffer) {
+ return jniGetNioBufferBaseArray(&env->functions, nioBuffer);
+}
+
+inline jint jniGetNioBufferBaseArrayOffset(JNIEnv* env, jobject nioBuffer) {
+ return jniGetNioBufferBaseArrayOffset(&env->functions, nioBuffer);
+}
+
+inline jlong jniGetNioBufferFields(JNIEnv* env, jobject nioBuffer,
+ jint* position, jint* limit, jint* elementSizeShift) {
+ return jniGetNioBufferFields(&env->functions, nioBuffer,
+ position, limit, elementSizeShift);
+}
+
+inline jlong jniGetNioBufferPointer(JNIEnv* env, jobject nioBuffer) {
+ return jniGetNioBufferPointer(&env->functions, nioBuffer);
+}
+
inline jobject jniGetReferent(JNIEnv* env, jobject ref) {
return jniGetReferent(&env->functions, ref);
}
diff --git a/libnativehelper.map.txt b/libnativehelper.map.txt
index 81579a5..62c980d 100644
--- a/libnativehelper.map.txt
+++ b/libnativehelper.map.txt
@@ -18,6 +18,10 @@ LIBNATIVEHELPER_1 {
jniGetFDFromFileDescriptor;
jniSetFileDescriptorOfFD;
jniGetOwnerIdFromFileDescriptor;
+ jniGetNioBufferBaseArray;
+ jniGetNioBufferBaseArrayOffset;
+ jniGetNioBufferPointer;
+ jniGetNioBufferFields;
jniGetReferent;
jniCreateString;
jniLogException;