Bug 751262 - Don't pop the JNI local ref frame if pushing it failed. r=kats a=mfinkle
authorBrad Lassey <blassey@mozilla.com>
Tue, 08 May 2012 20:21:36 -0400
changeset 95739 ff46c92d32e601cd13e02aa2609eac49fe30b759
parent 95738 c79b814c8538c55cec2bf259e5940b885e6a5200
child 95740 6b1cf014bfd58078f76d63289e0caece8b90c026
push id886
push userlsblakk@mozilla.com
push dateMon, 04 Jun 2012 19:57:52 +0000
treeherdermozilla-beta@bbd8d5efd6d1 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerskats, mfinkle
bugs751262
milestone14.0a2
Bug 751262 - Don't pop the JNI local ref frame if pushing it failed. r=kats a=mfinkle
widget/android/AndroidBridge.h
--- a/widget/android/AndroidBridge.h
+++ b/widget/android/AndroidBridge.h
@@ -545,36 +545,37 @@ protected:
     int (* Surface_unlockAndPost)(void* surface);
     void (* Region_constructor)(void* region);
     void (* Region_set)(void* region, void* rect);
 };
 
 class AutoLocalJNIFrame {
 public:
     AutoLocalJNIFrame(int nEntries = 128)
-        : mEntries(nEntries)
+        : mEntries(nEntries), mHasFrameBeenPushed(false)
     {
         mJNIEnv = AndroidBridge::GetJNIEnv();
         Push();
     }
 
     AutoLocalJNIFrame(JNIEnv* aJNIEnv, int nEntries = 128)
-        : mEntries(nEntries)
+        : mEntries(nEntries), mHasFrameBeenPushed(false)
     {
         mJNIEnv = aJNIEnv ? aJNIEnv : AndroidBridge::GetJNIEnv();
 
         Push();
     }
 
     // Note! Calling Purge makes all previous local refs created in
     // the AutoLocalJNIFrame's scope INVALID; be sure that you locked down
     // any local refs that you need to keep around in global refs!
     void Purge() {
         if (mJNIEnv) {
-            mJNIEnv->PopLocalFrame(NULL);
+            if (mHasFrameBeenPushed)
+                mJNIEnv->PopLocalFrame(NULL);
             Push();
         }
     }
 
     bool CheckForException() {
         if (mJNIEnv->ExceptionCheck()) {
             mJNIEnv->ExceptionDescribe();
             mJNIEnv->ExceptionClear();
@@ -585,36 +586,39 @@ public:
     }
 
     ~AutoLocalJNIFrame() {
         if (!mJNIEnv)
             return;
 
         CheckForException();
 
-        mJNIEnv->PopLocalFrame(NULL);
+        if (mHasFrameBeenPushed)
+            mJNIEnv->PopLocalFrame(NULL);
     }
 
 private:
     void Push() {
         if (!mJNIEnv)
             return;
 
         // Make sure there is enough space to store a local ref to the
         // exception.  I am not completely sure this is needed, but does
         // not hurt.
         jint ret = mJNIEnv->PushLocalFrame(mEntries + 1);
         NS_ABORT_IF_FALSE(ret == 0, "Failed to push local JNI frame");
-        if (ret < 0) {
+        if (ret < 0)
             CheckForException();
-        }
+        else
+            mHasFrameBeenPushed = true;
     }
 
     int mEntries;
     JNIEnv* mJNIEnv;
+    bool mHasFrameBeenPushed;
 };
 
 }
 
 #define NS_ANDROIDBRIDGE_CID \
 { 0x0FE2321D, 0xEBD9, 0x467D, \
     { 0xA7, 0x43, 0x03, 0xA6, 0x8D, 0x40, 0x59, 0x9E } }