From 3a726628f13c8f46b447cf0844eb8a5b740a1993 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20Str=C3=B8mme?= Date: Wed, 6 May 2015 18:15:03 +0200 Subject: Android: Store and use the class names as key when caching. Previously the jclass handle was part of the key used for caching the class' methods and fields. Using the jclass handle is not ideal, but it meant that we could easily create a key when the only identifier we had was the jobject or jclass handle. However, in Android 5.1, the re-use of handles seems to be more aggressive and therefore increasing the chance of a collision in the cache look-up. This change removes caching for all calls where we don't know the class name, as that is the only thing that guarantees that we create unique keys for each class. The consequence of this is that only calls that provide a class name will benefit from the internal caching. Task-number: QTBUG-45748 Change-Id: I0039d04e7c068debc9e3b3983632c45dc8e52309 Reviewed-by: Frank Meerkoetter Reviewed-by: Alex Blasche --- src/corelib/kernel/qjni.cpp | 472 +++++++++++++++++++++++++++----------------- src/corelib/kernel/qjni_p.h | 1 + 2 files changed, 293 insertions(+), 180 deletions(-) (limited to 'src/corelib') diff --git a/src/corelib/kernel/qjni.cpp b/src/corelib/kernel/qjni.cpp index 8431ee3b67..344f7725a0 100644 --- a/src/corelib/kernel/qjni.cpp +++ b/src/corelib/kernel/qjni.cpp @@ -43,7 +43,7 @@ QT_BEGIN_NAMESPACE static inline QString keyBase() { - return QStringLiteral("%1%2%3"); + return QStringLiteral("%1%2:%3"); } static QString qt_convertJString(jstring string) @@ -72,15 +72,15 @@ typedef QHash JClassHash; Q_GLOBAL_STATIC(JClassHash, cachedClasses) Q_GLOBAL_STATIC(QReadWriteLock, cachedClassesLock) -static QString toDotEncodedClassName(const char *className) +static QByteArray toBinaryEncClassName(const QByteArray &className) { - return QString::fromLatin1(className).replace(QLatin1Char('/'), QLatin1Char('.')); + return QByteArray(className).replace('/', '.'); } -static jclass getCachedClass(const QString &classDotEnc, bool *isCached = 0) +static jclass getCachedClass(const QByteArray &classBinEnc, bool *isCached = 0) { QReadLocker locker(cachedClassesLock); - const QHash::const_iterator &it = cachedClasses->constFind(classDotEnc); + const QHash::const_iterator &it = cachedClasses->constFind(QString::fromLatin1(classBinEnc)); const bool found = (it != cachedClasses->constEnd()); if (isCached != 0) @@ -89,10 +89,12 @@ static jclass getCachedClass(const QString &classDotEnc, bool *isCached = 0) return found ? it.value() : 0; } -static jclass loadClassDotEnc(const QString &classDotEnc, JNIEnv *env) +inline static jclass loadClass(const QByteArray &className, JNIEnv *env, bool binEncoded = false) { + const QByteArray &binEncClassName = binEncoded ? className : toBinaryEncClassName(className); + bool isCached = false; - jclass clazz = getCachedClass(classDotEnc, &isCached); + jclass clazz = getCachedClass(binEncClassName, &isCached); if (clazz != 0 || isCached) return clazz; @@ -102,11 +104,12 @@ static jclass loadClassDotEnc(const QString &classDotEnc, JNIEnv *env) QWriteLocker locker(cachedClassesLock); // did we lose the race? - const QHash::const_iterator &it = cachedClasses->constFind(classDotEnc); + const QLatin1String key(binEncClassName); + const QHash::const_iterator &it = cachedClasses->constFind(key); if (it != cachedClasses->constEnd()) return it.value(); - QJNIObjectPrivate stringName = QJNIObjectPrivate::fromString(classDotEnc); + QJNIObjectPrivate stringName = QJNIObjectPrivate::fromString(key); QJNIObjectPrivate classObject = classLoader.callObjectMethod("loadClass", "(Ljava/lang/String;)Ljava/lang/Class;", stringName.object()); @@ -114,27 +117,40 @@ static jclass loadClassDotEnc(const QString &classDotEnc, JNIEnv *env) if (!exceptionCheckAndClear(env) && classObject.isValid()) clazz = static_cast(env->NewGlobalRef(classObject.object())); - cachedClasses->insert(classDotEnc, clazz); + cachedClasses->insert(key, clazz); return clazz; } -inline static jclass loadClass(const char *className, JNIEnv *env) -{ - return loadClassDotEnc(toDotEncodedClassName(className), env); -} - typedef QHash JMethodIDHash; Q_GLOBAL_STATIC(JMethodIDHash, cachedMethodID) Q_GLOBAL_STATIC(QReadWriteLock, cachedMethodIDLock) +static inline jmethodID getMethodID(JNIEnv *env, + jclass clazz, + const char *name, + const char *sig, + bool isStatic = false) +{ + jmethodID id = isStatic ? env->GetStaticMethodID(clazz, name, sig) + : env->GetMethodID(clazz, name, sig); + + if (exceptionCheckAndClear(env)) + return 0; + + return id; +} + static jmethodID getCachedMethodID(JNIEnv *env, jclass clazz, + const QByteArray &className, const char *name, const char *sig, bool isStatic = false) { - // TODO: We need to use something else then the ref. from clazz to avoid collisions. - const QString key = keyBase().arg(size_t(clazz)).arg(QLatin1String(name)).arg(QLatin1String(sig)); + if (className.isEmpty()) + return getMethodID(env, clazz, name, sig, isStatic); + + const QString key = keyBase().arg(QLatin1String(className)).arg(QLatin1String(name)).arg(QLatin1String(sig)); QHash::const_iterator it; { @@ -150,14 +166,7 @@ static jmethodID getCachedMethodID(JNIEnv *env, if (it != cachedMethodID->constEnd()) return it.value(); - jmethodID id = 0; - if (isStatic) - id = env->GetStaticMethodID(clazz, name, sig); - else - id = env->GetMethodID(clazz, name, sig); - - if (exceptionCheckAndClear(env)) - id = 0; + jmethodID id = getMethodID(env, clazz, name, sig, isStatic); cachedMethodID->insert(key, id); return id; @@ -168,13 +177,32 @@ typedef QHash JFieldIDHash; Q_GLOBAL_STATIC(JFieldIDHash, cachedFieldID) Q_GLOBAL_STATIC(QReadWriteLock, cachedFieldIDLock) +static inline jfieldID getFieldID(JNIEnv *env, + jclass clazz, + const char *name, + const char *sig, + bool isStatic = false) +{ + jfieldID id = isStatic ? env->GetStaticFieldID(clazz, name, sig) + : env->GetFieldID(clazz, name, sig); + + if (exceptionCheckAndClear(env)) + return 0; + + return id; +} + static jfieldID getCachedFieldID(JNIEnv *env, jclass clazz, + const QByteArray &className, const char *name, const char *sig, bool isStatic = false) { - const QString key = keyBase().arg(size_t(clazz)).arg(QLatin1String(name)).arg(QLatin1String(sig)); + if (className.isNull()) + return getFieldID(env, clazz, name, sig, isStatic); + + const QString key = keyBase().arg(QLatin1String(className)).arg(QLatin1String(name)).arg(QLatin1String(sig)); QHash::const_iterator it; { @@ -190,14 +218,7 @@ static jfieldID getCachedFieldID(JNIEnv *env, if (it != cachedFieldID->constEnd()) return it.value(); - jfieldID id = 0; - if (isStatic) - id = env->GetStaticFieldID(clazz, name, sig); - else - id = env->GetFieldID(clazz, name, sig); - - if (exceptionCheckAndClear(env)) - id = 0; + jfieldID id = getFieldID(env, clazz, name, sig, isStatic); cachedFieldID->insert(key, id); return id; @@ -241,7 +262,7 @@ JNIEnv *QJNIEnvironmentPrivate::operator->() jclass QJNIEnvironmentPrivate::findClass(const char *className, JNIEnv *env) { - const QString &classDotEnc = toDotEncodedClassName(className); + const QByteArray &classDotEnc = toBinaryEncClassName(className); bool isCached = false; jclass clazz = getCachedClass(classDotEnc, &isCached); @@ -250,9 +271,10 @@ jclass QJNIEnvironmentPrivate::findClass(const char *className, JNIEnv *env) if (found) return clazz; + const QLatin1String key(classDotEnc); if (env != 0) { // We got an env. pointer (We expect this to be the right env. and call FindClass()) QWriteLocker locker(cachedClassesLock); - const QHash::const_iterator &it = cachedClasses->constFind(classDotEnc); + const QHash::const_iterator &it = cachedClasses->constFind(key); // Did we lose the race? if (it != cachedClasses->constEnd()) return it.value(); @@ -264,11 +286,11 @@ jclass QJNIEnvironmentPrivate::findClass(const char *className, JNIEnv *env) } if (clazz != 0) - cachedClasses->insert(classDotEnc, clazz); + cachedClasses->insert(key, clazz); } if (clazz == 0) // We didn't get an env. pointer or we got one with the WRONG class loader... - clazz = loadClassDotEnc(classDotEnc, QJNIEnvironmentPrivate()); + clazz = loadClass(classDotEnc, QJNIEnvironmentPrivate(), true); return clazz; } @@ -309,11 +331,12 @@ QJNIObjectPrivate::QJNIObjectPrivate(const char *className) : d(new QJNIObjectData()) { QJNIEnvironmentPrivate env; - d->m_jclass = loadClass(className, env); + d->m_className = toBinaryEncClassName(className); + d->m_jclass = loadClass(d->m_className, env, true); d->m_own_jclass = false; if (d->m_jclass) { // get default constructor - jmethodID constructorId = getCachedMethodID(env, d->m_jclass, "", "()V"); + jmethodID constructorId = getCachedMethodID(env, d->m_jclass, d->m_className, "", "()V"); if (constructorId) { jobject obj = env->NewObject(d->m_jclass, constructorId); if (obj) { @@ -328,10 +351,11 @@ QJNIObjectPrivate::QJNIObjectPrivate(const char *className, const char *sig, ... : d(new QJNIObjectData()) { QJNIEnvironmentPrivate env; - d->m_jclass = loadClass(className, env); + d->m_className = toBinaryEncClassName(className); + d->m_jclass = loadClass(d->m_className, env, true); d->m_own_jclass = false; if (d->m_jclass) { - jmethodID constructorId = getCachedMethodID(env, d->m_jclass, "", sig); + jmethodID constructorId = getCachedMethodID(env, d->m_jclass, d->m_className, "", sig); if (constructorId) { va_list args; va_start(args, sig); @@ -349,10 +373,11 @@ QJNIObjectPrivate::QJNIObjectPrivate(const char *className, const char *sig, con : d(new QJNIObjectData()) { QJNIEnvironmentPrivate env; - d->m_jclass = loadClass(className, env); + d->m_className = toBinaryEncClassName(className); + d->m_jclass = loadClass(d->m_className, env, true); d->m_own_jclass = false; if (d->m_jclass) { - jmethodID constructorId = getCachedMethodID(env, d->m_jclass, "", sig); + jmethodID constructorId = getCachedMethodID(env, d->m_jclass, d->m_className, "", sig); if (constructorId) { jobject obj = env->NewObjectV(d->m_jclass, constructorId, args); if (obj) { @@ -370,7 +395,7 @@ QJNIObjectPrivate::QJNIObjectPrivate(jclass clazz) d->m_jclass = static_cast(env->NewGlobalRef(clazz)); if (d->m_jclass) { // get default constructor - jmethodID constructorId = getCachedMethodID(env, d->m_jclass, "", "()V"); + jmethodID constructorId = getMethodID(env, d->m_jclass, "", "()V"); if (constructorId) { jobject obj = env->NewObject(d->m_jclass, constructorId); if (obj) { @@ -388,7 +413,7 @@ QJNIObjectPrivate::QJNIObjectPrivate(jclass clazz, const char *sig, ...) if (clazz) { d->m_jclass = static_cast(env->NewGlobalRef(clazz)); if (d->m_jclass) { - jmethodID constructorId = getCachedMethodID(env, d->m_jclass, "", sig); + jmethodID constructorId = getMethodID(env, d->m_jclass, "", sig); if (constructorId) { va_list args; va_start(args, sig); @@ -410,7 +435,7 @@ QJNIObjectPrivate::QJNIObjectPrivate(jclass clazz, const char *sig, const QVaLis if (clazz) { d->m_jclass = static_cast(env->NewGlobalRef(clazz)); if (d->m_jclass) { - jmethodID constructorId = getCachedMethodID(env, d->m_jclass, "", sig); + jmethodID constructorId = getMethodID(env, d->m_jclass, "", sig); if (constructorId) { jobject obj = env->NewObjectV(d->m_jclass, constructorId, args); if (obj) { @@ -430,15 +455,15 @@ QJNIObjectPrivate::QJNIObjectPrivate(jobject obj) QJNIEnvironmentPrivate env; d->m_jobject = env->NewGlobalRef(obj); - jclass objectClass = env->GetObjectClass(d->m_jobject); - d->m_jclass = static_cast(env->NewGlobalRef(objectClass)); - env->DeleteLocalRef(objectClass); + jclass cls = env->GetObjectClass(obj); + d->m_jclass = static_cast(env->NewGlobalRef(cls)); + env->DeleteLocalRef(cls); } template <> void QJNIObjectPrivate::callMethodV(const char *methodName, const char *sig, va_list args) const { QJNIEnvironmentPrivate env; - jmethodID id = getCachedMethodID(env, d->m_jclass, methodName, sig); + jmethodID id = getCachedMethodID(env, d->m_jclass, d->m_className, methodName, sig); if (id) { env->CallVoidMethodV(d->m_jobject, id, args); } @@ -458,7 +483,7 @@ jboolean QJNIObjectPrivate::callMethodV(const char *methodName, const { QJNIEnvironmentPrivate env; jboolean res = 0; - jmethodID id = getCachedMethodID(env, d->m_jclass, methodName, sig); + jmethodID id = getCachedMethodID(env, d->m_jclass, d->m_className, methodName, sig); if (id) { res = env->CallBooleanMethodV(d->m_jobject, id, args); } @@ -480,7 +505,7 @@ jbyte QJNIObjectPrivate::callMethodV(const char *methodName, const char * { QJNIEnvironmentPrivate env; jbyte res = 0; - jmethodID id = getCachedMethodID(env, d->m_jclass, methodName, sig); + jmethodID id = getCachedMethodID(env, d->m_jclass, d->m_className, methodName, sig); if (id) { res = env->CallByteMethodV(d->m_jobject, id, args); } @@ -502,7 +527,7 @@ jchar QJNIObjectPrivate::callMethodV(const char *methodName, const char * { QJNIEnvironmentPrivate env; jchar res = 0; - jmethodID id = getCachedMethodID(env, d->m_jclass, methodName, sig); + jmethodID id = getCachedMethodID(env, d->m_jclass, d->m_className, methodName, sig); if (id) { res = env->CallCharMethodV(d->m_jobject, id, args); } @@ -524,7 +549,7 @@ jshort QJNIObjectPrivate::callMethodV(const char *methodName, const char { QJNIEnvironmentPrivate env; jshort res = 0; - jmethodID id = getCachedMethodID(env, d->m_jclass, methodName, sig); + jmethodID id = getCachedMethodID(env, d->m_jclass, d->m_className, methodName, sig); if (id) { res = env->CallShortMethodV(d->m_jobject, id, args); } @@ -546,7 +571,7 @@ jint QJNIObjectPrivate::callMethodV(const char *methodName, const char *si { QJNIEnvironmentPrivate env; jint res = 0; - jmethodID id = getCachedMethodID(env, d->m_jclass, methodName, sig); + jmethodID id = getCachedMethodID(env, d->m_jclass, d->m_className, methodName, sig); if (id) { res = env->CallIntMethodV(d->m_jobject, id, args); } @@ -568,7 +593,7 @@ jlong QJNIObjectPrivate::callMethodV(const char *methodName, const char * { QJNIEnvironmentPrivate env; jlong res = 0; - jmethodID id = getCachedMethodID(env, d->m_jclass, methodName, sig); + jmethodID id = getCachedMethodID(env, d->m_jclass, d->m_className, methodName, sig); if (id) { res = env->CallLongMethodV(d->m_jobject, id, args); } @@ -590,7 +615,7 @@ jfloat QJNIObjectPrivate::callMethodV(const char *methodName, const char { QJNIEnvironmentPrivate env; jfloat res = 0.f; - jmethodID id = getCachedMethodID(env, d->m_jclass, methodName, sig); + jmethodID id = getCachedMethodID(env, d->m_jclass, d->m_className, methodName, sig); if (id) { res = env->CallFloatMethodV(d->m_jobject, id, args); } @@ -612,7 +637,7 @@ jdouble QJNIObjectPrivate::callMethodV(const char *methodName, const ch { QJNIEnvironmentPrivate env; jdouble res = 0.; - jmethodID id = getCachedMethodID(env, d->m_jclass, methodName, sig); + jmethodID id = getCachedMethodID(env, d->m_jclass, d->m_className, methodName, sig); if (id) { res = env->CallDoubleMethodV(d->m_jobject, id, args); } @@ -692,7 +717,7 @@ void QJNIObjectPrivate::callStaticMethodV(const char *className, QJNIEnvironmentPrivate env; jclass clazz = loadClass(className, env); if (clazz) { - jmethodID id = getCachedMethodID(env, clazz, methodName, sig, true); + jmethodID id = getCachedMethodID(env, clazz, toBinaryEncClassName(className), methodName, sig, true); if (id) { env->CallStaticVoidMethodV(clazz, id, args); } @@ -718,7 +743,7 @@ void QJNIObjectPrivate::callStaticMethodV(jclass clazz, va_list args) { QJNIEnvironmentPrivate env; - jmethodID id = getCachedMethodID(env, clazz, methodName, sig, true); + jmethodID id = getMethodID(env, clazz, methodName, sig, true); if (id) { env->CallStaticVoidMethodV(clazz, id, args); } @@ -746,7 +771,7 @@ jboolean QJNIObjectPrivate::callStaticMethodV(const char *className, jboolean res = 0; jclass clazz = loadClass(className, env); if (clazz) { - jmethodID id = getCachedMethodID(env, clazz, methodName, sig, true); + jmethodID id = getCachedMethodID(env, clazz, toBinaryEncClassName(className), methodName, sig, true); if (id) { res = env->CallStaticBooleanMethodV(clazz, id, args); } @@ -776,7 +801,7 @@ jboolean QJNIObjectPrivate::callStaticMethodV(jclass clazz, { QJNIEnvironmentPrivate env; jboolean res = 0; - jmethodID id = getCachedMethodID(env, clazz, methodName, sig, true); + jmethodID id = getMethodID(env, clazz, methodName, sig, true); if (id) { res = env->CallStaticBooleanMethodV(clazz, id, args); } @@ -807,7 +832,7 @@ jbyte QJNIObjectPrivate::callStaticMethodV(const char *className, jbyte res = 0; jclass clazz = loadClass(className, env); if (clazz) { - jmethodID id = getCachedMethodID(env, clazz, methodName, sig, true); + jmethodID id = getCachedMethodID(env, clazz, toBinaryEncClassName(className), methodName, sig, true); if (id) { res = env->CallStaticByteMethodV(clazz, id, args); } @@ -837,7 +862,7 @@ jbyte QJNIObjectPrivate::callStaticMethodV(jclass clazz, { QJNIEnvironmentPrivate env; jbyte res = 0; - jmethodID id = getCachedMethodID(env, clazz, methodName, sig, true); + jmethodID id = getMethodID(env, clazz, methodName, sig, true); if (id) { res = env->CallStaticByteMethodV(clazz, id, args); } @@ -868,7 +893,7 @@ jchar QJNIObjectPrivate::callStaticMethodV(const char *className, jchar res = 0; jclass clazz = loadClass(className, env); if (clazz) { - jmethodID id = getCachedMethodID(env, clazz, methodName, sig, true); + jmethodID id = getCachedMethodID(env, clazz, toBinaryEncClassName(className), methodName, sig, true); if (id) { res = env->CallStaticCharMethodV(clazz, id, args); } @@ -898,7 +923,7 @@ jchar QJNIObjectPrivate::callStaticMethodV(jclass clazz, { QJNIEnvironmentPrivate env; jchar res = 0; - jmethodID id = getCachedMethodID(env, clazz, methodName, sig, true); + jmethodID id = getMethodID(env, clazz, methodName, sig, true); if (id) { res = env->CallStaticCharMethodV(clazz, id, args); } @@ -929,7 +954,7 @@ jshort QJNIObjectPrivate::callStaticMethodV(const char *className, jshort res = 0; jclass clazz = loadClass(className, env); if (clazz) { - jmethodID id = getCachedMethodID(env, clazz, methodName, sig, true); + jmethodID id = getCachedMethodID(env, clazz, toBinaryEncClassName(className), methodName, sig, true); if (id) { res = env->CallStaticShortMethodV(clazz, id, args); } @@ -959,7 +984,7 @@ jshort QJNIObjectPrivate::callStaticMethodV(jclass clazz, { QJNIEnvironmentPrivate env; jshort res = 0; - jmethodID id = getCachedMethodID(env, clazz, methodName, sig, true); + jmethodID id = getMethodID(env, clazz, methodName, sig, true); if (id) { res = env->CallStaticShortMethodV(clazz, id, args); } @@ -990,7 +1015,7 @@ jint QJNIObjectPrivate::callStaticMethodV(const char *className, jint res = 0; jclass clazz = loadClass(className, env); if (clazz) { - jmethodID id = getCachedMethodID(env, clazz, methodName, sig, true); + jmethodID id = getCachedMethodID(env, clazz, toBinaryEncClassName(className), methodName, sig, true); if (id) { res = env->CallStaticIntMethodV(clazz, id, args); } @@ -1020,7 +1045,7 @@ jint QJNIObjectPrivate::callStaticMethodV(jclass clazz, { QJNIEnvironmentPrivate env; jint res = 0; - jmethodID id = getCachedMethodID(env, clazz, methodName, sig, true); + jmethodID id = getMethodID(env, clazz, methodName, sig, true); if (id) { res = env->CallStaticIntMethodV(clazz, id, args); } @@ -1051,7 +1076,7 @@ jlong QJNIObjectPrivate::callStaticMethodV(const char *className, jlong res = 0; jclass clazz = loadClass(className, env); if (clazz) { - jmethodID id = getCachedMethodID(env, clazz, methodName, sig, true); + jmethodID id = getCachedMethodID(env, clazz, toBinaryEncClassName(className), methodName, sig, true); if (id) { res = env->CallStaticLongMethodV(clazz, id, args); } @@ -1081,7 +1106,7 @@ jlong QJNIObjectPrivate::callStaticMethodV(jclass clazz, { QJNIEnvironmentPrivate env; jlong res = 0; - jmethodID id = getCachedMethodID(env, clazz, methodName, sig, true); + jmethodID id = getMethodID(env, clazz, methodName, sig, true); if (id) { res = env->CallStaticLongMethodV(clazz, id, args); } @@ -1112,7 +1137,7 @@ jfloat QJNIObjectPrivate::callStaticMethodV(const char *className, jfloat res = 0.f; jclass clazz = loadClass(className, env); if (clazz) { - jmethodID id = getCachedMethodID(env, clazz, methodName, sig, true); + jmethodID id = getCachedMethodID(env, clazz, toBinaryEncClassName(className), methodName, sig, true); if (id) { res = env->CallStaticFloatMethodV(clazz, id, args); } @@ -1142,7 +1167,7 @@ jfloat QJNIObjectPrivate::callStaticMethodV(jclass clazz, { QJNIEnvironmentPrivate env; jfloat res = 0.f; - jmethodID id = getCachedMethodID(env, clazz, methodName, sig, true); + jmethodID id = getMethodID(env, clazz, methodName, sig, true); if (id) { res = env->CallStaticFloatMethodV(clazz, id, args); } @@ -1173,7 +1198,7 @@ jdouble QJNIObjectPrivate::callStaticMethodV(const char *className, jdouble res = 0.; jclass clazz = loadClass(className, env); if (clazz) { - jmethodID id = getCachedMethodID(env, clazz, methodName, sig, true); + jmethodID id = getCachedMethodID(env, clazz, toBinaryEncClassName(className), methodName, sig, true); if (id) { res = env->CallStaticDoubleMethodV(clazz, id, args); } @@ -1203,7 +1228,7 @@ jdouble QJNIObjectPrivate::callStaticMethodV(jclass clazz, { QJNIEnvironmentPrivate env; jdouble res = 0.; - jmethodID id = getCachedMethodID(env, clazz, methodName, sig, true); + jmethodID id = getMethodID(env, clazz, methodName, sig, true); if (id) { res = env->CallStaticDoubleMethodV(clazz, id, args); } @@ -1338,7 +1363,7 @@ QJNIObjectPrivate QJNIObjectPrivate::callObjectMethodV(const char *methodName, { QJNIEnvironmentPrivate env; jobject res = 0; - jmethodID id = getCachedMethodID(env, d->m_jclass, methodName, sig); + jmethodID id = getCachedMethodID(env, d->m_jclass, d->m_className, methodName, sig); if (id) { res = env->CallObjectMethodV(d->m_jobject, id, args); if (res && env->ExceptionCheck()) @@ -1418,7 +1443,7 @@ QJNIObjectPrivate QJNIObjectPrivate::callStaticObjectMethodV(const char *classNa jobject res = 0; jclass clazz = loadClass(className, env); if (clazz) { - jmethodID id = getCachedMethodID(env, clazz, methodName, sig, true); + jmethodID id = getCachedMethodID(env, clazz, toBinaryEncClassName(className), methodName, sig, true); if (id) { res = env->CallStaticObjectMethodV(clazz, id, args); if (res && env->ExceptionCheck()) @@ -1450,7 +1475,7 @@ QJNIObjectPrivate QJNIObjectPrivate::callStaticObjectMethodV(jclass clazz, { QJNIEnvironmentPrivate env; jobject res = 0; - jmethodID id = getCachedMethodID(env, clazz, methodName, sig, true); + jmethodID id = getMethodID(env, clazz, methodName, sig, true); if (id) { res = env->CallStaticObjectMethodV(clazz, id, args); if (res && env->ExceptionCheck()) @@ -1479,7 +1504,7 @@ jboolean QJNIObjectPrivate::getField(const char *fieldName) const { QJNIEnvironmentPrivate env; jboolean res = 0; - jfieldID id = getCachedFieldID(env, d->m_jclass, fieldName, "Z"); + jfieldID id = getCachedFieldID(env, d->m_jclass, d->m_className, fieldName, "Z"); if (id) res = env->GetBooleanField(d->m_jobject, id); @@ -1491,7 +1516,7 @@ jbyte QJNIObjectPrivate::getField(const char *fieldName) const { QJNIEnvironmentPrivate env; jbyte res = 0; - jfieldID id = getCachedFieldID(env, d->m_jclass, fieldName, "B"); + jfieldID id = getCachedFieldID(env, d->m_jclass, d->m_className, fieldName, "B"); if (id) res = env->GetByteField(d->m_jobject, id); @@ -1503,7 +1528,7 @@ jchar QJNIObjectPrivate::getField(const char *fieldName) const { QJNIEnvironmentPrivate env; jchar res = 0; - jfieldID id = getCachedFieldID(env, d->m_jclass, fieldName, "C"); + jfieldID id = getCachedFieldID(env, d->m_jclass, d->m_className, fieldName, "C"); if (id) res = env->GetCharField(d->m_jobject, id); @@ -1515,7 +1540,7 @@ jshort QJNIObjectPrivate::getField(const char *fieldName) const { QJNIEnvironmentPrivate env; jshort res = 0; - jfieldID id = getCachedFieldID(env, d->m_jclass, fieldName, "S"); + jfieldID id = getCachedFieldID(env, d->m_jclass, d->m_className, fieldName, "S"); if (id) res = env->GetShortField(d->m_jobject, id); @@ -1527,7 +1552,7 @@ jint QJNIObjectPrivate::getField(const char *fieldName) const { QJNIEnvironmentPrivate env; jint res = 0; - jfieldID id = getCachedFieldID(env, d->m_jclass, fieldName, "I"); + jfieldID id = getCachedFieldID(env, d->m_jclass, d->m_className, fieldName, "I"); if (id) res = env->GetIntField(d->m_jobject, id); @@ -1539,7 +1564,7 @@ jlong QJNIObjectPrivate::getField(const char *fieldName) const { QJNIEnvironmentPrivate env; jlong res = 0; - jfieldID id = getCachedFieldID(env, d->m_jclass, fieldName, "J"); + jfieldID id = getCachedFieldID(env, d->m_jclass, d->m_className, fieldName, "J"); if (id) res = env->GetLongField(d->m_jobject, id); @@ -1551,7 +1576,7 @@ jfloat QJNIObjectPrivate::getField(const char *fieldName) const { QJNIEnvironmentPrivate env; jfloat res = 0.f; - jfieldID id = getCachedFieldID(env, d->m_jclass, fieldName, "F"); + jfieldID id = getCachedFieldID(env, d->m_jclass, d->m_className, fieldName, "F"); if (id) res = env->GetFloatField(d->m_jobject, id); @@ -1563,7 +1588,7 @@ jdouble QJNIObjectPrivate::getField(const char *fieldName) const { QJNIEnvironmentPrivate env; jdouble res = 0.; - jfieldID id = getCachedFieldID(env, d->m_jclass, fieldName, "D"); + jfieldID id = getCachedFieldID(env, d->m_jclass, d->m_className, fieldName, "D"); if (id) res = env->GetDoubleField(d->m_jobject, id); @@ -1575,7 +1600,7 @@ jboolean QJNIObjectPrivate::getStaticField(jclass clazz, const char *f { QJNIEnvironmentPrivate env; jboolean res = 0; - jfieldID id = getCachedFieldID(env, clazz, fieldName, "Z", true); + jfieldID id = getFieldID(env, clazz, fieldName, "Z", true); if (id) res = env->GetStaticBooleanField(clazz, id); @@ -1586,12 +1611,15 @@ template <> jboolean QJNIObjectPrivate::getStaticField(const char *className, const char *fieldName) { QJNIEnvironmentPrivate env; - jboolean res = 0; jclass clazz = loadClass(className, env); - if (clazz) - res = getStaticField(clazz, fieldName); + if (clazz == 0) + return 0; - return res; + jfieldID id = getCachedFieldID(env, clazz, toBinaryEncClassName(className), fieldName, "Z", true); + if (id == 0) + return 0; + + return env->GetStaticBooleanField(clazz, id); } template <> @@ -1599,7 +1627,7 @@ jbyte QJNIObjectPrivate::getStaticField(jclass clazz, const char *fieldNa { QJNIEnvironmentPrivate env; jbyte res = 0; - jfieldID id = getCachedFieldID(env, clazz, fieldName, "B", true); + jfieldID id = getFieldID(env, clazz, fieldName, "B", true); if (id) res = env->GetStaticByteField(clazz, id); @@ -1610,12 +1638,15 @@ template <> jbyte QJNIObjectPrivate::getStaticField(const char *className, const char *fieldName) { QJNIEnvironmentPrivate env; - jbyte res = 0; jclass clazz = loadClass(className, env); - if (clazz) - res = getStaticField(clazz, fieldName); + if (clazz == 0) + return 0; - return res; + jfieldID id = getCachedFieldID(env, clazz, toBinaryEncClassName(className), fieldName, "B", true); + if (id == 0) + return 0; + + return env->GetStaticByteField(clazz, id); } template <> @@ -1623,7 +1654,7 @@ jchar QJNIObjectPrivate::getStaticField(jclass clazz, const char *fieldNa { QJNIEnvironmentPrivate env; jchar res = 0; - jfieldID id = getCachedFieldID(env, clazz, fieldName, "C", true); + jfieldID id = getFieldID(env, clazz, fieldName, "C", true); if (id) res = env->GetStaticCharField(clazz, id); @@ -1634,12 +1665,15 @@ template <> jchar QJNIObjectPrivate::getStaticField(const char *className, const char *fieldName) { QJNIEnvironmentPrivate env; - jchar res = 0; jclass clazz = loadClass(className, env); - if (clazz) - res = getStaticField(clazz, fieldName); + if (clazz == 0) + return 0; - return res; + jfieldID id = getCachedFieldID(env, clazz, toBinaryEncClassName(className), fieldName, "C", true); + if (id == 0) + return 0; + + return env->GetStaticCharField(clazz, id); } template <> @@ -1647,7 +1681,7 @@ jshort QJNIObjectPrivate::getStaticField(jclass clazz, const char *field { QJNIEnvironmentPrivate env; jshort res = 0; - jfieldID id = getCachedFieldID(env, clazz, fieldName, "S", true); + jfieldID id = getFieldID(env, clazz, fieldName, "S", true); if (id) res = env->GetStaticShortField(clazz, id); @@ -1658,12 +1692,15 @@ template <> jshort QJNIObjectPrivate::getStaticField(const char *className, const char *fieldName) { QJNIEnvironmentPrivate env; - jshort res = 0; jclass clazz = loadClass(className, env); - if (clazz) - res = getStaticField(clazz, fieldName); + if (clazz == 0) + return 0; - return res; + jfieldID id = getCachedFieldID(env, clazz, toBinaryEncClassName(className), fieldName, "S", true); + if (id == 0) + return 0; + + return env->GetStaticShortField(clazz, id); } template <> @@ -1671,7 +1708,7 @@ jint QJNIObjectPrivate::getStaticField(jclass clazz, const char *fieldName { QJNIEnvironmentPrivate env; jint res = 0; - jfieldID id = getCachedFieldID(env, clazz, fieldName, "I", true); + jfieldID id = getFieldID(env, clazz, fieldName, "I", true); if (id) res = env->GetStaticIntField(clazz, id); @@ -1682,12 +1719,15 @@ template <> jint QJNIObjectPrivate::getStaticField(const char *className, const char *fieldName) { QJNIEnvironmentPrivate env; - jint res = 0; jclass clazz = loadClass(className, env); - if (clazz) - res = getStaticField(clazz, fieldName); + if (clazz == 0) + return 0; - return res; + jfieldID id = getCachedFieldID(env, clazz, toBinaryEncClassName(className), fieldName, "I", true); + if (id == 0) + return 0; + + return env->GetStaticIntField(clazz, id); } template <> @@ -1695,7 +1735,7 @@ jlong QJNIObjectPrivate::getStaticField(jclass clazz, const char *fieldNa { QJNIEnvironmentPrivate env; jlong res = 0; - jfieldID id = getCachedFieldID(env, clazz, fieldName, "J", true); + jfieldID id = getFieldID(env, clazz, fieldName, "J", true); if (id) res = env->GetStaticLongField(clazz, id); @@ -1706,12 +1746,15 @@ template <> jlong QJNIObjectPrivate::getStaticField(const char *className, const char *fieldName) { QJNIEnvironmentPrivate env; - jlong res = 0; jclass clazz = loadClass(className, env); - if (clazz) - res = getStaticField(clazz, fieldName); + if (clazz == 0) + return 0; - return res; + jfieldID id = getCachedFieldID(env, clazz, toBinaryEncClassName(className), fieldName, "J", true); + if (id == 0) + return 0; + + return env->GetStaticLongField(clazz, id); } template <> @@ -1719,7 +1762,7 @@ jfloat QJNIObjectPrivate::getStaticField(jclass clazz, const char *field { QJNIEnvironmentPrivate env; jfloat res = 0.f; - jfieldID id = getCachedFieldID(env, clazz, fieldName, "F", true); + jfieldID id = getFieldID(env, clazz, fieldName, "F", true); if (id) res = env->GetStaticFloatField(clazz, id); @@ -1730,12 +1773,15 @@ template <> jfloat QJNIObjectPrivate::getStaticField(const char *className, const char *fieldName) { QJNIEnvironmentPrivate env; - jfloat res = 0.f; jclass clazz = loadClass(className, env); - if (clazz) - res = getStaticField(clazz, fieldName); + if (clazz == 0) + return 0.f; - return res; + jfieldID id = getCachedFieldID(env, clazz, toBinaryEncClassName(className), fieldName, "F", true); + if (id == 0) + return 0.f; + + return env->GetStaticFloatField(clazz, id); } template <> @@ -1743,7 +1789,7 @@ jdouble QJNIObjectPrivate::getStaticField(jclass clazz, const char *fie { QJNIEnvironmentPrivate env; jdouble res = 0.; - jfieldID id = getCachedFieldID(env, clazz, fieldName, "D", true); + jfieldID id = getFieldID(env, clazz, fieldName, "D", true); if (id) res = env->GetStaticDoubleField(clazz, id); @@ -1754,12 +1800,15 @@ template <> jdouble QJNIObjectPrivate::getStaticField(const char *className, const char *fieldName) { QJNIEnvironmentPrivate env; - jdouble res = 0.; jclass clazz = loadClass(className, env); - if (clazz) - res = getStaticField(clazz, fieldName); + if (clazz == 0) + return 0.; - return res; + jfieldID id = getCachedFieldID(env, clazz, toBinaryEncClassName(className), fieldName, "D", true); + if (id == 0) + return 0.; + + return env->GetStaticDoubleField(clazz, id); } QJNIObjectPrivate QJNIObjectPrivate::getObjectField(const char *fieldName, @@ -1767,7 +1816,7 @@ QJNIObjectPrivate QJNIObjectPrivate::getObjectField(const char *fieldName, { QJNIEnvironmentPrivate env; jobject res = 0; - jfieldID id = getCachedFieldID(env, d->m_jclass, fieldName, sig); + jfieldID id = getCachedFieldID(env, d->m_jclass, d->m_className, fieldName, sig); if (id) { res = env->GetObjectField(d->m_jobject, id); if (res && env->ExceptionCheck()) @@ -1784,12 +1833,21 @@ QJNIObjectPrivate QJNIObjectPrivate::getStaticObjectField(const char *className, const char *sig) { QJNIEnvironmentPrivate env; - QJNIObjectPrivate res; jclass clazz = loadClass(className, env); - if (clazz) - res = getStaticObjectField(clazz, fieldName, sig); + if (clazz == 0) + return QJNIObjectPrivate(); - return res; + jfieldID id = getCachedFieldID(env, clazz, toBinaryEncClassName(className), fieldName, sig, true); + if (id == 0) + return QJNIObjectPrivate(); + + jobject res = env->GetStaticObjectField(clazz, id); + if (res && env->ExceptionCheck()) + res = 0; + + QJNIObjectPrivate obj(res); + env->DeleteLocalRef(res); + return obj; } QJNIObjectPrivate QJNIObjectPrivate::getStaticObjectField(jclass clazz, @@ -1798,7 +1856,7 @@ QJNIObjectPrivate QJNIObjectPrivate::getStaticObjectField(jclass clazz, { QJNIEnvironmentPrivate env; jobject res = 0; - jfieldID id = getCachedFieldID(env, clazz, fieldName, sig, true); + jfieldID id = getFieldID(env, clazz, fieldName, sig, true); if (id) { res = env->GetStaticObjectField(clazz, id); if (res && env->ExceptionCheck()) @@ -1814,7 +1872,7 @@ template <> void QJNIObjectPrivate::setField(const char *fieldName, jboolean value) { QJNIEnvironmentPrivate env; - jfieldID id = getCachedFieldID(env, d->m_jclass, fieldName, "Z"); + jfieldID id = getCachedFieldID(env, d->m_jclass, d->m_className, fieldName, "Z"); if (id) env->SetBooleanField(d->m_jobject, id, value); @@ -1824,7 +1882,7 @@ template <> void QJNIObjectPrivate::setField(const char *fieldName, jbyte value) { QJNIEnvironmentPrivate env; - jfieldID id = getCachedFieldID(env, d->m_jclass, fieldName, "B"); + jfieldID id = getCachedFieldID(env, d->m_jclass, d->m_className, fieldName, "B"); if (id) env->SetByteField(d->m_jobject, id, value); @@ -1834,7 +1892,7 @@ template <> void QJNIObjectPrivate::setField(const char *fieldName, jchar value) { QJNIEnvironmentPrivate env; - jfieldID id = getCachedFieldID(env, d->m_jclass, fieldName, "C"); + jfieldID id = getCachedFieldID(env, d->m_jclass, d->m_className, fieldName, "C"); if (id) env->SetCharField(d->m_jobject, id, value); @@ -1844,7 +1902,7 @@ template <> void QJNIObjectPrivate::setField(const char *fieldName, jshort value) { QJNIEnvironmentPrivate env; - jfieldID id = getCachedFieldID(env, d->m_jclass, fieldName, "S"); + jfieldID id = getCachedFieldID(env, d->m_jclass, d->m_className, fieldName, "S"); if (id) env->SetShortField(d->m_jobject, id, value); @@ -1854,7 +1912,7 @@ template <> void QJNIObjectPrivate::setField(const char *fieldName, jint value) { QJNIEnvironmentPrivate env; - jfieldID id = getCachedFieldID(env, d->m_jclass, fieldName, "I"); + jfieldID id = getCachedFieldID(env, d->m_jclass, d->m_className, fieldName, "I"); if (id) env->SetIntField(d->m_jobject, id, value); @@ -1864,7 +1922,7 @@ template <> void QJNIObjectPrivate::setField(const char *fieldName, jlong value) { QJNIEnvironmentPrivate env; - jfieldID id = getCachedFieldID(env, d->m_jclass, fieldName, "J"); + jfieldID id = getCachedFieldID(env, d->m_jclass, d->m_className, fieldName, "J"); if (id) env->SetLongField(d->m_jobject, id, value); @@ -1874,7 +1932,7 @@ template <> void QJNIObjectPrivate::setField(const char *fieldName, jfloat value) { QJNIEnvironmentPrivate env; - jfieldID id = getCachedFieldID(env, d->m_jclass, fieldName, "F"); + jfieldID id = getCachedFieldID(env, d->m_jclass, d->m_className, fieldName, "F"); if (id) env->SetFloatField(d->m_jobject, id, value); @@ -1884,7 +1942,7 @@ template <> void QJNIObjectPrivate::setField(const char *fieldName, jdouble value) { QJNIEnvironmentPrivate env; - jfieldID id = getCachedFieldID(env, d->m_jclass, fieldName, "D"); + jfieldID id = getCachedFieldID(env, d->m_jclass, d->m_className, fieldName, "D"); if (id) env->SetDoubleField(d->m_jobject, id, value); @@ -1894,7 +1952,7 @@ template <> void QJNIObjectPrivate::setField(const char *fieldName, jbooleanArray value) { QJNIEnvironmentPrivate env; - jfieldID id = getCachedFieldID(env, d->m_jclass, fieldName, "[Z"); + jfieldID id = getCachedFieldID(env, d->m_jclass, d->m_className, fieldName, "[Z"); if (id) env->SetObjectField(d->m_jobject, id, value); @@ -1904,7 +1962,7 @@ template <> void QJNIObjectPrivate::setField(const char *fieldName, jbyteArray value) { QJNIEnvironmentPrivate env; - jfieldID id = getCachedFieldID(env, d->m_jclass, fieldName, "[B"); + jfieldID id = getCachedFieldID(env, d->m_jclass, d->m_className, fieldName, "[B"); if (id) env->SetObjectField(d->m_jobject, id, value); @@ -1914,7 +1972,7 @@ template <> void QJNIObjectPrivate::setField(const char *fieldName, jcharArray value) { QJNIEnvironmentPrivate env; - jfieldID id = getCachedFieldID(env, d->m_jclass, fieldName, "[C"); + jfieldID id = getCachedFieldID(env, d->m_jclass, d->m_className, fieldName, "[C"); if (id) env->SetObjectField(d->m_jobject, id, value); @@ -1924,7 +1982,7 @@ template <> void QJNIObjectPrivate::setField(const char *fieldName, jshortArray value) { QJNIEnvironmentPrivate env; - jfieldID id = getCachedFieldID(env, d->m_jclass, fieldName, "[S"); + jfieldID id = getCachedFieldID(env, d->m_jclass, d->m_className, fieldName, "[S"); if (id) env->SetObjectField(d->m_jobject, id, value); @@ -1934,7 +1992,7 @@ template <> void QJNIObjectPrivate::setField(const char *fieldName, jintArray value) { QJNIEnvironmentPrivate env; - jfieldID id = getCachedFieldID(env, d->m_jclass, fieldName, "[I"); + jfieldID id = getCachedFieldID(env, d->m_jclass, d->m_className, fieldName, "[I"); if (id) env->SetObjectField(d->m_jobject, id, value); @@ -1944,7 +2002,7 @@ template <> void QJNIObjectPrivate::setField(const char *fieldName, jlongArray value) { QJNIEnvironmentPrivate env; - jfieldID id = getCachedFieldID(env, d->m_jclass, fieldName, "[J"); + jfieldID id = getCachedFieldID(env, d->m_jclass, d->m_className, fieldName, "[J"); if (id) env->SetObjectField(d->m_jobject, id, value); @@ -1954,7 +2012,7 @@ template <> void QJNIObjectPrivate::setField(const char *fieldName, jfloatArray value) { QJNIEnvironmentPrivate env; - jfieldID id = getCachedFieldID(env, d->m_jclass, fieldName, "[F"); + jfieldID id = getCachedFieldID(env, d->m_jclass, d->m_className, fieldName, "[F"); if (id) env->SetObjectField(d->m_jobject, id, value); @@ -1964,7 +2022,7 @@ template <> void QJNIObjectPrivate::setField(const char *fieldName, jdoubleArray value) { QJNIEnvironmentPrivate env; - jfieldID id = getCachedFieldID(env, d->m_jclass, fieldName, "[D"); + jfieldID id = getCachedFieldID(env, d->m_jclass, d->m_className, fieldName, "[D"); if (id) env->SetObjectField(d->m_jobject, id, value); @@ -1974,7 +2032,7 @@ template <> void QJNIObjectPrivate::setField(const char *fieldName, jstring value) { QJNIEnvironmentPrivate env; - jfieldID id = getCachedFieldID(env, d->m_jclass, fieldName, "Ljava/lang/String;"); + jfieldID id = getCachedFieldID(env, d->m_jclass, d->m_className, fieldName, "Ljava/lang/String;"); if (id) env->SetObjectField(d->m_jobject, id, value); @@ -1986,7 +2044,7 @@ void QJNIObjectPrivate::setField(const char *fieldName, jobject value) { QJNIEnvironmentPrivate env; - jfieldID id = getCachedFieldID(env, d->m_jclass, fieldName, sig); + jfieldID id = getCachedFieldID(env, d->m_jclass, d->m_className, fieldName, sig); if (id) env->SetObjectField(d->m_jobject, id, value); @@ -1998,7 +2056,7 @@ void QJNIObjectPrivate::setField(const char *fieldName, jobjectArray value) { QJNIEnvironmentPrivate env; - jfieldID id = getCachedFieldID(env, d->m_jclass, fieldName, sig); + jfieldID id = getCachedFieldID(env, d->m_jclass, d->m_className, fieldName, sig); if (id) env->SetObjectField(d->m_jobject, id, value); @@ -2010,7 +2068,7 @@ void QJNIObjectPrivate::setStaticField(jclass clazz, jboolean value) { QJNIEnvironmentPrivate env; - jfieldID id = getCachedFieldID(env, clazz, fieldName, "Z", true); + jfieldID id = getFieldID(env, clazz, fieldName, "Z", true); if (id) env->SetStaticBooleanField(clazz, id, value); } @@ -2022,8 +2080,14 @@ void QJNIObjectPrivate::setStaticField(const char *className, { QJNIEnvironmentPrivate env; jclass clazz = loadClass(className, env); - if (clazz) - setStaticField(clazz, fieldName, value); + if (clazz == 0) + return; + + jfieldID id = getCachedFieldID(env, clazz, className, fieldName, "Z", true); + if (id == 0) + return; + + env->SetStaticBooleanField(clazz, id, value); } template <> @@ -2032,7 +2096,7 @@ void QJNIObjectPrivate::setStaticField(jclass clazz, jbyte value) { QJNIEnvironmentPrivate env; - jfieldID id = getCachedFieldID(env, clazz, fieldName, "B", true); + jfieldID id = getFieldID(env, clazz, fieldName, "B", true); if (id) env->SetStaticByteField(clazz, id, value); } @@ -2044,8 +2108,14 @@ void QJNIObjectPrivate::setStaticField(const char *className, { QJNIEnvironmentPrivate env; jclass clazz = loadClass(className, env); - if (clazz) - setStaticField(clazz, fieldName, value); + if (clazz == 0) + return; + + jfieldID id = getCachedFieldID(env, clazz, className, fieldName, "B", true); + if (id == 0) + return; + + env->SetStaticByteField(clazz, id, value); } template <> @@ -2054,7 +2124,7 @@ void QJNIObjectPrivate::setStaticField(jclass clazz, jchar value) { QJNIEnvironmentPrivate env; - jfieldID id = getCachedFieldID(env, clazz, fieldName, "C", true); + jfieldID id = getFieldID(env, clazz, fieldName, "C", true); if (id) env->SetStaticCharField(clazz, id, value); } @@ -2066,8 +2136,14 @@ void QJNIObjectPrivate::setStaticField(const char *className, { QJNIEnvironmentPrivate env; jclass clazz = loadClass(className, env); - if (clazz) - setStaticField(clazz, fieldName, value); + if (clazz == 0) + return; + + jfieldID id = getCachedFieldID(env, clazz, className, fieldName, "C", true); + if (id == 0) + return; + + env->SetStaticCharField(clazz, id, value); } template <> @@ -2076,7 +2152,7 @@ void QJNIObjectPrivate::setStaticField(jclass clazz, jshort value) { QJNIEnvironmentPrivate env; - jfieldID id = getCachedFieldID(env, clazz, fieldName, "S", true); + jfieldID id = getFieldID(env, clazz, fieldName, "S", true); if (id) env->SetStaticShortField(clazz, id, value); } @@ -2088,8 +2164,14 @@ void QJNIObjectPrivate::setStaticField(const char *className, { QJNIEnvironmentPrivate env; jclass clazz = loadClass(className, env); - if (clazz) - setStaticField(clazz, fieldName, value); + if (clazz == 0) + return; + + jfieldID id = getCachedFieldID(env, clazz, className, fieldName, "S", true); + if (id == 0) + return; + + env->SetStaticShortField(clazz, id, value); } template <> @@ -2098,7 +2180,7 @@ void QJNIObjectPrivate::setStaticField(jclass clazz, jint value) { QJNIEnvironmentPrivate env; - jfieldID id = getCachedFieldID(env, clazz, fieldName, "I", true); + jfieldID id = getFieldID(env, clazz, fieldName, "I", true); if (id) env->SetStaticIntField(clazz, id, value); } @@ -2110,8 +2192,14 @@ void QJNIObjectPrivate::setStaticField(const char *className, { QJNIEnvironmentPrivate env; jclass clazz = loadClass(className, env); - if (clazz) - setStaticField(clazz, fieldName, value); + if (clazz == 0) + return; + + jfieldID id = getCachedFieldID(env, clazz, className, fieldName, "I", true); + if (id == 0) + return; + + env->SetStaticIntField(clazz, id, value); } template <> @@ -2120,7 +2208,7 @@ void QJNIObjectPrivate::setStaticField(jclass clazz, jlong value) { QJNIEnvironmentPrivate env; - jfieldID id = getCachedFieldID(env, clazz, fieldName, "J", true); + jfieldID id = getFieldID(env, clazz, fieldName, "J", true); if (id) env->SetStaticLongField(clazz, id, value); } @@ -2132,8 +2220,14 @@ void QJNIObjectPrivate::setStaticField(const char *className, { QJNIEnvironmentPrivate env; jclass clazz = loadClass(className, env); - if (clazz) - setStaticField(clazz, fieldName, value); + if (clazz == 0) + return; + + jfieldID id = getCachedFieldID(env, clazz, className, fieldName, "J", true); + if (id == 0) + return; + + env->SetStaticLongField(clazz, id, value); } template <> @@ -2142,7 +2236,7 @@ void QJNIObjectPrivate::setStaticField(jclass clazz, jfloat value) { QJNIEnvironmentPrivate env; - jfieldID id = getCachedFieldID(env, clazz, fieldName, "F", true); + jfieldID id = getFieldID(env, clazz, fieldName, "F", true); if (id) env->SetStaticFloatField(clazz, id, value); } @@ -2154,8 +2248,14 @@ void QJNIObjectPrivate::setStaticField(const char *className, { QJNIEnvironmentPrivate env; jclass clazz = loadClass(className, env); - if (clazz) - setStaticField(clazz, fieldName, value); + if (clazz == 0) + return; + + jfieldID id = getCachedFieldID(env, clazz, className, fieldName, "F", true); + if (id == 0) + return; + + env->SetStaticFloatField(clazz, id, value); } template <> @@ -2164,7 +2264,7 @@ void QJNIObjectPrivate::setStaticField(jclass clazz, jdouble value) { QJNIEnvironmentPrivate env; - jfieldID id = getCachedFieldID(env, clazz, fieldName, "D", true); + jfieldID id = getFieldID(env, clazz, fieldName, "D", true); if (id) env->SetStaticDoubleField(clazz, id, value); } @@ -2176,8 +2276,14 @@ void QJNIObjectPrivate::setStaticField(const char *className, { QJNIEnvironmentPrivate env; jclass clazz = loadClass(className, env); - if (clazz) - setStaticField(clazz, fieldName, value); + if (clazz == 0) + return; + + jfieldID id = getCachedFieldID(env, clazz, className, fieldName, "D", true); + if (id == 0) + return; + + env->SetStaticDoubleField(clazz, id, value); } template <> @@ -2187,7 +2293,7 @@ void QJNIObjectPrivate::setStaticField(jclass clazz, jobject value) { QJNIEnvironmentPrivate env; - jfieldID id = getCachedFieldID(env, clazz, fieldName, sig, true); + jfieldID id = getFieldID(env, clazz, fieldName, sig, true); if (id) env->SetStaticObjectField(clazz, id, value); } @@ -2200,8 +2306,14 @@ void QJNIObjectPrivate::setStaticField(const char *className, { QJNIEnvironmentPrivate env; jclass clazz = loadClass(className, env); - if (clazz) - setStaticField(clazz, fieldName, sig, value); + if (clazz == 0) + return; + + jfieldID id = getCachedFieldID(env, clazz, className, fieldName, sig, true); + if (id == 0) + return; + + env->SetStaticObjectField(clazz, id, value); } QJNIObjectPrivate QJNIObjectPrivate::fromString(const QString &string) diff --git a/src/corelib/kernel/qjni_p.h b/src/corelib/kernel/qjni_p.h index fb1982dc74..a62e9ee056 100644 --- a/src/corelib/kernel/qjni_p.h +++ b/src/corelib/kernel/qjni_p.h @@ -74,6 +74,7 @@ public: jobject m_jobject; jclass m_jclass; bool m_own_jclass; + QByteArray m_className; }; class Q_CORE_EXPORT QJNIObjectPrivate -- cgit v1.2.3 From 3eca75de67b3fd2c890715b30c7899cebc096fe9 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Mon, 11 May 2015 18:30:00 +0900 Subject: Make qglobal.h complain if you use -fPIE Prior to Qt 5.4.2 (commit 36d6eb721e7d5997ade75e289d4088dc48678d0d), we allowed it, but now we need to enforce that it is not used. Note that -fPIE does define __PIC__, so we need this to catch the use of -fPIE. [ChangeLog][Important Behavior Changes] On x86 and x86-64 systems with ELF binaries (especially Linux), due to a new optimization in GCC 5.x in combination with a recent version of GNU binutils, compiling Qt applications with -fPIE is no longer enough. Applications now need to be compiled with the -fPIC option if Qt's option "reduce relocations" is active. Note that Clang is known to generate incompatible code even with -fPIC if the -flto option is active. Task-number: QTBUG-45755 Change-Id: I66a35ce5f88941f29aa6ffff13dd210e0aa2728f Reviewed-by: Dmitry Shachnev Reviewed-by: Simon Hausmann --- src/corelib/global/qglobal.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/corelib') diff --git a/src/corelib/global/qglobal.h b/src/corelib/global/qglobal.h index ef84662036..4547877da6 100644 --- a/src/corelib/global/qglobal.h +++ b/src/corelib/global/qglobal.h @@ -1047,9 +1047,9 @@ Q_CORE_EXPORT int qrand(); # define QT_NO_SHAREDMEMORY #endif -#if !defined(QT_BOOTSTRAPPED) && defined(QT_REDUCE_RELOCATIONS) && defined(__ELF__) && !defined(__PIC__) +#if !defined(QT_BOOTSTRAPPED) && defined(QT_REDUCE_RELOCATIONS) && defined(__ELF__) && (!defined(__PIC__) || defined(__PIE__)) # error "You must build your code with position independent code if Qt was built with -reduce-relocations. "\ - "Compile your code with -fPIC." + "Compile your code with -fPIC (-fPIE is not enough)." #endif namespace QtPrivate { -- cgit v1.2.3 From 5a3251a0324d65d688c3702a327d7a71a0de5ab9 Mon Sep 17 00:00:00 2001 From: Joerg Bornemann Date: Wed, 22 Apr 2015 15:43:50 +0200 Subject: Doc: fix QSystemSemaphore example acquire() doesn't take arguments. Change-Id: I16f0169c40433cc3cbfcb577bd8386d217cccb12 Task-number: QTBUG-40055 Reviewed-by: Oliver Wolff Reviewed-by: Friedemann Kleint --- .../doc/snippets/code/src_corelib_kernel_qsystemsemaphore.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'src/corelib') diff --git a/src/corelib/doc/snippets/code/src_corelib_kernel_qsystemsemaphore.cpp b/src/corelib/doc/snippets/code/src_corelib_kernel_qsystemsemaphore.cpp index bc03770f16..9cded446d1 100644 --- a/src/corelib/doc/snippets/code/src_corelib_kernel_qsystemsemaphore.cpp +++ b/src/corelib/doc/snippets/code/src_corelib_kernel_qsystemsemaphore.cpp @@ -51,8 +51,9 @@ sem.release(2); // resources available == 3 //! [1] QSystemSemaphore sem("market", 5, QSystemSemaphore::Create); -sem.acquire(5); // acquire all 5 resources -sem.release(5); // release the 5 resources +for (int i = 0; i < 5; ++i) // acquire all 5 resources + sem.acquire(); +sem.release(5); // release the 5 resources //! [1] -- cgit v1.2.3 From 50c41bc8efb52b2b3f2aad66d79167320e9b2b31 Mon Sep 17 00:00:00 2001 From: Nico Vertriest Date: Mon, 24 Nov 2014 14:53:05 +0100 Subject: Doc: corrected autolink issues statemachine.qdoc MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Task-number: QTBUG-40362 Change-Id: Ia686ebdfd722f448aa30fb1f1f266b6148df4026 Reviewed-by: Topi Reiniƶ --- src/corelib/doc/src/statemachine.qdoc | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) (limited to 'src/corelib') diff --git a/src/corelib/doc/src/statemachine.qdoc b/src/corelib/doc/src/statemachine.qdoc index 846eb7d1f0..4b50174b88 100644 --- a/src/corelib/doc/src/statemachine.qdoc +++ b/src/corelib/doc/src/statemachine.qdoc @@ -63,7 +63,7 @@ used to effectively embed the elements and semantics of statecharts in Qt applications. The framework integrates tightly with Qt's meta-object system; for example, transitions between states can be triggered by signals, and - states can be configured to set properties and invoke methods on QObjects. + states can be configured to set properties and invoke methods on {QObject}s. Qt's event system is used to drive the state machines. The state graph in the State Machine framework is hierarchical. States can be nested inside of @@ -126,9 +126,9 @@ The QState::entered() signal is emitted when the state is entered, and the QState::exited() signal is emitted when the state is exited. In the - following snippet, the button's showMaximized() slot will be called when - state \c s3 is entered, and the button's showMinimized() slot will be called - when \c s3 is exited: + following snippet, the button's \l {QPushButton::}{showMaximized()} slot + will be called when state \c s3 is entered, and the button's \l {QPushButton::}{showMinimized()} + slot will be called when \c s3 is exited: \snippet statemachine/main.cpp 5 @@ -151,7 +151,7 @@ Assume we wanted the user to be able to quit the application at any time by clicking a Quit button. In order to achieve this, we need to create a final state and make it the target of a transition associated with the Quit - button's clicked() signal. We could add a transition from each of \c s1, \c + button's \l{QPushButton::}{clicked()} signal. We could add a transition from each of \c s1, \c s2 and \c s3; however, this seems redundant, and one would also have to remember to add such a transition from every new state that is added in the future. @@ -184,8 +184,8 @@ \snippet statemachine/main2.cpp 1 In this case we want the application to quit when the state machine is - finished, so the machine's finished() signal is connected to the - application's quit() slot. + finished, so the machine's \l {QStateMachine::}{finished()} signal is connected to the + application's \l {QCoreApplication::}{quit()} slot. A child state can override an inherited transition. For example, the following code adds a transition that effectively causes the Quit button to @@ -290,7 +290,7 @@ \endomit When \c s1 's final state is entered, \c s1 will automatically emit - finished(). We use a signal transition to cause this event to trigger a + \l {QState::}{finished()}. We use a signal transition to cause this event to trigger a state change: \snippet statemachine/main3.cpp 1 @@ -302,7 +302,7 @@ encapsulation mechanism when building complex (deeply nested) state machines. (In the above example, you could of course create a transition directly from \c s1 's \c done state rather than relying on \c s1 's - finished() signal, but with the consequence that implementation details of + \l {QState::}{finished()} signal, but with the consequence that implementation details of \c s1 are exposed and depended on). For parallel state groups, the QState::finished() signal is emitted when \e @@ -365,8 +365,8 @@ \snippet statemachine/main4.cpp 1 - In the eventTest() reimplementation, we first check if the event type is the - desired one; if so, we cast the event to a StringEvent and perform the + In the \l {QAbstractTransition::}{eventTest()} reimplementation, we first check if the event type is the + desired one; if so, we cast the event to a \c StringEvent and perform the string comparison. The following is a statechart that uses the custom event and transition: @@ -486,7 +486,7 @@ message box will pop up before the geometry of the button has actually been set. To ensure that the message box does not pop up until the geometry actually reaches its final - value, we can use the state's propertiesAssigned() signal. The propertiesAssigned() signal will be + value, we can use the state's \l {QState::}{propertiesAssigned()} signal. The \l {QState::}{propertiesAssigned()} signal will be emitted when the property is assigned its final value, whether this is done immediately or after the animation has finished playing. @@ -503,14 +503,14 @@ has been assigned the defined value. If the global restore policy is set to QStateMachine::RestoreProperties, the state will not emit - the propertiesAssigned() signal until these have been executed as well. + the \l {QState::}{propertiesAssigned()} signal until these have been executed as well. \section1 What Happens If A State Is Exited Before The Animation Has Finished If a state has property assignments, and the transition into the state has animations for the properties, the state can potentially be exited before the properties have been assigned to the values defines by the state. This is true in particular when there are transitions out from the - state that do not depend on the propertiesAssigned signal, as described in the previous section. + state that do not depend on the \l {QState::}{propertiesAssigned()} signal, as described in the previous section. The State Machine API guarantees that a property assigned by the state machine either: \list @@ -563,13 +563,13 @@ The parent state machine treats the child machine as an \e atomic state in the state machine algorithm. The child state machine is self-contained; it maintains its own event queue and - configuration. In particular, note that the \l{QStateMachine::configuration()}{configuration} + configuration. In particular, note that the \l{QStateMachine::}{configuration()} of the child machine is not part of the parent machine's configuration (only the child machine itself is). States of the child state machine cannot be specified as targets of transitions in the parent state machine; only the child state machine itself can. Conversely, states of the parent state machine cannot be specified as targets of transitions in the child state machine. The child - state machine's \l{QState::finished()}{finished}() signal can be used to trigger a transition + state machine's \l{QState::}{finished}() signal can be used to trigger a transition in the parent machine. */ -- cgit v1.2.3 From 083c9269ed73e8771e1dbe10812696b45b7389f3 Mon Sep 17 00:00:00 2001 From: Evangelos Foutras Date: Mon, 11 May 2015 12:20:57 +0300 Subject: Try to ensure that -fPIC is used in CMake builds In commit 36d6eb721e7d5997ade75e289d4088dc48678d0d the -fPIE switch was replaced with -fPIC in an effort to avoid generating copy relocations which are incompatible with Qt5 when built with -reduce-relocations. Task-number: QTBUG-45755 Change-Id: I59a55ea15052f498104848c5fd867e563ddc2290 Reviewed-by: Thiago Macieira --- src/corelib/Qt5CoreConfigExtras.cmake.in | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src/corelib') diff --git a/src/corelib/Qt5CoreConfigExtras.cmake.in b/src/corelib/Qt5CoreConfigExtras.cmake.in index 48d5f21447..d4abc5f271 100644 --- a/src/corelib/Qt5CoreConfigExtras.cmake.in +++ b/src/corelib/Qt5CoreConfigExtras.cmake.in @@ -70,8 +70,9 @@ set(_qt5_corelib_extra_includes) # Qt5_POSITION_INDEPENDENT_CODE variable is used in the # qt5_use_module # macro to add it. set(Qt5_POSITION_INDEPENDENT_CODE True) -set_property(TARGET Qt5::Core PROPERTY INTERFACE_POSITION_INDEPENDENT_CODE \"ON\") set(Qt5Core_EXECUTABLE_COMPILE_FLAGS \"-fPIC\") +set_property(TARGET Qt5::Core PROPERTY INTERFACE_POSITION_INDEPENDENT_CODE \"ON\") +set_property(TARGET Qt5::Core APPEND PROPERTY INTERFACE_COMPILE_OPTIONS ${Qt5Core_EXECUTABLE_COMPILE_FLAGS}) !!IF !isEmpty(QT_NAMESPACE) list(APPEND Qt5Core_DEFINITIONS -DQT_NAMESPACE=$$QT_NAMESPACE) -- cgit v1.2.3 From 20e36879d72f840005a0361368985b72ce4dc6a4 Mon Sep 17 00:00:00 2001 From: Venugopal Shivashankar Date: Fri, 15 May 2015 14:42:45 +0200 Subject: Doc: Excluded qdoc files that caused unnecessary Qt Creator warnings. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The customcompleter and textcodes are widget examples, but they end up in the Qt Core exampledirs boundary because of a reference to the plugandpaint example in the docs. This resulted in a couple of wrong entries being written into the examples-manifest.xml, which is used by Qt Creator. This change explicitly exludes the qdoc pages for the two examples so that qdoc doesn't add the corresponding entries into examples-manifest.xml. Task-number: QTBUG-41996 Change-Id: I0e95b6d4d93e0ce18f5b34e5034b279598b4924f Reviewed-by: Topi Reiniƶ Reviewed-by: Martin Smith --- src/corelib/doc/qtcore.qdocconf | 3 +++ 1 file changed, 3 insertions(+) (limited to 'src/corelib') diff --git a/src/corelib/doc/qtcore.qdocconf b/src/corelib/doc/qtcore.qdocconf index f3aff83a8b..a166df1143 100644 --- a/src/corelib/doc/qtcore.qdocconf +++ b/src/corelib/doc/qtcore.qdocconf @@ -42,5 +42,8 @@ imagedirs += images excludedirs += snippets +excludefiles += ../../../examples/widgets/tools/customcompleter/doc/src/customcompleter.qdoc \ + ../../../examples/widgets/tools/codecs/doc/src/codecs.qdoc + navigation.landingpage = "Qt Core" navigation.cppclassespage = "Qt Core C++ Classes" -- cgit v1.2.3 From e96ad10fd8f1d6badfe8ff7befbd397d5cbfe2b4 Mon Sep 17 00:00:00 2001 From: Andy Shaw Date: Wed, 20 May 2015 19:28:44 +0200 Subject: Ensure the same behavior on Win as Unix re the host in isApparentlyStale When the hostname is empty then it is assumed that the lock file is from the same host as the one running the application. Change-Id: Iba8aefc171a209294371dc2022d93ede3035b242 Reviewed-by: Will Wagner Reviewed-by: David Faure --- src/corelib/io/qlockfile_win.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/corelib') diff --git a/src/corelib/io/qlockfile_win.cpp b/src/corelib/io/qlockfile_win.cpp index 3587c7bffe..21ab8f8fea 100644 --- a/src/corelib/io/qlockfile_win.cpp +++ b/src/corelib/io/qlockfile_win.cpp @@ -120,7 +120,7 @@ bool QLockFilePrivate::isApparentlyStale() const // processes due to sandboxing #ifndef Q_OS_WINRT if (getLockInfo(&pid, &hostname, &appname)) { - if (hostname == QString::fromLocal8Bit(localHostName())) { + if (hostname.isEmpty() || hostname == QString::fromLocal8Bit(localHostName())) { HANDLE procHandle = ::OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, pid); if (!procHandle) return true; -- cgit v1.2.3 From a42330dc12bf7ee920e5c3c5a230e4fccae727bc Mon Sep 17 00:00:00 2001 From: Oliver Wolff Date: Tue, 26 May 2015 14:03:11 +0200 Subject: winrt: Fixed timer handling in case where additional user events occur When timers are used in connection with widgets, it is possible that additional events occur (e.g. deferred deletions). If these happen, the event dispatcher also has to handle timers after handling these events as timer events might not be handled at all otherwise. So instead of returning early, we check whether timer events happened and might return afterwards. Task-number: QTBUG-46299 Change-Id: I3ef0fb23b3ae9a1e13e42497bcfb0976cf4e1b91 Reviewed-by: Andrew Knight --- src/corelib/kernel/qeventdispatcher_winrt.cpp | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'src/corelib') diff --git a/src/corelib/kernel/qeventdispatcher_winrt.cpp b/src/corelib/kernel/qeventdispatcher_winrt.cpp index b5cfccd649..1509996199 100644 --- a/src/corelib/kernel/qeventdispatcher_winrt.cpp +++ b/src/corelib/kernel/qeventdispatcher_winrt.cpp @@ -203,9 +203,9 @@ bool QEventDispatcherWinRT::processEvents(QEventLoop::ProcessEventsFlags flags) } } - // Dispatch accumulated user events - if (sendPostedEvents(flags)) - return true; + // Additional user events have to be handled before timer events, but the function may not + // return yet. + const bool userEventsSent = sendPostedEvents(flags); emit aboutToBlock(); const QVector timerHandles = d->timerIdToHandle.values().toVector(); @@ -228,6 +228,9 @@ bool QEventDispatcherWinRT::processEvents(QEventLoop::ProcessEventsFlags flags) return true; } emit awake(); + + if (userEventsSent) + return true; } while (flags & QEventLoop::WaitForMoreEvents); return false; } -- cgit v1.2.3 From 8829ce67d8d0eac90e9fd6fde088b41f157177a5 Mon Sep 17 00:00:00 2001 From: Stephen Kelly Date: Mon, 25 May 2015 14:55:38 +0200 Subject: Only add -fPIC flags for compilers known to require it. Commit 083c9269 (Try to ensure that -fPIC is used in CMake builds, 2015-05-11) added a raw -fPIC to the INTERFACE_COMPILE_OPTIONS of Qt5::Core, which affects all consuming compilers. Use the qmake variable $$QMAKE_CXXFLAGS_APP instead, which at least currently contains only the -fPIC variable or harmlessly expands to nothing. If the content of that qmake variable changes in the future, a $$QMAKE_CXXFLAGS_APP_PIC variable should be extracted in qmake and used here. Don't use the POSITION_INDEPENDENT_CODE feature of CMake. That adds the -fPIE flag for executables, which is explicitly what qglobal.h forbids since commit 3eca75de (Make qglobal.h complain if you use -fPIE, 2015-05-11). The current behavior of that CMake feature is tracked here: http://public.kitware.com/Bug/view.php?id=15570 Change-Id: I5c5bcc40fe4b310b55a681a3505f45c50adfa054 Reviewed-by: Oswald Buddenhagen Reviewed-by: Simon Hausmann --- src/corelib/Qt5CoreConfigExtras.cmake.in | 3 +-- src/corelib/Qt5CoreMacros.cmake | 4 ---- 2 files changed, 1 insertion(+), 6 deletions(-) (limited to 'src/corelib') diff --git a/src/corelib/Qt5CoreConfigExtras.cmake.in b/src/corelib/Qt5CoreConfigExtras.cmake.in index d4abc5f271..a5cab880ba 100644 --- a/src/corelib/Qt5CoreConfigExtras.cmake.in +++ b/src/corelib/Qt5CoreConfigExtras.cmake.in @@ -71,8 +71,7 @@ set(_qt5_corelib_extra_includes) # macro to add it. set(Qt5_POSITION_INDEPENDENT_CODE True) set(Qt5Core_EXECUTABLE_COMPILE_FLAGS \"-fPIC\") -set_property(TARGET Qt5::Core PROPERTY INTERFACE_POSITION_INDEPENDENT_CODE \"ON\") -set_property(TARGET Qt5::Core APPEND PROPERTY INTERFACE_COMPILE_OPTIONS ${Qt5Core_EXECUTABLE_COMPILE_FLAGS}) +set_property(TARGET Qt5::Core APPEND PROPERTY INTERFACE_COMPILE_OPTIONS $$QMAKE_CXXFLAGS_APP) !!IF !isEmpty(QT_NAMESPACE) list(APPEND Qt5Core_DEFINITIONS -DQT_NAMESPACE=$$QT_NAMESPACE) diff --git a/src/corelib/Qt5CoreMacros.cmake b/src/corelib/Qt5CoreMacros.cmake index 9c81754302..c10880f787 100644 --- a/src/corelib/Qt5CoreMacros.cmake +++ b/src/corelib/Qt5CoreMacros.cmake @@ -281,10 +281,6 @@ if (NOT CMAKE_VERSION VERSION_LESS 2.8.9) set_property(TARGET ${_target} APPEND PROPERTY COMPILE_DEFINITIONS_RELEASE QT_NO_DEBUG) set_property(TARGET ${_target} APPEND PROPERTY COMPILE_DEFINITIONS_RELWITHDEBINFO QT_NO_DEBUG) set_property(TARGET ${_target} APPEND PROPERTY COMPILE_DEFINITIONS_MINSIZEREL QT_NO_DEBUG) - - if (Qt5_POSITION_INDEPENDENT_CODE) - set_property(TARGET ${_target} PROPERTY POSITION_INDEPENDENT_CODE ${Qt5_POSITION_INDEPENDENT_CODE}) - endif() endforeach() endmacro() endif() -- cgit v1.2.3 From 95b6c4fed6521aa2212cab67cb8a6e5553e86117 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Thu, 28 May 2015 11:21:35 -0700 Subject: Make qglobal.h only complain for GCC >= 5 about -fPIE Commit 3eca75de67b3fd2c890715b30c7899cebc096fe9 introduced the #error nagging about use of -fPIE, but it makes the transition quite difficult for people using other buildsystems. So let's give people a grace period and enforce only for GCC >= 5. Clang is affected, but differently. The problem only happens with -flto -- that is, it happens when the linker detects that it's creating a final executable. Maybe -Wl,-pie would fix it. Change-Id: If4d5ac8db0ed4a84a3eaffff13e275edc29a72b7 Reviewed-by: Simon Hausmann Reviewed-by: Dmitry Shachnev --- src/corelib/global/qglobal.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src/corelib') diff --git a/src/corelib/global/qglobal.h b/src/corelib/global/qglobal.h index 4547877da6..d9742408a3 100644 --- a/src/corelib/global/qglobal.h +++ b/src/corelib/global/qglobal.h @@ -1047,7 +1047,8 @@ Q_CORE_EXPORT int qrand(); # define QT_NO_SHAREDMEMORY #endif -#if !defined(QT_BOOTSTRAPPED) && defined(QT_REDUCE_RELOCATIONS) && defined(__ELF__) && (!defined(__PIC__) || defined(__PIE__)) +#if !defined(QT_BOOTSTRAPPED) && defined(QT_REDUCE_RELOCATIONS) && defined(__ELF__) && \ + (!defined(__PIC__) || (defined(__PIE__) && defined(Q_CC_GNU) && Q_CC_GNU >= 500)) # error "You must build your code with position independent code if Qt was built with -reduce-relocations. "\ "Compile your code with -fPIC (-fPIE is not enough)." #endif -- cgit v1.2.3 From e3983c87280ade48b243d9c60bed639713851be9 Mon Sep 17 00:00:00 2001 From: Stephen Kelly Date: Thu, 28 May 2015 21:20:55 +0200 Subject: Revert some changes in light of GCC 4 -fPIE reversal The -fPIE option is now accepted when using GCC 4, which means it is available for backward compatibility for clients using CMake 2.8.11 or older which makes use of the POSITION_INDEPENDENT_CODE feature. Conditionally use that feature for old versions of cmake with GCC 4. Restore the tests for those versions, and clarify the situation in the ChangeLog. Change-Id: I5a06b155dda7db559d86841a2b34fd8ed95acbd0 Reviewed-by: Thiago Macieira --- src/corelib/Qt5CoreConfigExtras.cmake.in | 8 +++++++- src/corelib/Qt5CoreMacros.cmake | 6 ++++++ 2 files changed, 13 insertions(+), 1 deletion(-) (limited to 'src/corelib') diff --git a/src/corelib/Qt5CoreConfigExtras.cmake.in b/src/corelib/Qt5CoreConfigExtras.cmake.in index a5cab880ba..65fd1f9383 100644 --- a/src/corelib/Qt5CoreConfigExtras.cmake.in +++ b/src/corelib/Qt5CoreConfigExtras.cmake.in @@ -71,7 +71,13 @@ set(_qt5_corelib_extra_includes) # macro to add it. set(Qt5_POSITION_INDEPENDENT_CODE True) set(Qt5Core_EXECUTABLE_COMPILE_FLAGS \"-fPIC\") -set_property(TARGET Qt5::Core APPEND PROPERTY INTERFACE_COMPILE_OPTIONS $$QMAKE_CXXFLAGS_APP) +if (CMAKE_VERSION VERSION_LESS 2.8.12 + AND (NOT CMAKE_CXX_COMPILER_ID STREQUAL \"GNU\" + OR CMAKE_CXX_COMPILER_VERSION VERSION_LESS 5.0)) + set_property(TARGET Qt5::Core APPEND PROPERTY INTERFACE_POSITION_INDEPENDENT_CODE \"ON\") +else() + set_property(TARGET Qt5::Core APPEND PROPERTY INTERFACE_COMPILE_OPTIONS $$QMAKE_CXXFLAGS_APP) +endif() !!IF !isEmpty(QT_NAMESPACE) list(APPEND Qt5Core_DEFINITIONS -DQT_NAMESPACE=$$QT_NAMESPACE) diff --git a/src/corelib/Qt5CoreMacros.cmake b/src/corelib/Qt5CoreMacros.cmake index c10880f787..cfbb381df5 100644 --- a/src/corelib/Qt5CoreMacros.cmake +++ b/src/corelib/Qt5CoreMacros.cmake @@ -281,6 +281,12 @@ if (NOT CMAKE_VERSION VERSION_LESS 2.8.9) set_property(TARGET ${_target} APPEND PROPERTY COMPILE_DEFINITIONS_RELEASE QT_NO_DEBUG) set_property(TARGET ${_target} APPEND PROPERTY COMPILE_DEFINITIONS_RELWITHDEBINFO QT_NO_DEBUG) set_property(TARGET ${_target} APPEND PROPERTY COMPILE_DEFINITIONS_MINSIZEREL QT_NO_DEBUG) + if (Qt5_POSITION_INDEPENDENT_CODE + AND (CMAKE_VERSION VERSION_LESS 2.8.12 + AND (NOT CMAKE_CXX_COMPILER_ID STREQUAL \"GNU\" + OR CMAKE_CXX_COMPILER_VERSION VERSION_LESS 5.0))) + set_property(TARGET ${_target} PROPERTY POSITION_INDEPENDENT_CODE ${Qt5_POSITION_INDEPENDENT_CODE}) + endif() endforeach() endmacro() endif() -- cgit v1.2.3