bug 378637 part 5 - move Spdy*::EnsureBuffer to nsHttp r=hurley
authorPatrick McManus <mcmanus@ducksong.com>
Tue, 15 Apr 2014 17:06:59 -0400
changeset 183600 1455ff7a4ecf
parent 183599 ec87f45db49e
child 183601 fcf7f73bd7bb
push id26799
push userphilringnalda@gmail.com
push date2014-05-18 00:55 +0000
treeherdermozilla-central@00ef3a7d7aa7 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewershurley
bugs378637
milestone32.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 378637 part 5 - move Spdy*::EnsureBuffer to nsHttp r=hurley
netwerk/protocol/http/Http2Push.cpp
netwerk/protocol/http/Http2Session.cpp
netwerk/protocol/http/Http2Session.h
netwerk/protocol/http/Http2Stream.cpp
netwerk/protocol/http/SpdyPush3.cpp
netwerk/protocol/http/SpdyPush31.cpp
netwerk/protocol/http/SpdySession3.cpp
netwerk/protocol/http/SpdySession3.h
netwerk/protocol/http/SpdySession31.cpp
netwerk/protocol/http/SpdySession31.h
netwerk/protocol/http/SpdyStream3.cpp
netwerk/protocol/http/SpdyStream31.cpp
netwerk/protocol/http/nsHttp.cpp
netwerk/protocol/http/nsHttp.h
--- a/netwerk/protocol/http/Http2Push.cpp
+++ b/netwerk/protocol/http/Http2Push.cpp
@@ -228,20 +228,18 @@ Http2PushTransactionBuffer::ReadSegments
   return NS_ERROR_NOT_IMPLEMENTED;
 }
 
 nsresult
 Http2PushTransactionBuffer::WriteSegments(nsAHttpSegmentWriter *writer,
                                           uint32_t count, uint32_t *countWritten)
 {
   if ((mBufferedHTTP1Size - mBufferedHTTP1Used) < 20480) {
-    Http2Session::EnsureBuffer(mBufferedHTTP1,
-                                mBufferedHTTP1Size + kDefaultBufferSize,
-                                mBufferedHTTP1Used,
-                                mBufferedHTTP1Size);
+    EnsureBuffer(mBufferedHTTP1,mBufferedHTTP1Size + kDefaultBufferSize,
+                 mBufferedHTTP1Used, mBufferedHTTP1Size);
   }
 
   count = std::min(count, mBufferedHTTP1Size - mBufferedHTTP1Used);
   nsresult rv = writer->OnWriteSegment(mBufferedHTTP1 + mBufferedHTTP1Used,
                                        count, countWritten);
   if (NS_SUCCEEDED(rv)) {
     mBufferedHTTP1Used += *countWritten;
   }
--- a/netwerk/protocol/http/Http2Session.cpp
+++ b/netwerk/protocol/http/Http2Session.cpp
@@ -570,44 +570,16 @@ Http2Session::ResetDownstreamState()
     LOG3(("  SetRecvdFin id=0x%x\n", mInputFrameDataStream->StreamID()));
     mInputFrameDataStream->SetRecvdFin(true);
     MaybeDecrementConcurrent(mInputFrameDataStream);
   }
   mInputFrameBufferUsed = 0;
   mInputFrameDataStream = nullptr;
 }
 
-template<typename T> void
-Http2Session::EnsureBuffer(nsAutoArrayPtr<T> &buf, uint32_t newSize,
-                           uint32_t preserve, uint32_t &objSize)
-{
-  if (objSize >= newSize)
-    return;
-
-  // Leave a little slop on the new allocation - add 2KB to
-  // what we need and then round the result up to a 4KB (page)
-  // boundary.
-
-  objSize = (newSize + 2048 + 4095) & ~4095;
-
-  static_assert(sizeof(T) == 1, "sizeof(T) must be 1");
-  nsAutoArrayPtr<T> tmp(new T[objSize]);
-  memcpy(tmp, buf, preserve);
-  buf = tmp;
-}
-
-// Instantiate supported templates explicitly.
-template void
-Http2Session::EnsureBuffer(nsAutoArrayPtr<char> &buf, uint32_t newSize,
-                                  uint32_t preserve, uint32_t &objSize);
-
-template void
-Http2Session::EnsureBuffer(nsAutoArrayPtr<uint8_t> &buf, uint32_t newSize,
-                                  uint32_t preserve, uint32_t &objSize);
-
 // call with data length (i.e. 0 for 0 data bytes - ignore 8 byte header)
 // dest must have 8 bytes of allocated space
 template<typename charType> void
 Http2Session::CreateFrameHeader(charType dest, uint16_t frameLength,
                                 uint8_t frameType, uint8_t frameFlags,
                                 uint32_t streamID)
 {
   MOZ_ASSERT(frameLength <= kMaxFrameData, "framelength too large");
--- a/netwerk/protocol/http/Http2Session.h
+++ b/netwerk/protocol/http/Http2Session.h
@@ -161,19 +161,16 @@ public:
   static nsresult RecvPushPromise(Http2Session *);
   static nsresult RecvPing(Http2Session *);
   static nsresult RecvGoAway(Http2Session *);
   static nsresult RecvWindowUpdate(Http2Session *);
   static nsresult RecvContinuation(Http2Session *);
   static nsresult RecvAltSvc(Http2Session *);
   static nsresult RecvBlocked(Http2Session *);
 
-  template<typename T>
-  static void EnsureBuffer(nsAutoArrayPtr<T> &,
-                           uint32_t, uint32_t, uint32_t &);
   char       *EnsureOutputBuffer(uint32_t needed);
 
   template<typename charType>
   void CreateFrameHeader(charType dest, uint16_t frameLength,
                          uint8_t frameType, uint8_t frameFlags,
                          uint32_t streamID);
 
   // For writing the data stream to LOG4
--- a/netwerk/protocol/http/Http2Stream.cpp
+++ b/netwerk/protocol/http/Http2Stream.cpp
@@ -416,20 +416,18 @@ Http2Stream::ParseHttpRequestHeaders(con
   }
 
   // note that we could still have 1 frame for 0 bytes of data. that's ok.
 
   uint32_t messageSize = dataLength;
   messageSize += 13; // frame header + priority overhead in HEADERS frame
   messageSize += (numFrames - 1) * 8; // frame header overhead in CONTINUATION frames
 
-  Http2Session::EnsureBuffer(mTxInlineFrame,
-                             dataLength + messageSize,
-                             mTxInlineFrameUsed,
-                             mTxInlineFrameSize);
+  EnsureBuffer(mTxInlineFrame, dataLength + messageSize,
+               mTxInlineFrameUsed, mTxInlineFrameSize);
 
   mTxInlineFrameUsed += messageSize;
   LOG3(("%p Generating %d bytes of HEADERS for stream 0x%X with priority weight %u frames %u\n",
         this, mTxInlineFrameUsed, mStreamID, mPriorityWeight, numFrames));
 
   uint32_t outputOffset = 0;
   uint32_t compressedDataOffset = 0;
   for (uint32_t idx = 0; idx < numFrames; ++idx) {
@@ -541,20 +539,18 @@ Http2Stream::AdjustInitialWindow()
 
     // If the pushed stream has recvd a FIN, there is no reason to update
     // the window
     if (stream->RecvdFin() || stream->RecvdReset())
       return;
   }
 
   uint8_t *packet = mTxInlineFrame.get() + mTxInlineFrameUsed;
-  Http2Session::EnsureBuffer(mTxInlineFrame,
-                             mTxInlineFrameUsed + 12,
-                             mTxInlineFrameUsed,
-                             mTxInlineFrameSize);
+  EnsureBuffer(mTxInlineFrame, mTxInlineFrameUsed + 12,
+               mTxInlineFrameUsed, mTxInlineFrameSize);
   mTxInlineFrameUsed += 12;
 
   mSession->CreateFrameHeader(packet, 4,
                               Http2Session::FRAME_TYPE_WINDOW_UPDATE,
                               0, stream->mStreamID);
 
   MOZ_ASSERT(mClientReceiveWindow <= ASpdySession::kInitialRwin);
   uint32_t bump = ASpdySession::kInitialRwin - mClientReceiveWindow;
@@ -577,20 +573,18 @@ Http2Stream::AdjustPushedPriority()
   MOZ_ASSERT(mPushSource->mStreamID && !(mPushSource->mStreamID & 1));
 
   // If the pushed stream has recvd a FIN, there is no reason to update
   // the window
   if (mPushSource->RecvdFin() || mPushSource->RecvdReset())
     return;
 
   uint8_t *packet = mTxInlineFrame.get() + mTxInlineFrameUsed;
-  Http2Session::EnsureBuffer(mTxInlineFrame,
-                             mTxInlineFrameUsed + 13,
-                             mTxInlineFrameUsed,
-                             mTxInlineFrameSize);
+  EnsureBuffer(mTxInlineFrame, mTxInlineFrameUsed + 13,
+               mTxInlineFrameUsed, mTxInlineFrameSize);
   mTxInlineFrameUsed += 13;
 
   mSession->CreateFrameHeader(packet, 5,
                               Http2Session::FRAME_TYPE_PRIORITY,
                               Http2Session::kFlag_PRIORITY,
                               mPushSource->mStreamID);
 
   mPushSource->SetPriority(mPriority);
--- a/netwerk/protocol/http/SpdyPush3.cpp
+++ b/netwerk/protocol/http/SpdyPush3.cpp
@@ -252,20 +252,18 @@ SpdyPush3TransactionBuffer::ReadSegments
   return NS_ERROR_NOT_IMPLEMENTED;
 }
 
 nsresult
 SpdyPush3TransactionBuffer::WriteSegments(nsAHttpSegmentWriter *writer,
                                          uint32_t count, uint32_t *countWritten)
 {
   if ((mBufferedHTTP1Size - mBufferedHTTP1Used) < 20480) {
-    SpdySession3::EnsureBuffer(mBufferedHTTP1,
-                               mBufferedHTTP1Size + kDefaultBufferSize,
-                               mBufferedHTTP1Used,
-                               mBufferedHTTP1Size);
+    EnsureBuffer(mBufferedHTTP1, mBufferedHTTP1Size + kDefaultBufferSize,
+                 mBufferedHTTP1Used, mBufferedHTTP1Size);
   }
 
   count = std::min(count, mBufferedHTTP1Size - mBufferedHTTP1Used);
   nsresult rv = writer->OnWriteSegment(mBufferedHTTP1 + mBufferedHTTP1Used,
                                        count, countWritten);
   if (NS_SUCCEEDED(rv)) {
     mBufferedHTTP1Used += *countWritten;
   }
--- a/netwerk/protocol/http/SpdyPush31.cpp
+++ b/netwerk/protocol/http/SpdyPush31.cpp
@@ -250,20 +250,18 @@ SpdyPush31TransactionBuffer::ReadSegment
   return NS_ERROR_NOT_IMPLEMENTED;
 }
 
 nsresult
 SpdyPush31TransactionBuffer::WriteSegments(nsAHttpSegmentWriter *writer,
                                            uint32_t count, uint32_t *countWritten)
 {
   if ((mBufferedHTTP1Size - mBufferedHTTP1Used) < 20480) {
-    SpdySession31::EnsureBuffer(mBufferedHTTP1,
-                                mBufferedHTTP1Size + kDefaultBufferSize,
-                                mBufferedHTTP1Used,
-                                mBufferedHTTP1Size);
+    EnsureBuffer(mBufferedHTTP1, mBufferedHTTP1Size + kDefaultBufferSize,
+                 mBufferedHTTP1Used, mBufferedHTTP1Size);
   }
 
   count = std::min(count, mBufferedHTTP1Size - mBufferedHTTP1Used);
   nsresult rv = writer->OnWriteSegment(mBufferedHTTP1 + mBufferedHTTP1Used,
                                        count, countWritten);
   if (NS_SUCCEEDED(rv)) {
     mBufferedHTTP1Used += *countWritten;
   }
--- a/netwerk/protocol/http/SpdySession3.cpp
+++ b/netwerk/protocol/http/SpdySession3.cpp
@@ -530,50 +530,16 @@ SpdySession3::ResetDownstreamState()
       mInputFrameDataStream->SetRecvdFin(true);
       DecrementConcurrent(mInputFrameDataStream);
     }
   }
   mInputFrameBufferUsed = 0;
   mInputFrameDataStream = nullptr;
 }
 
-template<typename T> void
-SpdySession3::EnsureBuffer(nsAutoArrayPtr<T> &buf,
-                          uint32_t newSize,
-                          uint32_t preserve,
-                          uint32_t &objSize)
-{
-  if (objSize >= newSize)
-      return;
-
-  // Leave a little slop on the new allocation - add 2KB to
-  // what we need and then round the result up to a 4KB (page)
-  // boundary.
-
-  objSize = (newSize + 2048 + 4095) & ~4095;
-
-  static_assert(sizeof(T) == 1, "sizeof(T) must be 1");
-  nsAutoArrayPtr<T> tmp(new T[objSize]);
-  memcpy(tmp, buf, preserve);
-  buf = tmp;
-}
-
-// Instantiate supported templates explicitly.
-template void
-SpdySession3::EnsureBuffer(nsAutoArrayPtr<char> &buf,
-                           uint32_t newSize,
-                           uint32_t preserve,
-                           uint32_t &objSize);
-
-template void
-SpdySession3::EnsureBuffer(nsAutoArrayPtr<uint8_t> &buf,
-                           uint32_t newSize,
-                           uint32_t preserve,
-                           uint32_t &objSize);
-
 void
 SpdySession3::DecrementConcurrent(SpdyStream3 *aStream)
 {
   uint32_t id = aStream->StreamID();
 
   if (id && !(id & 0x1))
     return; // pushed streams aren't counted in concurrent limit
 
--- a/netwerk/protocol/http/SpdySession3.h
+++ b/netwerk/protocol/http/SpdySession3.h
@@ -153,20 +153,16 @@ public:
   static nsresult HandleSettings(SpdySession3 *);
   static nsresult HandleNoop(SpdySession3 *);
   static nsresult HandlePing(SpdySession3 *);
   static nsresult HandleGoAway(SpdySession3 *);
   static nsresult HandleHeaders(SpdySession3 *);
   static nsresult HandleWindowUpdate(SpdySession3 *);
   static nsresult HandleCredential(SpdySession3 *);
 
-  template<typename T>
-  static void EnsureBuffer(nsAutoArrayPtr<T> &,
-                           uint32_t, uint32_t, uint32_t &);
-
   // For writing the SPDY data stream to LOG4
   static void LogIO(SpdySession3 *, SpdyStream3 *, const char *,
                     const char *, uint32_t);
 
   // an overload of nsAHttpConnection
   void TransactionHasDataToWrite(nsAHttpTransaction *);
 
   // a similar version for SpdyStream3
--- a/netwerk/protocol/http/SpdySession31.cpp
+++ b/netwerk/protocol/http/SpdySession31.cpp
@@ -535,50 +535,16 @@ SpdySession31::ResetDownstreamState()
       mInputFrameDataStream->SetRecvdFin(true);
       DecrementConcurrent(mInputFrameDataStream);
     }
   }
   mInputFrameBufferUsed = 0;
   mInputFrameDataStream = nullptr;
 }
 
-template<typename T> void
-SpdySession31::EnsureBuffer(nsAutoArrayPtr<T> &buf,
-                            uint32_t newSize,
-                            uint32_t preserve,
-                            uint32_t &objSize)
-{
-  if (objSize >= newSize)
-    return;
-
-  // Leave a little slop on the new allocation - add 2KB to
-  // what we need and then round the result up to a 4KB (page)
-  // boundary.
-
-  objSize = (newSize + 2048 + 4095) & ~4095;
-
-  static_assert(sizeof(T) == 1, "sizeof(T) must be 1");
-  nsAutoArrayPtr<T> tmp(new T[objSize]);
-  memcpy(tmp, buf, preserve);
-  buf = tmp;
-}
-
-// Instantiate supported templates explicitly.
-template void
-SpdySession31::EnsureBuffer(nsAutoArrayPtr<char> &buf,
-                            uint32_t newSize,
-                            uint32_t preserve,
-                            uint32_t &objSize);
-
-template void
-SpdySession31::EnsureBuffer(nsAutoArrayPtr<uint8_t> &buf,
-                            uint32_t newSize,
-                            uint32_t preserve,
-                            uint32_t &objSize);
-
 void
 SpdySession31::DecrementConcurrent(SpdyStream31 *aStream)
 {
   uint32_t id = aStream->StreamID();
 
   if (id && !(id & 0x1))
     return; // pushed streams aren't counted in concurrent limit
 
--- a/netwerk/protocol/http/SpdySession31.h
+++ b/netwerk/protocol/http/SpdySession31.h
@@ -152,20 +152,16 @@ public:
   static nsresult HandleSettings(SpdySession31 *);
   static nsresult HandleNoop(SpdySession31 *);
   static nsresult HandlePing(SpdySession31 *);
   static nsresult HandleGoAway(SpdySession31 *);
   static nsresult HandleHeaders(SpdySession31 *);
   static nsresult HandleWindowUpdate(SpdySession31 *);
   static nsresult HandleCredential(SpdySession31 *);
 
-  template<typename T>
-    static void EnsureBuffer(nsAutoArrayPtr<T> &,
-                             uint32_t, uint32_t, uint32_t &);
-
   // For writing the SPDY data stream to LOG4
   static void LogIO(SpdySession31 *, SpdyStream31 *, const char *,
                     const char *, uint32_t);
 
   // an overload of nsAHttpConnection
   void TransactionHasDataToWrite(nsAHttpTransaction *);
 
   // a similar version for SpdyStream31
--- a/netwerk/protocol/http/SpdyStream3.cpp
+++ b/netwerk/protocol/http/SpdyStream3.cpp
@@ -564,20 +564,18 @@ SpdyStream3::AdjustInitialWindow()
     stream->mLocalUnacked = toack64 - 0x7fffffff;
     toack64 = 0x7fffffff;
   }
   uint32_t toack = static_cast<uint32_t>(toack64);
   if (!toack)
     return;
   toack = PR_htonl(toack);
 
-  SpdySession3::EnsureBuffer(mTxInlineFrame,
-                             mTxInlineFrameUsed + 16,
-                             mTxInlineFrameUsed,
-                             mTxInlineFrameSize);
+  EnsureBuffer(mTxInlineFrame, mTxInlineFrameUsed + 16,
+               mTxInlineFrameUsed, mTxInlineFrameSize);
 
   unsigned char *packet = mTxInlineFrame.get() + mTxInlineFrameUsed;
   mTxInlineFrameUsed += 16;
 
   memset(packet, 0, 8);
   packet[0] = SpdySession3::kFlag_Control;
   packet[1] = SpdySession3::kVersion;
   packet[3] = SpdySession3::CONTROL_TYPE_WINDOW_UPDATE;
@@ -1034,20 +1032,18 @@ SpdyStream3::Uncompress(z_stream *contex
       context->avail_out;
 
     // When there is no more output room, but input still available then
     // increase the output space
     if (zlib_rv == Z_OK &&
         !context->avail_out && context->avail_in) {
       LOG3(("SpdyStream3::Uncompress %p Large Headers - so far %d",
             this, mDecompressBufferSize));
-      SpdySession3::EnsureBuffer(mDecompressBuffer,
-                                 mDecompressBufferSize + 4096,
-                                 mDecompressBufferUsed,
-                                 mDecompressBufferSize);
+      EnsureBuffer(mDecompressBuffer, mDecompressBufferSize + 4096,
+                   mDecompressBufferUsed, mDecompressBufferSize);
     }
   }
   while (context->avail_in);
   return NS_OK;
 }
 
 // mDecompressBuffer contains 0 to N uncompressed Name/Value Header blocks
 nsresult
@@ -1258,20 +1254,18 @@ SpdyStream3::ExecuteCompress(uint32_t fl
 {
   // Expect mZlib->avail_in and mZlib->next_in to be set.
   // Append the compressed version of next_in to mTxInlineFrame
 
   do
   {
     uint32_t avail = mTxInlineFrameSize - mTxInlineFrameUsed;
     if (avail < 1) {
-      SpdySession3::EnsureBuffer(mTxInlineFrame,
-                                mTxInlineFrameSize + 2000,
-                                mTxInlineFrameUsed,
-                                mTxInlineFrameSize);
+      EnsureBuffer(mTxInlineFrame, mTxInlineFrameSize + 2000,
+                   mTxInlineFrameUsed, mTxInlineFrameSize);
       avail = mTxInlineFrameSize - mTxInlineFrameUsed;
     }
 
     mZlib->next_out = mTxInlineFrame + mTxInlineFrameUsed;
     mZlib->avail_out = avail;
     deflate(mZlib, flushMode);
     mTxInlineFrameUsed += avail - mZlib->avail_out;
   } while (mZlib->avail_in > 0 || !mZlib->avail_out);
--- a/netwerk/protocol/http/SpdyStream31.cpp
+++ b/netwerk/protocol/http/SpdyStream31.cpp
@@ -570,20 +570,18 @@ SpdyStream31::AdjustInitialWindow()
     stream->mLocalUnacked = toack64 - 0x7fffffff;
     toack64 = 0x7fffffff;
   }
   uint32_t toack = static_cast<uint32_t>(toack64);
   if (!toack)
     return;
   toack = PR_htonl(toack);
 
-  SpdySession31::EnsureBuffer(mTxInlineFrame,
-                              mTxInlineFrameUsed + 16,
-                              mTxInlineFrameUsed,
-                              mTxInlineFrameSize);
+  EnsureBuffer(mTxInlineFrame, mTxInlineFrameUsed + 16,
+               mTxInlineFrameUsed, mTxInlineFrameSize);
 
   unsigned char *packet = mTxInlineFrame.get() + mTxInlineFrameUsed;
   mTxInlineFrameUsed += 16;
 
   memset(packet, 0, 8);
   packet[0] = SpdySession31::kFlag_Control;
   packet[1] = SpdySession31::kVersion;
   packet[3] = SpdySession31::CONTROL_TYPE_WINDOW_UPDATE;
@@ -1050,20 +1048,18 @@ SpdyStream31::Uncompress(z_stream *conte
       context->avail_out;
 
     // When there is no more output room, but input still available then
     // increase the output space
     if (zlib_rv == Z_OK &&
         !context->avail_out && context->avail_in) {
       LOG3(("SpdyStream31::Uncompress %p Large Headers - so far %d",
             this, mDecompressBufferSize));
-      SpdySession31::EnsureBuffer(mDecompressBuffer,
-                                  mDecompressBufferSize + 4096,
-                                  mDecompressBufferUsed,
-                                  mDecompressBufferSize);
+      EnsureBuffer(mDecompressBuffer, mDecompressBufferSize + 4096,
+                   mDecompressBufferUsed, mDecompressBufferSize);
     }
   }
   while (context->avail_in);
   return NS_OK;
 }
 
 // mDecompressBuffer contains 0 to N uncompressed Name/Value Header blocks
 nsresult
@@ -1274,20 +1270,18 @@ SpdyStream31::ExecuteCompress(uint32_t f
 {
   // Expect mZlib->avail_in and mZlib->next_in to be set.
   // Append the compressed version of next_in to mTxInlineFrame
 
   do
   {
     uint32_t avail = mTxInlineFrameSize - mTxInlineFrameUsed;
     if (avail < 1) {
-      SpdySession31::EnsureBuffer(mTxInlineFrame,
-                                  mTxInlineFrameSize + 2000,
-                                  mTxInlineFrameUsed,
-                                  mTxInlineFrameSize);
+      EnsureBuffer(mTxInlineFrame, mTxInlineFrameSize + 2000,
+                   mTxInlineFrameUsed, mTxInlineFrameSize);
       avail = mTxInlineFrameSize - mTxInlineFrameUsed;
     }
 
     mZlib->next_out = mTxInlineFrame + mTxInlineFrameUsed;
     mZlib->avail_out = avail;
     deflate(mZlib, flushMode);
     mTxInlineFrameUsed += avail - mZlib->avail_out;
   } while (mZlib->avail_in > 0 || !mZlib->avail_out);
--- a/netwerk/protocol/http/nsHttp.cpp
+++ b/netwerk/protocol/http/nsHttp.cpp
@@ -290,10 +290,44 @@ nsHttp::ParseInt64(const char *input, co
 }
 
 bool
 nsHttp::IsPermanentRedirect(uint32_t httpStatus)
 {
   return httpStatus == 301 || httpStatus == 308;
 }
 
+
+template<typename T> void
+localEnsureBuffer(nsAutoArrayPtr<T> &buf, uint32_t newSize,
+             uint32_t preserve, uint32_t &objSize)
+{
+  if (objSize >= newSize)
+    return;
+
+  // Leave a little slop on the new allocation - add 2KB to
+  // what we need and then round the result up to a 4KB (page)
+  // boundary.
+
+  objSize = (newSize + 2048 + 4095) & ~4095;
+
+  static_assert(sizeof(T) == 1, "sizeof(T) must be 1");
+  nsAutoArrayPtr<T> tmp(new T[objSize]);
+  if (preserve) {
+    memcpy(tmp, buf, preserve);
+  }
+  buf = tmp;
+}
+
+void EnsureBuffer(nsAutoArrayPtr<char> &buf, uint32_t newSize,
+                  uint32_t preserve, uint32_t &objSize)
+{
+    localEnsureBuffer<char> (buf, newSize, preserve, objSize);
+}
+
+void EnsureBuffer(nsAutoArrayPtr<uint8_t> &buf, uint32_t newSize,
+                  uint32_t preserve, uint32_t &objSize)
+{
+    localEnsureBuffer<uint8_t> (buf, newSize, preserve, objSize);
+}
+
 } // namespace mozilla::net
 } // namespace mozilla
--- a/netwerk/protocol/http/nsHttp.h
+++ b/netwerk/protocol/http/nsHttp.h
@@ -4,16 +4,17 @@
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef nsHttp_h__
 #define nsHttp_h__
 
 #include <stdint.h>
 #include "prtime.h"
+#include "nsAutoPtr.h"
 #include "nsString.h"
 #include "nsError.h"
 
 // http version codes
 #define NS_HTTP_VERSION_UNKNOWN  0
 #define NS_HTTP_VERSION_0_9      9
 #define NS_HTTP_VERSION_1_0     10
 #define NS_HTTP_VERSION_1_1     11
@@ -185,12 +186,17 @@ PRTimeToSeconds(PRTime t_usec)
 #define NowInSeconds() PRTimeToSeconds(PR_Now())
 
 // Round q-value to 2 decimal places; return 2 most significant digits as uint.
 #define QVAL_TO_UINT(q) ((unsigned int) ((q + 0.005) * 100.0))
 
 #define HTTP_LWS " \t"
 #define HTTP_HEADER_VALUE_SEPS HTTP_LWS ","
 
+void EnsureBuffer(nsAutoArrayPtr<char> &buf, uint32_t newSize,
+                  uint32_t preserve, uint32_t &objSize);
+void EnsureBuffer(nsAutoArrayPtr<uint8_t> &buf, uint32_t newSize,
+                  uint32_t preserve, uint32_t &objSize);
+
 } // namespace mozilla::net
 } // namespace mozilla
 
 #endif // nsHttp_h__