Omaha #4259 speed up get_jtype, ensure correct jep types are chosen

Change-Id: I11a7c072f8b460d2728cf2a4a018932159c0e1b0

Former-commit-id: c13284d74b6c561cd305cf714722e4904b4ab0bf
This commit is contained in:
Nate Jensen 2015-04-30 11:57:21 -05:00
parent b546751b9d
commit 15b501ce07
3 changed files with 82 additions and 73 deletions

View file

@ -551,18 +551,7 @@ PyObject* pyjmethod_call_internal(PyJmethod_Object *self,
Py_BLOCK_THREADS;
if(!process_java_exception(env) && obj != NULL) {
jclass retClazz;
int type_id = -1;
retClazz = (*env)->GetObjectClass(env, obj);
type_id = get_jtype(env, retClazz);
if(type_id == -1) {
process_java_exception(env);
} else if(type_id == JARRAY_ID){
result = pyjarray_new(env, obj);
} else {
result = pyjobject_new(env, obj);
}
result = pyjobject_new(env, obj);
}
break;

View file

@ -60,6 +60,7 @@
#include "pyjfield.h"
#include "pyjclass.h"
#include "util.h"
#include "pyjarray.h"
#include "pyjmethodwrapper.h"
#include "pyjlist.h"
@ -78,6 +79,8 @@ static PyObject *classnamePyJMethodsDict = NULL;
// called internally to make new PyJobject_Object instances
PyObject* pyjobject_new(JNIEnv *env, jobject obj) {
PyJobject_Object *pyjob;
jclass objClz;
int jtype;
if(PyType_Ready(&PyJobject_Type) < 0)
return NULL;
@ -86,25 +89,42 @@ PyObject* pyjobject_new(JNIEnv *env, jobject obj) {
return NULL;
}
#if USE_NUMPY
objClz = (*env)->GetObjectClass(env, obj);
/*
* check for jep/NDArray and autoconvert to numpy.ndarray instead of
* pyjobject
* There exist situations where a Java method signature has a return
* type of Object but actually returns a Class or array. Also if you
* call Jep.set(String, Object[]) it should be treated as an array, not
* an object. Hence this check here to build the optimal jep type in
* the interpreter regardless of signature.
*/
if(jndarray_check(env, obj)) {
return convert_jndarray_pyndarray(env, obj);
}
if(PyErr_Occurred()) {
return NULL;
}
jtype = get_jtype(env, objClz);
if(jtype == JARRAY_ID) {
return pyjarray_new(env, obj);
} else if(jtype == JCLASS_ID) {
return pyjobject_new_class(env, obj);
} else {
#if USE_NUMPY
/*
* check for jep/NDArray and autoconvert to numpy.ndarray instead of
* pyjobject
*/
if(jndarray_check(env, obj)) {
return convert_jndarray_pyndarray(env, obj);
}
if(PyErr_Occurred()) {
return NULL;
}
#endif
if((*env)->IsInstanceOf(env, obj, JLIST_TYPE)) {
pyjob = (PyJobject_Object*) pyjlist_new();
} else {
pyjob = PyObject_NEW(PyJobject_Object, &PyJobject_Type);
if((*env)->IsInstanceOf(env, obj, JLIST_TYPE)) {
pyjob = (PyJobject_Object*) pyjlist_new();
} else {
pyjob = PyObject_NEW(PyJobject_Object, &PyJobject_Type);
}
}
pyjob->object = (*env)->NewGlobalRef(env, obj);
pyjob->clazz = (*env)->NewGlobalRef(env, (*env)->GetObjectClass(env, obj));
pyjob->pyjclass = NULL;

View file

@ -108,7 +108,6 @@ jclass JEP_NDARRAY_TYPE = NULL;
// cached methodids
jmethodID objectToString = 0;
jmethodID objectEquals = 0;
jmethodID objectIsArray = 0;
// for convert_jobject
@ -1255,16 +1254,6 @@ int get_jtype(JNIEnv *env, jclass clazz) {
jboolean equals = JNI_FALSE;
jboolean array = JNI_FALSE;
// have to find the equals() method.
if(objectEquals == 0) {
objectEquals = (*env)->GetMethodID(env,
JCLASS_TYPE,
"equals",
"(Ljava/lang/Object;)Z");
if((*env)->ExceptionCheck(env) || !objectEquals)
return -1;
}
// have to find Class.isArray() method
if(objectIsArray == 0) {
objectIsArray = (*env)->GetMethodID(env,
@ -1275,92 +1264,103 @@ int get_jtype(JNIEnv *env, jclass clazz) {
return -1;
}
// object checks
if((*env)->IsAssignableFrom(env, clazz, JOBJECT_TYPE)) {
// check for string
equals = (*env)->IsSameObject(env, clazz, JSTRING_TYPE);
if((*env)->ExceptionCheck(env))
return -1;
if(equals)
return JSTRING_ID;
// check if it's an array first
array = (*env)->CallBooleanMethod(env, clazz, objectIsArray);
if((*env)->ExceptionCheck(env))
return -1;
if(array)
return JARRAY_ID;
// check for class
if((*env)->IsAssignableFrom(env, clazz, JCLASS_TYPE))
return JCLASS_ID;
/*
* TODO: contemplate adding List and jep.NDArray check in here
*/
// ok it's not a string, array, or class, so let's call it object
return JOBJECT_ID;
}
/*
* check primitive types
*/
// int
equals = (*env)->CallBooleanMethod(env, clazz, objectEquals, JINT_TYPE);
equals = (*env)->IsSameObject(env, clazz, JINT_TYPE);
if((*env)->ExceptionCheck(env))
return -1;
if(equals)
return JINT_ID;
// short
equals = (*env)->CallBooleanMethod(env, clazz, objectEquals, JSHORT_TYPE);
if((*env)->ExceptionCheck(env))
return -1;
if(equals)
return JSHORT_ID;
// double
equals = (*env)->CallBooleanMethod(env, clazz, objectEquals, JDOUBLE_TYPE);
equals = (*env)->IsSameObject(env, clazz, JDOUBLE_TYPE);
if((*env)->ExceptionCheck(env))
return -1;
if(equals)
return JDOUBLE_ID;
// float
equals = (*env)->CallBooleanMethod(env, clazz, objectEquals, JFLOAT_TYPE);
equals = (*env)->IsSameObject(env, clazz, JFLOAT_TYPE);
if((*env)->ExceptionCheck(env))
return -1;
if(equals)
return JFLOAT_ID;
// boolean
equals = (*env)->CallBooleanMethod(env, clazz, objectEquals, JBOOLEAN_TYPE);
if((*env)->ExceptionCheck(env))
return -1;
if(equals)
return JBOOLEAN_ID;
// long
equals = (*env)->CallBooleanMethod(env, clazz, objectEquals, JLONG_TYPE);
equals = (*env)->IsSameObject(env, clazz, JLONG_TYPE);
if((*env)->ExceptionCheck(env))
return -1;
if(equals)
return JLONG_ID;
// string
equals = (*env)->CallBooleanMethod(env, clazz, objectEquals, JSTRING_TYPE);
// boolean
equals = (*env)->IsSameObject(env, clazz, JBOOLEAN_TYPE);
if((*env)->ExceptionCheck(env))
return -1;
if(equals)
return JSTRING_ID;
return JBOOLEAN_ID;
// void
equals = (*env)->CallBooleanMethod(env, clazz, objectEquals, JVOID_TYPE);
equals = (*env)->IsSameObject(env, clazz, JVOID_TYPE);
if((*env)->ExceptionCheck(env))
return -1;
if(equals)
return JVOID_ID;
// char
equals = (*env)->CallBooleanMethod(env, clazz, objectEquals, JCHAR_TYPE);
equals = (*env)->IsSameObject(env, clazz, JCHAR_TYPE);
if((*env)->ExceptionCheck(env))
return -1;
if(equals)
return JCHAR_ID;
// byte
equals = (*env)->CallBooleanMethod(env, clazz, objectEquals, JBYTE_TYPE);
equals = (*env)->IsSameObject(env, clazz, JBYTE_TYPE);
if((*env)->ExceptionCheck(env))
return -1;
if(equals)
return JBYTE_ID;
// object checks
// check if it's an array first
array = (*env)->CallBooleanMethod(env, clazz, objectIsArray);
// short
equals = (*env)->IsSameObject(env, clazz, JSHORT_TYPE);
if((*env)->ExceptionCheck(env))
return -1;
if(array)
return JARRAY_ID;
if(equals)
return JSHORT_ID;
if((*env)->IsAssignableFrom(env, clazz, JCLASS_TYPE))
return JCLASS_ID;
if((*env)->IsAssignableFrom(env, clazz, JOBJECT_TYPE))
return JOBJECT_ID;
return -1;
}