Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 9188b4bb authored by Hiroshi Yamauchi's avatar Hiroshi Yamauchi Committed by Gerrit Code Review
Browse files

Merge "Replace JNI primitive array critical calls with non-critical ones."

parents f984bad9 569bc1bc
Loading
Loading
Loading
Loading
+78 −0
Original line number Diff line number Diff line
@@ -191,6 +191,84 @@ public class JType {
        (baseType.indexOf("Buffer") != -1);
    }

    public JType getArrayTypeForTypedBuffer() {
      if (!isTypedBuffer()) {
          throw new RuntimeException("Not typed buffer type " + this);
      }
      switch (baseType) {
        case "java.nio.ByteBuffer":
          return new JType("byte", false, true);
        case "java.nio.BooleanBuffer":
          return new JType("boolean", false, true);
        case "java.nio.ShortBuffer":
          return new JType("short", false, true);
        case "java.nio.CharBuffer":
          return new JType("char", false, true);
        case "java.nio.IntBuffer":
          return new JType("int", false, true);
        case "java.nio.LongBuffer":
          return new JType("long", false, true);
        case "java.nio.FloatBuffer":
          return new JType("float", false, true);
        case "java.nio.DoubleBuffer":
          return new JType("double", false, true);
        default:
          throw new RuntimeException("Unknown typed buffer type " + this);
      }
    }

    public String getArrayGetterForPrimitiveArray() {
      if (!isArray() || isClass()) {
          throw new RuntimeException("Not array type " + this);
      }
      switch (baseType) {
        case "byte":
          return "GetByteArrayElements";
        case "boolean":
          return "GetBooleanArrayElements";
        case "short":
          return "GetShortArrayElements";
        case "char":
          return "GetCharArrayElements";
        case "int":
          return "GetIntArrayElements";
        case "long":
          return "GetLongArrayElements";
        case "float":
          return "GetFloatArrayElements";
        case "double":
          return "GetDoubleArrayElements";
        default:
          throw new RuntimeException("Unknown array type " + this);
      }
    }

    public String getArrayReleaserForPrimitiveArray() {
      if (!isArray() || isClass()) {
          throw new RuntimeException("Not array type " + this);
      }
      switch (baseType) {
        case "byte":
          return "ReleaseByteArrayElements";
        case "boolean":
          return "ReleaseBooleanArrayElements";
        case "short":
          return "ReleaseShortArrayElements";
        case "char":
          return "ReleaseCharArrayElements";
        case "int":
          return "ReleaseIntArrayElements";
        case "long":
          return "ReleaseLongArrayElements";
        case "float":
          return "ReleaseFloatArrayElements";
        case "double":
          return "ReleaseDoubleArrayElements";
        default:
          throw new RuntimeException("Unknown array type " + this);
      }
    }

    public boolean isEGLHandle() {
    return !isPrimitive() &&
        (baseType.startsWith("EGL"));
+58 −18
Original line number Diff line number Diff line
@@ -812,6 +812,7 @@ public class JniCodeEmitter {
        List<Integer> stringArgs = new ArrayList<Integer>();
        int numBufferArgs = 0;
        List<String> bufferArgNames = new ArrayList<String>();
        List<JType> bufferArgTypes = new ArrayList<JType>();

        // Emit JNI signature (arguments)
        //
@@ -835,6 +836,7 @@ public class JniCodeEmitter {
                    int cIndex = jfunc.getArgCIndex(i);
                    String cname = cfunc.getArgName(cIndex);
                    bufferArgNames.add(cname);
                    bufferArgTypes.add(jfunc.getArgType(i));
                    numBufferArgs++;
                }
            }
@@ -948,12 +950,25 @@ public class JniCodeEmitter {

        // Emit a single _array or multiple _XXXArray variables
        if (numBufferArgs == 1) {
            JType bufferType = bufferArgTypes.get(0);
            if (bufferType.isTypedBuffer()) {
                String typedArrayType = getJniType(bufferType.getArrayTypeForTypedBuffer());
                out.println(indent + typedArrayType + " _array = (" + typedArrayType + ") 0;");
            } else {
                out.println(indent + "jarray _array = (jarray) 0;");
            }
            out.println(indent + "jint _bufferOffset = (jint) 0;");
        } else {
            for (int i = 0; i < numBufferArgs; i++) {
                JType bufferType = bufferArgTypes.get(0);
                if (bufferType.isTypedBuffer()) {
                    String typedArrayType = getJniType(bufferType.getArrayTypeForTypedBuffer());
                    out.println(indent + typedArrayType + " _" + bufferArgNames.get(i) +
                                "Array = (" + typedArrayType + ") 0;");
                } else {
                    out.println(indent + "jarray _" + bufferArgNames.get(i) +
                                "Array = (jarray) 0;");
                }
                out.println(indent + "jint _" + bufferArgNames.get(i) +
                            "BufferOffset = (jint) 0;");
            }
@@ -1135,9 +1150,10 @@ public class JniCodeEmitter {
                                "_base = (" +
                                cfunc.getArgType(cIndex).getDeclaration() +
                                ")");
                    String arrayGetter = jfunc.getArgType(idx).getArrayGetterForPrimitiveArray();
                    out.println(indent + "    " +
                                (mUseCPlusPlus ? "_env" : "(*_env)") +
                                "->GetPrimitiveArrayCritical(" +
                                "->" + arrayGetter + "(" +
                                (mUseCPlusPlus ? "" : "_env, ") +
                                jfunc.getArgName(idx) +
                                "_ref, (jboolean *)0);");
@@ -1209,7 +1225,7 @@ public class JniCodeEmitter {
                                    cfunc.getArgType(cIndex).getDeclaration() +
                                    ")getPointer(_env, " +
                                    cname +
                                    "_buf, &" + array + ", &" + remaining + ", &" + bufferOffset +
                                    "_buf, (jarray*)&" + array + ", &" + remaining + ", &" + bufferOffset +
                                    ");");
                    }

@@ -1244,11 +1260,19 @@ public class JniCodeEmitter {
                } else {
                    out.println(indent + "if (" + cname +" == NULL) {");
                }
                JType argType = jfunc.getArgType(idx);
                if (argType.isTypedBuffer()) {
                    String arrayGetter = argType.getArrayTypeForTypedBuffer().getArrayGetterForPrimitiveArray();
                    out.println(indent + indent + "char * _" + cname + "Base = (char *)_env->" + arrayGetter + "(" + array + ", (jboolean *) 0);");
                    out.println(indent + indent + cname + " = (" +cfunc.getArgType(cIndex).getDeclaration() +") (_" + cname + "Base + " + bufferOffset + ");");
                    out.println(indent + "}");
                } else {
                    out.println(indent + indent + "char * _" + cname + "Base = (char *)_env->GetPrimitiveArrayCritical(" + array + ", (jboolean *) 0);");
                    out.println(indent + indent + cname + " = (" +cfunc.getArgType(cIndex).getDeclaration() +") (_" + cname + "Base + " + bufferOffset + ");");
                    out.println(indent + "}");
                }
             }
        }


        if (!isVoid) {
@@ -1336,12 +1360,13 @@ public class JniCodeEmitter {
                    // the need to write back to the Java array
                    out.println(indent +
                                "if (" + jfunc.getArgName(idx) + "_base) {");
                    String arrayReleaser = jfunc.getArgType(idx).getArrayReleaserForPrimitiveArray();
                    out.println(indent + indent +
                                (mUseCPlusPlus ? "_env" : "(*_env)") +
                                "->ReleasePrimitiveArrayCritical(" +
                                "->" + arrayReleaser + "(" +
                                (mUseCPlusPlus ? "" : "_env, ") +
                                jfunc.getArgName(idx) + "_ref, " +
                                cfunc.getArgName(cIndex) +
                                "(j" + jfunc.getArgType(idx).getBaseType() + "*)" + cfunc.getArgName(cIndex) +
                                "_base,");
                    out.println(indent + indent + indent +
                                (cfunc.getArgType(cIndex).isConst() ?
@@ -1350,9 +1375,23 @@ public class JniCodeEmitter {
                    out.println(indent + "}");
                } else if (jfunc.getArgType(idx).isBuffer()) {
                    if (! isPointerFunc) {
                        JType argType = jfunc.getArgType(idx);
                        String array = numBufferArgs <= 1 ? "_array" :
                            "_" + cfunc.getArgName(cIndex) + "Array";
                        out.println(indent + "if (" + array + ") {");
                        if (argType.isTypedBuffer()) {
                            String arrayReleaser =
                                argType.getArrayTypeForTypedBuffer().getArrayReleaserForPrimitiveArray();
                            out.println(indent + indent +
                                "_env->" + arrayReleaser + "(" + array + ", " +
                                "(j" + argType.getArrayTypeForTypedBuffer().getBaseType() + "*)" +
                                cfunc.getArgName(cIndex) +
                                ", " +
                                (cfunc.getArgType(cIndex).isConst() ?
                                    "JNI_ABORT" : (emitExceptionCheck ?
                                        "_exception ? JNI_ABORT : 0" : "0")) +
                                ");");
                        } else {
                            out.println(indent + indent +
                                "releasePointer(_env, " + array + ", " +
                                cfunc.getArgName(cIndex) +
@@ -1361,6 +1400,7 @@ public class JniCodeEmitter {
                                    "JNI_FALSE" : (emitExceptionCheck ?
                                        "_exception ? JNI_FALSE : JNI_TRUE" : "JNI_TRUE")) +
                                ");");
                        }
                        out.println(indent + "}");
                    }
                }
+2 −3
Original line number Diff line number Diff line
@@ -27,7 +27,7 @@ android_eglCreatePbufferFromClientBuffer
    }
    _remaining = _env->GetArrayLength(attrib_list_ref) - offset;
    attrib_list_base = (EGLint *)
        _env->GetPrimitiveArrayCritical(attrib_list_ref, (jboolean *)0);
        _env->GetIntArrayElements(attrib_list_ref, (jboolean *)0);
    attrib_list = attrib_list_base + offset;
    attrib_list_sentinel = false;
    for (int i = _remaining - 1; i >= 0; i--)  {
@@ -53,7 +53,7 @@ android_eglCreatePbufferFromClientBuffer

exit:
    if (attrib_list_base) {
        _env->ReleasePrimitiveArrayCritical(attrib_list_ref, attrib_list_base,
        _env->ReleaseIntArrayElements(attrib_list_ref, attrib_list_base,
            JNI_ABORT);
    }
    if (_exception) {
@@ -71,4 +71,3 @@ android_eglCreatePbufferFromClientBufferInt
    }
    return android_eglCreatePbufferFromClientBuffer(_env, _this, dpy, buftype, buffer, config, attrib_list_ref, offset);
}
+4 −4
Original line number Diff line number Diff line
@@ -41,7 +41,7 @@ not_valid_surface:

    _remaining = _env->GetArrayLength(attrib_list_ref) - offset;
    attrib_list_base = (EGLint *)
        _env->GetPrimitiveArrayCritical(attrib_list_ref, (jboolean *)0);
        _env->GetIntArrayElements(attrib_list_ref, (jboolean *)0);
    attrib_list = attrib_list_base + offset;
    attrib_list_sentinel = 0;
    for (int i = _remaining - 1; i >= 0; i--)  {
@@ -66,7 +66,7 @@ not_valid_surface:

exit:
    if (attrib_list_base) {
        _env->ReleasePrimitiveArrayCritical(attrib_list_ref, attrib_list_base,
        _env->ReleaseIntArrayElements(attrib_list_ref, attrib_list_base,
            JNI_ABORT);
    }
    if (_exception) {
@@ -123,7 +123,7 @@ not_valid_surface:

    _remaining = _env->GetArrayLength(attrib_list_ref) - offset;
    attrib_list_base = (EGLint *)
        _env->GetPrimitiveArrayCritical(attrib_list_ref, (jboolean *)0);
        _env->GetIntArrayElements(attrib_list_ref, (jboolean *)0);
    attrib_list = attrib_list_base + offset;
    attrib_list_sentinel = 0;
    for (int i = _remaining - 1; i >= 0; i--)  {
@@ -148,7 +148,7 @@ not_valid_surface:

exit:
    if (attrib_list_base) {
        _env->ReleasePrimitiveArrayCritical(attrib_list_ref, attrib_list_base,
        _env->ReleaseIntArrayElements(attrib_list_ref, attrib_list_base,
            JNI_ABORT);
    }
    if (_exception) {
+124 −10
Original line number Diff line number Diff line
@@ -100,6 +100,116 @@ getPointer(JNIEnv *_env, jobject buffer, jarray *array, jint *remaining, jint *o
    return NULL;
}

class ByteArrayGetter {
public:
    static void* Get(JNIEnv* _env, jbyteArray array, jboolean* is_copy) {
        return _env->GetByteArrayElements(array, is_copy);
    }
};
class BooleanArrayGetter {
public:
    static void* Get(JNIEnv* _env, jbooleanArray array, jboolean* is_copy) {
        return _env->GetBooleanArrayElements(array, is_copy);
    }
};
class CharArrayGetter {
public:
    static void* Get(JNIEnv* _env, jcharArray array, jboolean* is_copy) {
        return _env->GetCharArrayElements(array, is_copy);
    }
};
class ShortArrayGetter {
public:
    static void* Get(JNIEnv* _env, jshortArray array, jboolean* is_copy) {
        return _env->GetShortArrayElements(array, is_copy);
    }
};
class IntArrayGetter {
public:
    static void* Get(JNIEnv* _env, jintArray array, jboolean* is_copy) {
        return _env->GetIntArrayElements(array, is_copy);
    }
};
class LongArrayGetter {
public:
    static void* Get(JNIEnv* _env, jlongArray array, jboolean* is_copy) {
        return _env->GetLongArrayElements(array, is_copy);
    }
};
class FloatArrayGetter {
public:
    static void* Get(JNIEnv* _env, jfloatArray array, jboolean* is_copy) {
        return _env->GetFloatArrayElements(array, is_copy);
    }
};
class DoubleArrayGetter {
public:
    static void* Get(JNIEnv* _env, jdoubleArray array, jboolean* is_copy) {
        return _env->GetDoubleArrayElements(array, is_copy);
    }
};

template<typename JTYPEARRAY, typename ARRAYGETTER>
static void*
getArrayPointer(JNIEnv *_env, JTYPEARRAY array, jboolean* is_copy) {
    return ARRAYGETTER::Get(_env, array, is_copy);
}

class ByteArrayReleaser {
public:
    static void Release(JNIEnv* _env, jbyteArray array, jbyte* data, jboolean commit) {
        _env->ReleaseByteArrayElements(array, data, commit ? 0 : JNI_ABORT);
    }
};
class BooleanArrayReleaser {
public:
    static void Release(JNIEnv* _env, jbooleanArray array, jboolean* data, jboolean commit) {
        _env->ReleaseBooleanArrayElements(array, data, commit ? 0 : JNI_ABORT);
    }
};
class CharArrayReleaser {
public:
    static void Release(JNIEnv* _env, jcharArray array, jchar* data, jboolean commit) {
        _env->ReleaseCharArrayElements(array, data, commit ? 0 : JNI_ABORT);
    }
};
class ShortArrayReleaser {
public:
    static void Release(JNIEnv* _env, jshortArray array, jshort* data, jboolean commit) {
        _env->ReleaseShortArrayElements(array, data, commit ? 0 : JNI_ABORT);
    }
};
class IntArrayReleaser {
public:
    static void Release(JNIEnv* _env, jintArray array, jint* data, jboolean commit) {
        _env->ReleaseIntArrayElements(array, data, commit ? 0 : JNI_ABORT);
    }
};
class LongArrayReleaser {
public:
    static void Release(JNIEnv* _env, jlongArray array, jlong* data, jboolean commit) {
        _env->ReleaseLongArrayElements(array, data, commit ? 0 : JNI_ABORT);
    }
};
class FloatArrayReleaser {
public:
    static void Release(JNIEnv* _env, jfloatArray array, jfloat* data, jboolean commit) {
        _env->ReleaseFloatArrayElements(array, data, commit ? 0 : JNI_ABORT);
    }
};
class DoubleArrayReleaser {
public:
    static void Release(JNIEnv* _env, jdoubleArray array, jdouble* data, jboolean commit) {
        _env->ReleaseDoubleArrayElements(array, data, commit ? 0 : JNI_ABORT);
    }
};

template<typename JTYPEARRAY, typename NTYPEARRAY, typename ARRAYRELEASER>
static void
releaseArrayPointer(JNIEnv *_env, JTYPEARRAY array, NTYPEARRAY data, jboolean commit) {
    ARRAYRELEASER::Release(_env, array, data, commit);
}

static void
releasePointer(JNIEnv *_env, jarray array, void *data, jboolean commit)
{
@@ -203,7 +313,8 @@ static int getNeededCount(GLint pname) {
    return needed;
}

template <typename JTYPEARRAY, typename CTYPE, void GET(GLenum, CTYPE*)>
template <typename JTYPEARRAY, typename ARRAYGETTER, typename NTYPEARRAY,
          typename ARRAYRELEASER, typename CTYPE, void GET(GLenum, CTYPE*)>
static void
get
  (JNIEnv *_env, jobject _this, jint pname, JTYPEARRAY params_ref, jint offset) {
@@ -238,8 +349,8 @@ get
        _exceptionMessage = "length - offset < needed";
        goto exit;
    }
    params_base = (CTYPE *)
        _env->GetPrimitiveArrayCritical(params_ref, (jboolean *)0);
    params_base = (CTYPE *) getArrayPointer<JTYPEARRAY, ARRAYGETTER>(
        _env, params_ref, (jboolean *)0);
    params = params_base + offset;

    GET(
@@ -249,8 +360,8 @@ get

exit:
    if (params_base) {
        _env->ReleasePrimitiveArrayCritical(params_ref, params_base,
            _exception ? JNI_ABORT: 0);
        releaseArrayPointer<JTYPEARRAY, NTYPEARRAY, ARRAYRELEASER>(
            _env, params_ref, params_base, !_exception);
    }
    if (_exception) {
        jniThrowException(_env, _exceptionType, _exceptionMessage);
@@ -258,20 +369,21 @@ exit:
}


template <typename CTYPE, void GET(GLenum, CTYPE*)>
template <typename CTYPE, typename JTYPEARRAY, typename ARRAYGETTER, typename NTYPEARRAY,
          typename ARRAYRELEASER, void GET(GLenum, CTYPE*)>
static void
getarray
  (JNIEnv *_env, jobject _this, jint pname, jobject params_buf) {
    jint _exception = 0;
    const char * _exceptionType;
    const char * _exceptionMessage;
    jarray _array = (jarray) 0;
    JTYPEARRAY _array = (JTYPEARRAY) 0;
    jint _bufferOffset = (jint) 0;
    jint _remaining;
    CTYPE *params = (CTYPE *) 0;
    int _needed = 0;

    params = (CTYPE *)getPointer(_env, params_buf, &_array, &_remaining, &_bufferOffset);
    params = (CTYPE *)getPointer(_env, params_buf, (jarray*)&_array, &_remaining, &_bufferOffset);
    _remaining /= sizeof(CTYPE);    // convert from bytes to item count
    _needed = getNeededCount(pname);
    // if we didn't find this pname, we just assume the user passed
@@ -284,7 +396,8 @@ getarray
        goto exit;
    }
    if (params == NULL) {
        char * _paramsBase = (char *)_env->GetPrimitiveArrayCritical(_array, (jboolean *) 0);
        char * _paramsBase = (char *) getArrayPointer<JTYPEARRAY, ARRAYGETTER>(
            _env, _array, (jboolean *) 0);
        params = (CTYPE *) (_paramsBase + _bufferOffset);
    }
    GET(
@@ -294,7 +407,8 @@ getarray

exit:
    if (_array) {
        releasePointer(_env, _array, params, _exception ? JNI_FALSE : JNI_TRUE);
        releaseArrayPointer<JTYPEARRAY, NTYPEARRAY, ARRAYRELEASER>(
            _env, _array, (NTYPEARRAY)params, _exception ? JNI_FALSE : JNI_TRUE);
    }
    if (_exception) {
        jniThrowException(_env, _exceptionType, _exceptionMessage);
Loading