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

Commit 6f48c7f3 authored by Hiroshi Yamauchi's avatar Hiroshi Yamauchi Committed by Android (Google) Code Review
Browse files

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

parents 4866f087 4e7de461
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