зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1192043 - Add more JNIEnv support and null-check refs in JNI ref classs; r=snorp
Add more constructors in LocalRef and GlobalRef to accommodate use cases where a JNIEnv is already available for performance reasons. Also add more null-checks when creating references for performance reasons.
This commit is contained in:
Родитель
4149622c41
Коммит
4403af4250
|
@ -214,8 +214,6 @@ template<class Cls>
|
||||||
class Ref : public RefBase<Cls, jobject>
|
class Ref : public RefBase<Cls, jobject>
|
||||||
{
|
{
|
||||||
template<class C, typename T> friend class RefBase;
|
template<class C, typename T> friend class RefBase;
|
||||||
friend class jni::LocalRef<Cls>;
|
|
||||||
friend class jni::GlobalRef<Cls>;
|
|
||||||
friend struct detail::TypeAdapter<Ref<Cls>>;
|
friend struct detail::TypeAdapter<Ref<Cls>>;
|
||||||
|
|
||||||
typedef RefBase<Cls, jobject> Base;
|
typedef RefBase<Cls, jobject> Base;
|
||||||
|
@ -248,8 +246,6 @@ class Ref<TypedObject<T>>
|
||||||
: public RefBase<TypedObject<T>, T>
|
: public RefBase<TypedObject<T>, T>
|
||||||
{
|
{
|
||||||
friend class RefBase<TypedObject<T>, T>;
|
friend class RefBase<TypedObject<T>, T>;
|
||||||
friend class jni::LocalRef<TypedObject<T>>;
|
|
||||||
friend class jni::GlobalRef<TypedObject<T>>;
|
|
||||||
friend struct detail::TypeAdapter<Ref<TypedObject<T>>>;
|
friend struct detail::TypeAdapter<Ref<TypedObject<T>>>;
|
||||||
|
|
||||||
typedef RefBase<TypedObject<T>, T> Base;
|
typedef RefBase<TypedObject<T>, T> Base;
|
||||||
|
@ -300,6 +296,14 @@ private:
|
||||||
template<class C> using GenericLocalRef
|
template<class C> using GenericLocalRef
|
||||||
= typename GenericLocalRef<Cls>::template Type<C>;
|
= typename GenericLocalRef<Cls>::template Type<C>;
|
||||||
|
|
||||||
|
static jobject NewLocalRef(JNIEnv* env, jobject obj)
|
||||||
|
{
|
||||||
|
if (!obj) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
return env->NewLocalRef(obj);
|
||||||
|
}
|
||||||
|
|
||||||
JNIEnv* const mEnv;
|
JNIEnv* const mEnv;
|
||||||
|
|
||||||
LocalRef(JNIEnv* env, jobject instance)
|
LocalRef(JNIEnv* env, jobject instance)
|
||||||
|
@ -331,7 +335,7 @@ public:
|
||||||
|
|
||||||
// Copy constructor.
|
// Copy constructor.
|
||||||
LocalRef(const LocalRef<Cls>& ref)
|
LocalRef(const LocalRef<Cls>& ref)
|
||||||
: Ref<Cls>(ref.mEnv->NewLocalRef(ref.mInstance))
|
: Ref<Cls>(NewLocalRef(ref.mEnv, ref.mInstance))
|
||||||
, mEnv(ref.mEnv)
|
, mEnv(ref.mEnv)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
@ -354,9 +358,14 @@ public:
|
||||||
: Ref<Cls>(nullptr)
|
: Ref<Cls>(nullptr)
|
||||||
, mEnv(GetEnvForThread())
|
, mEnv(GetEnvForThread())
|
||||||
{
|
{
|
||||||
Ref<Cls>::mInstance = mEnv->NewLocalRef(ref.mInstance);
|
Ref<Cls>::mInstance = NewLocalRef(mEnv, ref.Get());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
LocalRef(JNIEnv* env, const Ref<Cls>& ref)
|
||||||
|
: Ref<Cls>(NewLocalRef(env, ref.Get()))
|
||||||
|
, mEnv(env)
|
||||||
|
{}
|
||||||
|
|
||||||
// Move a LocalRef<Object> into a LocalRef<Cls> without
|
// Move a LocalRef<Object> into a LocalRef<Cls> without
|
||||||
// creating/deleting local references.
|
// creating/deleting local references.
|
||||||
MOZ_IMPLICIT LocalRef(LocalRef<GenericObject>&& ref)
|
MOZ_IMPLICIT LocalRef(LocalRef<GenericObject>&& ref)
|
||||||
|
@ -410,7 +419,7 @@ public:
|
||||||
|
|
||||||
LocalRef<Cls>& operator=(const Ref<Cls>& ref)
|
LocalRef<Cls>& operator=(const Ref<Cls>& ref)
|
||||||
{
|
{
|
||||||
LocalRef<Cls> newRef(mEnv, mEnv->NewLocalRef(ref.mInstance));
|
LocalRef<Cls> newRef(mEnv, ref);
|
||||||
return swap(newRef);
|
return swap(newRef);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -444,9 +453,6 @@ private:
|
||||||
if (!instance) {
|
if (!instance) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
if (!env) {
|
|
||||||
env = GetEnvForThread();
|
|
||||||
}
|
|
||||||
return env->NewGlobalRef(instance);
|
return env->NewGlobalRef(instance);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -465,7 +471,7 @@ public:
|
||||||
|
|
||||||
// Copy constructor
|
// Copy constructor
|
||||||
GlobalRef(const GlobalRef& ref)
|
GlobalRef(const GlobalRef& ref)
|
||||||
: Ref<Cls>(NewGlobalRef(nullptr, ref.mInstance))
|
: Ref<Cls>(NewGlobalRef(GetEnvForThread(), ref.mInstance))
|
||||||
{}
|
{}
|
||||||
|
|
||||||
// Move constructor
|
// Move constructor
|
||||||
|
@ -476,11 +482,15 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
MOZ_IMPLICIT GlobalRef(const Ref<Cls>& ref)
|
MOZ_IMPLICIT GlobalRef(const Ref<Cls>& ref)
|
||||||
: Ref<Cls>(NewGlobalRef(nullptr, ref.mInstance))
|
: Ref<Cls>(NewGlobalRef(GetEnvForThread(), ref.Get()))
|
||||||
{}
|
{}
|
||||||
|
|
||||||
GlobalRef(JNIEnv* env, const Ref<Cls>& ref)
|
GlobalRef(JNIEnv* env, const Ref<Cls>& ref)
|
||||||
: Ref<Cls>(NewGlobalRef(env, ref.mInstance))
|
: Ref<Cls>(NewGlobalRef(env, ref.Get()))
|
||||||
|
{}
|
||||||
|
|
||||||
|
MOZ_IMPLICIT GlobalRef(const LocalRef<Cls>& ref)
|
||||||
|
: Ref<Cls>(NewGlobalRef(ref.Env(), ref.Get()))
|
||||||
{}
|
{}
|
||||||
|
|
||||||
// Implicitly converts nullptr to GlobalRef.
|
// Implicitly converts nullptr to GlobalRef.
|
||||||
|
@ -491,9 +501,7 @@ public:
|
||||||
~GlobalRef()
|
~GlobalRef()
|
||||||
{
|
{
|
||||||
if (Ref<Cls>::mInstance) {
|
if (Ref<Cls>::mInstance) {
|
||||||
JNIEnv* const env = GetEnvForThread();
|
Clear(GetEnvForThread());
|
||||||
env->DeleteGlobalRef(Ref<Cls>::mInstance);
|
|
||||||
Ref<Cls>::mInstance = nullptr;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -506,6 +514,14 @@ public:
|
||||||
return obj;
|
return obj;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Clear(JNIEnv* env)
|
||||||
|
{
|
||||||
|
if (Ref<Cls>::mInstance) {
|
||||||
|
env->DeleteGlobalRef(Ref<Cls>::mInstance);
|
||||||
|
Ref<Cls>::mInstance = nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
GlobalRef<Cls>& operator=(GlobalRef<Cls> ref)
|
GlobalRef<Cls>& operator=(GlobalRef<Cls> ref)
|
||||||
{
|
{
|
||||||
return swap(ref);
|
return swap(ref);
|
||||||
|
@ -530,8 +546,6 @@ template<>
|
||||||
class Ref<String> : public RefBase<String, jstring>
|
class Ref<String> : public RefBase<String, jstring>
|
||||||
{
|
{
|
||||||
friend class RefBase<String, jstring>;
|
friend class RefBase<String, jstring>;
|
||||||
friend class jni::LocalRef<String>;
|
|
||||||
friend class jni::GlobalRef<String>;
|
|
||||||
friend struct detail::TypeAdapter<Ref<String>>;
|
friend struct detail::TypeAdapter<Ref<String>>;
|
||||||
|
|
||||||
typedef RefBase<TypedObject<jstring>, jstring> Base;
|
typedef RefBase<TypedObject<jstring>, jstring> Base;
|
||||||
|
@ -625,10 +639,9 @@ public:
|
||||||
|
|
||||||
operator String::LocalRef() const
|
operator String::LocalRef() const
|
||||||
{
|
{
|
||||||
JNIEnv* const env = mEnv ? mEnv : GetEnvForThread();
|
|
||||||
// We can't return our existing ref because the returned
|
// We can't return our existing ref because the returned
|
||||||
// LocalRef could be freed first, so we need a new local ref.
|
// LocalRef could be freed first, so we need a new local ref.
|
||||||
return String::LocalRef::Adopt(env, env->NewLocalRef(Get()));
|
return String::LocalRef(mEnv ? mEnv : GetEnvForThread(), *this);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Загрузка…
Ссылка в новой задаче