Commit c6bc15db authored by torne's avatar torne Committed by Commit bot

Small improvements to JNI references.

Add a move constructor and move assignment operator to local, global and
weak references to reduce reference churn (saves a small number of bytes).
Allow weak references to be constructed from JavaRef.
Replace NULL with nullptr in jni_weak_ref code.

BUG=

Review-Url: https://codereview.chromium.org/2268553002
Cr-Commit-Position: refs/heads/master@{#414444}
parent 330958dd
...@@ -4,26 +4,38 @@ ...@@ -4,26 +4,38 @@
#include "base/android/jni_weak_ref.h" #include "base/android/jni_weak_ref.h"
#include <utility>
#include "base/android/jni_android.h" #include "base/android/jni_android.h"
#include "base/logging.h" #include "base/logging.h"
using base::android::AttachCurrentThread; using base::android::AttachCurrentThread;
JavaObjectWeakGlobalRef::JavaObjectWeakGlobalRef() JavaObjectWeakGlobalRef::JavaObjectWeakGlobalRef() : obj_(nullptr) {}
: obj_(NULL) {
}
JavaObjectWeakGlobalRef::JavaObjectWeakGlobalRef( JavaObjectWeakGlobalRef::JavaObjectWeakGlobalRef(
const JavaObjectWeakGlobalRef& orig) const JavaObjectWeakGlobalRef& orig)
: obj_(NULL) { : obj_(nullptr) {
Assign(orig); Assign(orig);
} }
JavaObjectWeakGlobalRef::JavaObjectWeakGlobalRef(JavaObjectWeakGlobalRef&& orig)
: obj_(orig.obj_) {
orig.obj_ = nullptr;
}
JavaObjectWeakGlobalRef::JavaObjectWeakGlobalRef(JNIEnv* env, jobject obj) JavaObjectWeakGlobalRef::JavaObjectWeakGlobalRef(JNIEnv* env, jobject obj)
: obj_(env->NewWeakGlobalRef(obj)) { : obj_(env->NewWeakGlobalRef(obj)) {
DCHECK(obj_); DCHECK(obj_);
} }
JavaObjectWeakGlobalRef::JavaObjectWeakGlobalRef(
JNIEnv* env,
const base::android::JavaRef<jobject>& obj)
: obj_(env->NewWeakGlobalRef(obj.obj())) {
DCHECK(obj_);
}
JavaObjectWeakGlobalRef::~JavaObjectWeakGlobalRef() { JavaObjectWeakGlobalRef::~JavaObjectWeakGlobalRef() {
reset(); reset();
} }
...@@ -32,10 +44,14 @@ void JavaObjectWeakGlobalRef::operator=(const JavaObjectWeakGlobalRef& rhs) { ...@@ -32,10 +44,14 @@ void JavaObjectWeakGlobalRef::operator=(const JavaObjectWeakGlobalRef& rhs) {
Assign(rhs); Assign(rhs);
} }
void JavaObjectWeakGlobalRef::operator=(JavaObjectWeakGlobalRef&& rhs) {
std::swap(obj_, rhs.obj_);
}
void JavaObjectWeakGlobalRef::reset() { void JavaObjectWeakGlobalRef::reset() {
if (obj_) { if (obj_) {
AttachCurrentThread()->DeleteWeakGlobalRef(obj_); AttachCurrentThread()->DeleteWeakGlobalRef(obj_);
obj_ = NULL; obj_ = nullptr;
} }
} }
...@@ -46,7 +62,7 @@ base::android::ScopedJavaLocalRef<jobject> ...@@ -46,7 +62,7 @@ base::android::ScopedJavaLocalRef<jobject>
base::android::ScopedJavaLocalRef<jobject> GetRealObject( base::android::ScopedJavaLocalRef<jobject> GetRealObject(
JNIEnv* env, jweak obj) { JNIEnv* env, jweak obj) {
jobject real = NULL; jobject real = nullptr;
if (obj) if (obj)
real = env->NewLocalRef(obj); real = env->NewLocalRef(obj);
return base::android::ScopedJavaLocalRef<jobject>(env, real); return base::android::ScopedJavaLocalRef<jobject>(env, real);
...@@ -60,5 +76,5 @@ void JavaObjectWeakGlobalRef::Assign(const JavaObjectWeakGlobalRef& other) { ...@@ -60,5 +76,5 @@ void JavaObjectWeakGlobalRef::Assign(const JavaObjectWeakGlobalRef& other) {
if (obj_) if (obj_)
env->DeleteWeakGlobalRef(obj_); env->DeleteWeakGlobalRef(obj_);
obj_ = other.obj_ ? env->NewWeakGlobalRef(other.obj_) : NULL; obj_ = other.obj_ ? env->NewWeakGlobalRef(other.obj_) : nullptr;
} }
...@@ -18,14 +18,18 @@ class BASE_EXPORT JavaObjectWeakGlobalRef { ...@@ -18,14 +18,18 @@ class BASE_EXPORT JavaObjectWeakGlobalRef {
public: public:
JavaObjectWeakGlobalRef(); JavaObjectWeakGlobalRef();
JavaObjectWeakGlobalRef(const JavaObjectWeakGlobalRef& orig); JavaObjectWeakGlobalRef(const JavaObjectWeakGlobalRef& orig);
JavaObjectWeakGlobalRef(JavaObjectWeakGlobalRef&& orig);
JavaObjectWeakGlobalRef(JNIEnv* env, jobject obj); JavaObjectWeakGlobalRef(JNIEnv* env, jobject obj);
JavaObjectWeakGlobalRef(JNIEnv* env,
const base::android::JavaRef<jobject>& obj);
virtual ~JavaObjectWeakGlobalRef(); virtual ~JavaObjectWeakGlobalRef();
void operator=(const JavaObjectWeakGlobalRef& rhs); void operator=(const JavaObjectWeakGlobalRef& rhs);
void operator=(JavaObjectWeakGlobalRef&& rhs);
base::android::ScopedJavaLocalRef<jobject> get(JNIEnv* env) const; base::android::ScopedJavaLocalRef<jobject> get(JNIEnv* env) const;
bool is_empty() const { return obj_ == NULL; } bool is_empty() const { return obj_ == nullptr; }
void reset(); void reset();
......
...@@ -9,6 +9,7 @@ ...@@ -9,6 +9,7 @@
#include <stddef.h> #include <stddef.h>
#include <type_traits> #include <type_traits>
#include <utility>
#include "base/base_export.h" #include "base/base_export.h"
#include "base/logging.h" #include "base/logging.h"
...@@ -70,6 +71,8 @@ class BASE_EXPORT JavaRef<jobject> { ...@@ -70,6 +71,8 @@ class BASE_EXPORT JavaRef<jobject> {
JavaRef(JNIEnv* env, jobject obj) : obj_(obj) {} JavaRef(JNIEnv* env, jobject obj) : obj_(obj) {}
#endif #endif
void swap(JavaRef& other) { std::swap(obj_, other.obj_); }
// The following are implementation detail convenience methods, for // The following are implementation detail convenience methods, for
// use by the sub-classes. // use by the sub-classes.
JNIEnv* SetNewLocalRef(JNIEnv* env, jobject obj); JNIEnv* SetNewLocalRef(JNIEnv* env, jobject obj);
...@@ -153,6 +156,10 @@ class ScopedJavaLocalRef : public JavaRef<T> { ...@@ -153,6 +156,10 @@ class ScopedJavaLocalRef : public JavaRef<T> {
this->SetNewLocalRef(env_, other.obj()); this->SetNewLocalRef(env_, other.obj());
} }
ScopedJavaLocalRef(ScopedJavaLocalRef<T>&& other) : env_(other.env_) {
this->swap(other);
}
template <typename U> template <typename U>
explicit ScopedJavaLocalRef(const U& other) : env_(nullptr) { explicit ScopedJavaLocalRef(const U& other) : env_(nullptr) {
this->Reset(other); this->Reset(other);
...@@ -172,6 +179,11 @@ class ScopedJavaLocalRef : public JavaRef<T> { ...@@ -172,6 +179,11 @@ class ScopedJavaLocalRef : public JavaRef<T> {
this->Reset(other); this->Reset(other);
} }
void operator=(ScopedJavaLocalRef<T>&& other) {
env_ = other.env_;
this->swap(other);
}
void Reset() { void Reset() {
this->ResetLocalRef(env_); this->ResetLocalRef(env_);
} }
...@@ -231,6 +243,8 @@ class ScopedJavaGlobalRef : public JavaRef<T> { ...@@ -231,6 +243,8 @@ class ScopedJavaGlobalRef : public JavaRef<T> {
this->Reset(other); this->Reset(other);
} }
ScopedJavaGlobalRef(ScopedJavaGlobalRef<T>&& other) { this->swap(other); }
ScopedJavaGlobalRef(JNIEnv* env, T obj) { this->Reset(env, obj); } ScopedJavaGlobalRef(JNIEnv* env, T obj) { this->Reset(env, obj); }
template<typename U> template<typename U>
...@@ -248,6 +262,8 @@ class ScopedJavaGlobalRef : public JavaRef<T> { ...@@ -248,6 +262,8 @@ class ScopedJavaGlobalRef : public JavaRef<T> {
this->Reset(other); this->Reset(other);
} }
void operator=(ScopedJavaGlobalRef<T>&& other) { this->swap(other); }
void Reset() { void Reset() {
this->ResetGlobalRef(); this->ResetGlobalRef();
} }
......
...@@ -106,6 +106,17 @@ TEST_F(ScopedJavaRefTest, RefCounts) { ...@@ -106,6 +106,17 @@ TEST_F(ScopedJavaRefTest, RefCounts) {
EXPECT_EQ(2, g_local_refs); EXPECT_EQ(2, g_local_refs);
} }
EXPECT_EQ(1, g_local_refs); EXPECT_EQ(1, g_local_refs);
{
ScopedJavaLocalRef<jstring> str4((ScopedJavaLocalRef<jstring>(str2)));
EXPECT_EQ(2, g_local_refs);
}
EXPECT_EQ(1, g_local_refs);
{
ScopedJavaLocalRef<jstring> str5;
str5 = ScopedJavaLocalRef<jstring>(str2);
EXPECT_EQ(2, g_local_refs);
}
EXPECT_EQ(1, g_local_refs);
str2.Reset(); str2.Reset();
EXPECT_EQ(0, g_local_refs); EXPECT_EQ(0, g_local_refs);
global_str.Reset(); global_str.Reset();
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment