JNI: replace QString with QByteArray as the cache key type
The data combined into keys for the various caches is either QByteArray or plain const char *, so don't blow them up to QString. Standardize cache-key generation using a fold expression instead of QString::arg, which then makes use of QStringBuilder. Change-Id: I12bb104b0d57156358d93deec8ecd37e10b4f864 Reviewed-by: Juha Vuolle <juha.vuolle@qt.io> Reviewed-by: Zoltan Gera <zoltan.gera@qt.io> Reviewed-by: Tinja Paavoseppä <tinja.paavoseppa@qt.io>
This commit is contained in:
parent
19ce55c3b1
commit
a948b12423
@ -303,19 +303,20 @@ public:
|
|||||||
QByteArray m_className;
|
QByteArray m_className;
|
||||||
};
|
};
|
||||||
|
|
||||||
static inline QLatin1StringView keyBase()
|
template <typename ...Args>
|
||||||
|
static inline QByteArray cacheKey(Args &&...args)
|
||||||
{
|
{
|
||||||
return "%1%2:%3"_L1;
|
return (QByteArrayView(":") + ... + QByteArrayView(args));
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef QHash<QString, jclass> JClassHash;
|
typedef QHash<QByteArray, jclass> JClassHash;
|
||||||
Q_GLOBAL_STATIC(JClassHash, cachedClasses)
|
Q_GLOBAL_STATIC(JClassHash, cachedClasses)
|
||||||
Q_GLOBAL_STATIC(QReadWriteLock, cachedClassesLock)
|
Q_GLOBAL_STATIC(QReadWriteLock, cachedClassesLock)
|
||||||
|
|
||||||
static jclass getCachedClass(const QByteArray &classBinEnc, bool *isCached = nullptr)
|
static jclass getCachedClass(const QByteArray &classBinEnc, bool *isCached = nullptr)
|
||||||
{
|
{
|
||||||
QReadLocker locker(cachedClassesLock);
|
QReadLocker locker(cachedClassesLock);
|
||||||
const QHash<QString, jclass>::const_iterator &it = cachedClasses->constFind(QString::fromLatin1(classBinEnc));
|
const auto &it = cachedClasses->constFind(classBinEnc);
|
||||||
const bool found = (it != cachedClasses->constEnd());
|
const bool found = (it != cachedClasses->constEnd());
|
||||||
|
|
||||||
if (isCached)
|
if (isCached)
|
||||||
@ -344,12 +345,11 @@ jclass QJniObject::loadClass(const QByteArray &className, JNIEnv *env, bool binE
|
|||||||
|
|
||||||
QWriteLocker locker(cachedClassesLock);
|
QWriteLocker locker(cachedClassesLock);
|
||||||
// did we lose the race?
|
// did we lose the race?
|
||||||
const QLatin1StringView key(binEncClassName);
|
const auto &it = cachedClasses->constFind(binEncClassName);
|
||||||
const QHash<QString, jclass>::const_iterator &it = cachedClasses->constFind(key);
|
|
||||||
if (it != cachedClasses->constEnd())
|
if (it != cachedClasses->constEnd())
|
||||||
return it.value();
|
return it.value();
|
||||||
|
|
||||||
QJniObject stringName = QJniObject::fromString(key);
|
QJniObject stringName = QJniObject::fromString(QString::fromLatin1(binEncClassName));
|
||||||
QJniObject classObject = classLoader.callObjectMethod("loadClass",
|
QJniObject classObject = classLoader.callObjectMethod("loadClass",
|
||||||
"(Ljava/lang/String;)Ljava/lang/Class;",
|
"(Ljava/lang/String;)Ljava/lang/Class;",
|
||||||
stringName.object());
|
stringName.object());
|
||||||
@ -357,11 +357,11 @@ jclass QJniObject::loadClass(const QByteArray &className, JNIEnv *env, bool binE
|
|||||||
if (!QJniEnvironment::checkAndClearExceptions(env) && classObject.isValid())
|
if (!QJniEnvironment::checkAndClearExceptions(env) && classObject.isValid())
|
||||||
clazz = static_cast<jclass>(env->NewGlobalRef(classObject.object()));
|
clazz = static_cast<jclass>(env->NewGlobalRef(classObject.object()));
|
||||||
|
|
||||||
cachedClasses->insert(key, clazz);
|
cachedClasses->insert(binEncClassName, clazz);
|
||||||
return clazz;
|
return clazz;
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef QHash<QString, jmethodID> JMethodIDHash;
|
typedef QHash<QByteArray, jmethodID> JMethodIDHash;
|
||||||
Q_GLOBAL_STATIC(JMethodIDHash, cachedMethodID)
|
Q_GLOBAL_STATIC(JMethodIDHash, cachedMethodID)
|
||||||
Q_GLOBAL_STATIC(QReadWriteLock, cachedMethodIDLock)
|
Q_GLOBAL_STATIC(QReadWriteLock, cachedMethodIDLock)
|
||||||
|
|
||||||
@ -403,10 +403,8 @@ jmethodID QJniObject::getCachedMethodID(JNIEnv *env,
|
|||||||
if (className.isEmpty())
|
if (className.isEmpty())
|
||||||
return getMethodID(env, clazz, name, signature, isStatic);
|
return getMethodID(env, clazz, name, signature, isStatic);
|
||||||
|
|
||||||
const QString key = keyBase().arg(QLatin1StringView(className),
|
const QByteArray key = cacheKey(className, name, signature);
|
||||||
QLatin1StringView(name),
|
QHash<QByteArray, jmethodID>::const_iterator it;
|
||||||
QLatin1StringView(signature));
|
|
||||||
QHash<QString, jmethodID>::const_iterator it;
|
|
||||||
|
|
||||||
{
|
{
|
||||||
QReadLocker locker(cachedMethodIDLock);
|
QReadLocker locker(cachedMethodIDLock);
|
||||||
@ -434,7 +432,7 @@ jmethodID QJniObject::getCachedMethodID(JNIEnv *env, const char *name,
|
|||||||
return QJniObject::getCachedMethodID(env, d->m_jclass, d->m_className, name, signature, isStatic);
|
return QJniObject::getCachedMethodID(env, d->m_jclass, d->m_className, name, signature, isStatic);
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef QHash<QString, jfieldID> JFieldIDHash;
|
typedef QHash<QByteArray, jfieldID> JFieldIDHash;
|
||||||
Q_GLOBAL_STATIC(JFieldIDHash, cachedFieldID)
|
Q_GLOBAL_STATIC(JFieldIDHash, cachedFieldID)
|
||||||
Q_GLOBAL_STATIC(QReadWriteLock, cachedFieldIDLock)
|
Q_GLOBAL_STATIC(QReadWriteLock, cachedFieldIDLock)
|
||||||
|
|
||||||
@ -463,10 +461,8 @@ jfieldID QJniObject::getCachedFieldID(JNIEnv *env,
|
|||||||
if (className.isNull())
|
if (className.isNull())
|
||||||
return getFieldID(env, clazz, name, signature, isStatic);
|
return getFieldID(env, clazz, name, signature, isStatic);
|
||||||
|
|
||||||
const QString key = keyBase().arg(QLatin1StringView(className),
|
const QByteArray key = cacheKey(className, name, signature);
|
||||||
QLatin1StringView(name),
|
QHash<QByteArray, jfieldID>::const_iterator it;
|
||||||
QLatin1StringView(signature));
|
|
||||||
QHash<QString, jfieldID>::const_iterator it;
|
|
||||||
|
|
||||||
{
|
{
|
||||||
QReadLocker locker(cachedFieldIDLock);
|
QReadLocker locker(cachedFieldIDLock);
|
||||||
@ -505,10 +501,9 @@ jclass QtAndroidPrivate::findClass(const char *className, JNIEnv *env)
|
|||||||
if (clazz || isCached)
|
if (clazz || isCached)
|
||||||
return clazz;
|
return clazz;
|
||||||
|
|
||||||
const QLatin1StringView key(classDotEnc);
|
|
||||||
if (env) { // We got an env. pointer (We expect this to be the right env. and call FindClass())
|
if (env) { // We got an env. pointer (We expect this to be the right env. and call FindClass())
|
||||||
QWriteLocker locker(cachedClassesLock);
|
QWriteLocker locker(cachedClassesLock);
|
||||||
const QHash<QString, jclass>::const_iterator &it = cachedClasses->constFind(key);
|
const auto &it = cachedClasses->constFind(classDotEnc);
|
||||||
// Did we lose the race?
|
// Did we lose the race?
|
||||||
if (it != cachedClasses->constEnd())
|
if (it != cachedClasses->constEnd())
|
||||||
return it.value();
|
return it.value();
|
||||||
@ -520,7 +515,7 @@ jclass QtAndroidPrivate::findClass(const char *className, JNIEnv *env)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (clazz)
|
if (clazz)
|
||||||
cachedClasses->insert(key, clazz);
|
cachedClasses->insert(classDotEnc, clazz);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!clazz) // We didn't get an env. pointer or we got one with the WRONG class loader...
|
if (!clazz) // We didn't get an env. pointer or we got one with the WRONG class loader...
|
||||||
|
Loading…
x
Reference in New Issue
Block a user