Bug 803439 - Add removeFrom() that takes a list and asserts the element is initially present in it. r=jlebar
authorJeff Walden <jwalden@mit.edu>
Tue, 23 Oct 2012 17:43:23 -0700
changeset 120998 5bd42ae5efd23bb82e6891055bbab7f74b5708ea
parent 120997 dfe6972056d658a674394f4d28b81dc020447b1f
child 120999 5c5e4097dd20b5fc8b8dbcd6a0bdae83ee9142cd
push id273
push userlsblakk@mozilla.com
push dateThu, 14 Feb 2013 23:19:38 +0000
treeherdermozilla-release@c5e807a3f8b8 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjlebar
bugs803439
milestone19.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 803439 - Add removeFrom() that takes a list and asserts the element is initially present in it. r=jlebar
content/base/src/nsCrossSiteListenerProxy.cpp
content/canvas/src/WebGLContext.h
image/src/RasterImage.cpp
mfbt/LinkedList.h
parser/html/nsHtml5TreeOpExecutor.cpp
--- a/content/base/src/nsCrossSiteListenerProxy.cpp
+++ b/content/base/src/nsCrossSiteListenerProxy.cpp
@@ -184,17 +184,17 @@ nsPreflightCache::GetEntry(nsIURI* aURI,
   }
 
   CacheEntry* entry;
 
   if (mTable.Get(key, &entry)) {
     // Entry already existed so just return it. Also update the LRU list.
 
     // Move to the head of the list.
-    entry->remove();
+    entry->removeFrom(mList);
     mList.insertFront(entry);
 
     return entry;
   }
 
   if (!aCreate) {
     return nullptr;
   }
@@ -238,23 +238,23 @@ nsPreflightCache::GetEntry(nsIURI* aURI,
 
 void
 nsPreflightCache::RemoveEntries(nsIURI* aURI, nsIPrincipal* aPrincipal)
 {
   CacheEntry* entry;
   nsCString key;
   if (GetCacheKey(aURI, aPrincipal, true, key) &&
       mTable.Get(key, &entry)) {
-    entry->remove();
+    entry->removeFrom(mList);
     mTable.Remove(key);
   }
 
   if (GetCacheKey(aURI, aPrincipal, false, key) &&
       mTable.Get(key, &entry)) {
-    entry->remove();
+    entry->removeFrom(mList);
     mTable.Remove(key);
   }
 }
 
 void
 nsPreflightCache::Clear()
 {
   mList.clear();
@@ -268,17 +268,17 @@ nsPreflightCache::RemoveExpiredEntries(c
 {
   PRTime* now = static_cast<PRTime*>(aUserData);
   
   aValue->PurgeExpired(*now);
   
   if (aValue->mHeaders.IsEmpty() &&
       aValue->mMethods.IsEmpty()) {
     // Expired, remove from the list as well as the hash table.
-    aValue->remove();
+    aValue->removeFrom(sPreflightCache->mList);
     return PL_DHASH_REMOVE;
   }
   
   return PL_DHASH_NEXT;
 }
 
 /* static */ bool
 nsPreflightCache::GetCacheKey(nsIURI* aURI,
--- a/content/canvas/src/WebGLContext.h
+++ b/content/canvas/src/WebGLContext.h
@@ -1557,17 +1557,17 @@ public:
         DeleteOnce();
     }
 
     void Delete() {
         mContext->MakeContextCurrent();
         mContext->gl->fDeleteBuffers(1, &mGLName);
         mByteLength = 0;
         mCache = nullptr;
-        LinkedListElement<WebGLBuffer>::remove(); // remove from mContext->mBuffers
+        LinkedListElement<WebGLBuffer>::removeFrom(mContext->mBuffers);
     }
 
     size_t SizeOfIncludingThis(nsMallocSizeOfFun aMallocSizeOf) const {
         size_t sizeOfCache = mCache ? mCache->SizeOfIncludingThis(aMallocSizeOf) : 0;
         return aMallocSizeOf(this) + sizeOfCache;
     }
 
     bool HasEverBeenBound() { return mHasEverBeenBound; }
@@ -1650,17 +1650,17 @@ public:
     ~WebGLTexture() {
         DeleteOnce();
     }
 
     void Delete() {
         mImageInfos.Clear();
         mContext->MakeContextCurrent();
         mContext->gl->fDeleteTextures(1, &mGLName);
-        LinkedListElement<WebGLTexture>::remove(); // remove from mContext->mTextures
+        LinkedListElement<WebGLTexture>::removeFrom(mContext->mTextures);
     }
 
     bool HasEverBeenBound() { return mHasEverBeenBound; }
     void SetHasEverBeenBound(bool x) { mHasEverBeenBound = x; }
     WebGLuint GLName() { return mGLName; }
     GLenum Target() const { return mTarget; }
 
     WebGLContext *GetParentObject() const {
@@ -2168,17 +2168,17 @@ public:
                mTranslationLog.SizeOfExcludingThisIfUnshared(aMallocSizeOf);
     }
 
     void Delete() {
         mSource.Truncate();
         mTranslationLog.Truncate();
         mContext->MakeContextCurrent();
         mContext->gl->fDeleteShader(mGLName);
-        LinkedListElement<WebGLShader>::remove(); // remove from mContext->mShaders
+        LinkedListElement<WebGLShader>::removeFrom(mContext->mShaders);
     }
 
     WebGLuint GLName() { return mGLName; }
     WebGLenum ShaderType() { return mType; }
 
     void SetSource(const nsAString& src) {
         // XXX do some quick gzip here maybe -- getting this will be very rare
         mSource.Assign(src);
@@ -2290,17 +2290,17 @@ public:
     ~WebGLProgram() {
         DeleteOnce();
     }
 
     void Delete() {
         DetachShaders();
         mContext->MakeContextCurrent();
         mContext->gl->fDeleteProgram(mGLName);
-        LinkedListElement<WebGLProgram>::remove(); // remove from mContext->mPrograms
+        LinkedListElement<WebGLProgram>::removeFrom(mContext->mPrograms);
     }
 
     void DetachShaders() {
         mAttachedShaders.Clear();
     }
 
     WebGLuint GLName() { return mGLName; }
     const nsTArray<WebGLRefPtr<WebGLShader> >& AttachedShaders() const { return mAttachedShaders; }
@@ -2573,17 +2573,17 @@ public:
 
     ~WebGLRenderbuffer() {
         DeleteOnce();
     }
 
     void Delete() {
         mContext->MakeContextCurrent();
         mContext->gl->fDeleteRenderbuffers(1, &mGLName);
-        LinkedListElement<WebGLRenderbuffer>::remove(); // remove from mContext->mRenderbuffers
+        LinkedListElement<WebGLRenderbuffer>::removeFrom(mContext->mRenderbuffers);
     }
 
     bool HasEverBeenBound() { return mHasEverBeenBound; }
     void SetHasEverBeenBound(bool x) { mHasEverBeenBound = x; }
     WebGLuint GLName() const { return mGLName; }
 
     bool Initialized() const { return mInitialized; }
     void SetInitialized(bool aInitialized) { mInitialized = aInitialized; }
@@ -2818,17 +2818,17 @@ public:
 
     void Delete() {
         mColorAttachment.Reset();
         mDepthAttachment.Reset();
         mStencilAttachment.Reset();
         mDepthStencilAttachment.Reset();
         mContext->MakeContextCurrent();
         mContext->gl->fDeleteFramebuffers(1, &mGLName);
-        LinkedListElement<WebGLFramebuffer>::remove(); // remove from mContext->mFramebuffers
+        LinkedListElement<WebGLFramebuffer>::removeFrom(mContext->mFramebuffers);
     }
 
     bool HasEverBeenBound() { return mHasEverBeenBound; }
     void SetHasEverBeenBound(bool x) { mHasEverBeenBound = x; }
     WebGLuint GLName() { return mGLName; }
 
     void FramebufferRenderbuffer(WebGLenum target,
                                  WebGLenum attachment,
--- a/image/src/RasterImage.cpp
+++ b/image/src/RasterImage.cpp
@@ -3271,17 +3271,17 @@ RasterImage::DecodeWorker::MarkAsASAP(Ra
   }
 
   request->mIsASAP = true;
 
   if (request->isInList()) {
     // If the decode request is in a list, it must be in the normal decode
     // requests list -- if it had been in the ASAP list, then mIsASAP would
     // have been true above.  Move the request to the ASAP list.
-    request->remove();
+    request->removeFrom(mNormalDecodeRequests);
     mASAPDecodeRequests.insertBack(request);
 
     // Since request is in a list, one of the decode worker's lists is
     // non-empty, so the worker should be pending in the event loop.
     //
     // (Note that this invariant only holds while we are not in Run(), because
     // DecodeSomeOfImage adds requests to the decode worker using
     // AddDecodeRequest, not RequestDecode, and AddDecodeRequest does not call
--- a/mfbt/LinkedList.h
+++ b/mfbt/LinkedList.h
@@ -35,16 +35,18 @@
  *       void addObserver(Observer* observer) {
  *         // Will assert if |observer| is part of another list.
  *         list.insertBack(observer);
  *       }
  *
  *       void removeObserver(Observer* observer) {
  *         // Will assert if |observer| is not part of some list.
  *         observer.remove();
+ *         // Or, will assert if |observer| is not part of |list| specifically.
+ *         // observer.removeFrom(list);
  *       }
  *
  *       void notifyObservers(char* topic) {
  *         for (Observer* o = list.getFirst(); o != NULL; o = o->getNext())
  *           o->Observe(topic);
  *       }
  *   };
  *
@@ -169,16 +171,25 @@ class LinkedListElement
 
       prev->next = next;
       next->prev = prev;
       next = this;
       prev = this;
     }
 
     /*
+     * Identical to remove(), but also asserts in debug builds that this element
+     * is in list.
+     */
+    void removeFrom(const LinkedList<T>& list) {
+      list.assertContains(asT());
+      remove();
+    }
+
+    /*
      * Return true if |this| part is of a linked list, and false otherwise.
      */
     bool isInList() const {
       MOZ_ASSERT((next == this) == (prev == this));
       return next != this;
     }
 
   private:
@@ -388,16 +399,31 @@ class LinkedList
 
           prev = cur;
           cur = cur->next;
       } while (cur != sentinel);
 #endif /* ifdef DEBUG */
     }
 
   private:
+    friend class LinkedListElement<T>;
+
+    void assertContains(const T* t) const {
+#ifdef DEBUG
+      for (const T* elem = getFirst();
+           elem;
+           elem = elem->getNext())
+      {
+        if (elem == t)
+          return;
+      }
+      MOZ_NOT_REACHED("element wasn't found in this list!");
+#endif
+    }
+
     LinkedList& operator=(const LinkedList<T>& other) MOZ_DELETE;
     LinkedList(const LinkedList<T>& other) MOZ_DELETE;
 };
 
 } /* namespace mozilla */
 
 #endif /* ifdef __cplusplus */
 #endif /* ifdef mozilla_LinkedList_h_ */
--- a/parser/html/nsHtml5TreeOpExecutor.cpp
+++ b/parser/html/nsHtml5TreeOpExecutor.cpp
@@ -78,17 +78,17 @@ nsHtml5TreeOpExecutor::nsHtml5TreeOpExec
   mPreloadedURLs.Init(23); // Mean # of preloadable resources per page on dmoz
   // zeroing operator new for everything else
 }
 
 nsHtml5TreeOpExecutor::~nsHtml5TreeOpExecutor()
 {
   if (gBackgroundFlushList && isInList()) {
     mOpQueue.Clear();
-    remove();
+    removeFrom(*gBackgroundFlushList);
     if (gBackgroundFlushList->isEmpty()) {
       delete gBackgroundFlushList;
       gBackgroundFlushList = nullptr;
       if (gFlushTimer) {
         gFlushTimer->Cancel();
         NS_RELEASE(gFlushTimer);
       }
     }