Bug 1492308 - 2. Create new native handle before clearing old one; r=snorp
authorJim Chen <nchen@mozilla.com>
Tue, 02 Oct 2018 19:59:32 +0000
changeset 495019 8ab31240dbec5dbe913462a7d68dfa3f5526cdce
parent 495018 0f4cf0de3dfa19eea89f6d5c55ac7f4e980e0c90
child 495020 7893e8aae29590b426a71fb7fe151dc75b385143
push id9984
push userffxbld-merge
push dateMon, 15 Oct 2018 21:07:35 +0000
treeherdermozilla-beta@183d27ea8570 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssnorp
bugs1492308
milestone64.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1492308 - 2. Create new native handle before clearing old one; r=snorp Create a new native handle first before deleting any old ones, so we can be sure the new handle would not have the same value as the old handle, which can confuse our code. Differential Revision: https://phabricator.services.mozilla.com/D7107
widget/android/jni/Natives.h
--- a/widget/android/jni/Natives.h
+++ b/widget/android/jni/Natives.h
@@ -220,19 +220,22 @@ struct NativePtr<Impl, /* Type = */ Nati
     static Impl* Get(const LocalRef& instance)
     {
         return Get(instance.Env(), instance.Get());
     }
 
     template<class LocalRef>
     static void Set(const LocalRef& instance, Impl* ptr)
     {
+        // Create the new handle first before clearing any old handle, so the
+        // new handle is guaranteed to have different value than any old handle.
+        const uintptr_t handle =
+                reinterpret_cast<uintptr_t>(new WeakPtr<Impl>(ptr));
         Clear(instance);
-        SetNativeHandle(instance.Env(), instance.Get(),
-                          reinterpret_cast<uintptr_t>(new WeakPtr<Impl>(ptr)));
+        SetNativeHandle(instance.Env(), instance.Get(), handle);
         MOZ_CATCH_JNI_EXCEPTION(instance.Env());
     }
 
     template<class LocalRef>
     static void Clear(const LocalRef& instance)
     {
         const auto ptr = reinterpret_cast<WeakPtr<Impl>*>(
                 GetNativeHandle(instance.Env(), instance.Get()));
@@ -265,19 +268,22 @@ struct NativePtr<Impl, /* Type = */ Nati
     static Impl* Get(const LocalRef& instance)
     {
         return Get(instance.Env(), instance.Get());
     }
 
     template<class LocalRef>
     static void Set(const LocalRef& instance, Impl* ptr)
     {
+        // Create the new handle first before clearing any old handle, so the
+        // new handle is guaranteed to have different value than any old handle.
+        const uintptr_t handle =
+                reinterpret_cast<uintptr_t>(new RefPtr<Impl>(ptr));
         Clear(instance);
-        SetNativeHandle(instance.Env(), instance.Get(),
-                        reinterpret_cast<uintptr_t>(new RefPtr<Impl>(ptr)));
+        SetNativeHandle(instance.Env(), instance.Get(), handle);
         MOZ_CATCH_JNI_EXCEPTION(instance.Env());
     }
 
     template<class LocalRef>
     static void Clear(const LocalRef& instance)
     {
         const auto ptr = reinterpret_cast<RefPtr<Impl>*>(
                 GetNativeHandle(instance.Env(), instance.Get()));