JNI: optimize out CallIntMethod/CallBooleanMethod() calls from WolfSSLSession.read(ByteBuffer), improves performance

pull/262/head
Chris Conlon 2025-05-01 15:04:25 -06:00
parent 6f880d8d85
commit 3368a5eb47
3 changed files with 20 additions and 30 deletions

View File

@ -1361,18 +1361,15 @@ JNIEXPORT jint JNICALL Java_com_wolfssl_WolfSSLSession_read__J_3BIII
return size;
}
JNIEXPORT jint JNICALL Java_com_wolfssl_WolfSSLSession_read__JLjava_nio_ByteBuffer_2II
(JNIEnv* jenv, jobject jcl, jlong sslPtr, jobject buf, jint length, jint timeout)
JNIEXPORT jint JNICALL Java_com_wolfssl_WolfSSLSession_read__JLjava_nio_ByteBuffer_2IIZII
(JNIEnv* jenv, jobject jcl, jlong sslPtr, jobject buf, jint position,
jint limit, jboolean hasArray, jint length, jint timeout)
{
int size = 0;
int maxOutputSz;
int outSz = length;
byte* data = NULL;
WOLFSSL* ssl = (WOLFSSL*)(uintptr_t)sslPtr;
jint position;
jint limit;
jboolean hasArray;
jbyteArray bufArr = NULL;
(void)jcl;
@ -1382,17 +1379,6 @@ JNIEXPORT jint JNICALL Java_com_wolfssl_WolfSSLSession_read__JLjava_nio_ByteBuff
}
if (length > 0) {
/* Get ByteBuffer position */
position = (*jenv)->CallIntMethod(jenv, buf, g_bufferPositionMethodId);
if ((*jenv)->ExceptionCheck(jenv)) {
return SSL_FAILURE;
}
/* Get ByteBuffer limit */
limit = (*jenv)->CallIntMethod(jenv, buf, g_bufferLimitMethodId);
if ((*jenv)->ExceptionCheck(jenv)) {
return SSL_FAILURE;
}
/* Only read up to maximum space we have in this ByteBuffer */
maxOutputSz = (limit - position);
@ -1404,13 +1390,6 @@ JNIEXPORT jint JNICALL Java_com_wolfssl_WolfSSLSession_read__JLjava_nio_ByteBuff
return BAD_FUNC_ARG;
}
/* Get and call ByteBuffer.hasArray() before calling array() */
hasArray = (*jenv)->CallBooleanMethod(jenv, buf,
g_bufferHasArrayMethodId);
if ((*jenv)->ExceptionCheck(jenv)) {
return SSL_FAILURE;
}
if (hasArray) {
/* Get reference to underlying byte[] from ByteBuffer */
bufArr = (jbyteArray)(*jenv)->CallObjectMethod(jenv, buf,
@ -1460,7 +1439,9 @@ JNIEXPORT jint JNICALL Java_com_wolfssl_WolfSSLSession_read__JLjava_nio_ByteBuff
}
}
/* Update ByteBuffer position() based on bytes written, on success */
/* Update ByteBuffer position() based on bytes written, on success.
* This seems to be more performant if we do it from JNI rather
* than back in Java after the return of this method. */
if (size > 0) {
(*jenv)->CallVoidMethod(jenv, buf, g_bufferSetPositionMethodId,
position + size);

View File

@ -106,10 +106,10 @@ JNIEXPORT jint JNICALL Java_com_wolfssl_WolfSSLSession_read__J_3BIII
/*
* Class: com_wolfssl_WolfSSLSession
* Method: read
* Signature: (JLjava/nio/ByteBuffer;II)I
* Signature: (JLjava/nio/ByteBuffer;IIZII)I
*/
JNIEXPORT jint JNICALL Java_com_wolfssl_WolfSSLSession_read__JLjava_nio_ByteBuffer_2II
(JNIEnv *, jobject, jlong, jobject, jint, jint);
JNIEXPORT jint JNICALL Java_com_wolfssl_WolfSSLSession_read__JLjava_nio_ByteBuffer_2IIZII
(JNIEnv *, jobject, jlong, jobject, jint, jint, jboolean, jint, jint);
/*
* Class: com_wolfssl_WolfSSLSession

View File

@ -382,7 +382,8 @@ public class WolfSSLSession {
int timeout);
private native int read(long ssl, byte[] data, int offset, int sz,
int timeout);
private native int read(long ssl, ByteBuffer data, int sz, int timeout)
private native int read(long ssl, ByteBuffer data, final int position,
final int limit, boolean hasArray, int sz, int timeout)
throws WolfSSLException;
private native int pending(long ssl);
private native int accept(long ssl, int timeout);
@ -1323,6 +1324,9 @@ public class WolfSSLSession {
final int err;
final int readSz = sz;
final int readTimeout = timeout;
final int bbPosition;
final int bbLimit;
boolean hasArray;
long localPtr;
confirmObjectIsActive();
@ -1344,7 +1348,12 @@ public class WolfSSLSession {
* could timeout waiting for corresponding write() operation to
* occur if needed */
try {
ret = read(localPtr, data, readSz, readTimeout);
bbPosition = data.position();
bbLimit = data.limit();
hasArray = data.hasArray();
ret = read(localPtr, data, bbPosition, bbLimit, hasArray,
readSz, readTimeout);
err = getError(ret);
} catch (WolfSSLException e) {
/* JNI code may throw WolfSSLException on JNI specific errors */