Bug 1352882 - Part 1. Add releasing nsIDcoument option to recycle nsIDocumentEncoder. r?smaug draft
authorMakoto Kato <m_kato@ga2.so-net.ne.jp>
Thu, 13 Apr 2017 15:47:02 +0900
changeset 561819 13734f8ccc7bb51cafad9741f00131736892e723
parent 561690 aca6b2a5a2ab3338436c9e819dc2244a022b6425
child 561820 02356927a18ffee80859ad67e1603ffd5fd93c8b
push id53876
push userm_kato@ga2.so-net.ne.jp
push dateThu, 13 Apr 2017 07:39:56 +0000
reviewerssmaug
bugs1352882
milestone55.0a1
Bug 1352882 - Part 1. Add releasing nsIDcoument option to recycle nsIDocumentEncoder. r?smaug Editor uses weak reference for nsIDocument. But nsDocumentEncoder uses strong reference for it. So to recycle it, editor wants the option that it release nsIDocument into nsDocumentEncoder after EncodeTo* is called. MozReview-Commit-ID: K3E9XhgD8FY
dom/base/nsDocumentEncoder.cpp
dom/base/nsIDocumentEncoder.idl
--- a/dom/base/nsDocumentEncoder.cpp
+++ b/dom/base/nsDocumentEncoder.cpp
@@ -41,16 +41,17 @@
 #include "nsITransferable.h" // for kUnicodeMime
 #include "nsContentUtils.h"
 #include "nsNodeUtils.h"
 #include "nsUnicharUtils.h"
 #include "nsReadableUtils.h"
 #include "nsTArray.h"
 #include "nsIFrame.h"
 #include "nsStringBuffer.h"
+#include "mozilla/AutoRestore.h"
 #include "mozilla/dom/Element.h"
 #include "mozilla/dom/ShadowRoot.h"
 #include "mozilla/dom/EncodingUtils.h"
 #include "nsLayoutUtils.h"
 
 using namespace mozilla;
 using namespace mozilla::dom;
 
@@ -137,16 +138,35 @@ protected:
           return false;
       }
     }
     return true;
   }
 
   virtual bool IncludeInContext(nsINode *aNode);
 
+  class MOZ_STACK_CLASS AutoReleaseDocumentIfNeeded final
+  {
+  public:
+    AutoReleaseDocumentIfNeeded(nsDocumentEncoder* aEncoder)
+      : mEncoder(aEncoder)
+    {
+    }
+
+    ~AutoReleaseDocumentIfNeeded()
+    {
+      if (mEncoder->mFlags & ReleaseDocumentAfterOutput) {
+        mEncoder->mDocument = nullptr;
+      }
+    }
+
+  private:
+    nsDocumentEncoder* mEncoder;
+  };
+
   nsCOMPtr<nsIDocument>          mDocument;
   nsCOMPtr<nsISelection>         mSelection;
   RefPtr<nsRange>              mRange;
   nsCOMPtr<nsINode>              mNode;
   nsCOMPtr<nsIOutputStream>      mStream;
   nsCOMPtr<nsIContentSerializer> mSerializer;
   nsCOMPtr<nsIUnicodeEncoder>    mUnicodeEncoder;
   nsCOMPtr<nsINode>              mCommonParent;
@@ -1004,16 +1024,18 @@ nsDocumentEncoder::EncodeToString(nsAStr
 
 NS_IMETHODIMP
 nsDocumentEncoder::EncodeToStringWithMaxLength(uint32_t aMaxLength,
                                                nsAString& aOutputString)
 {
   if (!mDocument)
     return NS_ERROR_NOT_INITIALIZED;
 
+  AutoReleaseDocumentIfNeeded autoReleaseDocument(this);
+
   aOutputString.Truncate();
 
   nsString output;
   static const size_t bufferSize = 2048;
   if (!mCachedBuffer) {
     mCachedBuffer = nsStringBuffer::Alloc(bufferSize).take();
     if (NS_WARN_IF(!mCachedBuffer)) {
       return NS_ERROR_OUT_OF_MEMORY;
--- a/dom/base/nsIDocumentEncoder.idl
+++ b/dom/base/nsIDocumentEncoder.idl
@@ -243,16 +243,23 @@ interface nsIDocumentEncoder : nsISuppor
   /**
    * Disallow breaking of long character strings. This is important
    * for serializing e-mail which contains CJK strings. These must
    * not be broken just as "normal" longs strings aren't broken.
    */
   const unsigned long OutputDisallowLineBreaking = (1 << 27);
 
   /**
+   * Release reference of nsIDocument after using encodeTo* method to recycle
+   * this encoder without holding nsIDocument. To use this encoder again,
+   * we have to call init again.
+   */
+  const unsigned long ReleaseDocumentAfterOutput = (1 << 28);
+
+  /**
    * Initialize with a pointer to the document and the mime type.
    * @param aDocument Document to encode.
    * @param aMimeType MimeType to use. May also be set by SetMimeType.
    * @param aFlags Flags to use while encoding. May also be set by SetFlags.
    */
   void init(in nsIDOMDocument aDocument,
             in AString aMimeType,
             in unsigned long aFlags);