Merge m-c to autoland, a=merge
authorWes Kocher <wkocher@mozilla.com>
Thu, 02 Mar 2017 15:03:44 -0800
changeset 374702 ab7bf038105690a52c33d7f6fb3c9dc3b85aa1ae
parent 374701 092a88bec83a99c284c2ea686166cc0ec20d2d93 (current diff)
parent 374669 b23d6277acca34a4b1be9a4c24efd3b999e47ec3 (diff)
child 374703 2c60f5f03a7805d51577586e9c038f3b65c5b823
push id10863
push userjlorenzo@mozilla.com
push dateMon, 06 Mar 2017 23:02:23 +0000
treeherdermozilla-aurora@0931190cd725 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmerge
milestone54.0a1
Merge m-c to autoland, a=merge MozReview-Commit-ID: AZeTEvGhLd1
browser/app/profile/firefox.js
gfx/thebes/gfxPrefs.h
modules/libpref/init/all.js
netwerk/protocol/http/nsHttpPipeline.cpp
netwerk/protocol/http/nsHttpPipeline.h
netwerk/test/unit/test_assoc.js
xpcom/glue/nsStringAPI.cpp
xpcom/glue/nsStringAPI.h
--- a/build/valgrind/x86_64-redhat-linux-gnu.sup
+++ b/build/valgrind/x86_64-redhat-linux-gnu.sup
@@ -225,23 +225,24 @@
    fun:_ZN11gfxPlatform11GetPlatformEv
 }
 
 # Conditional jump or move depends on uninitialised value(s)
 #    at 0xFD5B218: SkOpts::Init()
 #    by 0xE757308: gfxPlatform::Init()
 #    by 0xE75772C: gfxPlatform::GetPlatform()
 #    by 0xF1A3691: mozilla::dom::ContentProcess::Init()
+#               or mozilla::dom::ContentChild::RecvSetXPCOMProcessAttributes()
 {
    Skia and CPUID, Jan 2017, #2
    Memcheck:Cond
    fun:_ZN6SkOpts4InitEv
    fun:_ZN11gfxPlatform4InitEv
    fun:_ZN11gfxPlatform11GetPlatformEv
-   fun:_ZN7mozilla3dom14ContentProcess4InitEv
+   fun:_ZN7mozilla3dom*Content*
 }
 
 
 ###################################################
 #  For valgrind-mochitest ("tc-M-V [tier 2]") runs on taskcluster.
 #  See bug 1248365.
 #  These are specific to Ubuntu 12.04.5, 64-bit.
 ###################################################
--- a/docshell/test/browser/browser.ini
+++ b/docshell/test/browser/browser.ini
@@ -1,10 +1,11 @@
 [DEFAULT]
 support-files =
+  dummy_page.html
   favicon_bug655270.ico
   file_bug234628-1-child.html
   file_bug234628-1.html
   file_bug234628-10-child.xhtml
   file_bug234628-10.html
   file_bug234628-11-child.xhtml
   file_bug234628-11-child.xhtml^headers^
   file_bug234628-11.html
@@ -92,8 +93,9 @@ skip-if = true # Bug 1220415
 [browser_timelineMarkers-05.js]
 [browser_ua_emulation.js]
 [browser_grouped_shistory_dead_navigate.js]
 skip-if = !e10s
 [browser_grouped_shistory_crossproc.js]
 skip-if = !e10s
 [browser_grouped_shistory_bfcache_cleaning.js]
 skip-if = !e10s
+[browser_history_triggeringprincipal_viewsource.js]
new file mode 100644
--- /dev/null
+++ b/docshell/test/browser/browser_history_triggeringprincipal_viewsource.js
@@ -0,0 +1,50 @@
+"use strict";
+
+const TEST_PATH = getRootDirectory(gTestPath).replace("chrome://mochitests/content", "http://example.com");
+const HTML_URI = TEST_PATH + "dummy_page.html";
+const VIEW_SRC_URI = "view-source:" + HTML_URI;
+
+add_task(function*() {
+  info("load baseline html in new tab");
+  yield BrowserTestUtils.withNewTab(HTML_URI, function*(aBrowser) {
+    is(gBrowser.selectedBrowser.currentURI.spec, HTML_URI,
+       "sanity check to make sure html loaded");
+
+    info("right-click -> view-source of html");
+    let vSrcCtxtMenu = document.getElementById("contentAreaContextMenu");
+    let popupPromise = BrowserTestUtils.waitForEvent(vSrcCtxtMenu, "popupshown");
+    BrowserTestUtils.synthesizeMouseAtCenter("body", { type: "contextmenu", button: 2 }, aBrowser);
+    yield popupPromise;
+    let tabPromise = BrowserTestUtils.waitForNewTab(gBrowser, VIEW_SRC_URI);
+    let vSrcItem = vSrcCtxtMenu.getElementsByAttribute("id", "context-viewsource")[0];
+    vSrcItem.click();
+    vSrcCtxtMenu.hidePopup();
+    let tab = yield tabPromise;
+    is(gBrowser.selectedBrowser.currentURI.spec, VIEW_SRC_URI,
+       "loading view-source of html succeeded");
+
+    info ("load html file again before going .back()");
+    let loadPromise = BrowserTestUtils.browserLoaded(tab.linkedBrowser, false, HTML_URI);
+    yield ContentTask.spawn(tab.linkedBrowser, HTML_URI, HTML_URI => {
+      content.document.location = HTML_URI;
+    });
+    yield loadPromise;
+    is(gBrowser.selectedBrowser.currentURI.spec, HTML_URI,
+      "loading html another time succeeded");
+
+    info("click .back() to view-source of html again and make sure the history entry has a triggeringPrincipal");
+    let backCtxtMenu = document.getElementById("contentAreaContextMenu");
+    popupPromise = BrowserTestUtils.waitForEvent(backCtxtMenu, "popupshown");
+    BrowserTestUtils.synthesizeMouseAtCenter("body", { type: "contextmenu", button: 2 }, aBrowser);
+    yield popupPromise;
+    loadPromise = BrowserTestUtils.browserLoaded(tab.linkedBrowser, false, VIEW_SRC_URI);
+    let backItem = backCtxtMenu.getElementsByAttribute("id", "context-back")[0];
+    backItem.click();
+    backCtxtMenu.hidePopup();
+    yield loadPromise;
+    is(gBrowser.selectedBrowser.currentURI.spec, VIEW_SRC_URI,
+      "clicking .back() to view-source of html succeeded");
+
+    yield BrowserTestUtils.removeTab(tab);
+  });
+});
new file mode 100644
--- /dev/null
+++ b/docshell/test/browser/dummy_page.html
@@ -0,0 +1,6 @@
+<html>
+<head> <meta charset="utf-8"> </head>
+  <body>
+    just a dummy html file
+  </body>
+</html>
--- a/dom/base/TimeoutManager.cpp
+++ b/dom/base/TimeoutManager.cpp
@@ -469,16 +469,18 @@ TimeoutManager::RunTimeout(Timeout* aTim
         timeout->mFiringDepth = firingDepth;
         last_expired_timeout_is_normal = expiredIter.PickedNormalIter();
         if (last_expired_timeout_is_normal) {
           last_expired_normal_timeout = timeout;
         } else {
           last_expired_tracking_timeout = timeout;
         }
 
+        numTimersToRun += 1;
+
         // Note that we have seen our target timer.  This means we can now
         // stop processing timers once we hit our threshold below.
         if (timeout == aTimeout) {
           targetTimerSeen = true;
         }
 
         // Run only a limited number of timers based on the configured
         // maximum.  Note, we must always run our target timer however.
@@ -490,18 +492,16 @@ TimeoutManager::RunTimeout(Timeout* aTim
         // trust chrome windows not to misbehave and partly because a
         // number of browser chrome tests have races that depend on this
         // coalescing.
         if (targetTimerSeen &&
             numTimersToRun >= gTargetMaxConsecutiveCallbacks &&
             !mWindow.IsChromeWindow()) {
           break;
         }
-
-        numTimersToRun += 1;
       }
 
       expiredIter.UpdateIterator();
     }
   }
 
   // Maybe the timeout that the event was fired for has been deleted
   // and there are no others timeouts with deadlines that make them
--- a/dom/base/nsGlobalWindow.h
+++ b/dom/base/nsGlobalWindow.h
@@ -389,23 +389,23 @@ public:
 
   virtual PopupControlState PushPopupControlState(PopupControlState state, bool aForce) const override;
   virtual void PopPopupControlState(PopupControlState state) const override;
   virtual PopupControlState GetPopupControlState() const override;
 
   virtual already_AddRefed<nsISupports> SaveWindowState() override;
   virtual nsresult RestoreWindowState(nsISupports *aState) override;
 
-  virtual void Suspend();
-  virtual void Resume();
+  void Suspend();
+  void Resume();
   virtual bool IsSuspended() const override;
-  virtual void Freeze();
-  virtual void Thaw();
+  void Freeze();
+  void Thaw();
   virtual bool IsFrozen() const override;
-  virtual void SyncStateFromParentWindow();
+  void SyncStateFromParentWindow();
 
   virtual nsresult FireDelayedDOMEvents() override;
 
   // Outer windows only.
   virtual bool WouldReuseInnerWindow(nsIDocument* aNewDocument) override;
 
   virtual void SetDocShell(nsIDocShell* aDocShell) override;
   virtual void DetachFromDocShell() override;
--- a/dom/bindings/BindingUtils.h
+++ b/dom/bindings/BindingUtils.h
@@ -1526,29 +1526,29 @@ struct WrapNativeHelper
 {
   static inline JSObject* Wrap(JSContext* cx, T* parent, nsWrapperCache* cache)
   {
     MOZ_ASSERT(cache);
 
     JSObject* obj;
     if ((obj = cache->GetWrapper())) {
       // GetWrapper always unmarks gray.
-      MOZ_ASSERT(!JS::ObjectIsMarkedGray(obj));
+      MOZ_ASSERT(JS::ObjectIsNotGray(obj));
       return obj;
     }
 
     // Inline this here while we have non-dom objects in wrapper caches.
     if (!CouldBeDOMBinding(parent)) {
       // WrapNativeFallback never returns a gray thing.
       obj = WrapNativeFallback<T>::Wrap(cx, parent, cache);
-      MOZ_ASSERT_IF(obj, !JS::ObjectIsMarkedGray(obj));
+      MOZ_ASSERT(JS::ObjectIsNotGray(obj));
     } else {
       // WrapObject never returns a gray thing.
       obj = parent->WrapObject(cx, nullptr);
-      MOZ_ASSERT_IF(obj, !JS::ObjectIsMarkedGray(obj));
+      MOZ_ASSERT(JS::ObjectIsNotGray(obj));
     }
 
     return obj;
   }
 };
 
 // Wrapping of our native parent, for cases when it's not a WebIDL object.  In
 // this case it must be nsISupports.
@@ -1560,22 +1560,22 @@ struct WrapNativeHelper<T, false>
     JSObject* obj;
     if (cache && (obj = cache->GetWrapper())) {
 #ifdef DEBUG
       JS::Rooted<JSObject*> rootedObj(cx, obj);
       NS_ASSERTION(WrapNativeISupports(cx, parent, cache) == rootedObj,
                    "Unexpected object in nsWrapperCache");
       obj = rootedObj;
 #endif
-      MOZ_ASSERT(!JS::ObjectIsMarkedGray(obj));
+      MOZ_ASSERT(JS::ObjectIsNotGray(obj));
       return obj;
     }
 
     obj = WrapNativeISupports(cx, parent, cache);
-    MOZ_ASSERT_IF(obj, !JS::ObjectIsMarkedGray(obj));
+    MOZ_ASSERT(JS::ObjectIsNotGray(obj));
     return obj;
   }
 };
 
 // Finding the associated global for an object.
 template<typename T>
 static inline JSObject*
 FindAssociatedGlobal(JSContext* cx, T* p, nsWrapperCache* cache,
@@ -1584,34 +1584,34 @@ FindAssociatedGlobal(JSContext* cx, T* p
   if (!p) {
     return JS::CurrentGlobalOrNull(cx);
   }
 
   JSObject* obj = WrapNativeHelper<T>::Wrap(cx, p, cache);
   if (!obj) {
     return nullptr;
   }
-  MOZ_ASSERT(!JS::ObjectIsMarkedGray(obj));
+  MOZ_ASSERT(JS::ObjectIsNotGray(obj));
 
   obj = js::GetGlobalForObjectCrossCompartment(obj);
 
   if (!useXBLScope) {
     return obj;
   }
 
   // If useXBLScope is true, it means that the canonical reflector for this
   // native object should live in the content XBL scope. Note that we never put
   // anonymous content inside an add-on scope.
   if (xpc::IsInContentXBLScope(obj)) {
     return obj;
   }
   JS::Rooted<JSObject*> rootedObj(cx, obj);
   JSObject* xblScope = xpc::GetXBLScope(cx, rootedObj);
   MOZ_ASSERT_IF(xblScope, JS_IsGlobalObject(xblScope));
-  MOZ_ASSERT_IF(xblScope, !JS::ObjectIsMarkedGray(xblScope));
+  MOZ_ASSERT(JS::ObjectIsNotGray(xblScope));
   return xblScope;
 }
 
 // Finding of the associated global for an object, when we don't want to
 // explicitly pass in things like the nsWrapperCache for it.
 template<typename T>
 static inline JSObject*
 FindAssociatedGlobal(JSContext* cx, const T& p)
--- a/dom/bindings/CallbackObject.h
+++ b/dom/bindings/CallbackObject.h
@@ -121,17 +121,17 @@ public:
 
   /*
    * If the callback is known to be non-gray, then this method can be
    * used instead of CallbackOrNull() to avoid the overhead of
    * ExposeObjectToActiveJS().
    */
   JS::Handle<JSObject*> CallbackKnownNotGray() const
   {
-    MOZ_ASSERT(!JS::ObjectIsMarkedGray(mCallback));
+    MOZ_ASSERT(JS::ObjectIsNotGray(mCallback));
     return CallbackPreserveColor();
   }
 
   nsIGlobalObject* IncumbentGlobalOrNull() const
   {
     return mIncumbentGlobal;
   }
 
--- a/dom/bindings/Codegen.py
+++ b/dom/bindings/Codegen.py
@@ -3247,17 +3247,17 @@ class CGGetPerInterfaceObject(CGAbstract
              * traced by TraceProtoAndIfaceCache() and its contents are never
              * changed after they have been set.
              *
              * Calling address() avoids the read read barrier that does gray
              * unmarking, but it's not possible for the object to be gray here.
              */
 
             const JS::Heap<JSObject*>& entrySlot = protoAndIfaceCache.EntrySlotMustExist(${id});
-            MOZ_ASSERT_IF(entrySlot, !JS::ObjectIsMarkedGray(entrySlot));
+            MOZ_ASSERT(JS::ObjectIsNotGray(entrySlot));
             return JS::Handle<JSObject*>::fromMarkedLocation(entrySlot.address());
             """,
             id=self.id)
 
 
 class CGGetProtoObjectHandleMethod(CGGetPerInterfaceObject):
     """
     A method for getting the interface prototype object.
@@ -3764,17 +3764,17 @@ class CGWrapWithCacheMethod(CGAbstractMe
             MOZ_ASSERT(ToSupportsIsOnPrimaryInheritanceChain(aObject, aCache),
                        "nsISupports must be on our primary inheritance chain");
 
             JS::Rooted<JSObject*> global(aCx, FindAssociatedGlobal(aCx, aObject->GetParentObject()));
             if (!global) {
               return false;
             }
             MOZ_ASSERT(JS_IsGlobalObject(global));
-            MOZ_ASSERT(!JS::ObjectIsMarkedGray(global));
+            MOZ_ASSERT(JS::ObjectIsNotGray(global));
 
             // That might have ended up wrapping us already, due to the wonders
             // of XBL.  Check for that, and bail out as needed.
             aReflector.set(aCache->GetWrapper());
             if (aReflector) {
             #ifdef DEBUG
               binding_detail::AssertReflectorHasGivenProto(aCx, aReflector, aGivenProto);
             #endif // DEBUG
--- a/gfx/thebes/gfxPrefs.h
+++ b/gfx/thebes/gfxPrefs.h
@@ -440,16 +440,17 @@ private:
 
   DECL_GFX_PREF(Once, "image.cache.size",                      ImageCacheSize, int32_t, 5*1024*1024);
   DECL_GFX_PREF(Once, "image.cache.timeweight",                ImageCacheTimeWeight, int32_t, 500);
   DECL_GFX_PREF(Live, "image.decode-immediately.enabled",      ImageDecodeImmediatelyEnabled, bool, false);
   DECL_GFX_PREF(Live, "image.downscale-during-decode.enabled", ImageDownscaleDuringDecodeEnabled, bool, true);
   DECL_GFX_PREF(Live, "image.infer-src-animation.threshold-ms", ImageInferSrcAnimationThresholdMS, uint32_t, 2000);
   DECL_GFX_PREF(Once, "image.mem.decode_bytes_at_a_time",      ImageMemDecodeBytesAtATime, uint32_t, 200000);
   DECL_GFX_PREF(Live, "image.mem.discardable",                 ImageMemDiscardable, bool, false);
+  DECL_GFX_PREF(Once, "image.mem.animated.discardable",        ImageMemAnimatedDiscardable, bool, false);
   DECL_GFX_PREF(Live, "image.mem.shared",                      ImageMemShared, bool, false);
   DECL_GFX_PREF(Once, "image.mem.surfacecache.discard_factor", ImageMemSurfaceCacheDiscardFactor, uint32_t, 1);
   DECL_GFX_PREF(Once, "image.mem.surfacecache.max_size_kb",    ImageMemSurfaceCacheMaxSizeKB, uint32_t, 100 * 1024);
   DECL_GFX_PREF(Once, "image.mem.surfacecache.min_expiration_ms", ImageMemSurfaceCacheMinExpirationMS, uint32_t, 60*1000);
   DECL_GFX_PREF(Once, "image.mem.surfacecache.size_factor",    ImageMemSurfaceCacheSizeFactor, uint32_t, 64);
   DECL_GFX_PREF(Once, "image.multithreaded_decoding.limit",    ImageMTDecodingLimit, int32_t, -1);
 
   DECL_GFX_PREF(Once, "layers.acceleration.disabled",          LayersAccelerationDisabledDoNotUseDirectly, bool, false);
--- a/image/FrameAnimator.cpp
+++ b/image/FrameAnimator.cpp
@@ -6,33 +6,34 @@
 #include "FrameAnimator.h"
 
 #include "mozilla/MemoryReporting.h"
 #include "mozilla/Move.h"
 #include "imgIContainer.h"
 #include "LookupResult.h"
 #include "MainThreadUtils.h"
 #include "RasterImage.h"
+#include "gfxPrefs.h"
 
 #include "pixman.h"
 
 namespace mozilla {
 
 using namespace gfx;
 
 namespace image {
 
 ///////////////////////////////////////////////////////////////////////////////
 // AnimationState implementation.
 ///////////////////////////////////////////////////////////////////////////////
 
 void
-AnimationState::SetDoneDecoding(bool aDone)
+AnimationState::NotifyDecodeComplete()
 {
-  mDoneDecoding = aDone;
+  mHasBeenDecoded = true;
 }
 
 void
 AnimationState::ResetAnimation()
 {
   mCurrentAnimationFrameIndex = 0;
 }
 
@@ -47,26 +48,26 @@ AnimationState::UpdateKnownFrameCount(ui
 {
   if (aFrameCount <= mFrameCount) {
     // Nothing to do. Since we can redecode animated images, we may see the same
     // sequence of updates replayed again, so seeing a smaller frame count than
     // what we already know about doesn't indicate an error.
     return;
   }
 
-  MOZ_ASSERT(!mDoneDecoding, "Adding new frames after decoding is finished?");
+  MOZ_ASSERT(!mHasBeenDecoded, "Adding new frames after decoding is finished?");
   MOZ_ASSERT(aFrameCount <= mFrameCount + 1, "Skipped a frame?");
 
   mFrameCount = aFrameCount;
 }
 
 Maybe<uint32_t>
 AnimationState::FrameCount() const
 {
-  return mDoneDecoding ? Some(mFrameCount) : Nothing();
+  return mHasBeenDecoded ? Some(mFrameCount) : Nothing();
 }
 
 void
 AnimationState::SetFirstFrameRefreshArea(const IntRect& aRefreshArea)
 {
   mFirstFrameRefreshArea = aRefreshArea;
 }
 
@@ -93,17 +94,17 @@ AnimationState::GetCurrentAnimationFrame
 FrameTimeout
 AnimationState::LoopLength() const
 {
   // If we don't know the loop length yet, we have to treat it as infinite.
   if (!mLoopLength) {
     return FrameTimeout::Forever();
   }
 
-  MOZ_ASSERT(mDoneDecoding, "We know the loop length but decoding isn't done?");
+  MOZ_ASSERT(mHasBeenDecoded, "We know the loop length but decoding isn't done?");
 
   // If we're not looping, a single loop time has no meaning.
   if (mAnimationMode != imgIContainer::kNormalAnimMode) {
     return FrameTimeout::Forever();
   }
 
   return *mLoopLength;
 }
--- a/image/FrameAnimator.h
+++ b/image/FrameAnimator.h
@@ -10,40 +10,45 @@
 #include "mozilla/Maybe.h"
 #include "mozilla/MemoryReporting.h"
 #include "mozilla/TimeStamp.h"
 #include "gfxTypes.h"
 #include "imgFrame.h"
 #include "nsCOMPtr.h"
 #include "nsRect.h"
 #include "SurfaceCache.h"
+#include "gfxPrefs.h"
 
 namespace mozilla {
 namespace image {
 
 class RasterImage;
 
 class AnimationState
 {
 public:
   explicit AnimationState(uint16_t aAnimationMode)
     : mFrameCount(0)
     , mCurrentAnimationFrameIndex(0)
     , mLoopRemainingCount(-1)
     , mLoopCount(-1)
     , mFirstFrameTimeout(FrameTimeout::FromRawMilliseconds(0))
     , mAnimationMode(aAnimationMode)
-    , mDoneDecoding(false)
+    , mHasBeenDecoded(false)
   { }
 
   /**
-   * Call when this image is finished decoding so we know that there aren't any
-   * more frames coming.
+   * Call when a decode of this image has been completed.
    */
-  void SetDoneDecoding(bool aDone);
+  void NotifyDecodeComplete();
+
+  /**
+   * Returns true if this image has been fully decoded before.
+   */
+  bool GetHasBeenDecoded() { return mHasBeenDecoded; }
 
   /**
    * Call when you need to re-start animating. Ensures we start from the first
    * frame.
    */
   void ResetAnimation();
 
   /**
@@ -135,18 +140,18 @@ private:
   Maybe<FrameTimeout> mLoopLength;
 
   //! The timeout for the first frame of this image.
   FrameTimeout mFirstFrameTimeout;
 
   //! The animation mode of this image. Constants defined in imgIContainer.
   uint16_t mAnimationMode;
 
-  //! Whether this image is done being decoded.
-  bool mDoneDecoding;
+  //! Whether this image has been decoded at least once.
+  bool mHasBeenDecoded;
 };
 
 /**
  * RefreshResult is used to let callers know how the state of the animation
  * changed during a call to FrameAnimator::RequestRefresh().
  */
 struct RefreshResult
 {
--- a/image/RasterImage.cpp
+++ b/image/RasterImage.cpp
@@ -1643,17 +1643,17 @@ RasterImage::NotifyDecodeComplete(const 
   // Send out any final notifications.
   NotifyProgress(aProgress, aInvalidRect, aFrameCount,
                  aDecoderFlags, aSurfaceFlags);
 
   if (!(aDecoderFlags & DecoderFlags::FIRST_FRAME_ONLY) &&
       mHasBeenDecoded && mAnimationState) {
     // We've finished a full decode of all animation frames and our AnimationState
     // has been notified about them all, so let it know not to expect anymore.
-    mAnimationState->SetDoneDecoding(true);
+    mAnimationState->NotifyDecodeComplete();
   }
 
   // Do some telemetry if this isn't a metadata decode.
   if (!aStatus.mWasMetadataDecode) {
     if (aTelemetry.mChunkCount) {
       Telemetry::Accumulate(Telemetry::IMAGE_DECODE_CHUNKS, aTelemetry.mChunkCount);
     }
 
--- a/image/imgLoader.cpp
+++ b/image/imgLoader.cpp
@@ -50,16 +50,17 @@
 
 // we want to explore making the document own the load group
 // so we can associate the document URI with the load group.
 // until this point, we have an evil hack:
 #include "nsIHttpChannelInternal.h"
 #include "nsILoadContext.h"
 #include "nsILoadGroupChild.h"
 #include "nsIDOMDocument.h"
+#include "nsIDocShell.h"
 
 using namespace mozilla;
 using namespace mozilla::dom;
 using namespace mozilla::image;
 using namespace mozilla::net;
 
 MOZ_DEFINE_MALLOC_SIZE_OF(ImagesMallocSizeOf)
 
@@ -582,16 +583,29 @@ ShouldLoadCachedImage(imgRequest* aImgRe
                                  nsContentUtils::GetSecurityManager());
   if (NS_FAILED(rv) || !NS_CP_ACCEPTED(decision)) {
     return false;
   }
 
   // We call all Content Policies above, but we also have to call mcb
   // individually to check the intermediary redirect hops are secure.
   if (insecureRedirect) {
+    // Bug 1314356: If the image ended up in the cache upgraded by HSTS and the page
+    // uses upgrade-inscure-requests it had an insecure redirect (http->https).
+    // We need to invalidate the image and reload it because mixed content blocker
+    // only bails if upgrade-insecure-requests is set on the doc and the resource
+    // load is http: which would result in an incorrect mixed content warning.
+    nsCOMPtr<nsIDocShell> docShell = NS_CP_GetDocShellFromContext(aLoadingContext);
+    if (docShell) {
+      nsIDocument* document = docShell->GetDocument();
+      if (document && document->GetUpgradeInsecureRequests(false)) {
+        return false;
+      }
+    }
+
     if (!nsContentUtils::IsSystemPrincipal(aLoadingPrincipal)) {
       // Set the requestingLocation from the aLoadingPrincipal.
       nsCOMPtr<nsIURI> requestingLocation;
       if (aLoadingPrincipal) {
         rv = aLoadingPrincipal->GetURI(getter_AddRefs(requestingLocation));
         NS_ENSURE_SUCCESS(rv, false);
       }
 
--- a/js/public/CallArgs.h
+++ b/js/public/CallArgs.h
@@ -284,18 +284,20 @@ class MOZ_STACK_CLASS CallArgs : public 
 
     static CallArgs create(unsigned argc, Value* argv, bool constructing) {
         CallArgs args;
         args.clearUsedRval();
         args.argv_ = argv;
         args.argc_ = argc;
         args.constructing_ = constructing;
 #ifdef DEBUG
+        MOZ_ASSERT(ValueIsNotGray(args.thisv()));
+        MOZ_ASSERT(ValueIsNotGray(args.calleev()));
         for (unsigned i = 0; i < argc; ++i)
-            MOZ_ASSERT_IF(argv[i].isGCThing(), !GCThingIsMarkedGray(GCCellPtr(argv[i])));
+            MOZ_ASSERT(ValueIsNotGray(argv[i]));
 #endif
         return args;
     }
 
   public:
     /*
      * Returns true if there are at least |required| arguments passed in. If
      * false, it reports an error message on the context.
--- a/js/public/HeapAPI.h
+++ b/js/public/HeapAPI.h
@@ -305,16 +305,21 @@ CellIsMarkedGray(const Cell* cell)
     uintptr_t* word, mask;
     js::gc::detail::GetGCThingMarkWordAndMask(uintptr_t(cell), js::gc::GRAY, &word, &mask);
     return *word & mask;
 }
 
 extern JS_PUBLIC_API(bool)
 CellIsMarkedGrayIfKnown(const Cell* cell);
 
+#ifdef DEBUG
+extern JS_PUBLIC_API(bool)
+CellIsNotGray(const Cell* cell);
+#endif
+
 } /* namespace detail */
 
 MOZ_ALWAYS_INLINE bool
 IsInsideNursery(const js::gc::Cell* cell)
 {
     if (!cell)
         return false;
     uintptr_t addr = uintptr_t(cell);
--- a/js/public/RootingAPI.h
+++ b/js/public/RootingAPI.h
@@ -318,29 +318,41 @@ ObjectIsMarkedGray(JSObject* obj)
 }
 
 static MOZ_ALWAYS_INLINE bool
 ObjectIsMarkedGray(const JS::Heap<JSObject*>& obj)
 {
     return ObjectIsMarkedGray(obj.unbarrieredGet());
 }
 
-static MOZ_ALWAYS_INLINE bool
-ScriptIsMarkedGray(JSScript* script)
+// The following *IsNotGray functions are for use in assertions and take account
+// of the eventual gray marking state at the end of any ongoing incremental GC.
+#ifdef DEBUG
+inline bool
+CellIsNotGray(js::gc::Cell* maybeCell)
 {
-    auto cell = reinterpret_cast<js::gc::Cell*>(script);
-    return js::gc::detail::CellIsMarkedGrayIfKnown(cell);
+    if (!maybeCell)
+        return true;
+
+    return js::gc::detail::CellIsNotGray(maybeCell);
 }
 
-static MOZ_ALWAYS_INLINE bool
-ScriptIsMarkedGray(const Heap<JSScript*>& script)
+inline bool
+ObjectIsNotGray(JSObject* maybeObj)
 {
-    return ScriptIsMarkedGray(script.unbarrieredGet());
+    return CellIsNotGray(reinterpret_cast<js::gc::Cell*>(maybeObj));
 }
 
+inline bool
+ObjectIsNotGray(const JS::Heap<JSObject*>& obj)
+{
+    return ObjectIsNotGray(obj.unbarrieredGet());
+}
+#endif
+
 /**
  * The TenuredHeap<T> class is similar to the Heap<T> class above in that it
  * encapsulates the GC concerns of an on-heap reference to a JS object. However,
  * it has two important differences:
  *
  *  1) Pointers which are statically known to only reference "tenured" objects
  *     can avoid the extra overhead of SpiderMonkey's write barriers.
  *
--- a/js/public/Value.h
+++ b/js/public/Value.h
@@ -1447,16 +1447,37 @@ DispatchTyped(F f, const JS::Value& val,
 }
 
 template <class S> struct VoidDefaultAdaptor { static void defaultValue(const S&) {} };
 template <class S> struct IdentityDefaultAdaptor { static S defaultValue(const S& v) {return v;} };
 template <class S, bool v> struct BoolDefaultAdaptor { static bool defaultValue(const S&) { return v; } };
 
 } // namespace js
 
+#ifdef DEBUG
+namespace JS {
+
+MOZ_ALWAYS_INLINE bool
+ValueIsNotGray(const Value& value)
+{
+    if (!value.isGCThing())
+        return true;
+
+    return CellIsNotGray(value.toGCThing());
+}
+
+MOZ_ALWAYS_INLINE bool
+ValueIsNotGray(const Heap<Value>& value)
+{
+    return ValueIsNotGray(value.unbarrieredGet());
+}
+
+} // namespace JS
+#endif
+
 /************************************************************************/
 
 namespace JS {
 
 extern JS_PUBLIC_DATA(const HandleValue) NullHandleValue;
 extern JS_PUBLIC_DATA(const HandleValue) UndefinedHandleValue;
 extern JS_PUBLIC_DATA(const HandleValue) TrueHandleValue;
 extern JS_PUBLIC_DATA(const HandleValue) FalseHandleValue;
--- a/js/src/gc/Barrier.cpp
+++ b/js/src/gc/Barrier.cpp
@@ -26,17 +26,17 @@ RuntimeFromActiveCooperatingThreadIsHeap
 {
     MOZ_ASSERT(CurrentThreadCanAccessRuntime(shadowZone->runtimeFromActiveCooperatingThread()));
     return JS::CurrentThreadIsHeapMajorCollecting();
 }
 
 #ifdef DEBUG
 
 bool
-IsMarkedBlack(NativeObject* obj)
+IsMarkedBlack(JSObject* obj)
 {
     // Note: we assume conservatively that Nursery things will be live.
     if (!obj->isTenured())
         return true;
 
     gc::TenuredCell& tenured = obj->asTenured();
     if (tenured.isMarked(gc::BLACK) || tenured.arena()->allocatedDuringIncremental)
         return true;
@@ -56,18 +56,17 @@ void
 HeapSlot::assertPreconditionForWriteBarrierPost(NativeObject* obj, Kind kind, uint32_t slot,
                                                 const Value& target) const
 {
     if (kind == Slot)
         MOZ_ASSERT(obj->getSlotAddressUnchecked(slot)->get() == target);
     else
         MOZ_ASSERT(static_cast<HeapSlot*>(obj->getDenseElements() + slot)->get() == target);
 
-    MOZ_ASSERT_IF(target.isGCThing() && IsMarkedBlack(obj),
-                  !JS::GCThingIsMarkedGray(JS::GCCellPtr(target)));
+    CheckEdgeIsNotBlackToGray(obj, target);
 }
 
 bool
 CurrentThreadIsIonCompiling()
 {
     return TlsContext.get()->ionCompiling;
 }
 
--- a/js/src/gc/Barrier.h
+++ b/js/src/gc/Barrier.h
@@ -237,19 +237,25 @@ CurrentThreadIsIonCompiling();
 
 bool
 CurrentThreadIsIonCompilingSafeForMinorGC();
 
 bool
 CurrentThreadIsGCSweeping();
 
 bool
-IsMarkedBlack(NativeObject* obj);
+IsMarkedBlack(JSObject* obj);
 #endif
 
+MOZ_ALWAYS_INLINE void
+CheckEdgeIsNotBlackToGray(JSObject* src, const Value& dst)
+{
+    MOZ_ASSERT_IF(IsMarkedBlack(src), JS::ValueIsNotGray(dst));
+}
+
 template <typename T>
 struct InternalBarrierMethods {};
 
 template <typename T>
 struct InternalBarrierMethods<T*>
 {
     static bool isMarkable(T* v) { return v != nullptr; }
 
--- a/js/src/gc/Marking.cpp
+++ b/js/src/gc/Marking.cpp
@@ -2249,17 +2249,17 @@ MarkStackIter::position() const
 }
 
 inline bool
 MarkStackIter::done() const
 {
     return position() == 0;
 }
 
-inline const MarkStack::TaggedPtr&
+inline MarkStack::TaggedPtr
 MarkStackIter::peekPtr() const
 {
     MOZ_ASSERT(!done());
     return pos_[-1];
 }
 
 inline MarkStack::Tag
 MarkStackIter::peekTag() const
@@ -2282,16 +2282,25 @@ inline void
 MarkStackIter::nextPtr()
 {
     MOZ_ASSERT(!done());
     MOZ_ASSERT(!TagIsArrayTag(peekTag()));
     pos_--;
 }
 
 inline void
+MarkStackIter::next()
+{
+    if (TagIsArrayTag(peekTag()))
+        nextArray();
+    else
+        nextPtr();
+}
+
+inline void
 MarkStackIter::nextArray()
 {
     MOZ_ASSERT(TagIsArrayTag(peekTag()));
     MOZ_ASSERT(position() >= ValueArrayWords);
     pos_ -= ValueArrayWords;
 }
 
 void
@@ -2554,16 +2563,39 @@ size_t
 GCMarker::sizeOfExcludingThis(mozilla::MallocSizeOf mallocSizeOf) const
 {
     size_t size = stack.sizeOfExcludingThis(mallocSizeOf);
     for (ZonesIter zone(runtime(), WithAtoms); !zone.done(); zone.next())
         size += zone->gcGrayRoots().sizeOfExcludingThis(mallocSizeOf);
     return size;
 }
 
+#ifdef DEBUG
+Zone*
+GCMarker::stackContainsCrossZonePointerTo(const TenuredCell* target) const
+{
+    MOZ_ASSERT(!JS::CurrentThreadIsHeapCollecting());
+
+    for (MarkStackIter iter(stack); !iter.done(); iter.next()) {
+        if (iter.peekTag() != MarkStack::ObjectTag)
+            continue;
+
+        auto source = iter.peekPtr().as<JSObject>();
+        if (source->is<ProxyObject>() &&
+            source->as<ProxyObject>().target() == static_cast<const Cell*>(target) &&
+            source->zone() != target->zone())
+        {
+            return source->zone();
+        }
+    }
+
+    return nullptr;
+}
+#endif // DEBUG
+
 
 /*** Tenuring Tracer *****************************************************************************/
 
 namespace js {
 template <typename T>
 void
 TenuringTracer::traverse(T** tp)
 {
--- a/js/src/gc/Marking.h
+++ b/js/src/gc/Marking.h
@@ -188,26 +188,27 @@ class MarkStackIter
     MarkStack::TaggedPtr* pos_;
 
   public:
     explicit MarkStackIter(const MarkStack& stack);
     ~MarkStackIter();
 
     bool done() const;
     MarkStack::Tag peekTag() const;
+    MarkStack::TaggedPtr peekPtr() const;
     MarkStack::ValueArray peekValueArray() const;
+    void next();
     void nextPtr();
     void nextArray();
 
     // Mutate the current ValueArray to a SavedValueArray.
     void saveValueArray(NativeObject* obj, uintptr_t index, HeapSlot::Kind kind);
 
   private:
     size_t position() const;
-    const MarkStack::TaggedPtr& peekPtr() const;
 };
 
 struct WeakKeyTableHashPolicy {
     typedef JS::GCCellPtr Lookup;
     static HashNumber hash(const Lookup& v, const mozilla::HashCodeScrambler&) {
         return mozilla::HashGeneric(v.asCell());
     }
     static bool match(const JS::GCCellPtr& k, const Lookup& l) { return k == l; }
@@ -295,17 +296,21 @@ class GCMarker : public JSTracer
 
     MOZ_MUST_USE bool drainMarkStack(SliceBudget& budget);
 
     void setGCMode(JSGCMode mode) { stack.setGCMode(mode); }
 
     size_t sizeOfExcludingThis(mozilla::MallocSizeOf mallocSizeOf) const;
 
 #ifdef DEBUG
+
     bool shouldCheckCompartments() { return strictCompartmentChecking; }
+
+    Zone* stackContainsCrossZonePointerTo(const gc::TenuredCell* cell) const;
+
 #endif
 
     void markEphemeronValues(gc::Cell* markedCell, gc::WeakEntryVector& entry);
 
     static GCMarker* fromTracer(JSTracer* trc) {
         MOZ_ASSERT(trc->isMarkingTracer());
         return static_cast<GCMarker*>(trc);
     }
--- a/js/src/jit/Lowering.cpp
+++ b/js/src/jit/Lowering.cpp
@@ -4406,24 +4406,33 @@ LIRGenerator::visitWasmCall(MWasmCall* i
     if (!args) {
         abort(AbortReason::Alloc, "Couldn't allocate for MWasmCall");
         return;
     }
 
     for (unsigned i = 0; i < ins->numArgs(); i++)
         args[i] = useFixedAtStart(ins->getOperand(i), ins->registerForArg(i));
 
-    if (ins->callee().isTable())
-        args[ins->numArgs()] = useFixedAtStart(ins->getOperand(ins->numArgs()), WasmTableCallIndexReg);
+    bool needsBoundsCheck = true;
+    if (ins->callee().isTable()) {
+        MDefinition* index = ins->getOperand(ins->numArgs());
+
+        if (ins->callee().which() == wasm::CalleeDesc::WasmTable && index->isConstant()) {
+            if (uint32_t(index->toConstant()->toInt32()) < ins->callee().wasmTableMinLength())
+                needsBoundsCheck = false;
+        }
+
+        args[ins->numArgs()] = useFixedAtStart(index, WasmTableCallIndexReg);
+    }
 
     LInstruction* lir;
     if (ins->type() == MIRType::Int64)
-        lir = new(alloc()) LWasmCallI64(args, ins->numOperands());
+        lir = new(alloc()) LWasmCallI64(args, ins->numOperands(), needsBoundsCheck);
     else
-        lir = new(alloc()) LWasmCall(args, ins->numOperands());
+        lir = new(alloc()) LWasmCall(args, ins->numOperands(), needsBoundsCheck);
 
     if (ins->type() == MIRType::None)
         add(lir, ins);
     else
         defineReturn(lir, ins);
 }
 
 void
--- a/js/src/jit/MacroAssembler.cpp
+++ b/js/src/jit/MacroAssembler.cpp
@@ -2814,17 +2814,18 @@ MacroAssembler::wasmCallBuiltinInstanceM
     } else {
         MOZ_CRASH("Unknown abi passing style for pointer");
     }
 
     call(builtin);
 }
 
 void
-MacroAssembler::wasmCallIndirect(const wasm::CallSiteDesc& desc, const wasm::CalleeDesc& callee)
+MacroAssembler::wasmCallIndirect(const wasm::CallSiteDesc& desc, const wasm::CalleeDesc& callee,
+                                 bool needsBoundsCheck)
 {
     Register scratch = WasmTableCallScratchReg;
     Register index = WasmTableCallIndexReg;
 
     if (callee.which() == wasm::CalleeDesc::AsmJSTable) {
         // asm.js tables require no signature check, have had their index masked
         // into range and thus need no bounds check and cannot be external.
         loadWasmGlobalPtr(callee.tableBaseGlobalDataOffset(), scratch);
@@ -2843,22 +2844,25 @@ MacroAssembler::wasmCallIndirect(const w
         break;
       case wasm::SigIdDesc::Kind::Immediate:
         move32(Imm32(sigId.immediate()), WasmTableCallSigReg);
         break;
       case wasm::SigIdDesc::Kind::None:
         break;
     }
 
+    wasm::TrapOffset trapOffset(desc.lineOrBytecode());
+
     // WebAssembly throws if the index is out-of-bounds.
-    loadWasmGlobalPtr(callee.tableLengthGlobalDataOffset(), scratch);
-
-    wasm::TrapOffset trapOffset(desc.lineOrBytecode());
-    wasm::TrapDesc oobTrap(trapOffset, wasm::Trap::OutOfBounds, framePushed());
-    branch32(Assembler::Condition::AboveOrEqual, index, scratch, oobTrap);
+    if (needsBoundsCheck) {
+        loadWasmGlobalPtr(callee.tableLengthGlobalDataOffset(), scratch);
+
+        wasm::TrapDesc oobTrap(trapOffset, wasm::Trap::OutOfBounds, framePushed());
+        branch32(Assembler::Condition::AboveOrEqual, index, scratch, oobTrap);
+    }
 
     // Load the base pointer of the table.
     loadWasmGlobalPtr(callee.tableBaseGlobalDataOffset(), scratch);
 
     // Load the callee from the table.
     wasm::TrapDesc nullTrap(trapOffset, wasm::Trap::IndirectCallToNull, framePushed());
     if (callee.wasmTableIsExternal()) {
         static_assert(sizeof(wasm::ExternalTableElem) == 8 || sizeof(wasm::ExternalTableElem) == 16,
--- a/js/src/jit/MacroAssembler.h
+++ b/js/src/jit/MacroAssembler.h
@@ -1426,17 +1426,17 @@ class MacroAssembler : public MacroAssem
     void outOfLineWasmTruncateDoubleToInt64(FloatRegister input, bool isUnsigned, wasm::TrapOffset off, Label* rejoin) DEFINED_ON(x86_shared);
     void outOfLineWasmTruncateFloat32ToInt64(FloatRegister input, bool isUnsigned, wasm::TrapOffset off, Label* rejoin) DEFINED_ON(x86_shared);
 
     // This function takes care of loading the callee's TLS and pinned regs but
     // it is the caller's responsibility to save/restore TLS or pinned regs.
     void wasmCallImport(const wasm::CallSiteDesc& desc, const wasm::CalleeDesc& callee);
 
     // WasmTableCallIndexReg must contain the index of the indirect call.
-    void wasmCallIndirect(const wasm::CallSiteDesc& desc, const wasm::CalleeDesc& callee);
+    void wasmCallIndirect(const wasm::CallSiteDesc& desc, const wasm::CalleeDesc& callee, bool needsBoundsCheck);
 
     // This function takes care of loading the pointer to the current instance
     // as the implicit first argument. It preserves TLS and pinned registers.
     // (TLS & pinned regs are non-volatile registers in the system ABI).
     void wasmCallBuiltinInstanceMethod(const ABIArg& instanceArg,
                                        wasm::SymbolicAddress builtin);
 
     // Emit the out-of-line trap code to which trapping jumps/branches are
--- a/js/src/jit/arm/Assembler-arm.cpp
+++ b/js/src/jit/arm/Assembler-arm.cpp
@@ -1668,44 +1668,23 @@ Assembler::SpewNodes::remove(uint32_t ke
             return true;
         }
     }
     return false;
 }
 
 #endif // JS_DISASM_ARM
 
-// Write a blob of binary into the instruction stream.
-BufferOffset
-Assembler::writeInst(uint32_t x)
-{
-    BufferOffset offs = m_buffer.putInt(x);
-#ifdef JS_DISASM_ARM
-    spew(m_buffer.getInstOrNull(offs));
-#endif
-    return offs;
-}
-
-BufferOffset
-Assembler::writeBranchInst(uint32_t x, Label* documentation)
-{
-    BufferOffset offs = m_buffer.putInt(x, /* markAsBranch = */ true);
-#ifdef JS_DISASM_ARM
-    spewBranch(m_buffer.getInstOrNull(offs), documentation);
-#endif
-    return offs;
-}
-
 // Allocate memory for a branch instruction, it will be overwritten
 // subsequently and should not be disassembled.
 
 BufferOffset
 Assembler::allocBranchInst()
 {
-    return m_buffer.putInt(Always | InstNOP::NopInst, /* markAsBranch = */ true);
+    return m_buffer.putInt(Always | InstNOP::NopInst);
 }
 
 void
 Assembler::WriteInstStatic(uint32_t x, uint32_t* dest)
 {
     MOZ_ASSERT(dest != nullptr);
     *dest = x;
 }
@@ -2149,44 +2128,38 @@ Assembler::as_extdtr(LoadStore ls, int s
 
 BufferOffset
 Assembler::as_dtm(LoadStore ls, Register rn, uint32_t mask,
                 DTMMode mode, DTMWriteBack wb, Condition c)
 {
     return writeInst(0x08000000 | RN(rn) | ls | mode | mask | c | wb);
 }
 
-// Note, it's possible for markAsBranch and loadToPC to disagree,
-// because some loads to the PC are not necessarily encoding
-// instructions that should be marked as branches: only patchable
-// near branch instructions should be marked.
-
 BufferOffset
 Assembler::allocEntry(size_t numInst, unsigned numPoolEntries,
                       uint8_t* inst, uint8_t* data, ARMBuffer::PoolEntry* pe,
-                      bool markAsBranch, bool loadToPC)
+                      bool loadToPC)
 {
-    BufferOffset offs = m_buffer.allocEntry(numInst, numPoolEntries, inst, data, pe, markAsBranch);
+    BufferOffset offs = m_buffer.allocEntry(numInst, numPoolEntries, inst, data, pe);
     propagateOOM(offs.assigned());
 #ifdef JS_DISASM_ARM
     spewData(offs, numInst, loadToPC);
 #endif
     return offs;
 }
 
 // This is also used for instructions that might be resolved into branches,
 // or might not.  If dest==pc then it is effectively a branch.
 
 BufferOffset
 Assembler::as_Imm32Pool(Register dest, uint32_t value, Condition c)
 {
     PoolHintPun php;
     php.phd.init(0, c, PoolHintData::PoolDTR, dest);
-    BufferOffset offs = allocEntry(1, 1, (uint8_t*)&php.raw, (uint8_t*)&value, nullptr, false,
-                                   dest == pc);
+    BufferOffset offs = allocEntry(1, 1, (uint8_t*)&php.raw, (uint8_t*)&value, nullptr, dest == pc);
     return offs;
 }
 
 /* static */ void
 Assembler::WritePoolEntry(Instruction* addr, Condition c, uint32_t data)
 {
     MOZ_ASSERT(addr->is<InstLDR>());
     *addr->as<InstLDR>()->dest() = data;
@@ -2195,17 +2168,17 @@ Assembler::WritePoolEntry(Instruction* a
 
 BufferOffset
 Assembler::as_BranchPool(uint32_t value, RepatchLabel* label, ARMBuffer::PoolEntry* pe, Condition c,
                          Label* documentation)
 {
     PoolHintPun php;
     php.phd.init(0, c, PoolHintData::PoolBranch, pc);
     BufferOffset ret = allocEntry(1, 1, (uint8_t*)&php.raw, (uint8_t*)&value, pe,
-                                  /* markAsBranch = */ true, /* loadToPC = */ true);
+                                  /* loadToPC = */ true);
     // If this label is already bound, then immediately replace the stub load
     // with a correct branch.
     if (label->bound()) {
         BufferOffset dest(label);
         BOffImm offset = dest.diffB<BOffImm>(ret);
         if (offset.isInvalid()) {
             m_buffer.fail_bail();
             return ret;
--- a/js/src/jit/arm/Assembler-arm.h
+++ b/js/src/jit/arm/Assembler-arm.h
@@ -1232,17 +1232,17 @@ class Assembler : public AssemblerShared
     BufferOffset nextOffset() {
         return m_buffer.nextOffset();
     }
 
   protected:
     // Shim around AssemblerBufferWithConstantPools::allocEntry.
     BufferOffset allocEntry(size_t numInst, unsigned numPoolEntries,
                             uint8_t* inst, uint8_t* data, ARMBuffer::PoolEntry* pe = nullptr,
-                            bool markAsBranch = false, bool loadToPC = false);
+                            bool loadToPC = false);
 
     Instruction* editSrc(BufferOffset bo) {
         return m_buffer.getInst(bo);
     }
 
 #ifdef JS_DISASM_ARM
     static void spewInst(Instruction* i);
     void spew(Instruction* i);
@@ -1422,22 +1422,35 @@ class Assembler : public AssemblerShared
     // Size of the jump relocation table, in bytes.
     size_t jumpRelocationTableBytes() const;
     size_t dataRelocationTableBytes() const;
     size_t preBarrierTableBytes() const;
 
     // Size of the data table, in bytes.
     size_t bytesNeeded() const;
 
-    // Write a blob of binary into the instruction stream *OR* into a
-    // destination address.
-    BufferOffset writeInst(uint32_t x);
+    // Write a single instruction into the instruction stream.  Very hot,
+    // inlined for performance
+    MOZ_ALWAYS_INLINE BufferOffset writeInst(uint32_t x) {
+        BufferOffset offs = m_buffer.putInt(x);
+#ifdef JS_DISASM_ARM
+        spew(m_buffer.getInstOrNull(offs));
+#endif
+        return offs;
+    }
 
-    // As above, but also mark the instruction as a branch.
-    BufferOffset writeBranchInst(uint32_t x, Label* documentation = nullptr);
+    // As above, but also mark the instruction as a branch.  Very hot, inlined
+    // for performance
+    MOZ_ALWAYS_INLINE BufferOffset writeBranchInst(uint32_t x, Label* documentation = nullptr) {
+        BufferOffset offs = m_buffer.putInt(x);
+#ifdef JS_DISASM_ARM
+        spewBranch(m_buffer.getInstOrNull(offs), documentation);
+#endif
+        return offs;
+    }
 
     // Write a placeholder NOP for a branch into the instruction stream
     // (in order to adjust assembler addresses and mark it as a branch), it will
     // be overwritten subsequently.
     BufferOffset allocBranchInst();
 
     // A static variant for the cases where we don't want to have an assembler
     // object.
--- a/js/src/jit/arm64/vixl/MozBaseAssembler-vixl.h
+++ b/js/src/jit/arm64/vixl/MozBaseAssembler-vixl.h
@@ -99,29 +99,30 @@ class MozBaseAssembler : public js::jit:
   BufferOffset nextOffset() const {
     return armbuffer_.nextOffset();
   }
 
   // Allocate memory in the buffer by forwarding to armbuffer_.
   // Propagate OOM errors.
   BufferOffset allocEntry(size_t numInst, unsigned numPoolEntries,
                           uint8_t* inst, uint8_t* data,
-                          ARMBuffer::PoolEntry* pe = nullptr,
-                          bool markAsBranch = false)
+                          ARMBuffer::PoolEntry* pe = nullptr)
   {
     BufferOffset offset = armbuffer_.allocEntry(numInst, numPoolEntries, inst,
-                                                data, pe, markAsBranch);
+                                                data, pe);
     propagateOOM(offset.assigned());
     return offset;
   }
 
   // Emit the instruction, returning its offset.
   BufferOffset Emit(Instr instruction, bool isBranch = false) {
     JS_STATIC_ASSERT(sizeof(instruction) == kInstructionSize);
-    return armbuffer_.putInt(*(uint32_t*)(&instruction), isBranch);
+    // TODO: isBranch is obsolete and should be removed.
+    (void)isBranch;
+    return armbuffer_.putInt(*(uint32_t*)(&instruction));
   }
 
   BufferOffset EmitBranch(Instr instruction) {
     return Emit(instruction, true);
   }
 
  public:
   // Emit the instruction at |at|.
--- a/js/src/jit/none/MacroAssembler-none.h
+++ b/js/src/jit/none/MacroAssembler-none.h
@@ -280,17 +280,17 @@ class MacroAssemblerNone : public Assemb
     template <typename T> void loadUnalignedSimd128Float(T, FloatRegister) { MOZ_CRASH(); }
     template <typename T> void loadPrivate(T, Register) { MOZ_CRASH(); }
     template <typename T> void load8SignExtend(T, Register) { MOZ_CRASH(); }
     template <typename T> void load8ZeroExtend(T, Register) { MOZ_CRASH(); }
     template <typename T> void load16SignExtend(T, Register) { MOZ_CRASH(); }
     template <typename T> void load16ZeroExtend(T, Register) { MOZ_CRASH(); }
     template <typename T> void load64(T, Register64 ) { MOZ_CRASH(); }
 
-    template <typename T, typename S> void storePtr(T, S) { MOZ_CRASH(); }
+    template <typename T, typename S> void storePtr(const T&, S) { MOZ_CRASH(); }
     template <typename T, typename S> void store32(T, S) { MOZ_CRASH(); }
     template <typename T, typename S> void store32_NoSecondScratch(T, S) { MOZ_CRASH(); }
     template <typename T, typename S> void storeFloat32(T, S) { MOZ_CRASH(); }
     template <typename T, typename S> void storeDouble(T, S) { MOZ_CRASH(); }
     template <typename T, typename S> void storeAlignedSimd128Int(T, S) { MOZ_CRASH(); }
     template <typename T, typename S> void storeUnalignedSimd128Int(T, S) { MOZ_CRASH(); }
     template <typename T, typename S> void storeAlignedSimd128Float(T, S) { MOZ_CRASH(); }
     template <typename T, typename S> void storeUnalignedSimd128Float(T, S) { MOZ_CRASH(); }
--- a/js/src/jit/shared/CodeGenerator-shared.cpp
+++ b/js/src/jit/shared/CodeGenerator-shared.cpp
@@ -1510,17 +1510,17 @@ CodeGeneratorShared::emitWasmCallBase(LW
       case wasm::CalleeDesc::Func:
         masm.call(desc, callee.funcIndex());
         break;
       case wasm::CalleeDesc::Import:
         masm.wasmCallImport(desc, callee);
         break;
       case wasm::CalleeDesc::WasmTable:
       case wasm::CalleeDesc::AsmJSTable:
-        masm.wasmCallIndirect(desc, callee);
+        masm.wasmCallIndirect(desc, callee, ins->needsBoundsCheck());
         break;
       case wasm::CalleeDesc::Builtin:
         masm.call(callee.builtin());
         break;
       case wasm::CalleeDesc::BuiltinInstanceMethod:
         masm.wasmCallBuiltinInstanceMethod(mir->instanceArg(), callee.builtin());
         break;
     }
--- a/js/src/jit/shared/IonAssemblerBuffer.h
+++ b/js/src/jit/shared/IonAssemblerBuffer.h
@@ -130,16 +130,25 @@ class BufferSlice
     }
 
     void putBytes(size_t numBytes, const void* source) {
         MOZ_ASSERT(bytelength_ + numBytes <= SliceSize);
         if (source)
             memcpy(&instructions[length()], source, numBytes);
         bytelength_ += numBytes;
     }
+
+    MOZ_ALWAYS_INLINE
+    void putU32Aligned(uint32_t value) {
+        MOZ_ASSERT(bytelength_ + 4 <= SliceSize);
+        MOZ_ASSERT((bytelength_ & 3) == 0);
+        MOZ_ASSERT((uintptr_t(&instructions[0]) & 3) == 0);
+        *reinterpret_cast<uint32_t*>(&instructions[bytelength_]) = value;
+        bytelength_ += 4;
+    }
 };
 
 template<int SliceSize, class Inst>
 class AssemblerBuffer
 {
   protected:
     typedef BufferSlice<SliceSize> Slice;
     typedef AssemblerBuffer<SliceSize, Inst> AssemblerBuffer_;
@@ -229,16 +238,26 @@ class AssemblerBuffer
     BufferOffset putShort(uint16_t value) {
         return putBytes(sizeof(value), &value);
     }
 
     BufferOffset putInt(uint32_t value) {
         return putBytes(sizeof(value), &value);
     }
 
+    MOZ_ALWAYS_INLINE
+    BufferOffset putU32Aligned(uint32_t value) {
+        if (!ensureSpace(sizeof(value)))
+            return BufferOffset();
+
+        BufferOffset ret = nextOffset();
+        tail->putU32Aligned(value);
+        return ret;
+    }
+
     // Add numBytes bytes to this buffer.
     // The data must fit in a single slice.
     BufferOffset putBytes(size_t numBytes, const void* inst) {
         if (!ensureSpace(numBytes))
             return BufferOffset();
 
         BufferOffset ret = nextOffset();
         tail->putBytes(numBytes, inst);
@@ -352,17 +371,18 @@ class AssemblerBuffer
             return nullptr;
         return getInst(off);
     }
 
     // Get a pointer to the instruction at offset |off| which must be within the
     // bounds of the buffer. Use |getInstOrNull()| if |off| may be unassigned.
     Inst* getInst(BufferOffset off) {
         const int offset = off.getOffset();
-        MOZ_RELEASE_ASSERT(off.assigned() && offset >= 0 && (unsigned)offset < size());
+        // This function is hot, do not make the next line a RELEASE_ASSERT.
+        MOZ_ASSERT(off.assigned() && offset >= 0 && unsigned(offset) < size());
 
         // Is the instruction in the last slice?
         if (offset >= int(bufferSize))
             return (Inst*)&tail->instructions[offset - bufferSize];
 
         // How close is this offset to the previous one we looked up?
         // If it is sufficiently far from the start and end of the buffer,
         // use the finger to start midway through the list.
--- a/js/src/jit/shared/IonAssemblerBufferWithConstantPools.h
+++ b/js/src/jit/shared/IonAssemblerBufferWithConstantPools.h
@@ -824,19 +824,19 @@ struct AssemblerBufferWithConstantPools 
         if (!hasSpaceForInsts(/* numInsts= */ 1, /* numPoolEntries= */ 0)) {
             JitSpew(JitSpew_Pools, "[%d] nextInstrOffset @ %d caused a constant pool spill", id,
                     this->nextOffset().getOffset());
             finishPool();
         }
         return this->nextOffset();
     }
 
+    MOZ_NEVER_INLINE
     BufferOffset allocEntry(size_t numInst, unsigned numPoolEntries,
-                            uint8_t* inst, uint8_t* data, PoolEntry* pe = nullptr,
-                            bool markAsBranch = false)
+                            uint8_t* inst, uint8_t* data, PoolEntry* pe = nullptr)
     {
         // The allocation of pool entries is not supported in a no-pool region,
         // check.
         MOZ_ASSERT_IF(numPoolEntries, !canNotPlacePool_);
 
         if (this->oom() && !this->bail())
             return BufferOffset();
 
@@ -872,18 +872,44 @@ struct AssemblerBufferWithConstantPools 
             poolEntryCount += numPoolEntries;
         }
         // Now inst is a valid thing to insert into the instruction stream.
         if (pe != nullptr)
             *pe = retPE;
         return this->putBytes(numInst * InstSize, inst);
     }
 
-    BufferOffset putInt(uint32_t value, bool markAsBranch = false) {
-        return allocEntry(1, 0, (uint8_t*)&value, nullptr, nullptr, markAsBranch);
+
+    // putInt is the workhorse for the assembler and higher-level buffer
+    // abstractions: it places one instruction into the instruction stream.
+    // Under normal circumstances putInt should just check that the constant
+    // pool does not need to be flushed, that there is space for the single word
+    // of the instruction, and write that word and update the buffer pointer.
+    //
+    // To do better here we need a status variable that handles both nopFill_
+    // and capacity, so that we can quickly know whether to go the slow path.
+    // That could be a variable that has the remaining number of simple
+    // instructions that can be inserted before a more expensive check,
+    // which is set to zero when nopFill_ is set.
+    //
+    // We assume that we don't have to check this->oom() if there is space to
+    // insert a plain instruction; there will always come a later time when it will be
+    // checked anyway.
+
+    MOZ_ALWAYS_INLINE
+    BufferOffset putInt(uint32_t value) {
+        if (nopFill_ || !hasSpaceForInsts(/* numInsts= */ 1, /* numPoolEntries= */ 0))
+            return allocEntry(1, 0, (uint8_t*)&value, nullptr, nullptr);
+
+#if defined(JS_CODEGEN_ARM) || defined(JS_CODEGEN_ARM64) || \
+    defined(JS_CODEGEN_MIPS32) || defined(JS_CODEGEN_MIPS64)
+        return this->putU32Aligned(value);
+#else
+        return this->AssemblerBuffer<SliceSize, Inst>::putInt(value);
+#endif
     }
 
     // Register a short-range branch deadline.
     //
     // After inserting a short-range forward branch, call this method to
     // register the branch 'deadline' which is the last buffer offset that the
     // branch instruction can reach.
     //
--- a/js/src/jit/shared/LIR-shared.h
+++ b/js/src/jit/shared/LIR-shared.h
@@ -8554,22 +8554,24 @@ class LWasmStackArgI64 : public LInstruc
         return getInt64Operand(0);
     }
 };
 
 class LWasmCallBase : public LInstruction
 {
     LAllocation* operands_;
     uint32_t numOperands_;
-
-  public:
-
-    LWasmCallBase(LAllocation* operands, uint32_t numOperands)
+    uint32_t needsBoundsCheck_;
+
+  public:
+
+    LWasmCallBase(LAllocation* operands, uint32_t numOperands, bool needsBoundsCheck)
       : operands_(operands),
-        numOperands_(numOperands)
+        numOperands_(numOperands),
+        needsBoundsCheck_(needsBoundsCheck)
     {}
 
     MWasmCall* mir() const {
         return mir_->toWasmCall();
     }
 
     bool isCall() const override {
         return true;
@@ -8607,27 +8609,30 @@ class LWasmCallBase : public LInstructio
         return 0;
     }
     MBasicBlock* getSuccessor(size_t i) const override {
         MOZ_CRASH("no successors");
     }
     void setSuccessor(size_t i, MBasicBlock*) override {
         MOZ_CRASH("no successors");
     }
+    bool needsBoundsCheck() const {
+        return needsBoundsCheck_;
+    }
 };
 
 class LWasmCall : public LWasmCallBase
 {
      LDefinition def_;
 
   public:
     LIR_HEADER(WasmCall);
 
-    LWasmCall(LAllocation* operands, uint32_t numOperands)
-      : LWasmCallBase(operands, numOperands),
+    LWasmCall(LAllocation* operands, uint32_t numOperands, bool needsBoundsCheck)
+      : LWasmCallBase(operands, numOperands, needsBoundsCheck),
         def_(LDefinition::BogusTemp())
     {}
 
     // LInstruction interface
     size_t numDefs() const {
         return def_.isBogusTemp() ? 0 : 1;
     }
     LDefinition* getDef(size_t index) {
@@ -8643,18 +8648,18 @@ class LWasmCall : public LWasmCallBase
 
 class LWasmCallI64 : public LWasmCallBase
 {
     LDefinition defs_[INT64_PIECES];
 
   public:
     LIR_HEADER(WasmCallI64);
 
-    LWasmCallI64(LAllocation* operands, uint32_t numOperands)
-      : LWasmCallBase(operands, numOperands)
+    LWasmCallI64(LAllocation* operands, uint32_t numOperands, bool needsBoundsCheck)
+      : LWasmCallBase(operands, numOperands, needsBoundsCheck)
     {
         for (size_t i = 0; i < numDefs(); i++)
             defs_[i] = LDefinition::BogusTemp();
     }
 
     // LInstruction interface
     size_t numDefs() const {
         return INT64_PIECES;
--- a/js/src/jsapi-tests/testGCGrayMarking.cpp
+++ b/js/src/jsapi-tests/testGCGrayMarking.cpp
@@ -99,28 +99,32 @@ TestMarking()
 
     JS_GC(cx);
 
     CHECK(IsMarkedBlack(sameSource));
     CHECK(IsMarkedBlack(crossSource));
     CHECK(IsMarkedBlack(sameTarget));
     CHECK(IsMarkedBlack(crossTarget));
 
+    CHECK(!JS::ObjectIsMarkedGray(sameSource));
+
     // Test GC with gray roots marks object gray.
 
     blackRoot1 = nullptr;
     blackRoot2 = nullptr;
 
     JS_GC(cx);
 
     CHECK(IsMarkedGray(sameSource));
     CHECK(IsMarkedGray(crossSource));
     CHECK(IsMarkedGray(sameTarget));
     CHECK(IsMarkedGray(crossTarget));
 
+    CHECK(JS::ObjectIsMarkedGray(sameSource));
+
     // Test ExposeToActiveJS marks gray objects black.
 
     JS::ExposeObjectToActiveJS(sameSource);
     JS::ExposeObjectToActiveJS(crossSource);
     CHECK(IsMarkedBlack(sameSource));
     CHECK(IsMarkedBlack(crossSource));
     CHECK(IsMarkedBlack(sameTarget));
     CHECK(IsMarkedBlack(crossTarget));
@@ -473,21 +477,22 @@ TestWatchpoints()
     grayRoots.grayRoot2 = nullptr;
 
     return true;
 }
 
 bool
 TestCCWs()
 {
-    RootedObject target(cx, AllocPlainObject());
+    JSObject* target = AllocPlainObject();
     CHECK(target);
 
     // Test getting a new wrapper doesn't return a gray wrapper.
 
+    RootedObject blackRoot(cx, target);
     JSObject* wrapper = GetCrossCompartmentWrapper(target);
     CHECK(wrapper);
     CHECK(!IsMarkedGray(wrapper));
 
     // Test getting an existing wrapper doesn't return a gray wrapper.
 
     grayRoots.grayRoot1 = wrapper;
     grayRoots.grayRoot2 = nullptr;
@@ -514,30 +519,66 @@ TestCCWs()
     CHECK(!IsMarkedBlack(wrapper));
     CHECK(wrapper->zone()->isGCMarkingBlack());
 
     CHECK(GetCrossCompartmentWrapper(target) == wrapper);
     CHECK(IsMarkedBlack(wrapper));
 
     JS::FinishIncrementalGC(cx, JS::gcreason::API);
 
-    target = nullptr;
+    // Test behaviour of gray CCWs marked black by a barrier during incremental
+    // GC.
+
+    // Initial state: source and target are gray.
+    blackRoot = nullptr;
+    grayRoots.grayRoot1 = wrapper;
+    grayRoots.grayRoot2 = nullptr;
+    JS_GC(cx);
+    CHECK(IsMarkedGray(wrapper));
+    CHECK(IsMarkedGray(target));
+
+    // Incremental zone GC started: the source is now unmarked.
+    JS_SetGCParameter(cx, JSGC_MODE, JSGC_MODE_INCREMENTAL);
+    JS::PrepareZoneForGC(wrapper->zone());
+    budget = js::SliceBudget(js::WorkBudget(1));
+    cx->runtime()->gc.startDebugGC(GC_NORMAL, budget);
+    CHECK(JS::IsIncrementalGCInProgress(cx));
+    CHECK(wrapper->zone()->isGCMarkingBlack());
+    CHECK(!target->zone()->wasGCStarted());
+    CHECK(!IsMarkedBlack(wrapper));
+    CHECK(!IsMarkedGray(wrapper));
+    CHECK(IsMarkedGray(target));
+
+    // Betweeen GC slices: source marked black by barrier, target is still gray.
+    // ObjectIsMarkedGray() and CheckObjectIsNotMarkedGray() should handle this
+    // case and report that target is not marked gray.
+    grayRoots.grayRoot1.get();
+    CHECK(IsMarkedBlack(wrapper));
+    CHECK(IsMarkedGray(target));
+    CHECK(!JS::ObjectIsMarkedGray(target));
+    MOZ_ASSERT(JS::ObjectIsNotGray(target));
+
+    // Final state: source and target are black.
+    JS::FinishIncrementalGC(cx, JS::gcreason::API);
+    CHECK(IsMarkedBlack(wrapper));
+    CHECK(IsMarkedBlack(target));
+
     grayRoots.grayRoot1 = nullptr;
     grayRoots.grayRoot2 = nullptr;
 
     return true;
 }
 
 JS::PersistentRootedObject global1;
 JS::PersistentRootedObject global2;
 
 struct GrayRoots
 {
-    JSObject* grayRoot1;
-    JSObject* grayRoot2;
+    JS::Heap<JSObject*> grayRoot1;
+    JS::Heap<JSObject*> grayRoot2;
 };
 
 GrayRoots grayRoots;
 
 bool
 InitGlobals()
 {
     global1.init(cx, global);
@@ -562,20 +603,18 @@ RemoveGrayRootTracer()
     grayRoots.grayRoot2 = nullptr;
     JS_SetGrayGCRootsTracer(cx, nullptr, nullptr);
 }
 
 static void
 TraceGrayRoots(JSTracer* trc, void* data)
 {
     auto grayRoots = static_cast<GrayRoots*>(data);
-    if (grayRoots->grayRoot1)
-        UnsafeTraceManuallyBarrieredEdge(trc, &grayRoots->grayRoot1, "gray root 1");
-    if (grayRoots->grayRoot2)
-        UnsafeTraceManuallyBarrieredEdge(trc, &grayRoots->grayRoot2, "gray root 2");
+    TraceEdge(trc, &grayRoots->grayRoot1, "gray root 1");
+    TraceEdge(trc, &grayRoots->grayRoot2, "gray root 2");
 }
 
 JSObject*
 AllocPlainObject()
 {
     JS::RootedObject obj(cx, JS_NewPlainObject(cx));
     EvictNursery();
 
--- a/js/src/jscntxtinlines.h
+++ b/js/src/jscntxtinlines.h
@@ -454,17 +454,17 @@ JSContext::enterCompartment(
     c->enter();
     setCompartment(c, maybeLock);
 }
 
 template <typename T>
 inline void
 JSContext::enterCompartmentOf(const T& target)
 {
-    MOZ_ASSERT(!js::gc::detail::CellIsMarkedGrayIfKnown(target));
+    MOZ_ASSERT(JS::CellIsNotGray(target));
     enterCompartment(target->compartment(), nullptr);
 }
 
 inline void
 JSContext::enterNullCompartment()
 {
     enterCompartmentDepth_++;
     setCompartment(nullptr);
--- a/js/src/jscompartment.cpp
+++ b/js/src/jscompartment.cpp
@@ -457,17 +457,17 @@ JSCompartment::wrap(JSContext* cx, Mutab
 
     if (!obj)
         return true;
 
     AutoDisableProxyCheck adpc;
 
     // Anything we're wrapping has already escaped into script, so must have
     // been unmarked-gray at some point in the past.
-    MOZ_ASSERT(!ObjectIsMarkedGray(obj));
+    MOZ_ASSERT(JS::ObjectIsNotGray(obj));
 
     // The passed object may already be wrapped, or may fit a number of special
     // cases that we need to check for and manually correct.
     if (!getNonWrapperObjectForCurrentCompartment(cx, obj))
         return false;
 
     // If the reification above did not result in a same-compartment object,
     // get or create a new wrapper object in this compartment for it.
--- a/js/src/jscompartmentinlines.h
+++ b/js/src/jscompartmentinlines.h
@@ -111,17 +111,17 @@ JSCompartment::wrap(JSContext* cx, JS::M
      * script. Unwrap and prewrap are both steps that we take to get to the
      * identity of an incoming objects, and as such, they shuld never map
      * one identity object to another object. This means that we can safely
      * check the cache immediately, and only risk false negatives. Do this
      * in opt builds, and do both in debug builds so that we can assert
      * that we get the same answer.
      */
 #ifdef DEBUG
-    MOZ_ASSERT(!JS::ObjectIsMarkedGray(&vp.toObject()));
+    MOZ_ASSERT(JS::ValueIsNotGray(vp));
     JS::RootedObject cacheResult(cx);
 #endif
     JS::RootedValue v(cx, vp);
     if (js::WrapperMap::Ptr p = crossCompartmentWrappers.lookup(js::CrossCompartmentKey(v))) {
 #ifdef DEBUG
         cacheResult = &p->value().get().toObject();
 #else
         vp.set(p->value().get());
--- a/js/src/jsfun.h
+++ b/js/src/jsfun.h
@@ -806,28 +806,26 @@ JSFunction::initializeExtended()
     toExtended()->extendedSlots[0].init(js::UndefinedValue());
     toExtended()->extendedSlots[1].init(js::UndefinedValue());
 }
 
 inline void
 JSFunction::initExtendedSlot(size_t which, const js::Value& val)
 {
     MOZ_ASSERT(which < mozilla::ArrayLength(toExtended()->extendedSlots));
-    MOZ_ASSERT_IF(js::IsMarkedBlack(this) && val.isGCThing(),
-                  !JS::GCThingIsMarkedGray(JS::GCCellPtr(val)));
+    js::CheckEdgeIsNotBlackToGray(this, val);
     MOZ_ASSERT(js::IsObjectValueInCompartment(val, compartment()));
     toExtended()->extendedSlots[which].init(val);
 }
 
 inline void
 JSFunction::setExtendedSlot(size_t which, const js::Value& val)
 {
     MOZ_ASSERT(which < mozilla::ArrayLength(toExtended()->extendedSlots));
-    MOZ_ASSERT_IF(js::IsMarkedBlack(this) && val.isGCThing(),
-                  !JS::GCThingIsMarkedGray(JS::GCCellPtr(val)));
+    js::CheckEdgeIsNotBlackToGray(this, val);
     MOZ_ASSERT(js::IsObjectValueInCompartment(val, compartment()));
     toExtended()->extendedSlots[which] = val;
 }
 
 inline const js::Value&
 JSFunction::getExtendedSlot(size_t which) const
 {
     MOZ_ASSERT(which < mozilla::ArrayLength(toExtended()->extendedSlots));
--- a/js/src/jsgc.cpp
+++ b/js/src/jsgc.cpp
@@ -7793,39 +7793,83 @@ js::gc::Cell::dump(FILE* fp) const
 // For use in a debugger.
 void
 js::gc::Cell::dump() const
 {
     dump(stderr);
 }
 #endif
 
-JS_PUBLIC_API(bool)
-js::gc::detail::CellIsMarkedGrayIfKnown(const Cell* cell)
+static inline bool
+CanCheckGrayBits(const Cell* cell)
 {
     MOZ_ASSERT(cell);
     if (!cell->isTenured())
         return false;
 
+    auto tc = &cell->asTenured();
+    auto rt = tc->runtimeFromAnyThread();
+    return CurrentThreadCanAccessRuntime(rt) && rt->gc.areGrayBitsValid();
+}
+
+JS_PUBLIC_API(bool)
+js::gc::detail::CellIsMarkedGrayIfKnown(const Cell* cell)
+{
     // We ignore the gray marking state of cells and return false in the
     // following cases:
     //
     // 1) When OOM has caused us to clear the gcGrayBitsValid_ flag.
     //
     // 2) When we are in an incremental GC and examine a cell that is in a zone
     // that is not being collected. Gray targets of CCWs that are marked black
     // by a barrier will eventually be marked black in the next GC slice.
     //
     // 3) When we are not on the runtime's active thread. Helper threads might
     // call this while parsing, and they are not allowed to inspect the
     // runtime's incremental state. The objects being operated on are not able
     // to be collected and will not be marked any color.
+
+    if (!CanCheckGrayBits(cell))
+        return false;
+
     auto tc = &cell->asTenured();
     auto rt = tc->runtimeFromAnyThread();
-    if (!CurrentThreadCanAccessRuntime(rt) ||
-        !rt->gc.areGrayBitsValid() ||
-        (rt->gc.isIncrementalGCInProgress() && !tc->zone()->wasGCStarted()))
-    {
+    if (rt->gc.isIncrementalGCInProgress() && !tc->zone()->wasGCStarted())
         return false;
-    }
 
     return detail::CellIsMarkedGray(tc);
 }
+
+#ifdef DEBUG
+JS_PUBLIC_API(bool)
+js::gc::detail::CellIsNotGray(const Cell* cell)
+{
+    // Check that a cell is not marked gray.
+    //
+    // Since this is a debug-only check, take account of the eventual mark state
+    // of cells that will be marked black by the next GC slice in an incremental
+    // GC. For performance reasons we don't do this in CellIsMarkedGrayIfKnown.
+
+    // TODO: I'd like to AssertHeapIsIdle() here, but this ends up getting
+    // called while iterating the heap for memory reporting.
+    MOZ_ASSERT(!JS::CurrentThreadIsHeapCollecting());
+    MOZ_ASSERT(!JS::CurrentThreadIsHeapCycleCollecting());
+
+    if (!CanCheckGrayBits(cell))
+        return true;
+
+    auto tc = &cell->asTenured();
+    if (!detail::CellIsMarkedGray(tc))
+        return true;
+
+    auto rt = tc->runtimeFromAnyThread();
+    Zone* sourceZone = nullptr;
+    if (rt->gc.isIncrementalGCInProgress() &&
+        !tc->zone()->wasGCStarted() &&
+        (sourceZone = rt->gc.marker.stackContainsCrossZonePointerTo(tc)) &&
+        sourceZone->wasGCStarted())
+    {
+        return true;
+    }
+
+    return false;
+}
+#endif
--- a/js/src/shell/ModuleLoader.js
+++ b/js/src/shell/ModuleLoader.js
@@ -9,29 +9,59 @@
 // Save standard built-ins before scripts can modify them.
 const ArrayPrototypeJoin = Array.prototype.join;
 const MapPrototypeGet = Map.prototype.get;
 const MapPrototypeHas = Map.prototype.has;
 const MapPrototypeSet = Map.prototype.set;
 const ObjectDefineProperty = Object.defineProperty;
 const ReflectApply = Reflect.apply;
 const StringPrototypeIndexOf = String.prototype.indexOf;
+const StringPrototypeLastIndexOf = String.prototype.lastIndexOf;
+const StringPrototypeStartsWith = String.prototype.startsWith;
 const StringPrototypeSubstring = String.prototype.substring;
 
 const ReflectLoader = new class {
     constructor() {
         this.registry = new Map();
+        this.modulePaths = new Map();
         this.loadPath = getModuleLoadPath();
     }
 
-    resolve(name) {
+    resolve(name, module) {
         if (os.path.isAbsolute(name))
             return name;
 
-        return os.path.join(this.loadPath, name);
+        let loadPath = this.loadPath;
+        if (module) {
+            // Treat |name| as a relative path if it starts with either "./"
+            // or "../".
+            let isRelative = ReflectApply(StringPrototypeStartsWith, name, ["./"])
+                          || ReflectApply(StringPrototypeStartsWith, name, ["../"])
+#ifdef XP_WIN
+                          || ReflectApply(StringPrototypeStartsWith, name, [".\\"])
+                          || ReflectApply(StringPrototypeStartsWith, name, ["..\\"])
+#endif
+                             ;
+
+            // If |name| is a relative path and |module|'s path is available,
+            // load |name| relative to the referring module.
+            if (isRelative && ReflectApply(MapPrototypeHas, this.modulePaths, [module])) {
+                let modulePath = ReflectApply(MapPrototypeGet, this.modulePaths, [module]);
+                let sepIndex = ReflectApply(StringPrototypeLastIndexOf, modulePath, ["/"]);
+#ifdef XP_WIN
+                let otherSepIndex = ReflectApply(StringPrototypeLastIndexOf, modulePath, ["\\"]);
+                if (otherSepIndex > sepIndex)
+                    sepIndex = otherSepIndex;
+#endif
+                if (sepIndex >= 0)
+                    loadPath = ReflectApply(StringPrototypeSubstring, modulePath, [0, sepIndex]);
+            }
+        }
+
+        return os.path.join(loadPath, name);
     }
 
     normalize(path) {
 #ifdef XP_WIN
         // Replace all forward slashes with backward slashes.
         // NB: It may be tempting to replace this loop with a call to
         // String.prototype.replace, but user scripts may have modified
         // String.prototype or RegExp.prototype built-in functions, which makes
@@ -119,34 +149,35 @@ const ReflectLoader = new class {
     loadAndParse(path) {
         let normalized = this.normalize(path);
         if (ReflectApply(MapPrototypeHas, this.registry, [normalized]))
             return ReflectApply(MapPrototypeGet, this.registry, [normalized]);
 
         let source = this.fetch(path);
         let module = parseModule(source, path);
         ReflectApply(MapPrototypeSet, this.registry, [normalized, module]);
+        ReflectApply(MapPrototypeSet, this.modulePaths, [module, path]);
         return module;
     }
 
     loadAndExecute(path) {
         let module = this.loadAndParse(path);
         module.declarationInstantiation();
         return module.evaluation();
     }
 
     importRoot(path) {
         return this.loadAndExecute(path);
     }
 
     ["import"](name, referrer) {
-        let path = this.resolve(name);
+        let path = this.resolve(name, null);
         return this.loadAndExecute(path);
     }
 };
 
 setModuleResolveHook((module, requestName) => {
-    let path = ReflectLoader.resolve(requestName);
+    let path = ReflectLoader.resolve(requestName, module);
     return ReflectLoader.loadAndParse(path)
 });
 
 Reflect.Loader = ReflectLoader;
 }
--- a/js/src/shell/js.cpp
+++ b/js/src/shell/js.cpp
@@ -5376,22 +5376,23 @@ static bool
 EnableGeckoProfiling(JSContext* cx, unsigned argc, Value* vp)
 {
     CallArgs args = CallArgsFromVp(argc, vp);
 
     ShellContext* sc = GetShellContext(cx);
 
     // Disable before re-enabling; see the assertion in |GeckoProfiler::setProfilingStack|.
     if (cx->runtime()->geckoProfiler().installed())
-        cx->runtime()->geckoProfiler().enable(false);
+        MOZ_ALWAYS_TRUE(cx->runtime()->geckoProfiler().enable(false));
 
     SetContextProfilingStack(cx, sc->geckoProfilingStack, &sc->geckoProfilingStackSize,
                              ShellContext::GeckoProfilingMaxStackSize);
     cx->runtime()->geckoProfiler().enableSlowAssertions(false);
-    cx->runtime()->geckoProfiler().enable(true);
+    if (!cx->runtime()->geckoProfiler().enable(true))
+        JS_ReportErrorASCII(cx, "Cannot ensure single threaded execution in profiler");
 
     args.rval().setUndefined();
     return true;
 }
 
 static bool
 EnableGeckoProfilingWithSlowAssertions(JSContext* cx, unsigned argc, Value* vp)
 {
@@ -5403,37 +5404,38 @@ EnableGeckoProfilingWithSlowAssertions(J
     if (cx->runtime()->geckoProfiler().enabled()) {
         // If profiling already enabled with slow assertions disabled,
         // this is a no-op.
         if (cx->runtime()->geckoProfiler().slowAssertionsEnabled())
             return true;
 
         // Slow assertions are off.  Disable profiling before re-enabling
         // with slow assertions on.
-        cx->runtime()->geckoProfiler().enable(false);
+        MOZ_ALWAYS_TRUE(cx->runtime()->geckoProfiler().enable(false));
     }
 
     // Disable before re-enabling; see the assertion in |GeckoProfiler::setProfilingStack|.
     if (cx->runtime()->geckoProfiler().installed())
-        cx->runtime()->geckoProfiler().enable(false);
+        MOZ_ALWAYS_TRUE(cx->runtime()->geckoProfiler().enable(false));
 
     SetContextProfilingStack(cx, sc->geckoProfilingStack, &sc->geckoProfilingStackSize,
                              ShellContext::GeckoProfilingMaxStackSize);
     cx->runtime()->geckoProfiler().enableSlowAssertions(true);
-    cx->runtime()->geckoProfiler().enable(true);
+    if (!cx->runtime()->geckoProfiler().enable(true))
+        JS_ReportErrorASCII(cx, "Cannot ensure single threaded execution in profiler");
 
     return true;
 }
 
 static bool
 DisableGeckoProfiling(JSContext* cx, unsigned argc, Value* vp)
 {
     CallArgs args = CallArgsFromVp(argc, vp);
     if (cx->runtime()->geckoProfiler().installed())
-        cx->runtime()->geckoProfiler().enable(false);
+        MOZ_ALWAYS_TRUE(cx->runtime()->geckoProfiler().enable(false));
     args.rval().setUndefined();
     return true;
 }
 
 // Global mailbox that is used to communicate a SharedArrayBuffer
 // value from one worker to another.
 //
 // For simplicity we store only the SharedArrayRawBuffer; retaining
new file mode 100644
--- /dev/null
+++ b/js/src/tests/ecma_6/TypedArray/set-wrapped.js
@@ -0,0 +1,81 @@
+// Test %TypedArray%.prototype.set(typedArray, offset) when called with wrapped
+// typed array.
+
+if (typeof newGlobal === "function") {
+    var otherGlobal = newGlobal();
+
+    function taintLengthProperty(obj) {
+        Object.defineProperty(obj, "length", {
+            get() {
+                assertEq(true, false);
+            }
+        });
+    }
+
+    for (var TA of anyTypedArrayConstructors) {
+        var target = new TA(4);
+        var source = new otherGlobal[TA.name]([10, 20]);
+
+        // Ensure "length" getter accessor isn't called.
+        taintLengthProperty(source);
+
+        assertEqArray(target, [0, 0, 0, 0]);
+        target.set(source, 1);
+        assertEqArray(target, [0, 10, 20, 0]);
+    }
+
+    // Detachment checks are also applied correctly for wrapped typed arrays.
+    if (typeof detachArrayBuffer === "function") {
+        // Create typed array from different global (explicit constructor call).
+        for (var TA of typedArrayConstructors) {
+            var target = new TA(4);
+            var source = new otherGlobal[TA.name](1);
+            taintLengthProperty(source);
+
+            // Called with wrapped typed array, array buffer already detached.
+            otherGlobal.detachArrayBuffer(source.buffer);
+            assertThrowsInstanceOf(() => target.set(source), TypeError);
+
+            var source = new otherGlobal[TA.name](1);
+            taintLengthProperty(source);
+
+            // Called with wrapped typed array, array buffer detached when
+            // processing offset parameter.
+            var offset = {
+                valueOf() {
+                    otherGlobal.detachArrayBuffer(source.buffer);
+                    return 0;
+                }
+            };
+            assertThrowsInstanceOf(() => target.set(source, offset), TypeError);
+        }
+
+        // Create typed array from different global (implictly created when
+        // ArrayBuffer is a CCW).
+        for (var TA of typedArrayConstructors) {
+            var target = new TA(4);
+            var source = new TA(new otherGlobal.ArrayBuffer(1 * TA.BYTES_PER_ELEMENT));
+            taintLengthProperty(source);
+
+            // Called with wrapped typed array, array buffer already detached.
+            otherGlobal.detachArrayBuffer(source.buffer);
+            assertThrowsInstanceOf(() => target.set(source), TypeError);
+
+            var source = new TA(new otherGlobal.ArrayBuffer(1 * TA.BYTES_PER_ELEMENT));
+            taintLengthProperty(source);
+
+            // Called with wrapped typed array, array buffer detached when
+            // processing offset parameter.
+            var offset = {
+                valueOf() {
+                    otherGlobal.detachArrayBuffer(source.buffer);
+                    return 0;
+                }
+            };
+            assertThrowsInstanceOf(() => target.set(source, offset), TypeError);
+        }
+    }
+}
+
+if (typeof reportCompare === "function")
+    reportCompare(true, true);
--- a/js/src/vm/GeckoProfiler.cpp
+++ b/js/src/vm/GeckoProfiler.cpp
@@ -58,23 +58,34 @@ GeckoProfiler::setProfilingStack(Profile
 }
 
 void
 GeckoProfiler::setEventMarker(void (*fn)(const char*))
 {
     eventMarker_ = fn;
 }
 
-void
+bool
 GeckoProfiler::enable(bool enabled)
 {
     MOZ_ASSERT(installed());
 
     if (enabled_ == enabled)
-        return;
+        return true;
+
+    // Execution in the runtime must be single threaded if the Gecko profiler
+    // is enabled. There is only a single profiler stack in the runtime, from
+    // which entries must be added/removed in a LIFO fashion.
+    JSContext* cx = rt->activeContextFromOwnThread();
+    if (enabled) {
+        if (!rt->beginSingleThreadedExecution(cx))
+            return false;
+    } else {
+        rt->endSingleThreadedExecution(cx);
+    }
 
     /*
      * Ensure all future generated code will be instrumented, or that all
      * currently instrumented code is discarded
      */
     ReleaseAllJITCode(rt->defaultFreeOp());
 
     // This function is called when the Gecko profiler makes a new Sampler
@@ -124,16 +135,18 @@ GeckoProfiler::enable(bool enabled)
                 while (jitActivation) {
                     jitActivation->setLastProfilingFrame(nullptr);
                     jitActivation->setLastProfilingCallSite(nullptr);
                     jitActivation = jitActivation->prevJitActivation();
                 }
             }
         }
     }
+
+    return true;
 }
 
 /* Lookup the string for the function/script, creating one if necessary */
 const char*
 GeckoProfiler::profileString(JSScript* script, JSFunction* maybeFun)
 {
     auto locked = strings.lock();
     MOZ_ASSERT(locked->initialized());
@@ -535,17 +548,18 @@ JS_FRIEND_API(void)
 js::SetContextProfilingStack(JSContext* cx, ProfileEntry* stack, uint32_t* size, uint32_t max)
 {
     cx->runtime()->geckoProfiler().setProfilingStack(stack, size, max);
 }
 
 JS_FRIEND_API(void)
 js::EnableContextProfilingStack(JSContext* cx, bool enabled)
 {
-    cx->runtime()->geckoProfiler().enable(enabled);
+    if (!cx->runtime()->geckoProfiler().enable(enabled))
+        MOZ_CRASH("Execution in this runtime should already be single threaded");
 }
 
 JS_FRIEND_API(void)
 js::RegisterContextProfilingEventMarker(JSContext* cx, void (*fn)(const char*))
 {
     MOZ_ASSERT(cx->runtime()->geckoProfiler().enabled());
     cx->runtime()->geckoProfiler().setEventMarker(fn);
 }
--- a/js/src/vm/GeckoProfiler.h
+++ b/js/src/vm/GeckoProfiler.h
@@ -161,17 +161,17 @@ class GeckoProfiler
     uint32_t* sizePointer() { return size_; }
     uint32_t maxSize() { return max_; }
     uint32_t size() { MOZ_ASSERT(installed()); return *size_; }
     ProfileEntry* stack() { return stack_; }
 
     /* management of whether instrumentation is on or off */
     bool enabled() { MOZ_ASSERT_IF(enabled_, installed()); return enabled_; }
     bool installed() { return stack_ != nullptr && size_ != nullptr; }
-    void enable(bool enabled);
+    MOZ_MUST_USE bool enable(bool enabled);
     void enableSlowAssertions(bool enabled) { slowAssertions = enabled; }
     bool slowAssertionsEnabled() { return slowAssertions; }
 
     /*
      * Functions which are the actual instrumentation to track run information
      *
      *   - enter: a function has started to execute
      *   - updatePC: updates the pc information about where a function
--- a/js/src/vm/Runtime.cpp
+++ b/js/src/vm/Runtime.cpp
@@ -307,17 +307,17 @@ JSRuntime::destroyRuntime()
         JS::PrepareForFullGC(cx);
         gc.gc(GC_NORMAL, JS::gcreason::DESTROY_RUNTIME);
     }
 
     AutoNoteSingleThreadedRegion anstr;
 
     MOZ_ASSERT(ionLazyLinkListSize_ == 0);
     MOZ_ASSERT(ionLazyLinkList().isEmpty());
-    MOZ_ASSERT(!singleThreadedExecutionRequired_);
+    MOZ_ASSERT_IF(!geckoProfiler().enabled(), !singleThreadedExecutionRequired_);
 
     MOZ_ASSERT(!hasHelperThreadZones());
     AutoLockForExclusiveAccess lock(this);
 
     /*
      * Even though all objects in the compartment are dead, we may have keep
      * some filenames around because of gcKeepAtoms.
      */
--- a/js/src/vm/TypedArrayObject-inl.h
+++ b/js/src/vm/TypedArrayObject-inl.h
@@ -268,16 +268,19 @@ class ElementSpecific
      * Act as if the assignments occurred from a fresh copy of |source|, in
      * case the two memory ranges overlap.
      */
     static bool
     setFromTypedArray(JSContext* cx,
                       Handle<TypedArrayObject*> target, Handle<TypedArrayObject*> source,
                       uint32_t offset)
     {
+        // WARNING: |source| may be an unwrapped typed array from a different
+        // compartment. Proceed with caution!
+
         MOZ_ASSERT(TypeIDOfType<T>::id == target->type(),
                    "calling wrong setFromTypedArray specialization");
         MOZ_ASSERT(!target->hasDetachedBuffer(), "target isn't detached");
         MOZ_ASSERT(!source->hasDetachedBuffer(), "source isn't detached");
 
         MOZ_ASSERT(offset <= target->length());
         MOZ_ASSERT(source->length() <= target->length() - offset);
 
@@ -477,16 +480,19 @@ class ElementSpecific
 
   private:
     static bool
     setFromOverlappingTypedArray(JSContext* cx,
                                  Handle<TypedArrayObject*> target,
                                  Handle<TypedArrayObject*> source,
                                  uint32_t offset)
     {
+        // WARNING: |source| may be an unwrapped typed array from a different
+        // compartment. Proceed with caution!
+
         MOZ_ASSERT(TypeIDOfType<T>::id == target->type(),
                    "calling wrong setFromTypedArray specialization");
         MOZ_ASSERT(!target->hasDetachedBuffer(), "target isn't detached");
         MOZ_ASSERT(!source->hasDetachedBuffer(), "source isn't detached");
         MOZ_ASSERT(TypedArrayObject::sameBuffer(target, source),
                    "the provided arrays don't actually overlap, so it's "
                    "undesirable to use this method");
 
--- a/js/src/vm/TypedArrayObject.cpp
+++ b/js/src/vm/TypedArrayObject.cpp
@@ -1498,16 +1498,19 @@ TypedArrayObject::protoAccessors[] = {
     JS_PS_END
 };
 
 template<typename T>
 static inline bool
 SetFromTypedArray(JSContext* cx, Handle<TypedArrayObject*> target,
                   Handle<TypedArrayObject*> source, uint32_t offset)
 {
+    // WARNING: |source| may be an unwrapped typed array from a different
+    // compartment. Proceed with caution!
+
     if (target->isSharedMemory() || source->isSharedMemory())
         return ElementSpecific<T, SharedOps>::setFromTypedArray(cx, target, source, offset);
     return ElementSpecific<T, UnsharedOps>::setFromTypedArray(cx, target, source, offset);
 }
 
 template<typename T>
 static inline bool
 SetFromNonTypedArray(JSContext* cx, Handle<TypedArrayObject*> target, HandleObject source,
@@ -1547,67 +1550,82 @@ TypedArrayObject::set_impl(JSContext* cx
     }
 
     // Steps 8-9.
     if (target->hasDetachedBuffer()) {
         JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_TYPED_ARRAY_DETACHED);
         return false;
     }
 
-    if (args.get(0).isObject() && args[0].toObject().is<TypedArrayObject>()) {
+    // 22.2.3.23.1, step 15. (22.2.3.23.2 only applies if args[0] is a typed
+    // array, so it doesn't make a difference there to apply ToObject here.)
+    RootedObject src(cx, ToObject(cx, args.get(0)));
+    if (!src)
+        return false;
+
+    Rooted<TypedArrayObject*> srcTypedArray(cx);
+    {
+        JSObject* obj = CheckedUnwrap(src);
+        if (!obj) {
+            ReportAccessDenied(cx);
+            return false;
+        }
+
+        if (obj->is<TypedArrayObject>())
+            srcTypedArray = &obj->as<TypedArrayObject>();
+    }
+
+    if (srcTypedArray) {
         // Remaining steps of 22.2.3.23.2.
-        Rooted<TypedArrayObject*> source(cx, &args[0].toObject().as<TypedArrayObject>());
+
+        // WARNING: |srcTypedArray| may be an unwrapped typed array from a
+        // different compartment. Proceed with caution!
 
         // Steps 11-12.
-        if (source->hasDetachedBuffer()) {
+        if (srcTypedArray->hasDetachedBuffer()) {
             JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_TYPED_ARRAY_DETACHED);
             return false;
         }
 
         // Step 10 (Reordered).
         uint32_t targetLength = target->length();
 
         // Step 22 (Split into two checks to provide better error messages).
         if (targetOffset > targetLength) {
             JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_BAD_INDEX);
             return false;
         }
 
         // Step 22 (Cont'd).
         uint32_t offset = uint32_t(targetOffset);
-        if (source->length() > targetLength - offset) {
+        if (srcTypedArray->length() > targetLength - offset) {
             JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_BAD_ARRAY_LENGTH);
             return false;
         }
 
         // Steps 13-21, 23-28.
         switch (target->type()) {
 #define SET_FROM_TYPED_ARRAY(T, N) \
           case Scalar::N: \
-            if (!SetFromTypedArray<T>(cx, target, source, offset)) \
+            if (!SetFromTypedArray<T>(cx, target, srcTypedArray, offset)) \
                 return false; \
             break;
 JS_FOR_EACH_TYPED_ARRAY(SET_FROM_TYPED_ARRAY)
 #undef SET_FROM_TYPED_ARRAY
           default:
             MOZ_CRASH("Unsupported TypedArray type");
         }
     } else {
         // Remaining steps of 22.2.3.23.1.
 
         // Step 10.
         // We can't reorder this step because side-effects in step 16 can
         // detach the underlying array buffer from the typed array.
         uint32_t targetLength = target->length();
 
-        // Step 15.
-        RootedObject src(cx, ToObject(cx, args.get(0)));
-        if (!src)
-            return false;
-
         // Step 16.
         uint32_t srcLength;
         if (!GetLengthProperty(cx, src, &srcLength))
             return false;
 
         // Step 17 (Split into two checks to provide better error messages).
         if (targetOffset > targetLength) {
             JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_BAD_INDEX);
--- a/js/src/wasm/WasmBaselineCompile.cpp
+++ b/js/src/wasm/WasmBaselineCompile.cpp
@@ -116,16 +116,17 @@ namespace wasm {
 using namespace js::jit;
 using JS::GenericNaN;
 
 typedef bool HandleNaNSpecially;
 typedef bool InvertBranch;
 typedef bool IsKnownNotZero;
 typedef bool IsSigned;
 typedef bool IsUnsigned;
+typedef bool NeedsBoundsCheck;
 typedef bool PopStack;
 typedef bool ZeroOnOverflow;
 
 typedef unsigned ByteSize;
 typedef unsigned BitSize;
 
 // UseABI::Wasm implies that the Tls/Heap/Global registers are nonvolatile,
 // except when InterModule::True is also set, when they are volatile.
@@ -2648,17 +2649,17 @@ class BaseCompiler
 
         MOZ_ASSERT(env_.tables.length() == 1);
         const TableDesc& table = env_.tables[0];
 
         loadI32(WasmTableCallIndexReg, indexVal);
 
         CallSiteDesc desc(call.lineOrBytecode, CallSiteDesc::Dynamic);
         CalleeDesc callee = CalleeDesc::wasmTable(table, sig.id);
-        masm.wasmCallIndirect(desc, callee);
+        masm.wasmCallIndirect(desc, callee, NeedsBoundsCheck(true));
     }
 
     // Precondition: sync()
 
     void callImport(unsigned globalDataOffset, const FunctionCall& call)
     {
         CallSiteDesc desc(call.lineOrBytecode, CallSiteDesc::Dynamic);
         CalleeDesc callee = CalleeDesc::import(globalDataOffset);
--- a/js/src/wasm/WasmTypes.h
+++ b/js/src/wasm/WasmTypes.h
@@ -1258,16 +1258,17 @@ class CalleeDesc
     union U {
         U() {}
         uint32_t funcIndex_;
         struct {
             uint32_t globalDataOffset_;
         } import;
         struct {
             uint32_t globalDataOffset_;
+            uint32_t minLength_;
             bool external_;
             SigIdDesc sigId_;
         } table;
         SymbolicAddress builtin_;
     } u;
 
   public:
     CalleeDesc() {}
@@ -1282,16 +1283,17 @@ class CalleeDesc
         c.which_ = Import;
         c.u.import.globalDataOffset_ = globalDataOffset;
         return c;
     }
     static CalleeDesc wasmTable(const TableDesc& desc, SigIdDesc sigId) {
         CalleeDesc c;
         c.which_ = WasmTable;
         c.u.table.globalDataOffset_ = desc.globalDataOffset;
+        c.u.table.minLength_ = desc.limits.initial;
         c.u.table.external_ = desc.external;
         c.u.table.sigId_ = sigId;
         return c;
     }
     static CalleeDesc asmJSTable(const TableDesc& desc) {
         CalleeDesc c;
         c.which_ = AsmJSTable;
         c.u.table.globalDataOffset_ = desc.globalDataOffset;
@@ -1334,16 +1336,20 @@ class CalleeDesc
     bool wasmTableIsExternal() const {
         MOZ_ASSERT(which_ == WasmTable);
         return u.table.external_;
     }
     SigIdDesc wasmTableSigId() const {
         MOZ_ASSERT(which_ == WasmTable);
         return u.table.sigId_;
     }
+    uint32_t wasmTableMinLength() const {
+        MOZ_ASSERT(which_ == WasmTable);
+        return u.table.minLength_;
+    }
     SymbolicAddress builtin() const {
         MOZ_ASSERT(which_ == Builtin || which_ == BuiltinInstanceMethod);
         return u.builtin_;
     }
 };
 
 // Because ARM has a fixed-width instruction encoding, ARM can only express a
 // limited subset of immediates (in a single instruction).
--- a/js/xpconnect/wrappers/WrapperFactory.cpp
+++ b/js/xpconnect/wrappers/WrapperFactory.cpp
@@ -96,17 +96,17 @@ WrapperFactory::WaiveXray(JSContext* cx,
     RootedObject obj(cx, objArg);
     obj = UncheckedUnwrap(obj);
     MOZ_ASSERT(!js::IsWindow(obj));
 
     JSObject* waiver = GetXrayWaiver(obj);
     if (!waiver) {
         waiver = CreateXrayWaiver(cx, obj);
     }
-    MOZ_ASSERT(!ObjectIsMarkedGray(waiver));
+    MOZ_ASSERT(JS::ObjectIsNotGray(waiver));
     return waiver;
 }
 
 /* static */ bool
 WrapperFactory::AllowWaiver(JSCompartment* target, JSCompartment* origin)
 {
     return CompartmentPrivate::Get(target)->allowWaivers &&
            AccessCheck::subsumes(target, origin);
@@ -317,17 +317,17 @@ WrapperFactory::PrepareForWrapping(JSCon
         nsXPConnect::XPConnect()->WrapNativeToJSVal(cx, wrapScope, wn->Native(), nullptr,
                                                     &NS_GET_IID(nsISupports), false, &v);
     if (NS_FAILED(rv)) {
         return;
     }
 
     obj.set(&v.toObject());
     MOZ_ASSERT(IS_WN_REFLECTOR(obj), "bad object");
-    MOZ_ASSERT(!ObjectIsMarkedGray(obj), "Should never return gray reflectors");
+    MOZ_ASSERT(JS::ObjectIsNotGray(obj), "Should never return gray reflectors");
 
     // Because the underlying native didn't have a PreCreate hook, we had
     // to a new (or possibly pre-existing) XPCWN in our compartment.
     // This could be a problem for chrome code that passes XPCOM objects
     // across compartments, because the effects of QI would disappear across
     // compartments.
     //
     // So whenever we pull an XPCWN across compartments in this manner, we
--- a/layout/reftests/w3c-css/submitted/check-for-references.sh
+++ b/layout/reftests/w3c-css/submitted/check-for-references.sh
@@ -10,17 +10,17 @@ do
         then
             REFTYPE="match"
         elif [ "$TYPE" == "!=" ]
         then
             REFTYPE="mismatch"
         else
             echo "Unexpected type $TYPE for $DIRNAME/$TEST"
         fi
-        if grep "rel=\"$REFTYPE\"" "$DIRNAME/$TEST" | head -1 | grep -q "href=\"$REF\""
+        if grep "rel=\(\"$REFTYPE\"\|'$REFTYPE'\)" "$DIRNAME/$TEST" | head -1 | grep -q "href=\(\"$REF\"\|'$REF'\)"
         then
             #echo "Good link for $DIRNAME/$TEST"
             echo -n
         else
             echo "Missing link for $DIRNAME/$TEST"
             #echo "<link rel=\"$REFTYPE\" href=\"$REF\">" >> "$DIRNAME/$TEST"
         fi
     done
--- a/layout/reftests/w3c-css/submitted/reftest.list
+++ b/layout/reftests/w3c-css/submitted/reftest.list
@@ -48,27 +48,20 @@ include multicol3/reftest.list
 
 # Ruby Layout Module
 include ruby/reftest.list
 
 # Selectors Level 4
 include selectors4/reftest.list
 
 # Shapes Level 1
-# Bug 1300355: Skip shapes reftests to prevent frequent intermittent failures
-# on Win7 debug.
-skip-if(winWidget&&isDebugBuild) include shapes1/reftest.list
+include shapes1/reftest.list
 
 # Text Level 3
-# In Bug 1316482, we've added a large number of tests in this folder, which
-# indirectly causes frequent reftest failures on win7 debug. (see Bug 1300355)
-# Since the root cause is not these tests, skip them on win7 debug for now.
-# Once we come up with a better solution, we should re-enable this folder on
-# win7 debug.
-skip-if(winWidget&&isDebugBuild) include text3/reftest.list
+include text3/reftest.list
 
 # Text Decoration Level 3
 include text-decor-3/reftest.list
 
 # Transforms
 include transforms/reftest.list
 
 # User Interface Level 3
--- a/media/libcubeb/README_MOZILLA
+++ b/media/libcubeb/README_MOZILLA
@@ -1,8 +1,8 @@
 The source from this directory was copied from the cubeb 
 git repository using the update.sh script.  The only changes
 made were those applied by update.sh and the addition of
 Makefile.in build files for the Mozilla build system.
 
 The cubeb git repository is: git://github.com/kinetiknz/cubeb.git
 
-The git commit ID used was 25b593fa59d0c284ff2de54b10db927d48579f5e (2017-02-23 14:05:03 +0200)
+The git commit ID used was 0753297e4c881c4adf900b6c14af3d52a2a7eb2a (2017-03-02 15:13:01 +1300)
--- a/media/libcubeb/src/cubeb_audiounit.cpp
+++ b/media/libcubeb/src/cubeb_audiounit.cpp
@@ -58,19 +58,16 @@ const char * DISPATCH_QUEUE_LABEL = "org
  * frames. */
 const uint32_t SAFE_MIN_LATENCY_FRAMES = 256;
 const uint32_t SAFE_MAX_LATENCY_FRAMES = 512;
 
 void audiounit_stream_stop_internal(cubeb_stream * stm);
 void audiounit_stream_start_internal(cubeb_stream * stm);
 static void audiounit_close_stream(cubeb_stream *stm);
 static int audiounit_setup_stream(cubeb_stream *stm);
-static int audiounit_create_unit(AudioUnit * unit, bool is_input,
-                                 const cubeb_stream_params * /* stream_params */,
-                                 AudioDeviceID device);
 
 extern cubeb_ops const audiounit_ops;
 
 struct cubeb {
   cubeb_ops const * ops = &audiounit_ops;
   owned_critical_section mutex;
   std::atomic<int> active_streams{ 0 };
   uint32_t global_latency_frames = 0;
@@ -253,16 +250,18 @@ struct cubeb_stream {
   uint32_t latency_frames = 0;
   std::atomic<uint64_t> current_latency_frames{ 0 };
   uint64_t hw_latency_frames = UINT64_MAX;
   std::atomic<float> panning{ 0 };
   std::unique_ptr<cubeb_resampler, decltype(&cubeb_resampler_destroy)> resampler;
   /* This is true if a device change callback is currently running.  */
   std::atomic<bool> switching_device{ false };
   std::atomic<bool> buffer_size_change_state{ false };
+  AudioDeviceID aggregate_device_id = 0;    // the aggregate device id
+  AudioObjectID plugin_id = 0;              // used to create aggregate device
 };
 
 bool has_input(cubeb_stream * stm)
 {
   return stm->input_stream_params.rate != 0;
 }
 
 bool has_output(cubeb_stream * stm)
@@ -784,16 +783,25 @@ audiounit_remove_listener(cubeb_stream *
       kAudioObjectPropertyElementMaster
   };
 
   return AudioObjectRemovePropertyListener(id, &address, listener, stm);
 }
 
 static AudioObjectID audiounit_get_default_device_id(cubeb_device_type type);
 
+static AudioObjectID
+audiounit_get_input_device_id(cubeb_stream * stm)
+{
+  AudioObjectID input_dev = stm->input_device ? stm->input_device :
+                            audiounit_get_default_device_id(CUBEB_DEVICE_TYPE_INPUT);
+  assert(input_dev);
+  return input_dev;
+}
+
 static int
 audiounit_install_device_changed_callback(cubeb_stream * stm)
 {
   OSStatus r;
 
   if (stm->output_unit) {
     /* This event will notify us when the data source on the same device changes,
      * for example when the user plugs in a normal (non-usb) headset in the
@@ -842,18 +850,17 @@ audiounit_install_device_changed_callbac
     r = audiounit_add_listener(stm, kAudioObjectSystemObject, kAudioHardwarePropertyDefaultInputDevice,
         kAudioObjectPropertyScopeGlobal, &audiounit_property_listener_callback);
     if (r != noErr) {
       LOG("AudioObjectAddPropertyListener/input/kAudioHardwarePropertyDefaultInputDevice rv=%d", r);
       return CUBEB_ERROR;
     }
 
     /* Event to notify when the input is going away. */
-    AudioDeviceID dev = stm->input_device ? stm->input_device :
-                                            audiounit_get_default_device_id(CUBEB_DEVICE_TYPE_INPUT);
+    AudioDeviceID dev = audiounit_get_input_device_id(stm);
     r = audiounit_add_listener(stm, dev, kAudioDevicePropertyDeviceIsAlive,
         kAudioObjectPropertyScopeGlobal, &audiounit_property_listener_callback);
     if (r != noErr) {
       LOG("AudioObjectAddPropertyListener/input/kAudioDevicePropertyDeviceIsAlive rv=%d", r);
       return CUBEB_ERROR;
     }
   }
 
@@ -899,19 +906,17 @@ audiounit_uninstall_device_changed_callb
     }
 
     r = audiounit_remove_listener(stm, kAudioObjectSystemObject, kAudioHardwarePropertyDefaultInputDevice,
         kAudioObjectPropertyScopeGlobal, &audiounit_property_listener_callback);
     if (r != noErr) {
       return CUBEB_ERROR;
     }
 
-    /* Event to notify when the input is going away. */
-    AudioDeviceID dev = stm->input_device ? stm->input_device :
-                        audiounit_get_default_device_id(CUBEB_DEVICE_TYPE_INPUT);
+    AudioDeviceID dev = audiounit_get_input_device_id(stm);
     r = audiounit_remove_listener(stm, dev, kAudioDevicePropertyDeviceIsAlive,
                                   kAudioObjectPropertyScopeGlobal, &audiounit_property_listener_callback);
     if (r != noErr) {
       LOG("AudioObjectRemovePropertyListener/input/kAudioDevicePropertyDeviceIsAlive rv=%d", r);
       return CUBEB_ERROR;
     }
   }
   return CUBEB_OK;
@@ -1154,16 +1159,18 @@ audiounit_get_preferred_channel_layout()
   rv = AudioObjectGetPropertyData(id, &adr, 0, NULL, &size, layout.get());
   if (rv != noErr) {
     return CUBEB_LAYOUT_UNDEFINED;
   }
 
   return audiounit_convert_channel_layout(layout.get());
 }
 
+static int audiounit_create_unit(AudioUnit * unit, io_side side, AudioDeviceID device);
+
 static int
 audiounit_get_preferred_channel_layout(cubeb * ctx, cubeb_channel_layout * layout)
 {
   // The preferred layout is only returned when the connected sound device
   // (e.g. ASUS Xonar U7), has preferred layout setting.
   // For default output on Mac, there is no preferred channel layout,
   // so it might return UNDEFINED.
   *layout = audiounit_get_preferred_channel_layout();
@@ -1175,17 +1182,17 @@ audiounit_get_preferred_channel_layout(c
     // layout must be updated. We can return it directly.
     if (ctx->active_streams) {
       return ctx->layout;
     }
 
     // If there is no existed stream, then we create a default ouput unit and
     // use it to get the current used channel layout.
     AudioUnit output_unit;
-    audiounit_create_unit(&output_unit, false, nullptr, 0);
+    audiounit_create_unit(&output_unit, OUTPUT, 0);
     *layout = audiounit_get_current_channel_layout(output_unit);
   }
 
   if (*layout == CUBEB_LAYOUT_UNDEFINED) {
     return CUBEB_ERROR;
   }
 
   return CUBEB_OK;
@@ -1341,38 +1348,378 @@ audiounit_layout_init(cubeb_stream * stm
   // Update the current used channel layout for the cubeb context.
   // Notice that this channel layout may be different from the layout we set above,
   // because OSX doesn't return error when the output device can NOT provide
   // our desired layout. Thus, we update the layout evertime when the cubeb_stream
   // is created and use it when we need to mix audio data.
   stm->context->layout = audiounit_get_current_channel_layout(stm->output_unit);
 }
 
+static std::vector<AudioObjectID>
+audiounit_get_sub_devices(AudioDeviceID device_id)
+{
+  std::vector<AudioDeviceID> sub_devices;
+  AudioObjectPropertyAddress property_address = { kAudioAggregateDevicePropertyActiveSubDeviceList,
+                                                  kAudioObjectPropertyScopeGlobal,
+                                                  kAudioObjectPropertyElementMaster };
+  UInt32 size = 0;
+  OSStatus rv = AudioObjectGetPropertyDataSize(device_id,
+                                               &property_address,
+                                               0,
+                                               nullptr,
+                                               &size);
+
+  if (rv != noErr) {
+    sub_devices.push_back(device_id);
+    return sub_devices;
+  }
+
+  uint32_t count = static_cast<uint32_t>(size / sizeof(AudioObjectID));
+  sub_devices.resize(count);
+  rv = AudioObjectGetPropertyData(device_id,
+                                  &property_address,
+                                  0,
+                                  nullptr,
+                                  &size,
+                                  sub_devices.data());
+  if (rv != noErr) {
+    sub_devices.clear();
+    sub_devices.push_back(device_id);
+  } else {
+    LOG("Found %u sub-devices", count);
+  }
+  return sub_devices;
+}
+
 static int
-audiounit_create_unit(AudioUnit * unit,
-                      bool is_input,
-                      const cubeb_stream_params * /* stream_params */,
-                      AudioDeviceID device)
+audiounit_create_blank_aggregate_device(AudioObjectID * plugin_id, AudioDeviceID * aggregate_device_id)
+{
+  AudioObjectPropertyAddress address_plugin_bundle_id = { kAudioHardwarePropertyPlugInForBundleID,
+                                                          kAudioObjectPropertyScopeGlobal,
+                                                          kAudioObjectPropertyElementMaster };
+  UInt32 size = 0;
+  OSStatus r = AudioObjectGetPropertyDataSize(kAudioObjectSystemObject,
+                                              &address_plugin_bundle_id,
+                                              0, NULL,
+                                              &size);
+  if (r != noErr) {
+    LOG("AudioHardwareGetPropertyInfo/kAudioHardwarePropertyPlugInForBundleID, rv=%d", r);
+    return CUBEB_ERROR;
+  }
+
+  AudioValueTranslation translation_value;
+  CFStringRef in_bundle_ref = CFSTR("com.apple.audio.CoreAudio");
+  translation_value.mInputData = &in_bundle_ref;
+  translation_value.mInputDataSize = sizeof(in_bundle_ref);
+  translation_value.mOutputData = plugin_id;
+  translation_value.mOutputDataSize = sizeof(*plugin_id);
+
+  r = AudioObjectGetPropertyData(kAudioObjectSystemObject,
+                                 &address_plugin_bundle_id,
+                                 0,
+                                 nullptr,
+                                 &size,
+                                 &translation_value);
+  if (r != noErr) {
+    LOG("AudioHardwareGetProperty/kAudioHardwarePropertyPlugInForBundleID, rv=%d", r);
+    return CUBEB_ERROR;
+  }
+
+  AudioObjectPropertyAddress create_aggregate_device_address = { kAudioPlugInCreateAggregateDevice,
+                                                                 kAudioObjectPropertyScopeGlobal,
+                                                                 kAudioObjectPropertyElementMaster };
+  r = AudioObjectGetPropertyDataSize(*plugin_id,
+                                     &create_aggregate_device_address,
+                                     0,
+                                     nullptr,
+                                     &size);
+  if (r != noErr) {
+    LOG("AudioObjectGetPropertyDataSize/kAudioPlugInCreateAggregateDevice, rv=%d", r);
+    return CUBEB_ERROR;
+  }
+
+  CFMutableDictionaryRef aggregate_device_dict = CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
+                                                                           &kCFTypeDictionaryKeyCallBacks,
+                                                                           &kCFTypeDictionaryValueCallBacks);
+
+  CFStringRef aggregate_device_name = CFSTR("CubebAggregateDevice");
+  CFDictionaryAddValue(aggregate_device_dict, CFSTR(kAudioAggregateDeviceNameKey), aggregate_device_name);
+
+  CFStringRef aggregate_device_UID = CFSTR("org.mozilla.CubebAggregateDevice");
+  CFDictionaryAddValue(aggregate_device_dict, CFSTR(kAudioAggregateDeviceUIDKey), aggregate_device_UID);
+
+  int private_key = 1;
+  CFNumberRef aggregate_device_private_key = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &private_key);
+  CFDictionaryAddValue(aggregate_device_dict, CFSTR(kAudioAggregateDeviceIsPrivateKey), aggregate_device_private_key);
+  CFRelease(aggregate_device_private_key);
+
+  r = AudioObjectGetPropertyData(*plugin_id,
+                                 &create_aggregate_device_address,
+                                 sizeof(aggregate_device_dict),
+                                 &aggregate_device_dict,
+                                 &size,
+                                 aggregate_device_id);
+  CFRelease(aggregate_device_dict);
+  if (r != noErr) {
+    LOG("AudioObjectGetPropertyData/kAudioPlugInCreateAggregateDevice, rv=%d", r);
+    return CUBEB_ERROR;
+  }
+  LOG("New aggregate device %u", *aggregate_device_id);
+
+  return CUBEB_OK;
+}
+
+static CFStringRef
+get_device_name(AudioDeviceID id)
+{
+  UInt32 size = sizeof(CFStringRef);
+  CFStringRef UIname;
+  AudioObjectPropertyAddress address_uuid = { kAudioDevicePropertyDeviceUID,
+                                              kAudioObjectPropertyScopeGlobal,
+                                              kAudioObjectPropertyElementMaster };
+  OSStatus err = AudioObjectGetPropertyData(id, &address_uuid, 0, nullptr, &size, &UIname);
+  return (err == noErr) ? UIname : NULL;
+}
+
+static int
+audiounit_set_aggregate_sub_device_list(cubeb_stream * stm)
+{
+  AudioDeviceID input_device_id = audiounit_get_input_device_id(stm);
+  const std::vector<AudioDeviceID> input_sub_devices = audiounit_get_sub_devices(input_device_id);
+
+
+  AudioDeviceID output_device_id = audiounit_get_default_device_id(CUBEB_DEVICE_TYPE_OUTPUT);
+  const std::vector<AudioDeviceID> output_sub_devices = audiounit_get_sub_devices(output_device_id);
+
+  CFMutableArrayRef aggregate_sub_devices_array = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
+  for (UInt32 i = 0; i < input_sub_devices.size(); i++) {
+    CFStringRef ref = get_device_name(input_sub_devices[i]);
+    if (ref == NULL) {
+      CFRelease(aggregate_sub_devices_array);
+      return CUBEB_ERROR;
+    }
+    CFArrayAppendValue(aggregate_sub_devices_array, ref);
+  }
+  for (UInt32 i = 0; i < output_sub_devices.size(); i++) {
+    CFStringRef ref = get_device_name(output_sub_devices[i]);
+    if (ref == NULL) {
+      CFRelease(aggregate_sub_devices_array);
+      return CUBEB_ERROR;
+    }
+    CFArrayAppendValue(aggregate_sub_devices_array, ref);
+  }
+
+  AudioObjectPropertyAddress aggregate_sub_device_list = { kAudioAggregateDevicePropertyFullSubDeviceList,
+                                                           kAudioObjectPropertyScopeGlobal,
+                                                           kAudioObjectPropertyElementMaster };
+  UInt32 size = sizeof(CFMutableArrayRef);
+  OSStatus rv = AudioObjectSetPropertyData(stm->aggregate_device_id,
+                                           &aggregate_sub_device_list,
+                                           0,
+                                           nullptr,
+                                           size,
+                                           &aggregate_sub_devices_array);
+  CFRelease(aggregate_sub_devices_array);
+  if (rv != noErr) {
+    LOG("AudioObjectSetPropertyData/kAudioAggregateDevicePropertyFullSubDeviceList, rv=%d", rv);
+    return CUBEB_ERROR;
+  }
+
+  return CUBEB_OK;
+}
+
+static int
+audiounit_set_master_aggregate_device(const AudioDeviceID aggregate_device_id)
+{
+  assert(aggregate_device_id);
+  AudioObjectPropertyAddress master_aggregate_sub_device =  { kAudioAggregateDevicePropertyMasterSubDevice,
+                                                              kAudioObjectPropertyScopeGlobal,
+                                                              kAudioObjectPropertyElementMaster };
+
+  // Master become the 1st output sub device
+  AudioDeviceID output_device_id = audiounit_get_default_device_id(CUBEB_DEVICE_TYPE_OUTPUT);
+  const std::vector<AudioDeviceID> output_sub_devices = audiounit_get_sub_devices(output_device_id);
+  CFStringRef master_sub_device = get_device_name(output_sub_devices[0]);
+
+  UInt32 size = sizeof(CFStringRef);
+  OSStatus rv = AudioObjectSetPropertyData(aggregate_device_id,
+                                           &master_aggregate_sub_device,
+                                           0,
+                                           NULL,
+                                           size,
+                                           &master_sub_device);
+  if (rv != noErr) {
+    LOG("AudioObjectSetPropertyData/kAudioAggregateDevicePropertyMasterSubDevice, rv=%d", rv);
+    return CUBEB_ERROR;
+  }
+
+  return CUBEB_OK;
+}
+
+static int
+audiounit_activate_clock_drift_compensation(const AudioDeviceID aggregate_device_id)
+{
+  assert(aggregate_device_id);
+  AudioObjectPropertyAddress address_owned = { kAudioObjectPropertyOwnedObjects,
+                                               kAudioObjectPropertyScopeGlobal,
+                                               kAudioObjectPropertyElementMaster };
+
+  UInt32 qualifier_data_size = sizeof(AudioObjectID);
+  AudioClassID class_id = kAudioSubDeviceClassID;
+  void * qualifier_data = &class_id;
+  UInt32 size = 0;
+  OSStatus rv = AudioObjectGetPropertyDataSize(aggregate_device_id,
+                                               &address_owned,
+                                               qualifier_data_size,
+                                               qualifier_data,
+                                               &size);
+  if (rv != noErr) {
+    LOG("AudioObjectGetPropertyDataSize/kAudioObjectPropertyOwnedObjects, rv=%d", rv);
+    return CUBEB_ERROR;
+  }
+
+  UInt32 subdevices_num = 0;
+  subdevices_num = size / sizeof(AudioObjectID);
+  AudioObjectID sub_devices[subdevices_num];
+  size = sizeof(sub_devices);
+
+  rv = AudioObjectGetPropertyData(aggregate_device_id,
+                                  &address_owned,
+                                  qualifier_data_size,
+                                  qualifier_data,
+                                  &size,
+                                  sub_devices);
+  if (rv != noErr) {
+    LOG("AudioObjectGetPropertyData/kAudioObjectPropertyOwnedObjects, rv=%d", rv);
+    return CUBEB_ERROR;
+  }
+
+  AudioObjectPropertyAddress address_drift = { kAudioSubDevicePropertyDriftCompensation,
+                                               kAudioObjectPropertyScopeGlobal,
+                                               kAudioObjectPropertyElementMaster };
+
+  for (UInt32 i = 0; i < subdevices_num; ++i) {
+    UInt32 drift_compensation_value = 1;
+    rv = AudioObjectSetPropertyData(sub_devices[i],
+                                    &address_drift,
+                                    0,
+                                    nullptr,
+                                    sizeof(UInt32),
+                                    &drift_compensation_value);
+    if (rv != noErr) {
+      LOG("AudioObjectSetPropertyData/kAudioSubDevicePropertyDriftCompensation, rv=%d", rv);
+      return CUBEB_OK;
+    }
+  }
+  return CUBEB_OK;
+}
+
+static int audiounit_destroy_aggregate_device(cubeb_stream * stm);
+
+/*
+ * Aggregate Device is a virtual audio interface which utilizes inputs and outputs
+ * of one or more physical audio interfaces. It is possible to use the clock of
+ * one of the devices as a master clock for all the combined devices and enable
+ * drift compensation for the devices that are not designated clock master.
+ *
+ * Creating a new aggregate device programmatically requires [0][1]:
+ * 1. Locate the base plug-in ("com.apple.audio.CoreAudio")
+ * 2. Create a dictionary that describes the aggregate device
+ *    (don't add sub-devices in that step, prone to fail [0])
+ * 3. Ask the base plug-in to create the aggregate device (blank)
+ * 4. Add the array of sub-devices.
+ * 5. Set the master device (1st output device in our case)
+ * 6. Enable drift compensation for the non-master devices
+ *
+ * [0] https://lists.apple.com/archives/coreaudio-api/2006/Apr/msg00092.html
+ * [1] https://lists.apple.com/archives/coreaudio-api/2005/Jul/msg00150.html
+ * [2] CoreAudio.framework/Headers/AudioHardware.h
+ * */
+static int
+audiounit_create_aggregate_device(cubeb_stream * stm)
+{
+  int r = audiounit_create_blank_aggregate_device(&stm->plugin_id, &stm->aggregate_device_id);
+  if (r != CUBEB_OK) {
+    LOG("(%p) Failed to create blank aggregate device", stm);
+    audiounit_destroy_aggregate_device(stm);
+    return CUBEB_ERROR;
+  }
+
+  r = audiounit_set_aggregate_sub_device_list(stm);
+  if (r != CUBEB_OK) {
+    LOG("(%p) Failed to set aggregate sub-device list", stm);
+    audiounit_destroy_aggregate_device(stm);
+    return CUBEB_ERROR;
+  }
+
+  r = audiounit_set_master_aggregate_device(stm->aggregate_device_id);
+  if (r != CUBEB_OK) {
+    LOG("(%p) Failed to set master sub-device for aggregate device", stm);
+    audiounit_destroy_aggregate_device(stm);
+    return  CUBEB_ERROR;
+  }
+
+  r = audiounit_activate_clock_drift_compensation(stm->aggregate_device_id);
+  if (r != CUBEB_OK) {
+    LOG("(%p) Failed to activate clock drift compensation for aggregate device", stm);
+    audiounit_destroy_aggregate_device(stm);
+    return  CUBEB_ERROR;
+  }
+
+  return CUBEB_OK;
+}
+
+static int
+audiounit_destroy_aggregate_device(cubeb_stream * stm)
+{
+  AudioObjectPropertyAddress destroy_aggregate_device_addr = { kAudioPlugInDestroyAggregateDevice,
+                                                               kAudioObjectPropertyScopeGlobal,
+                                                               kAudioObjectPropertyElementMaster};
+  UInt32 size;
+  OSStatus rv = AudioObjectGetPropertyDataSize(stm->plugin_id,
+                                               &destroy_aggregate_device_addr,
+                                               0,
+                                               NULL,
+                                               &size);
+  if (rv != noErr) {
+    LOG("AudioObjectGetPropertyDataSize/kAudioPlugInDestroyAggregateDevice, rv=%d", rv);
+    return CUBEB_ERROR;
+  }
+
+  rv = AudioObjectGetPropertyData(stm->plugin_id,
+                                  &destroy_aggregate_device_addr,
+                                  0,
+                                  NULL,
+                                  &size,
+                                  &stm->aggregate_device_id);
+  if (rv != noErr) {
+    LOG("AudioObjectGetPropertyData/kAudioPlugInDestroyAggregateDevice, rv=%d", rv);
+    return CUBEB_ERROR;
+  }
+
+  return CUBEB_OK;
+}
+
+static int
+audiounit_new_unit_instance(AudioUnit * unit, io_side side, AudioDeviceID device)
 {
   AudioComponentDescription desc;
   AudioComponent comp;
-  UInt32 enable;
-  AudioDeviceID devid;
   OSStatus rv;
 
   desc.componentType = kAudioUnitType_Output;
 #if TARGET_OS_IPHONE
   bool use_default_output = false;
   desc.componentSubType = kAudioUnitSubType_RemoteIO;
 #else
   // Use the DefaultOutputUnit for output when no device is specified
   // so we retain automatic output device switching when the default
   // changes.  Once we have complete support for device notifications
   // and switching, we can use the AUHAL for everything.
-  bool use_default_output = device == 0 && !is_input;
+  bool use_default_output = device == 0 && (side == OUTPUT);
   if (use_default_output) {
     desc.componentSubType = kAudioUnitSubType_DefaultOutput;
   } else {
     desc.componentSubType = kAudioUnitSubType_HALOutput;
   }
 #endif
   desc.componentManufacturer = kAudioUnitManufacturer_Apple;
   desc.componentFlags = 0;
@@ -1383,45 +1730,103 @@ audiounit_create_unit(AudioUnit * unit,
     return CUBEB_ERROR;
   }
 
   rv = AudioComponentInstanceNew(comp, unit);
   if (rv != noErr) {
     LOG("AudioComponentInstanceNew rv=%d", rv);
     return CUBEB_ERROR;
   }
+  return CUBEB_OK;
+}
+
+enum enable_state {
+  DISABLE,
+  ENABLE,
+};
+
+static int
+audiounit_enable_unit_scope(AudioUnit * unit, io_side side, enable_state state)
+{
+  OSStatus rv;
+  UInt32 enable = state;
+  rv = AudioUnitSetProperty(*unit, kAudioOutputUnitProperty_EnableIO,
+                            (side == INPUT) ? kAudioUnitScope_Input : kAudioUnitScope_Output,
+                            (side == INPUT) ? AU_IN_BUS : AU_OUT_BUS,
+                            &enable,
+                            sizeof(UInt32));
+  if (rv != noErr) {
+    LOG("AudioUnitSetProperty/kAudioOutputUnitProperty_EnableIO rv=%d", rv);
+    return CUBEB_ERROR;
+  }
+  return CUBEB_OK;
+}
+
+static int
+audiounit_create_unit(AudioUnit * unit, io_side side, AudioDeviceID device)
+{
+  AudioDeviceID devid;
+  OSStatus rv;
+  int r;
+
+  if (*unit == nullptr) {
+    int r = audiounit_new_unit_instance(unit, side, device);
+    if (r != CUBEB_OK) {
+      return r;
+    }
+  }
+  assert(*unit);
+
+#if TARGET_OS_IPHONE
+  bool use_default_output = false;
+#else
+  bool use_default_output = device == 0 && (side == OUTPUT);
+#endif
 
   if (!use_default_output) {
-    enable = 1;
-    rv = AudioUnitSetProperty(*unit, kAudioOutputUnitProperty_EnableIO,
-                              is_input ? kAudioUnitScope_Input : kAudioUnitScope_Output,
-                              is_input ? AU_IN_BUS : AU_OUT_BUS, &enable, sizeof(UInt32));
-    if (rv != noErr) {
-      LOG("AudioUnitSetProperty/kAudioOutputUnitProperty_EnableIO rv=%d", rv);
-      return CUBEB_ERROR;
-    }
-
-    enable = 0;
-    rv = AudioUnitSetProperty(*unit, kAudioOutputUnitProperty_EnableIO,
-                              is_input ? kAudioUnitScope_Output : kAudioUnitScope_Input,
-                              is_input ? AU_OUT_BUS : AU_IN_BUS, &enable, sizeof(UInt32));
-    if (rv != noErr) {
-      LOG("AudioUnitSetProperty/kAudioOutputUnitProperty_EnableIO rv=%d", rv);
-      return CUBEB_ERROR;
+    switch (side) {
+      case INPUT:
+        r = audiounit_enable_unit_scope(unit, INPUT, ENABLE);
+        if (r != CUBEB_OK) {
+          LOG("Failed to enable audiounit input scope ");
+          return r;
+        }
+        r = audiounit_enable_unit_scope(unit, OUTPUT, DISABLE);
+        if (r != CUBEB_OK) {
+          LOG("Failed to disable audiounit output scope ");
+          return r;
+        }
+        break;
+      case OUTPUT:
+        r = audiounit_enable_unit_scope(unit, OUTPUT, ENABLE);
+        if (r != CUBEB_OK) {
+          LOG("Failed to enable audiounit output scope ");
+          return r;
+        }
+        r = audiounit_enable_unit_scope(unit, INPUT, DISABLE);
+        if (r != CUBEB_OK) {
+          LOG("Failed to disable audiounit input scope ");
+          return r;
+        }
+        break;
+      default:
+        assert(false);
     }
 
     if (device == 0) {
-      assert(is_input);
+      assert(side == INPUT);
       devid = audiounit_get_default_device_id(CUBEB_DEVICE_TYPE_INPUT);
     } else {
       devid = device;
     }
-    rv = AudioUnitSetProperty(*unit, kAudioOutputUnitProperty_CurrentDevice,
+
+    rv = AudioUnitSetProperty(*unit,
+                              kAudioOutputUnitProperty_CurrentDevice,
                               kAudioUnitScope_Global,
-                              is_input ? AU_IN_BUS : AU_OUT_BUS,
+                              0,
                               &devid, sizeof(AudioDeviceID));
     if (rv != noErr) {
       LOG("AudioUnitSetProperty/kAudioOutputUnitProperty_CurrentDevice rv=%d", rv);
       return CUBEB_ERROR;
     }
   }
 
   return CUBEB_OK;
@@ -1445,16 +1850,17 @@ static uint32_t
 audiounit_clamp_latency(cubeb_stream * stm, uint32_t latency_frames)
 {
   // For the 1st stream set anything within safe min-max
   assert(stm->context->active_streams > 0);
   if (stm->context->active_streams == 1) {
     return std::max(std::min<uint32_t>(latency_frames, SAFE_MAX_LATENCY_FRAMES),
                     SAFE_MIN_LATENCY_FRAMES);
   }
+  assert(stm->output_unit);
 
   // If more than one stream operates in parallel
   // allow only lower values of latency
   int r;
   UInt32 output_buffer_size = 0;
   UInt32 size = sizeof(output_buffer_size);
   if (stm->output_unit) {
     r = AudioUnitGetProperty(stm->output_unit,
@@ -1522,17 +1928,17 @@ buffer_size_changed_callback(void * inCl
 {
   cubeb_stream * stm = (cubeb_stream *)inClientData;
 
   AudioUnit au = inUnit;
   AudioUnitScope au_scope = kAudioUnitScope_Input;
   AudioUnitElement au_element = inElement;
   char const * au_type = "output";
 
-  if (au == stm->input_unit) {
+  if (AU_IN_BUS == inElement) {
     au_scope = kAudioUnitScope_Output;
     au_type = "input";
   }
 
   switch (inPropertyID) {
 
     case kAudioDevicePropertyBufferFrameSize: {
       if (inScope != au_scope) {
@@ -1647,16 +2053,18 @@ audiounit_set_buffer_size(cubeb_stream *
 
   LOG("(%p) %s buffer size changed to %u frames.", stm, to_string(side), new_size_frames);
   return CUBEB_OK;
 }
 
 static int
 audiounit_configure_input(cubeb_stream * stm)
 {
+  assert(stm && stm->input_unit);
+
   int r = 0;
   UInt32 size;
   AURenderCallbackStruct aurcbs_in;
 
   LOG("(%p) Opening input side: rate %u, channels %u, format %d, latency in frames %u.",
       stm, stm->input_stream_params.rate, stm->input_stream_params.channels,
       stm->input_stream_params.format, stm->latency_frames);
 
@@ -1724,38 +2132,40 @@ audiounit_configure_input(cubeb_stream *
   if (has_output(stm)) {
     // Full-duplex increase capacity
     array_capacity = 8;
   }
   if (audiounit_init_input_linear_buffer(stm, array_capacity) != CUBEB_OK) {
     return CUBEB_ERROR;
   }
 
-  assert(stm->input_unit != NULL);
   aurcbs_in.inputProc = audiounit_input_callback;
   aurcbs_in.inputProcRefCon = stm;
 
   r = AudioUnitSetProperty(stm->input_unit,
                            kAudioOutputUnitProperty_SetInputCallback,
                            kAudioUnitScope_Global,
                            AU_OUT_BUS,
                            &aurcbs_in,
                            sizeof(aurcbs_in));
   if (r != noErr) {
     LOG("AudioUnitSetProperty/input/kAudioOutputUnitProperty_SetInputCallback rv=%d", r);
     return CUBEB_ERROR;
   }
+
   LOG("(%p) Input audiounit init successfully.", stm);
 
   return CUBEB_OK;
 }
 
 static int
 audiounit_configure_output(cubeb_stream * stm)
 {
+  assert(stm && stm->output_unit);
+
   int r;
   AURenderCallbackStruct aurcbs_out;
   UInt32 size;
 
 
   LOG("(%p) Opening output side: rate %u, channels %u, format %d, latency in frames %u.",
       stm, stm->output_stream_params.rate, stm->output_stream_params.channels,
       stm->output_stream_params.format, stm->latency_frames);
@@ -1807,17 +2217,16 @@ audiounit_configure_output(cubeb_stream 
                            AU_OUT_BUS,
                            &stm->latency_frames,
                            sizeof(UInt32));
   if (r != noErr) {
     LOG("AudioUnitSetProperty/output/kAudioUnitProperty_MaximumFramesPerSlice rv=%d", r);
     return CUBEB_ERROR;
   }
 
-  assert(stm->output_unit != NULL);
   aurcbs_out.inputProc = audiounit_output_callback;
   aurcbs_out.inputProcRefCon = stm;
   r = AudioUnitSetProperty(stm->output_unit,
                            kAudioUnitProperty_SetRenderCallback,
                            kAudioUnitScope_Global,
                            AU_OUT_BUS,
                            &aurcbs_out,
                            sizeof(aurcbs_out));
@@ -1833,30 +2242,48 @@ audiounit_configure_output(cubeb_stream 
 }
 
 static int
 audiounit_setup_stream(cubeb_stream * stm)
 {
   stm->mutex.assert_current_thread_owns();
 
   int r = 0;
+
+  AudioDeviceID in_dev = stm->input_device;
+  AudioDeviceID out_dev = stm->output_device;
+  if (has_input(stm) && has_output(stm)) {
+    r = audiounit_create_aggregate_device(stm);
+    if (r != CUBEB_OK) {
+      stm->aggregate_device_id = 0;
+      LOG("(%p) Create aggregate devices failed.", stm);
+      // !!!NOTE: It is not necessary to return here. If it does not
+      // return it will fallback to the old implementation. The intention
+      // is to investigate how often it fails. I plan to remove
+      // it after a couple of weeks.
+      return r;
+    } else {
+      in_dev = out_dev = stm->aggregate_device_id;
+    }
+  }
+
   if (has_input(stm)) {
-    r = audiounit_create_unit(&stm->input_unit, true,
-                              &stm->input_stream_params,
-                              stm->input_device);
+    r = audiounit_create_unit(&stm->input_unit,
+                              INPUT,
+                              in_dev);
     if (r != CUBEB_OK) {
       LOG("(%p) AudioUnit creation for input failed.", stm);
       return r;
     }
   }
 
   if (has_output(stm)) {
-    r = audiounit_create_unit(&stm->output_unit, false,
-                              &stm->output_stream_params,
-                              stm->output_device);
+    r = audiounit_create_unit(&stm->output_unit,
+                              OUTPUT,
+                              out_dev);
     if (r != CUBEB_OK) {
       LOG("(%p) AudioUnit creation for output failed.", stm);
       return r;
     }
   }
 
   /* Latency cannot change if another stream is operating in parallel. In this case
   * latecy is set to the other stream value. */
@@ -1867,26 +2294,25 @@ audiounit_setup_stream(cubeb_stream * st
     /* Silently clamp the latency down to the platform default, because we
     * synthetize the clock from the callbacks, and we want the clock to update
     * often. */
     stm->latency_frames = audiounit_clamp_latency(stm, stm->latency_frames);
     assert(stm->latency_frames); // Ungly error check
     audiounit_set_global_latency(stm, stm->latency_frames);
   }
 
-  /* Setup Input Stream! */
+  /* Configure I/O stream */
   if (has_input(stm)) {
     r = audiounit_configure_input(stm);
     if (r != CUBEB_OK) {
       LOG("(%p) Configure audiounit input failed.", stm);
       return r;
     }
   }
 
-  /* Setup Output Stream! */
   if (has_output(stm)) {
     r = audiounit_configure_output(stm);
     if (r != CUBEB_OK) {
       LOG("(%p) Configure audiounit output failed.", stm);
       return r;
     }
   }
 
@@ -1983,16 +2409,23 @@ audiounit_setup_stream(cubeb_stream * st
 
   if (stm->input_unit && stm->output_unit) {
     // According to the I/O hardware rate it is expected a specific pattern of callbacks
     // for example is input is 44100 and output is 48000 we expected no more than 2
     // out callback in a row.
     stm->expected_output_callbacks_in_a_row = ceilf(stm->output_hw_rate / stm->input_hw_rate);
   }
 
+  r = audiounit_install_device_changed_callback(stm);
+  if (r != CUBEB_OK) {
+    LOG("(%p) Could not install the device change callback.", stm);
+    return r;
+  }
+
+
   return CUBEB_OK;
 }
 
 cubeb_stream::cubeb_stream(cubeb * context)
   : context(context)
   , resampler(nullptr, cubeb_resampler_destroy)
 {
   PodZero(&input_desc, 1);
@@ -2052,66 +2485,66 @@ audiounit_stream_init(cubeb * context,
     r = audiounit_setup_stream(stm.get());
   }
 
   if (r != CUBEB_OK) {
     LOG("(%p) Could not setup the audiounit stream.", stm.get());
     return r;
   }
 
-  r = audiounit_install_device_changed_callback(stm.get());
-  if (r != CUBEB_OK) {
-    LOG("(%p) Could not install the device change callback.", stm.get());
-    return r;
-  }
-
   *stream = stm.release();
-  LOG("Cubeb stream (%p) init successful.", *stream);
+  LOG("(%p) Cubeb stream init successful.", *stream);
   return CUBEB_OK;
 }
 
 static void
 audiounit_close_stream(cubeb_stream *stm)
 {
   stm->mutex.assert_current_thread_owns();
+
+  int r = audiounit_uninstall_device_changed_callback(stm);
+  if (r != CUBEB_OK) {
+    LOG("(%p) Could not uninstall the device changed callback", stm);
+  }
+
   if (stm->input_unit) {
     AudioUnitUninitialize(stm->input_unit);
     AudioComponentInstanceDispose(stm->input_unit);
+    stm->input_unit = nullptr;
   }
 
   stm->input_linear_buffer.reset();
 
   if (stm->output_unit) {
     AudioUnitUninitialize(stm->output_unit);
     AudioComponentInstanceDispose(stm->output_unit);
+    stm->output_unit = nullptr;
   }
 
   stm->resampler.reset();
+
+  if (stm->aggregate_device_id) {
+    audiounit_destroy_aggregate_device(stm);
+    stm->aggregate_device_id = 0;
+  }
 }
 
 static void
 audiounit_stream_destroy(cubeb_stream * stm)
 {
   stm->shutdown = true;
 
   auto_lock context_locl(stm->context->mutex);
   audiounit_stream_stop_internal(stm);
 
   {
     auto_lock lock(stm->mutex);
     audiounit_close_stream(stm);
   }
 
-#if !TARGET_OS_IPHONE
-  int r = audiounit_uninstall_device_changed_callback(stm);
-  if (r != CUBEB_OK) {
-    LOG("(%p) Could not uninstall the device changed callback", stm);
-  }
-#endif
-
   assert(stm->context->active_streams >= 1);
   stm->context->active_streams -= 1;
 
   LOG("Cubeb stream (%p) destroyed successful.", stm);
   delete stm;
 }
 
 void
@@ -2256,18 +2689,18 @@ audiounit_stream_get_latency(cubeb_strea
   *latency = stm->hw_latency_frames + stm->current_latency_frames;
 
   return CUBEB_OK;
 #endif
 }
 
 int audiounit_stream_set_volume(cubeb_stream * stm, float volume)
 {
+  assert(stm->output_unit);
   OSStatus r;
-
   r = AudioUnitSetParameter(stm->output_unit,
                             kHALOutputParam_Volume,
                             kAudioUnitScope_Global,
                             0, volume, 0);
 
   if (r != noErr) {
     LOG("AudioUnitSetParameter/kHALOutputParam_Volume rv=%d", r);
     return CUBEB_ERROR;
--- a/mobile/android/app/mobile.js
+++ b/mobile/android/app/mobile.js
@@ -890,16 +890,20 @@ pref("dom.push.debug", false);
 // the App's sender ID; we bake this assumption directly into the URL.
 pref("dom.push.serverURL", "https://updates.push.services.mozilla.com/v1/gcm/@MOZ_ANDROID_GCM_SENDERID@");
 pref("dom.push.maxRecentMessageIDsPerSubscription", 0);
 
 #ifdef MOZ_ANDROID_GCM
 pref("dom.push.enabled", true);
 #endif
 
+// Maximum number of setTimeout()/setInterval() callbacks to run in a single
+// event loop runnable. Minimum value of 1.
+pref("dom.timeout.max_consecutive_callbacks", 3);
+
 // The remote content URL where FxAccountsWebChannel messages originate.  Must use HTTPS.
 pref("identity.fxaccounts.remote.webchannel.uri", "https://accounts.firefox.com");
 
 // The remote URL of the Firefox Account profile server.
 pref("identity.fxaccounts.remote.profile.uri", "https://profile.accounts.firefox.com/v1");
 
 // The remote URL of the Firefox Account oauth server.
 pref("identity.fxaccounts.remote.oauth.uri", "https://oauth.accounts.firefox.com/v1");
--- a/modules/libpref/init/all.js
+++ b/modules/libpref/init/all.js
@@ -1514,37 +1514,16 @@ pref("network.http.enablePerElementRefer
 pref("network.http.redirection-limit", 20);
 
 // Enable http compression: comment this out in case of problems with 1.1
 // NOTE: support for "compress" has been disabled per bug 196406.
 // NOTE: separate values with comma+space (", "): see bug 576033
 pref("network.http.accept-encoding", "gzip, deflate");
 pref("network.http.accept-encoding.secure", "gzip, deflate, br");
 
-pref("network.http.pipelining"      , false);
-pref("network.http.pipelining.ssl"  , false); // disable pipelining over SSL
-pref("network.http.pipelining.abtest", false);
-pref("network.http.proxy.pipelining", false);
-
-// Max number of requests in the pipeline
-pref("network.http.pipelining.maxrequests" , 32);
-
-// An optimistic request is one pipelined when policy might allow a new
-// connection instead
-pref("network.http.pipelining.max-optimistic-requests" , 4);
-
-pref("network.http.pipelining.aggressive", false);
-pref("network.http.pipelining.maxsize" , 300000);
-pref("network.http.pipelining.reschedule-on-timeout", true);
-pref("network.http.pipelining.reschedule-timeout", 1500);
-
-// The read-timeout is a ms timer that causes the transaction to be completely
-// restarted without pipelining.
-pref("network.http.pipelining.read-timeout", 30000);
-
 // Prompt for redirects resulting in unsafe HTTP requests
 pref("network.http.prompt-temp-redirect", false);
 
 // If true generate CORRUPTED_CONTENT errors for entities that
 // contain an invalid Assoc-Req response header
 pref("network.http.assoc-req.enforce", false);
 
 // On networks deploying QoS, it is recommended that these be lockpref()'d,
@@ -4321,17 +4300,21 @@ pref("font.name-list.sans-serif.zh-TW", 
 pref("font.name.serif.x-math", "Latin Modern Math");
 pref("font.name-list.serif.x-math", "Latin Modern Math, STIX Two Math, XITS Math, Cambria Math, Libertinus Math, DejaVu Math TeX Gyre, TeX Gyre Bonum Math, TeX Gyre Pagella Math, TeX Gyre Schola, TeX Gyre Termes Math, STIX Math, Asana Math, STIXGeneral, DejaVu Serif, DejaVu Sans, Charis SIL Compact");
 pref("font.name.sans-serif.x-math", "Fira Sans");
 pref("font.name.monospace.x-math", "Fira Mono");
 
 #elif defined(ANDROID)
 // We use the bundled fonts for Firefox for Android
 
-// ar
+pref("font.name.serif.ar", "Noto Naskh Arabic");
+pref("font.name.sans-serif.ar", "Noto Naskh Arabic");
+pref("font.name.monospace.ar", "Noto Naskh Arabic");
+pref("font.name-list.serif.ar", "Noto Naskh Arabic, Noto Serif, Droid Serif");
+pref("font.name-list.sans-serif.ar", "Noto Naskh Arabic, Clear Sans, Roboto, Droid Sans");
 
 pref("font.name.serif.el", "Droid Serif"); // not Charis SIL Compact, only has a few Greek chars
 pref("font.name.sans-serif.el", "Clear Sans");
 pref("font.name.monospace.el", "Droid Sans Mono");
 pref("font.name-list.serif.el", "Noto Serif");
 pref("font.name-list.sans-serif.el", "Clear Sans, Roboto, Droid Sans");
 
 pref("font.name.serif.he", "Droid Serif");
@@ -4486,16 +4469,20 @@ pref("image.infer-src-animation.threshol
 //
 // Image memory management prefs
 //
 
 // Discards inactive image frames and re-decodes them on demand from
 // compressed data.
 pref("image.mem.discardable", true);
 
+// Discards inactive image frames of _animated_ images and re-decodes them on
+// demand from compressed data. Has no effect if image.mem.discardable is false.
+pref("image.mem.animated.discardable", false);
+
 // Decodes images into shared memory to allow direct use in separate
 // rendering processes.
 pref("image.mem.shared", false);
 
 // Allows image locking of decoded image data in content processes.
 pref("image.mem.allow_locking_in_content_processes", true);
 
 // Chunk size for calls to the image decoders
@@ -5638,11 +5625,15 @@ pref("prompts.authentication_dialog_abus
 pref("browser.storageManager.enabled", false);
 pref("browser.storageManager.pressureNotification.minIntervalMS", 1200000);
 pref("browser.storageManager.pressureNotification.usageThresholdGB", 5);
 pref("dom.IntersectionObserver.enabled", false);
 
 // Whether module scripts (<script type="module">) are enabled for content.
 pref("dom.moduleScripts.enabled", false);
 
+// Maximum number of setTimeout()/setInterval() callbacks to run in a single
+// event loop runnable. Minimum value of 1.
+pref("dom.timeout.max_consecutive_callbacks", 5);
+
 #ifdef FUZZING
 pref("fuzzing.enabled", false);
 #endif
--- a/netwerk/base/Dashboard.cpp
+++ b/netwerk/base/Dashboard.cpp
@@ -887,23 +887,25 @@ typedef struct
     nsresult key;
     const char *error;
 } ErrorEntry;
 
 #undef ERROR
 #define ERROR(key, val) {key, #key}
 
 ErrorEntry socketTransportStatuses[] = {
-        ERROR(NS_NET_STATUS_RESOLVING_HOST,  FAILURE(3)),
-        ERROR(NS_NET_STATUS_RESOLVED_HOST,   FAILURE(11)),
-        ERROR(NS_NET_STATUS_CONNECTING_TO,   FAILURE(7)),
-        ERROR(NS_NET_STATUS_CONNECTED_TO,    FAILURE(4)),
-        ERROR(NS_NET_STATUS_SENDING_TO,      FAILURE(5)),
-        ERROR(NS_NET_STATUS_WAITING_FOR,     FAILURE(10)),
-        ERROR(NS_NET_STATUS_RECEIVING_FROM,  FAILURE(6)),
+        ERROR(NS_NET_STATUS_RESOLVING_HOST,         FAILURE(3)),
+        ERROR(NS_NET_STATUS_RESOLVED_HOST,          FAILURE(11)),
+        ERROR(NS_NET_STATUS_CONNECTING_TO,          FAILURE(7)),
+        ERROR(NS_NET_STATUS_CONNECTED_TO,           FAILURE(4)),
+        ERROR(NS_NET_STATUS_TLS_HANDSHAKE_STARTING, FAILURE(12)),
+        ERROR(NS_NET_STATUS_TLS_HANDSHAKE_ENDED,    FAILURE(13)),
+        ERROR(NS_NET_STATUS_SENDING_TO,             FAILURE(5)),
+        ERROR(NS_NET_STATUS_WAITING_FOR,            FAILURE(10)),
+        ERROR(NS_NET_STATUS_RECEIVING_FROM,         FAILURE(6)),
 };
 #undef ERROR
 
 
 static void
 GetErrorString(nsresult rv, nsAString& errorString)
 {
     for (size_t i = 0; i < ArrayLength(socketTransportStatuses); ++i) {
--- a/netwerk/ipc/NeckoChannelParams.ipdlh
+++ b/netwerk/ipc/NeckoChannelParams.ipdlh
@@ -103,17 +103,16 @@ struct HttpChannelOpenArgs
   uint32_t                    loadFlags;
   RequestHeaderTuples         requestHeaders;
   nsCString                   requestMethod;
   OptionalIPCStream           uploadStream;
   bool                        uploadStreamHasHeaders;
   int16_t                     priority;
   uint32_t                    classOfService;
   uint8_t                     redirectionLimit;
-  bool                        allowPipelining;
   bool                        allowSTS;
   uint32_t                    thirdPartyFlags;
   bool                        resumeAt;
   uint64_t                    startPos;
   nsCString                   entityID;
   bool                        chooseApplicationCache;
   nsCString                   appCacheClientID;
   bool                        allowSpdy;
--- a/netwerk/protocol/http/ConnectionDiagnostics.cpp
+++ b/netwerk/protocol/http/ConnectionDiagnostics.cpp
@@ -60,24 +60,18 @@ nsHttpConnectionMgr::OnMsgPrintDiagnosti
     mLogData.AppendPrintf("   Idle Conns Length = %" PRIuSIZE "\n",
                           ent->mIdleConns.Length());
     mLogData.AppendPrintf("   Half Opens Length = %" PRIuSIZE "\n",
                           ent->mHalfOpens.Length());
     mLogData.AppendPrintf("   Coalescing Keys Length = %" PRIuSIZE "\n",
                           ent->mCoalescingKeys.Length());
     mLogData.AppendPrintf("   Spdy using = %d, preferred = %d\n",
                           ent->mUsingSpdy, ent->mInPreferredHash);
-    mLogData.AppendPrintf("   pipelinestate = %d penalty = %d\n",
-                          ent->mPipelineState, ent->mPipeliningPenalty);
 
     uint32_t i;
-    for (i = 0; i < nsAHttpTransaction::CLASS_MAX; ++i) {
-      mLogData.AppendPrintf("   pipeline per class penalty 0x%x %d\n",
-                            i, ent->mPipeliningClassPenalty[i]);
-    }
     for (i = 0; i < ent->mActiveConns.Length(); ++i) {
       mLogData.AppendPrintf("   :: Active Connection #%u\n", i);
       ent->mActiveConns[i]->PrintDiagnostics(mLogData);
     }
     for (i = 0; i < ent->mIdleConns.Length(); ++i) {
       mLogData.AppendPrintf("   :: Idle Connection #%u\n", i);
       ent->mIdleConns[i]->PrintDiagnostics(mLogData);
     }
@@ -147,19 +141,16 @@ nsHttpConnection::PrintDiagnostics(nsCSt
   log.AppendPrintf("    max-read/read/written %" PRId64 "/%" PRId64 "/%" PRId64 "\n",
                    mMaxBytesRead, mTotalBytesRead, mTotalBytesWritten);
 
   log.AppendPrintf("    rtt = %ums\n", PR_IntervalToMilliseconds(mRtt));
 
   log.AppendPrintf("    idlemonitoring = %d transactionCount=%d\n",
                    mIdleMonitoring, mHttp1xTransactionCount);
 
-  log.AppendPrintf("    supports pipeline = %d classification = 0x%x\n",
-                   mSupportsPipelining, mClassification);
-
   if (mSpdySession)
     mSpdySession->PrintDiagnostics(log);
 }
 
 void
 Http2Session::PrintDiagnostics(nsCString &log)
 {
   log.AppendPrintf("     ::: HTTP2\n");
@@ -202,13 +193,12 @@ nsHttpTransaction::PrintDiagnostics(nsCS
     return;
 
   nsAutoCString requestURI;
   mRequestHead->RequestURI(requestURI);
   log.AppendPrintf("     ::: uri = %s\n", requestURI.get());
   log.AppendPrintf("     caps = 0x%x\n", mCaps);
   log.AppendPrintf("     priority = %d\n", mPriority);
   log.AppendPrintf("     restart count = %u\n", mRestartCount);
-  log.AppendPrintf("     classification = 0x%x\n", mClassification);
 }
 
 } // namespace net
 } // namespace mozilla
--- a/netwerk/protocol/http/Http2Push.cpp
+++ b/netwerk/protocol/http/Http2Push.cpp
@@ -463,40 +463,16 @@ Http2PushTransactionBuffer::SetProxyConn
 void
 Http2PushTransactionBuffer::Close(nsresult reason)
 {
   mStatus = reason;
   mIsDone = true;
 }
 
 nsresult
-Http2PushTransactionBuffer::AddTransaction(nsAHttpTransaction *trans)
-{
-  return NS_ERROR_NOT_IMPLEMENTED;
-}
-
-uint32_t
-Http2PushTransactionBuffer::PipelineDepth()
-{
-  return 0;
-}
-
-nsresult
-Http2PushTransactionBuffer::SetPipelinePosition(int32_t position)
-{
-  return NS_OK;
-}
-
-int32_t
-Http2PushTransactionBuffer::PipelinePosition()
-{
-  return 1;
-}
-
-nsresult
 Http2PushTransactionBuffer::GetBufferedData(char *buf,
                                             uint32_t count,
                                             uint32_t *countWritten)
 {
   *countWritten = std::min(count, static_cast<uint32_t>(Available()));
   if (*countWritten) {
     memcpy(buf, &mBufferedHTTP1[mBufferedHTTP1Consumed], *countWritten);
     mBufferedHTTP1Consumed += *countWritten;
--- a/netwerk/protocol/http/Http2Session.cpp
+++ b/netwerk/protocol/http/Http2Session.cpp
@@ -36,19 +36,17 @@
 #include "sslt.h"
 #include "mozilla/Sprintf.h"
 #include "nsSocketTransportService2.h"
 #include "nsNetUtil.h"
 
 namespace mozilla {
 namespace net {
 
-// Http2Session has multiple inheritance of things that implement
-// nsISupports, so this magic is taken from nsHttpPipeline that
-// implements some of the same abstract classes.
+// Http2Session has multiple inheritance of things that implement nsISupports
 NS_IMPL_ADDREF(Http2Session)
 NS_IMPL_RELEASE(Http2Session)
 NS_INTERFACE_MAP_BEGIN(Http2Session)
 NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsAHttpConnection)
 NS_INTERFACE_MAP_END
 
 // "magic" refers to the string that preceeds HTTP/2 on the wire
 // to help find any intermediaries speaking an older version of HTTP
@@ -3806,31 +3804,16 @@ Http2Session::TakeTransport(nsISocketTra
 
 already_AddRefed<nsHttpConnection>
 Http2Session::TakeHttpConnection()
 {
   MOZ_ASSERT(false, "TakeHttpConnection of Http2Session");
   return nullptr;
 }
 
-uint32_t
-Http2Session::CancelPipeline(nsresult reason)
-{
-  // we don't pipeline inside http/2, so this isn't an issue
-  return 0;
-}
-
-nsAHttpTransaction::Classifier
-Http2Session::Classification()
-{
-  if (!mConnection)
-    return nsAHttpTransaction::CLASS_GENERAL;
-  return mConnection->Classification();
-}
-
 void
 Http2Session::GetSecurityCallbacks(nsIInterfaceRequestor **aOut)
 {
   *aOut = nullptr;
 }
 
 //-----------------------------------------------------------------------------
 // unused methods of nsAHttpTransaction
@@ -3920,52 +3903,16 @@ Http2Session::TakeSubTransactions(
 
     // Removing the stream from the hash will delete the stream and drop the
     // transaction reference the hash held.
     iter.Remove();
   }
   return NS_OK;
 }
 
-nsresult
-Http2Session::AddTransaction(nsAHttpTransaction *)
-{
-  // This API is meant for pipelining, Http2Session's should be
-  // extended with AddStream()
-
-  MOZ_ASSERT(false,
-             "Http2Session::AddTransaction() should not be called");
-
-  return NS_ERROR_NOT_IMPLEMENTED;
-}
-
-uint32_t
-Http2Session::PipelineDepth()
-{
-  return IsDone() ? 0 : 1;
-}
-
-nsresult
-Http2Session::SetPipelinePosition(int32_t position)
-{
-  // This API is meant for pipelining, Http2Session's should be
-  // extended with AddStream()
-
-  MOZ_ASSERT(false,
-             "Http2Session::SetPipelinePosition() should not be called");
-
-  return NS_ERROR_NOT_IMPLEMENTED;
-}
-
-int32_t
-Http2Session::PipelinePosition()
-{
-  return 0;
-}
-
 //-----------------------------------------------------------------------------
 // Pass through methods of nsAHttpConnection
 //-----------------------------------------------------------------------------
 
 nsAHttpConnection *
 Http2Session::Connection()
 {
   MOZ_ASSERT(PR_GetCurrentThread() == gSocketThread);
--- a/netwerk/protocol/http/HttpBaseChannel.cpp
+++ b/netwerk/protocol/http/HttpBaseChannel.cpp
@@ -157,17 +157,16 @@ HttpBaseChannel::HttpBaseChannel()
   , mPriority(PRIORITY_NORMAL)
   , mRedirectionLimit(gHttpHandler->RedirectionLimit())
   , mApplyConversion(true)
   , mCanceled(false)
   , mIsPending(false)
   , mWasOpened(false)
   , mRequestObserversCalled(false)
   , mResponseHeadersModified(false)
-  , mAllowPipelining(true)
   , mAllowSTS(true)
   , mThirdPartyFlags(0)
   , mUploadStreamHasHeaders(false)
   , mInheritApplicationCache(true)
   , mChooseApplicationCache(false)
   , mLoadedFromApplicationCache(false)
   , mChannelIsForDownload(false)
   , mTracingEnabled(true)
@@ -1949,26 +1948,25 @@ HttpBaseChannel::VisitOriginalResponseHe
   return mResponseHead->VisitHeaders(aVisitor,
       nsHttpHeaderArray::eFilterResponseOriginal);
 }
 
 NS_IMETHODIMP
 HttpBaseChannel::GetAllowPipelining(bool *value)
 {
   NS_ENSURE_ARG_POINTER(value);
-  *value = mAllowPipelining;
+  *value = false;
   return NS_OK;
 }
 
 NS_IMETHODIMP
 HttpBaseChannel::SetAllowPipelining(bool value)
 {
   ENSURE_CALLED_BEFORE_CONNECT();
-
-  mAllowPipelining = value;
+  // nop
   return NS_OK;
 }
 
 NS_IMETHODIMP
 HttpBaseChannel::GetAllowSTS(bool *value)
 {
   NS_ENSURE_ARG_POINTER(value);
   *value = mAllowSTS;
@@ -3227,18 +3225,17 @@ HttpBaseChannel::SetupReplacementChannel
 
     nsAutoCString method;
     mRequestHead.Method(method);
     httpChannel->SetRequestMethod(method);
   }
   // convey the referrer if one was used for this channel to the next one
   if (mReferrer)
     httpChannel->SetReferrerWithPolicy(mReferrer, mReferrerPolicy);
-  // convey the mAllowPipelining and mAllowSTS flags
-  httpChannel->SetAllowPipelining(mAllowPipelining);
+  // convey the mAllowSTS flags
   httpChannel->SetAllowSTS(mAllowSTS);
   // convey the new redirection limit
   // make sure we don't underflow
   uint32_t redirectionLimit = mRedirectionLimit
     ? mRedirectionLimit - 1
     : 0;
   httpChannel->SetRedirectionLimit(redirectionLimit);
 
--- a/netwerk/protocol/http/HttpBaseChannel.h
+++ b/netwerk/protocol/http/HttpBaseChannel.h
@@ -174,18 +174,18 @@ public:
   NS_IMETHOD VisitNonDefaultRequestHeaders(nsIHttpHeaderVisitor *visitor) override;
   NS_IMETHOD GetResponseHeader(const nsACString &header, nsACString &value) override;
   NS_IMETHOD SetResponseHeader(const nsACString& header,
                                const nsACString& value, bool merge) override;
   NS_IMETHOD VisitResponseHeaders(nsIHttpHeaderVisitor *visitor) override;
   NS_IMETHOD GetOriginalResponseHeader(const nsACString &aHeader,
                                        nsIHttpHeaderVisitor *aVisitor) override;
   NS_IMETHOD VisitOriginalResponseHeaders(nsIHttpHeaderVisitor *aVisitor) override;
-  NS_IMETHOD GetAllowPipelining(bool *value) override;
-  NS_IMETHOD SetAllowPipelining(bool value) override;
+  NS_IMETHOD GetAllowPipelining(bool *value) override; // deprecated
+  NS_IMETHOD SetAllowPipelining(bool value) override;  // deprecated
   NS_IMETHOD GetAllowSTS(bool *value) override;
   NS_IMETHOD SetAllowSTS(bool value) override;
   NS_IMETHOD GetRedirectionLimit(uint32_t *value) override;
   NS_IMETHOD SetRedirectionLimit(uint32_t value) override;
   NS_IMETHOD IsNoStoreResponse(bool *value) override;
   NS_IMETHOD IsNoCacheResponse(bool *value) override;
   NS_IMETHOD IsPrivateResponse(bool *value) override;
   NS_IMETHOD GetResponseStatus(uint32_t *aValue) override;
@@ -482,17 +482,16 @@ protected:
 
   uint32_t                          mApplyConversion            : 1;
   uint32_t                          mCanceled                   : 1;
   uint32_t                          mIsPending                  : 1;
   uint32_t                          mWasOpened                  : 1;
   // if 1 all "http-on-{opening|modify|etc}-request" observers have been called
   uint32_t                          mRequestObserversCalled     : 1;
   uint32_t                          mResponseHeadersModified    : 1;
-  uint32_t                          mAllowPipelining            : 1;
   uint32_t                          mAllowSTS                   : 1;
   uint32_t                          mThirdPartyFlags            : 3;
   uint32_t                          mUploadStreamHasHeaders     : 1;
   uint32_t                          mInheritApplicationCache    : 1;
   uint32_t                          mChooseApplicationCache     : 1;
   uint32_t                          mLoadedFromApplicationCache : 1;
   uint32_t                          mChannelIsForDownload       : 1;
   uint32_t                          mTracingEnabled             : 1;
--- a/netwerk/protocol/http/HttpChannelChild.cpp
+++ b/netwerk/protocol/http/HttpChannelChild.cpp
@@ -2185,17 +2185,16 @@ HttpChannelChild::ContinueAsyncOpen()
   SerializeURI(mTopWindowURI, openArgs.topWindowURI());
 
   openArgs.preflightArgs() = optionalCorsPreflightArgs;
 
   openArgs.uploadStreamHasHeaders() = mUploadStreamHasHeaders;
   openArgs.priority() = mPriority;
   openArgs.classOfService() = mClassOfService;
   openArgs.redirectionLimit() = mRedirectionLimit;
-  openArgs.allowPipelining() = mAllowPipelining;
   openArgs.allowSTS() = mAllowSTS;
   openArgs.thirdPartyFlags() = mThirdPartyFlags;
   openArgs.resumeAt() = mSendResumeAt;
   openArgs.startPos() = mStartPos;
   openArgs.entityID() = mEntityID;
   openArgs.chooseApplicationCache() = mChooseApplicationCache;
   openArgs.appCacheClientID() = appCacheClientId;
   openArgs.allowSpdy() = mAllowSpdy;
--- a/netwerk/protocol/http/HttpChannelParent.cpp
+++ b/netwerk/protocol/http/HttpChannelParent.cpp
@@ -115,17 +115,17 @@ HttpChannelParent::Init(const HttpChanne
   case HttpChannelCreationArgs::THttpChannelOpenArgs:
   {
     const HttpChannelOpenArgs& a = aArgs.get_HttpChannelOpenArgs();
     return DoAsyncOpen(a.uri(), a.original(), a.doc(), a.referrer(),
                        a.referrerPolicy(), a.apiRedirectTo(), a.topWindowURI(),
                        a.loadFlags(), a.requestHeaders(),
                        a.requestMethod(), a.uploadStream(),
                        a.uploadStreamHasHeaders(), a.priority(), a.classOfService(),
-                       a.redirectionLimit(), a.allowPipelining(), a.allowSTS(),
+                       a.redirectionLimit(), a.allowSTS(),
                        a.thirdPartyFlags(), a.resumeAt(), a.startPos(),
                        a.entityID(), a.chooseApplicationCache(),
                        a.appCacheClientID(), a.allowSpdy(), a.allowAltSvc(), a.beConservative(),
                        a.loadInfo(), a.synthesizedResponseHead(),
                        a.synthesizedSecurityInfoSerialization(),
                        a.cacheKey(), a.requestContextID(), a.preflightArgs(),
                        a.initialRwin(), a.blockAuthPrompt(),
                        a.suspendAfterSynthesizeResponse(),
@@ -300,17 +300,16 @@ HttpChannelParent::DoAsyncOpen(  const U
                                  const uint32_t&            aLoadFlags,
                                  const RequestHeaderTuples& requestHeaders,
                                  const nsCString&           requestMethod,
                                  const OptionalIPCStream&   uploadStream,
                                  const bool&                uploadStreamHasHeaders,
                                  const int16_t&             priority,
                                  const uint32_t&            classOfService,
                                  const uint8_t&             redirectionLimit,
-                                 const bool&                allowPipelining,
                                  const bool&                allowSTS,
                                  const uint32_t&            thirdPartyFlags,
                                  const bool&                doResumeAt,
                                  const uint64_t&            startPos,
                                  const nsCString&           entityID,
                                  const bool&                chooseApplicationCache,
                                  const nsCString&           appCacheClientID,
                                  const bool&                allowSpdy,
@@ -521,17 +520,16 @@ HttpChannelParent::DoAsyncOpen(  const U
 
   if (priority != nsISupportsPriority::PRIORITY_NORMAL) {
     mChannel->SetPriority(priority);
   }
   if (classOfService) {
     mChannel->SetClassFlags(classOfService);
   }
   mChannel->SetRedirectionLimit(redirectionLimit);
-  mChannel->SetAllowPipelining(allowPipelining);
   mChannel->SetAllowSTS(allowSTS);
   mChannel->SetThirdPartyFlags(thirdPartyFlags);
   mChannel->SetAllowSpdy(allowSpdy);
   mChannel->SetAllowAltSvc(allowAltSvc);
   mChannel->SetBeConservative(beConservative);
   mChannel->SetInitialRwin(aInitialRwin);
   mChannel->SetBlockAuthPrompt(aBlockAuthPrompt);
 
--- a/netwerk/protocol/http/HttpChannelParent.h
+++ b/netwerk/protocol/http/HttpChannelParent.h
@@ -117,17 +117,16 @@ protected:
                    const uint32_t&            loadFlags,
                    const RequestHeaderTuples& requestHeaders,
                    const nsCString&           requestMethod,
                    const OptionalIPCStream&   uploadStream,
                    const bool&                uploadStreamHasHeaders,
                    const int16_t&             priority,
                    const uint32_t&            classOfService,
                    const uint8_t&             redirectionLimit,
-                   const bool&                allowPipelining,
                    const bool&                allowSTS,
                    const uint32_t&            thirdPartyFlags,
                    const bool&                doResumeAt,
                    const uint64_t&            startPos,
                    const nsCString&           entityID,
                    const bool&                chooseApplicationCache,
                    const nsCString&           appCacheClientID,
                    const bool&                allowSpdy,
--- a/netwerk/protocol/http/NullHttpTransaction.cpp
+++ b/netwerk/protocol/http/NullHttpTransaction.cpp
@@ -299,35 +299,11 @@ NullHttpTransaction::Close(nsresult reas
 }
 
 nsHttpConnectionInfo *
 NullHttpTransaction::ConnectionInfo()
 {
   return mConnectionInfo;
 }
 
-nsresult
-NullHttpTransaction::AddTransaction(nsAHttpTransaction *trans)
-{
-    return NS_ERROR_NOT_IMPLEMENTED;
-}
-
-uint32_t
-NullHttpTransaction::PipelineDepth()
-{
-  return 0;
-}
-
-nsresult
-NullHttpTransaction::SetPipelinePosition(int32_t position)
-{
-    return NS_OK;
-}
-
-int32_t
-NullHttpTransaction::PipelinePosition()
-{
-  return 1;
-}
-
 } // namespace net
 } // namespace mozilla
 
--- a/netwerk/protocol/http/TunnelUtils.cpp
+++ b/netwerk/protocol/http/TunnelUtils.cpp
@@ -684,69 +684,16 @@ TLSFilterTransaction::SetProxiedTransact
   nsCOMPtr<nsISSLSocketControl> secCtrl(do_QueryInterface(mSecInfo));
   if (secCtrl && callbacks) {
     secCtrl->SetNotificationCallbacks(callbacks);
   }
 
   return NS_OK;
 }
 
-// AddTransaction is for adding pipelined subtransactions
-nsresult
-TLSFilterTransaction::AddTransaction(nsAHttpTransaction *aTrans)
-{
-  LOG(("TLSFilterTransaction::AddTransaction passing on subtransaction "
-       "[this=%p] aTrans=%p ,mTransaction=%p\n", this, aTrans, mTransaction.get()));
-
-  if (!mTransaction) {
-    return NS_ERROR_FAILURE;
-  }
-
-  return mTransaction->AddTransaction(aTrans);
-}
-
-uint32_t
-TLSFilterTransaction::PipelineDepth()
-{
-  if (!mTransaction) {
-    return 0;
-  }
-
-  return mTransaction->PipelineDepth();
-}
-
-nsresult
-TLSFilterTransaction::SetPipelinePosition(int32_t aPosition)
-{
-  if (!mTransaction) {
-    return NS_OK;
-  }
-
-  return mTransaction->SetPipelinePosition(aPosition);
-}
-
-int32_t
-TLSFilterTransaction::PipelinePosition()
-{
-  if (!mTransaction) {
-    return 1;
-  }
-
-  return mTransaction->PipelinePosition();
-}
-
-nsHttpPipeline *
-TLSFilterTransaction::QueryPipeline()
-{
-  if (!mTransaction) {
-    return nullptr;
-  }
-  return mTransaction->QueryPipeline();
-}
-
 bool
 TLSFilterTransaction::IsNullTransaction()
 {
   if (!mTransaction) {
     return false;
   }
   return mTransaction->IsNullTransaction();
 }
--- a/netwerk/protocol/http/TunnelUtils.h
+++ b/netwerk/protocol/http/TunnelUtils.h
@@ -123,17 +123,16 @@ public:
   nsresult NudgeTunnel(NudgeTunnelCallback *callback);
   nsresult SetProxiedTransaction(nsAHttpTransaction *aTrans);
   void     newIODriver(nsIAsyncInputStream *aSocketIn,
                        nsIAsyncOutputStream *aSocketOut,
                        nsIAsyncInputStream **outSocketIn,
                        nsIAsyncOutputStream **outSocketOut);
 
   // nsAHttpTransaction overloads
-  nsHttpPipeline *QueryPipeline() override;
   bool IsNullTransaction() override;
   NullHttpTransaction *QueryNullTransaction() override;
   nsHttpTransaction *QueryHttpTransaction() override;
   SpdyConnectTransaction *QuerySpdyConnectTransaction() override;
 
 private:
   nsresult StartTimerCallback();
   void Cleanup();
--- a/netwerk/protocol/http/moz.build
+++ b/netwerk/protocol/http/moz.build
@@ -83,17 +83,16 @@ UNIFIED_SOURCES += [
     'nsHttpChannel.cpp',
     'nsHttpChunkedDecoder.cpp',
     'nsHttpConnection.cpp',
     'nsHttpConnectionInfo.cpp',
     'nsHttpConnectionMgr.cpp',
     'nsHttpDigestAuth.cpp',
     'nsHttpHeaderArray.cpp',
     'nsHttpNTLMAuth.cpp',
-    'nsHttpPipeline.cpp',
     'nsHttpRequestHead.cpp',
     'nsHttpResponseHead.cpp',
     'nsHttpTransaction.cpp',
     'NullHttpChannel.cpp',
     'NullHttpTransaction.cpp',
     'TunnelUtils.cpp',
 ]
 
--- a/netwerk/protocol/http/nsAHttpConnection.h
+++ b/netwerk/protocol/http/nsAHttpConnection.h
@@ -57,18 +57,18 @@ public:
     // called by a transaction to force a "send/recv from network" iteration
     // even if not scheduled by socket associated with connection
     virtual nsresult ForceSend() = 0;
     virtual nsresult ForceRecv() = 0;
 
     // After a connection has had ResumeSend() called by a transaction,
     // and it is ready to write to the network it may need to know the
     // transaction that has data to write. This is only an issue for
-    // multiplexed protocols like SPDY - plain HTTP or pipelined HTTP
-    // implicitly have this information in a 1:1 relationship with the
+    // multiplexed protocols like SPDY - h1
+    // implicitly has this information in a 1:1 relationship with the
     // transaction(s) they manage.
     virtual void TransactionHasDataToWrite(nsAHttpTransaction *)
     {
         // by default do nothing - only multiplexed protocols need to overload
         return;
     }
 
     // This is the companion to *HasDataToWrite() for the case
@@ -107,17 +107,17 @@ public:
     // persistent... important in determining the end of a response.
     virtual bool IsPersistent() = 0;
 
     // called to determine or set if a connection has been reused.
     virtual bool IsReused() = 0;
     virtual void DontReuse() = 0;
 
     // called by a transaction when the transaction reads more from the socket
-    // than it should have (eg. containing part of the next pipelined response).
+    // than it should have (eg. containing part of the next response).
     virtual nsresult PushBack(const char *data, uint32_t length) = 0;
 
     // Used to determine if the connection wants read events even though
     // it has not written out a transaction. Used when a connection has issued
     // a preamble such as a proxy ssl CONNECT sequence.
     virtual bool IsProxyConnectInProgress() = 0;
 
     // Used by a transaction to manage the state of previous response bodies on
@@ -128,24 +128,16 @@ public:
     // Transfer the base http connection object along with a
     // reference to it to the caller.
     virtual already_AddRefed<nsHttpConnection> TakeHttpConnection() = 0;
 
     // Get the nsISocketTransport used by the connection without changing
     //  references or ownership.
     virtual nsISocketTransport *Transport() = 0;
 
-    // Cancel and reschedule transactions deeper than the current response.
-    // Returns the number of canceled transactions.
-    virtual uint32_t CancelPipeline(nsresult originalReason) = 0;
-
-    // Read and write class of transaction that is carried on this connection
-    virtual nsAHttpTransaction::Classifier Classification() = 0;
-    virtual void Classify(nsAHttpTransaction::Classifier newclass) = 0;
-
     // The number of transaction bytes written out on this HTTP Connection, does
     // not count CONNECT tunnel setup
     virtual int64_t BytesWritten() = 0;
 
     // Update the callbacks used to provide security info. May be called on
     // any thread.
     virtual void SetSecurityCallbacks(nsIInterfaceRequestor* aCallbacks) = 0;
 
@@ -161,18 +153,16 @@ NS_DEFINE_STATIC_IID_ACCESSOR(nsAHttpCon
     nsresult TakeTransport(nsISocketTransport **,    \
                            nsIAsyncInputStream **,   \
                            nsIAsyncOutputStream **) override; \
     bool IsPersistent() override;                         \
     bool IsReused() override;                             \
     void DontReuse() override;                            \
     nsresult PushBack(const char *, uint32_t) override;   \
     already_AddRefed<nsHttpConnection> TakeHttpConnection() override; \
-    uint32_t CancelPipeline(nsresult originalReason) override; \
-    nsAHttpTransaction::Classifier Classification() override; \
     /*                                                    \
        Thes methods below have automatic definitions that just forward the \
        function to a lower level connection object        \
     */                                                    \
     void GetConnectionInfo(nsHttpConnectionInfo **result) \
       override                                            \
     {                                                     \
       if (!(fwdObject)) {                                 \
@@ -237,22 +227,16 @@ NS_DEFINE_STATIC_IID_ACCESSOR(nsAHttpCon
         (fwdObject)->LastTransactionExpectedNoContent();    \
     }                                                       \
     void SetLastTransactionExpectedNoContent(bool val)      \
       override                                              \
     {                                                       \
       if (fwdObject)                                        \
         (fwdObject)->SetLastTransactionExpectedNoContent(val); \
     }                                                       \
-    void Classify(nsAHttpTransaction::Classifier newclass)  \
-      override                                              \
-    {                                                       \
-    if (fwdObject)                                          \
-        (fwdObject)->Classify(newclass);                    \
-    }                                                       \
     int64_t BytesWritten() override                         \
     {     return fwdObject ? (fwdObject)->BytesWritten() : 0; } \
     void SetSecurityCallbacks(nsIInterfaceRequestor* aCallbacks) \
       override                                              \
     {                                                       \
         if (fwdObject)                                      \
             (fwdObject)->SetSecurityCallbacks(aCallbacks);  \
     }
--- a/netwerk/protocol/http/nsAHttpTransaction.h
+++ b/netwerk/protocol/http/nsAHttpTransaction.h
@@ -14,17 +14,16 @@ class nsITransport;
 class nsIRequestContext;
 
 namespace mozilla { namespace net {
 
 class nsAHttpConnection;
 class nsAHttpSegmentReader;
 class nsAHttpSegmentWriter;
 class nsHttpTransaction;
-class nsHttpPipeline;
 class nsHttpRequestHead;
 class nsHttpConnectionInfo;
 class NullHttpTransaction;
 class SpdyConnectTransaction;
 
 //----------------------------------------------------------------------------
 // Abstract base class for a HTTP transaction:
 //
@@ -95,58 +94,38 @@ public:
 
     // called to indicate a failure with proxy CONNECT
     virtual void SetProxyConnectFailed() = 0;
 
     // called to retrieve the request headers of the transaction
     virtual nsHttpRequestHead *RequestHead() = 0;
 
     // determine the number of real http/1.x transactions on this
-    // abstract object. Pipelines may have multiple, SPDY has 0,
+    // abstract object. Pipelines had multiple, SPDY has 0,
     // normal http transactions have 1.
     virtual uint32_t Http1xTransactionCount() = 0;
 
     // called to remove the unused sub transactions from an object that can
-    // handle multiple transactions simultaneously (i.e. pipelines or spdy).
+    // handle multiple transactions simultaneously (i.e. h2).
     //
     // Returns NS_ERROR_NOT_IMPLEMENTED if the object does not implement
     // sub-transactions.
     //
     // Returns NS_ERROR_ALREADY_OPENED if the subtransactions have been
     // at least partially written and cannot be moved.
     //
     virtual nsresult TakeSubTransactions(
         nsTArray<RefPtr<nsAHttpTransaction> > &outTransactions) = 0;
 
-    // called to add a sub-transaction in the case of pipelined transactions
-    // classes that do not implement sub transactions
-    // return NS_ERROR_NOT_IMPLEMENTED
-    virtual nsresult AddTransaction(nsAHttpTransaction *transaction) = 0;
-
-    // The total length of the outstanding pipeline comprised of transacations
-    // and sub-transactions.
-    virtual uint32_t PipelineDepth() = 0;
-
-    // Used to inform the connection that it is being used in a pipelined
-    // context. That may influence the handling of some errors.
-    // The value is the pipeline position (> 1).
-    virtual nsresult SetPipelinePosition(int32_t) = 0;
-    virtual int32_t  PipelinePosition() = 0;
-
     // Occasionally the abstract interface has to give way to base implementations
-    // to respect differences between spdy, pipelines, etc..
+    // to respect differences between spdy, h2, etc..
     // These Query* (and IsNullTransaction()) functions provide a way to do
     // that without using xpcom or rtti. Any calling code that can't deal with
     // a null response from one of them probably shouldn't be using nsAHttpTransaction
 
-    // If we used rtti this would be the result of doing
-    // dynamic_cast<nsHttpPipeline *>(this).. i.e. it can be nullptr for
-    // non pipeline implementations of nsAHttpTransaction
-    virtual nsHttpPipeline *QueryPipeline() { return nullptr; }
-
     // equivalent to !!dynamic_cast<NullHttpTransaction *>(this)
     // A null transaction is expected to return BASE_STREAM_CLOSED on all of
     // its IO functions all the time.
     virtual bool IsNullTransaction() { return false; }
     virtual NullHttpTransaction *QueryNullTransaction() { return nullptr; }
 
     // If we used rtti this would be the result of doing
     // dynamic_cast<nsHttpTransaction *>(this).. i.e. it can be nullptr for
@@ -163,39 +142,16 @@ public:
 
     // return the connection information associated with the transaction
     virtual nsHttpConnectionInfo *ConnectionInfo() = 0;
 
     // The base definition of these is done in nsHttpTransaction.cpp
     virtual bool ResponseTimeoutEnabled() const;
     virtual PRIntervalTime ResponseTimeout();
 
-    // Every transaction is classified into one of the types below. When using
-    // HTTP pipelines, only transactions with the same type appear on the same
-    // pipeline.
-    enum Classifier  {
-        // Transactions that expect a short 304 (no-content) response
-        CLASS_REVALIDATION,
-
-        // Transactions for content expected to be CSS or JS
-        CLASS_SCRIPT,
-
-        // Transactions for content expected to be an image
-        CLASS_IMAGE,
-
-        // Transactions that cannot involve a pipeline
-        CLASS_SOLO,
-
-        // Transactions that do not fit any of the other categories. HTML
-        // is normally GENERAL.
-        CLASS_GENERAL,
-
-        CLASS_MAX
-    };
-
     // conceptually the security info is part of the connection, but sometimes
     // in the case of TLS tunneled within TLS the transaction might present
     // a more specific security info that cannot be represented as a layer in
     // the connection due to multiplexing. This interface represents such an
     // overload. If it returns NS_FAILURE the connection should be considered
     // authoritative.
     virtual nsresult GetTransactionSecurityInfo(nsISupports **)
     {
@@ -240,21 +196,17 @@ NS_DEFINE_STATIC_IID_ACCESSOR(nsAHttpTra
     uint64_t Available() override; \
     virtual nsresult ReadSegments(nsAHttpSegmentReader *, uint32_t, uint32_t *) override; \
     virtual nsresult WriteSegments(nsAHttpSegmentWriter *, uint32_t, uint32_t *) override; \
     virtual void Close(nsresult reason) override;                                \
     nsHttpConnectionInfo *ConnectionInfo() override;                             \
     void     SetProxyConnectFailed() override;                                   \
     virtual nsHttpRequestHead *RequestHead() override;                                   \
     uint32_t Http1xTransactionCount() override;                                  \
-    nsresult TakeSubTransactions(nsTArray<RefPtr<nsAHttpTransaction> > &outTransactions) override; \
-    nsresult AddTransaction(nsAHttpTransaction *) override;                      \
-    uint32_t PipelineDepth() override;                                           \
-    nsresult SetPipelinePosition(int32_t) override;                              \
-    int32_t  PipelinePosition() override;
+    nsresult TakeSubTransactions(nsTArray<RefPtr<nsAHttpTransaction> > &outTransactions) override;
 
 //-----------------------------------------------------------------------------
 // nsAHttpSegmentReader
 //-----------------------------------------------------------------------------
 
 class nsAHttpSegmentReader
 {
 public:
--- a/netwerk/protocol/http/nsHttp.h
+++ b/netwerk/protocol/http/nsHttp.h
@@ -46,17 +46,17 @@ namespace net {
 
 typedef uint8_t nsHttpVersion;
 
 //-----------------------------------------------------------------------------
 // http connection capabilities
 //-----------------------------------------------------------------------------
 
 #define NS_HTTP_ALLOW_KEEPALIVE      (1<<0)
-#define NS_HTTP_ALLOW_PIPELINING     (1<<1)
+// NS_HTTP_ALLOW_PIPELINING          (1<<1) removed
 
 // a transaction with this caps flag will continue to own the connection,
 // preventing it from being reclaimed, even after the transaction completes.
 #define NS_HTTP_STICKY_CONNECTION    (1<<2)
 
 // a transaction with this caps flag will, upon opening a new connection,
 // bypass the local DNS cache
 #define NS_HTTP_REFRESH_DNS          (1<<3)
--- a/netwerk/protocol/http/nsHttpChannel.cpp
+++ b/netwerk/protocol/http/nsHttpChannel.cpp
@@ -793,62 +793,26 @@ nsHttpChannel::SetupTransactionRequestCo
 
     if (NS_FAILED(rv)) {
         return;
     }
 
     mTransaction->SetRequestContext(rc);
 }
 
-static bool
-SafeForPipelining(nsHttpRequestHead::ParsedMethodType method,
-                  const nsCString &methodString)
-{
-    if (method == nsHttpRequestHead::kMethod_Get ||
-        method == nsHttpRequestHead::kMethod_Head ||
-        method == nsHttpRequestHead::kMethod_Options) {
-        return true;
-    }
-
-    if (method != nsHttpRequestHead::kMethod_Custom) {
-        return false;
-    }
-
-    return (!strcmp(methodString.get(), "PROPFIND") ||
-            !strcmp(methodString.get(), "PROPPATCH"));
-}
-
 nsresult
 nsHttpChannel::SetupTransaction()
 {
     LOG(("nsHttpChannel::SetupTransaction [this=%p]\n", this));
 
     NS_ENSURE_TRUE(!mTransaction, NS_ERROR_ALREADY_INITIALIZED);
 
     nsresult rv;
 
     mUsedNetwork = 1;
-    if (mCaps & NS_HTTP_ALLOW_PIPELINING) {
-        //
-        // disable pipelining if:
-        //   (1) pipelining has been disabled by config
-        //   (2) pipelining has been disabled by connection mgr info
-        //   (3) request corresponds to a top-level document load (link click)
-        //   (4) request method is non-idempotent
-        //   (5) request is marked slow (e.g XHR)
-        //
-        nsAutoCString method;
-        mRequestHead.Method(method);
-        if (!mAllowPipelining ||
-           (mLoadFlags & (LOAD_INITIAL_DOCUMENT_URI | INHIBIT_PIPELINE)) ||
-            !SafeForPipelining(mRequestHead.ParsedMethod(), method)) {
-            LOG(("  pipelining disallowed\n"));
-            mCaps &= ~NS_HTTP_ALLOW_PIPELINING;
-        }
-    }
 
     if (!mAllowSpdy) {
         mCaps |= NS_HTTP_DISALLOW_SPDY;
     }
     if (mBeConservative) {
         mCaps |= NS_HTTP_BE_CONSERVATIVE;
     }
 
@@ -986,17 +950,16 @@ nsHttpChannel::SetupTransaction()
         mCaps |= NS_HTTP_TIMING_ENABLED;
 
     if (mUpgradeProtocolCallback) {
         mRequestHead.SetHeader(nsHttp::Upgrade, mUpgradeProtocol, false);
         mRequestHead.SetHeaderOnce(nsHttp::Connection,
                                    nsHttp::Upgrade.get(),
                                    true);
         mCaps |=  NS_HTTP_STICKY_CONNECTION;
-        mCaps &= ~NS_HTTP_ALLOW_PIPELINING;
         mCaps &= ~NS_HTTP_ALLOW_KEEPALIVE;
     }
 
     if (mPushedStream) {
         mTransaction->SetPushedStream(mPushedStream);
         mPushedStream = nullptr;
     }
 
@@ -1399,20 +1362,16 @@ nsHttpChannel::CallOnStartRequest()
         return rv;
       }
       if (listener) {
         mListener = listener;
         mCompressListener = listener;
       }
     }
 
-    rv = EnsureAssocReq();
-    if (NS_FAILED(rv))
-        return rv;
-
     // if this channel is for a download, close off access to the cache.
     if (mCacheEntry && mChannelIsForDownload) {
         mCacheEntry->AsyncDoom(nullptr);
 
         // We must keep the cache entry in case of partial request.
         // Concurrent access is the same, we need the entry in
         // OnStopRequest.
         if (!mCachedContentIsPartial && !mConcurrentCacheAccess)
@@ -2913,130 +2872,16 @@ nsHttpChannel::ResponseWouldVary(nsICach
 // to set a member function ptr to  a base class function.
 void
 nsHttpChannel::HandleAsyncAbort()
 {
     HttpAsyncAborter<nsHttpChannel>::HandleAsyncAbort();
 }
 
 
-nsresult
-nsHttpChannel::EnsureAssocReq()
-{
-    // Confirm Assoc-Req response header on pipelined transactions
-    // per draft-nottingham-http-pipeline-01.txt
-    // of the form: GET http://blah.com/foo/bar?qv
-    // return NS_OK as long as we don't find a violation
-    // (i.e. no header is ok, as are malformed headers, as are
-    // transactions that have not been pipelined (unless those have been
-    // opted in via pragma))
-
-    if (!mResponseHead)
-        return NS_OK;
-
-    nsAutoCString assoc_val;
-    if (NS_FAILED(mResponseHead->GetHeader(nsHttp::Assoc_Req, assoc_val))) {
-        return NS_OK;
-    }
-
-    if (!mTransaction || !mURI)
-        return NS_OK;
-
-    if (!mTransaction->PipelinePosition()) {
-        // "Pragma: X-Verify-Assoc-Req" can be used to verify even non pipelined
-        // transactions. It is used by test harness.
-
-        nsAutoCString pragma_val;
-        mResponseHead->GetHeader(nsHttp::Pragma, pragma_val);
-        if (pragma_val.IsEmpty() ||
-            !nsHttp::FindToken(pragma_val.get(), "X-Verify-Assoc-Req",
-                               HTTP_HEADER_VALUE_SEPS))
-            return NS_OK;
-    }
-
-    char *method = net_FindCharNotInSet(assoc_val.get(), HTTP_LWS);
-    if (!method)
-        return NS_OK;
-
-    bool equals;
-    char *endofmethod;
-
-    char * assoc_valChar = nullptr;
-    endofmethod = net_FindCharInSet(method, HTTP_LWS);
-    if (endofmethod)
-        assoc_valChar = net_FindCharNotInSet(endofmethod, HTTP_LWS);
-    if (!assoc_valChar)
-        return NS_OK;
-
-    // check the method
-    nsAutoCString methodHead;
-    mRequestHead.Method(methodHead);
-    if ((((int32_t)methodHead.Length()) != (endofmethod - method)) ||
-        PL_strncmp(method,
-                   methodHead.get(),
-                   endofmethod - method)) {
-        LOG(("  Assoc-Req failure Method %s", method));
-        if (mConnectionInfo)
-            gHttpHandler->ConnMgr()->
-                PipelineFeedbackInfo(mConnectionInfo,
-                                     nsHttpConnectionMgr::RedCorruptedContent,
-                                     nullptr, 0);
-
-        nsCOMPtr<nsIConsoleService> consoleService =
-            do_GetService(NS_CONSOLESERVICE_CONTRACTID);
-        if (consoleService) {
-            nsAutoString message
-                (NS_LITERAL_STRING("Failed Assoc-Req. Received "));
-            nsAutoCString assoc_req;
-            mResponseHead->GetHeader(nsHttp::Assoc_Req, assoc_req);
-            AppendASCIItoUTF16(assoc_req, message);
-            message += NS_LITERAL_STRING(" expected method ");
-            AppendASCIItoUTF16(methodHead, message);
-            consoleService->LogStringMessage(message.get());
-        }
-
-        if (gHttpHandler->EnforceAssocReq())
-            return NS_ERROR_CORRUPTED_CONTENT;
-        return NS_OK;
-    }
-
-    // check the URL
-    nsCOMPtr<nsIURI> assoc_url;
-    if (NS_FAILED(NS_NewURI(getter_AddRefs(assoc_url), assoc_valChar)) ||
-        !assoc_url)
-        return NS_OK;
-
-    mURI->Equals(assoc_url, &equals);
-    if (!equals) {
-        LOG(("  Assoc-Req failure URL %s", assoc_valChar));
-        if (mConnectionInfo)
-            gHttpHandler->ConnMgr()->
-                PipelineFeedbackInfo(mConnectionInfo,
-                                     nsHttpConnectionMgr::RedCorruptedContent,
-                                     nullptr, 0);
-
-        nsCOMPtr<nsIConsoleService> consoleService =
-            do_GetService(NS_CONSOLESERVICE_CONTRACTID);
-        if (consoleService) {
-            nsAutoString message
-                (NS_LITERAL_STRING("Failed Assoc-Req. Received "));
-            nsAutoCString assoc_req;
-            mResponseHead->GetHeader(nsHttp::Assoc_Req, assoc_req);
-            AppendASCIItoUTF16(assoc_req, message);
-            message += NS_LITERAL_STRING(" expected URL ");
-            AppendASCIItoUTF16(mSpec.get(), message);
-            consoleService->LogStringMessage(message.get());
-        }
-
-        if (gHttpHandler->EnforceAssocReq())
-            return NS_ERROR_CORRUPTED_CONTENT;
-    }
-    return NS_OK;
-}
-
 //-----------------------------------------------------------------------------
 // nsHttpChannel <byte-range>
 //-----------------------------------------------------------------------------
 
 bool
 nsHttpChannel::IsResumable(int64_t partialLen, int64_t contentLength,
                            bool ignoreMissingPartialLen) const
 {
@@ -3306,17 +3151,17 @@ nsHttpChannel::ProcessNotModified()
     MOZ_ASSERT(mCacheEntry);
     NS_ENSURE_TRUE(mCachedResponseHead && mCacheEntry, NS_ERROR_UNEXPECTED);
 
     // If the 304 response contains a Last-Modified different than the
     // one in our cache that is pretty suspicious and is, in at least the
     // case of bug 716840, a sign of the server having previously corrupted
     // our cache with a bad response. Take the minor step here of just dooming
     // that cache entry so there is a fighting chance of getting things on the
-    // right track as well as disabling pipelining for that host.
+    // right track.
 
     nsAutoCString lastModifiedCached;
     nsAutoCString lastModified304;
 
     rv = mCachedResponseHead->GetHeader(nsHttp::Last_Modified,
                                         lastModifiedCached);
     if (NS_SUCCEEDED(rv)) {
         rv = mResponseHead->GetHeader(nsHttp::Last_Modified,
@@ -3324,21 +3169,16 @@ nsHttpChannel::ProcessNotModified()
     }
 
     if (NS_SUCCEEDED(rv) && !lastModified304.Equals(lastModifiedCached)) {
         LOG(("Cache Entry and 304 Last-Modified Headers Do Not Match "
              "[%s] and [%s]\n",
              lastModifiedCached.get(), lastModified304.get()));
 
         mCacheEntry->AsyncDoom(nullptr);
-        if (mConnectionInfo)
-            gHttpHandler->ConnMgr()->
-                PipelineFeedbackInfo(mConnectionInfo,
-                                     nsHttpConnectionMgr::RedCorruptedContent,
-                                     nullptr, 0);
         Telemetry::Accumulate(Telemetry::CACHE_LM_INCONSISTENT, true);
     }
 
     // merge any new headers with the cached response headers
     rv = mCachedResponseHead->UpdateHeaders(mResponseHead);
     if (NS_FAILED(rv)) return rv;
 
     // update the cached response head
@@ -6144,23 +5984,16 @@ nsHttpChannel::BeginConnect()
         }
     }
 
     // If mTimingEnabled flag is not set after OnModifyRequest() then
     // clear the already recorded AsyncOpen value for consistency.
     if (!mTimingEnabled)
         mAsyncOpenTime = TimeStamp();
 
-    // when proxying only use the pipeline bit if ProxyPipelining() allows it.
-    if (!mConnectionInfo->UsingConnect() && mConnectionInfo->UsingHttpProxy()) {
-        mCaps &= ~NS_HTTP_ALLOW_PIPELINING;
-        if (gHttpHandler->ProxyPipelining())
-            mCaps |= NS_HTTP_ALLOW_PIPELINING;
-    }
-
     // if this somehow fails we can go on without it
     gHttpHandler->AddConnectionHeader(&mRequestHead, mCaps);
 
     if (mLoadFlags & VALIDATE_ALWAYS || BYPASS_LOCAL_CACHE(mLoadFlags))
         mCaps |= NS_HTTP_REFRESH_DNS;
 
     if (!mLocalBlocklist && !mConnectionInfo->UsingHttpProxy() &&
         !(mLoadFlags & (LOAD_NO_NETWORK_IO | LOAD_ONLY_FROM_CACHE))) {
@@ -6182,17 +6015,17 @@ nsHttpChannel::BeginConnect()
         mDNSPrefetch = new nsDNSPrefetch(mURI, this, mTimingEnabled);
         mDNSPrefetch->PrefetchHigh(mCaps & NS_HTTP_REFRESH_DNS);
     }
 
     // Adjust mCaps according to our request headers:
     //  - If "Connection: close" is set as a request header, then do not bother
     //    trying to establish a keep-alive connection.
     if (mRequestHead.HasHeaderValue(nsHttp::Connection, "close"))
-        mCaps &= ~(NS_HTTP_ALLOW_KEEPALIVE | NS_HTTP_ALLOW_PIPELINING);
+        mCaps &= ~(NS_HTTP_ALLOW_KEEPALIVE);
 
     if (gHttpHandler->CriticalRequestPrioritization()) {
         if (mClassOfService & nsIClassOfService::Leader) {
             mCaps |= NS_HTTP_LOAD_AS_BLOCKING;
         }
         if (mClassOfService & nsIClassOfService::Unblocked) {
             mCaps |= NS_HTTP_LOAD_UNBLOCKED;
         }
@@ -6200,17 +6033,16 @@ nsHttpChannel::BeginConnect()
 
     // Force-Reload should reset the persistent connection pool for this host
     if (mLoadFlags & LOAD_FRESH_CONNECTION) {
         // just the initial document resets the whole pool
         if (mLoadFlags & LOAD_INITIAL_DOCUMENT_URI) {
             gHttpHandler->ConnMgr()->ClearAltServiceMappings();
             gHttpHandler->ConnMgr()->DoShiftReloadConnectionCleanup(mConnectionInfo);
         }
-        mCaps &= ~NS_HTTP_ALLOW_PIPELINING;
     }
 
     // We may have been cancelled already, either by on-modify-request
     // listeners or load group observers; in that case, we should not send the
     // request to the server
     if (mCanceled) {
         return mStatus;
     }
@@ -6872,24 +6704,16 @@ nsHttpChannel::OnStopRequest(nsIRequest 
             LOG(("  transaction %p provides connection %p", mTransaction.get(), conn.get()));
             // This is so far a workaround to fix leak when reusing unpersistent
             // connection for authentication retry. See bug 459620 comment 4
             // for details.
             if (conn && !conn->IsPersistent()) {
                 LOG(("  connection is not persistent, not reusing it"));
                 conn = nullptr;
             }
-            // We do not use a sticky connection in case of a nsHttpPipeline as
-            // well (see bug 1337826). This is a quick fix, because
-            // nsHttpPipeline is turned off by default.
-            RefPtr<nsAHttpTransaction> tranConn = do_QueryObject(conn);
-            if (tranConn && tranConn->QueryPipeline()) {
-                LOG(("Do not use this connection, it is a nsHttpPipeline."));
-                conn = nullptr;
-            }
         }
 
         RefPtr<nsAHttpConnection> stickyConn;
         if (mCaps & NS_HTTP_STICKY_CONNECTION) {
             stickyConn = mTransaction->GetConnectionReference();
         }
 
         mTransferSize = mTransaction->GetTransferSize();
@@ -7677,19 +7501,18 @@ nsHttpChannel::DoAuthRetry(nsAHttpConnec
 
     // rewind the upload stream
     if (mUploadStream) {
         nsCOMPtr<nsISeekableStream> seekable = do_QueryInterface(mUploadStream);
         if (seekable)
             seekable->Seek(nsISeekableStream::NS_SEEK_SET, 0);
     }
 
-    // set sticky connection flag and disable pipelining.
+    // set sticky connection flag
     mCaps |=  NS_HTTP_STICKY_CONNECTION;
-    mCaps &= ~NS_HTTP_ALLOW_PIPELINING;
 
     // and create a new one...
     rv = SetupTransaction();
     if (NS_FAILED(rv)) return rv;
 
     // transfer ownership of connection to transaction
     if (conn)
         mTransaction->SetConnection(conn);
--- a/netwerk/protocol/http/nsHttpConnection.cpp
+++ b/netwerk/protocol/http/nsHttpConnection.cpp
@@ -17,17 +17,16 @@
 #define TLS_EARLY_DATA_AVAILABLE_BUT_NOT_USED 1
 #define TLS_EARLY_DATA_AVAILABLE_AND_USED 2
 
 #include "ASpdySession.h"
 #include "mozilla/ChaosMode.h"
 #include "mozilla/Telemetry.h"
 #include "nsHttpConnection.h"
 #include "nsHttpHandler.h"
-#include "nsHttpPipeline.h"
 #include "nsHttpRequestHead.h"
 #include "nsHttpResponseHead.h"
 #include "nsIOService.h"
 #include "nsISocketTransport.h"
 #include "nsSocketTransportService2.h"
 #include "nsISSLSocketControl.h"
 #include "nsISupportsPriority.h"
 #include "nsPreloadedStream.h"
@@ -54,29 +53,27 @@ nsHttpConnection::nsHttpConnection()
     , mMaxBytesRead(0)
     , mTotalBytesRead(0)
     , mTotalBytesWritten(0)
     , mContentBytesWritten(0)
     , mConnectedTransport(false)
     , mKeepAlive(true) // assume to keep-alive by default
     , mKeepAliveMask(true)
     , mDontReuse(false)
-    , mSupportsPipelining(false) // assume low-grade server
     , mIsReused(false)
     , mCompletedProxyConnect(false)
     , mLastTransactionExpectedNoContent(false)
     , mIdleMonitoring(false)
     , mProxyConnectInProgress(false)
     , mExperienced(false)
     , mInSpdyTunnel(false)
     , mForcePlainText(false)
     , mTrafficStamp(false)
     , mHttp1xTransactionCount(0)
     , mRemainingConnectionUses(0xffffffff)
-    , mClassification(nsAHttpTransaction::CLASS_GENERAL)
     , mNPNComplete(false)
     , mSetupSSLCalled(false)
     , mUsingSpdyVersion(0)
     , mPriority(nsISupportsPriority::PRIORITY_NORMAL)
     , mReportedSpdy(false)
     , mEverUsedSpdy(false)
     , mLastHttpResponseVersion(NS_HTTP_VERSION_1_1)
     , mTransactionCaps(0)
@@ -136,18 +133,16 @@ nsHttpConnection::Init(nsHttpConnectionI
 {
     LOG(("nsHttpConnection::Init this=%p", this));
     NS_ENSURE_ARG_POINTER(info);
     NS_ENSURE_TRUE(!mConnInfo, NS_ERROR_ALREADY_INITIALIZED);
 
     mConnectedTransport = connectedTransport;
     mConnInfo = info;
     mLastWriteTime = mLastReadTime = PR_IntervalNow();
-    mSupportsPipelining =
-        gHttpHandler->ConnMgr()->SupportsPipelining(mConnInfo);
     mRtt = rtt;
     mMaxHangTime = PR_SecondsToInterval(maxHangTime);
 
     mSocketTransport = transport;
     mSocketIn = instream;
     mSocketOut = outstream;
 
     // See explanation for non-strictness of this operation in SetSecurityCallbacks.
@@ -273,17 +268,17 @@ nsHttpConnection::StartSpdy(uint8_t spdy
     }
 
     // Setting the connection as reused allows some transactions that fail
     // with NS_ERROR_NET_RESET to be restarted and SPDY uses that code
     // to handle clean rejections (such as those that arrived after
     // a server goaway was generated).
     mIsReused = true;
 
-    // If mTransaction is a pipeline object it might represent
+    // If mTransaction is a muxed object it might represent
     // several requests. If so, we need to unpack that and
     // pack them all into a new spdy session.
 
     nsTArray<RefPtr<nsAHttpTransaction> > list;
     nsresult rv = NS_OK;
     if (!mDid0RTTSpdy) {
         rv = TryTakeSubTransactions(list);
 
@@ -320,17 +315,16 @@ nsHttpConnection::StartSpdy(uint8_t spdy
 
     // Disable TCP Keepalives - use SPDY ping instead.
     rv = DisableTCPKeepalives();
     if (NS_FAILED(rv)) {
         LOG(("nsHttpConnection::StartSpdy [%p] DisableTCPKeepalives failed "
              "rv[0x%" PRIx32 "]", this, static_cast<uint32_t>(rv)));
     }
 
-    mSupportsPipelining = false; // don't use http/1 pipelines with spdy
     mIdleTimeout = gHttpHandler->SpdyTimeout();
 
     if (!mTLSFilter) {
         mTransaction = mSpdySession;
     } else {
         mTLSFilter->SetProxiedTransaction(mSpdySession);
     }
     if (mDontReuse) {
@@ -368,16 +362,23 @@ nsHttpConnection::EnsureNPNComplete(nsre
     if (!securityInfo) {
         goto npnComplete;
     }
 
     ssl = do_QueryInterface(securityInfo, &rv);
     if (NS_FAILED(rv))
         goto npnComplete;
 
+    if (!m0RTTChecked) {
+        // We reuse m0RTTChecked. We want to send this status only once.
+        mTransaction->OnTransportStatus(mSocketTransport,
+                                        NS_NET_STATUS_TLS_HANDSHAKE_STARTING,
+                                        0);
+    }
+
     rv = ssl->GetNegotiatedNPN(negotiatedNPN);
     if (!m0RTTChecked && (rv == NS_ERROR_NOT_CONNECTED) &&
         !mConnInfo->UsingProxy()) {
         // There is no ALPN info (yet!). We need to consider doing 0RTT. We
         // will do so if there is ALPN information from a previous session
         // (AlpnEarlySelection), we are using HTTP/1, and the request data can
         // be safely retried.
         m0RTTChecked = true;
@@ -513,16 +514,20 @@ nsHttpConnection::EnsureNPNComplete(nsre
         }
 
         Telemetry::Accumulate(Telemetry::SPDY_NPN_CONNECT, UsingSpdy());
     }
 
 npnComplete:
     LOG(("nsHttpConnection::EnsureNPNComplete [this=%p] setting complete to true", this));
     mNPNComplete = true;
+
+    mTransaction->OnTransportStatus(mSocketTransport,
+                                    NS_NET_STATUS_TLS_HANDSHAKE_ENDED,
+                                    0);
     if (mWaitingFor0RTTResponse) {
         // Didn't get 0RTT OK, back out of the "attempting 0RTT" state
         mWaitingFor0RTTResponse = false;
         LOG(("nsHttpConnection::EnsureNPNComplete [this=%p] 0rtt failed", this));
         if (NS_FAILED(mTransaction->Finish0RTT(true, negotiatedNPN != mEarlyNegotiatedALPN))) {
             mTransaction->Close(NS_ERROR_NET_RESET);
         }
         mContentBytesWritten0RTT = 0;
@@ -865,48 +870,34 @@ nsHttpConnection::DontReuse()
     mKeepAliveMask = false;
     mKeepAlive = false;
     mDontReuse = true;
     mIdleTimeout = 0;
     if (mSpdySession)
         mSpdySession->DontReuse();
 }
 
-// Checked by the Connection Manager before scheduling a pipelined transaction
-bool
-nsHttpConnection::SupportsPipelining()
-{
-    if (mTransaction &&
-        mTransaction->PipelineDepth() >= mRemainingConnectionUses) {
-        LOG(("nsHttpConnection::SupportsPipelining this=%p deny pipeline "
-             "because current depth %d exceeds max remaining uses %d\n",
-             this, mTransaction->PipelineDepth(), mRemainingConnectionUses));
-        return false;
-    }
-    return mSupportsPipelining && IsKeepAlive() && !mDontReuse;
-}
-
 bool
 nsHttpConnection::CanReuse()
 {
-    if (mDontReuse)
+    if (mDontReuse || !mRemainingConnectionUses) {
         return false;
+    }
 
-    if ((mTransaction ? mTransaction->PipelineDepth() : 0) >=
+    if ((mTransaction ? (mTransaction->IsDone() ? 0U : 1U) : 0U) >=
         mRemainingConnectionUses) {
         return false;
     }
 
     bool canReuse;
-
-    if (mSpdySession)
+    if (mSpdySession) {
         canReuse = mSpdySession->CanReuse();
-    else
+    } else {
         canReuse = IsKeepAlive();
-
+    }
     canReuse = canReuse && (IdleTime() < mIdleTimeout) && IsAlive();
 
     // An idle persistent connection should not have data waiting to be read
     // before a request is sent. Data here is likely a 408 timeout response
     // which we would deal with later on through the restart logic, but that
     // path is more expensive than just closing the socket now.
 
     uint64_t dataSize;
@@ -975,74 +966,16 @@ nsHttpConnection::IsAlive()
         LOG(("pretending socket is still alive to test restart logic\n"));
         alive = true;
     }
 #endif
 
     return alive;
 }
 
-bool
-nsHttpConnection::SupportsPipelining(nsHttpResponseHead *responseHead)
-{
-    // SPDY supports infinite parallelism, so no need to pipeline.
-    if (mUsingSpdyVersion)
-        return false;
-
-    // assuming connection is HTTP/1.1 with keep-alive enabled
-    if (mConnInfo->UsingHttpProxy() && !mConnInfo->UsingConnect()) {
-        // XXX check for bad proxy servers...
-        return true;
-    }
-
-    // check for bad origin servers
-    nsAutoCString val;
-    responseHead->GetHeader(nsHttp::Server, val);
-
-    // If there is no server header we will assume it should not be banned
-    // as facebook and some other prominent sites do this
-    if (val.IsEmpty())
-        return true;
-
-    // The blacklist is indexed by the first character. All of these servers are
-    // known to return their identifier as the first thing in the server string,
-    // so we can do a leading match.
-
-    static const char *bad_servers[26][6] = {
-        { nullptr }, { nullptr }, { nullptr }, { nullptr },                 // a - d
-        { "EFAServer/", nullptr },                                       // e
-        { nullptr }, { nullptr }, { nullptr }, { nullptr },                 // f - i
-        { nullptr }, { nullptr }, { nullptr },                             // j - l
-        { "Microsoft-IIS/4.", "Microsoft-IIS/5.", nullptr },             // m
-        { "Netscape-Enterprise/3.", "Netscape-Enterprise/4.",
-          "Netscape-Enterprise/5.", "Netscape-Enterprise/6.", nullptr }, // n
-        { nullptr }, { nullptr }, { nullptr }, { nullptr },                 // o - r
-        { nullptr }, { nullptr }, { nullptr }, { nullptr },                 // s - v
-        { "WebLogic 3.", "WebLogic 4.","WebLogic 5.", "WebLogic 6.",
-          "Winstone Servlet Engine v0.", nullptr },                      // w
-        { nullptr }, { nullptr }, { nullptr }                              // x - z
-    };
-
-    int index = val.get()[0] - 'A'; // the whole table begins with capital letters
-    if ((index >= 0) && (index <= 25))
-    {
-        for (int i = 0; bad_servers[index][i] != nullptr; i++) {
-            if (val.Equals(bad_servers[index][i])) {
-                LOG(("looks like this server does not support pipelining"));
-                gHttpHandler->ConnMgr()->PipelineFeedbackInfo(
-                    mConnInfo, nsHttpConnectionMgr::RedBannedServer, this , 0);
-                return false;
-            }
-        }
-    }
-
-    // ok, let's allow pipelining to this server
-    return true;
-}
-
 //----------------------------------------------------------------------------
 // nsHttpConnection::nsAHttpConnection compatible methods
 //----------------------------------------------------------------------------
 
 nsresult
 nsHttpConnection::OnHeadersAvailable(nsAHttpTransaction *trans,
                                      nsHttpRequestHead *requestHead,
                                      nsHttpResponseHead *responseHead,
@@ -1090,82 +1023,30 @@ nsHttpConnection::OnHeadersAvailable(nsA
 
         // timeouts that are not caused by persistent connection reuse should
         // not be retried for browser compatibility reasons. bug 907800. The
         // server driven close is implicit in the 408.
         explicitClose = true;
         explicitKeepAlive = false;
     }
 
-    // reset to default (the server may have changed since we last checked)
-    mSupportsPipelining = false;
-
     if ((responseHead->Version() < NS_HTTP_VERSION_1_1) ||
         (requestHead->Version() < NS_HTTP_VERSION_1_1)) {
         // HTTP/1.0 connections are by default NOT persistent
         if (explicitKeepAlive)
             mKeepAlive = true;
         else
             mKeepAlive = false;
-
-        // We need at least version 1.1 to use pipelines
-        gHttpHandler->ConnMgr()->PipelineFeedbackInfo(
-            mConnInfo, nsHttpConnectionMgr::RedVersionTooLow, this, 0);
     }
     else {
         // HTTP/1.1 connections are by default persistent
-        if (explicitClose) {
-            mKeepAlive = false;
-
-            // persistent connections are required for pipelining to work - if
-            // this close was not pre-announced then generate the negative
-            // BadExplicitClose feedback
-            if (mRemainingConnectionUses > 1)
-                gHttpHandler->ConnMgr()->PipelineFeedbackInfo(
-                    mConnInfo, nsHttpConnectionMgr::BadExplicitClose, this, 0);
-        }
-        else {
-            mKeepAlive = true;
-
-            // Do not support pipelining when we are establishing
-            // an SSL tunnel though an HTTP proxy. Pipelining support
-            // determination must be based on comunication with the
-            // target server in this case. See bug 422016 for futher
-            // details.
-            if (!mProxyConnectStream)
-              mSupportsPipelining = SupportsPipelining(responseHead);
-        }
+        mKeepAlive = !explicitClose;
     }
     mKeepAliveMask = mKeepAlive;
 
-    // Update the pipelining status in the connection info object
-    // and also read it back. It is possible the ci status is
-    // locked to false if pipelining has been banned on this ci due to
-    // some kind of observed flaky behavior
-    if (mSupportsPipelining) {
-        // report the pipelining-compatible header to the connection manager
-        // as positive feedback. This will undo 1 penalty point the host
-        // may have accumulated in the past.
-
-        gHttpHandler->ConnMgr()->PipelineFeedbackInfo(
-            mConnInfo, nsHttpConnectionMgr::NeutralExpectedOK, this, 0);
-
-        mSupportsPipelining =
-            gHttpHandler->ConnMgr()->SupportsPipelining(mConnInfo);
-    }
-
-    // If this connection is reserved for revalidations and we are
-    // receiving a document that failed revalidation then switch the
-    // classification to general to avoid pipelining more revalidations behind
-    // it.
-    if (mClassification == nsAHttpTransaction::CLASS_REVALIDATION &&
-        responseStatus != 304) {
-        mClassification = nsAHttpTransaction::CLASS_GENERAL;
-    }
-
     // if this connection is persistent, then the server may send a "Keep-Alive"
     // header specifying the maximum number of times the connection can be
     // reused as well as the maximum amount of time the connection can be idle
     // before the server will close it.  we ignore the max reuse count, because
     // a "keep-alive" connection is by definition capable of being reused, and
     // we only care about being able to reuse it once.  if a timeout is not
     // specified then we use our advertized timeout value.
     bool foundKeepAliveMax = false;
@@ -1381,77 +1262,17 @@ nsHttpConnection::ReadTimeoutTick(PRInte
             CloseTransaction(mTransaction, NS_ERROR_NET_TIMEOUT);
             return UINT32_MAX;
         }
         nextTickAfter = PR_IntervalToSeconds(mTransaction->ResponseTimeout()) -
                         PR_IntervalToSeconds(initialResponseDelta);
         nextTickAfter = std::max(nextTickAfter, 1U);
     }
 
-    if (!gHttpHandler->GetPipelineRescheduleOnTimeout())
-        return nextTickAfter;
-
-    PRIntervalTime delta = now - mLastReadTime;
-
-    // we replicate some of the checks both here and in OnSocketReadable() as
-    // they will be discovered under different conditions. The ones here
-    // will generally be discovered if we are totally hung and OSR does
-    // not get called at all, however OSR discovers them with lower latency
-    // if the issue is just very slow (but not stalled) reading.
-    //
-    // Right now we only take action if pipelining is involved, but this would
-    // be the place to add general read timeout handling if it is desired.
-
-    uint32_t pipelineDepth = mTransaction->PipelineDepth();
-    if (pipelineDepth > 1) {
-        // if we have pipelines outstanding (not just an idle connection)
-        // then get a fairly quick tick
-        nextTickAfter = 1;
-    }
-
-    if (delta >= gHttpHandler->GetPipelineRescheduleTimeout() &&
-        pipelineDepth > 1) {
-
-        // this just reschedules blocked transactions. no transaction
-        // is aborted completely.
-        LOG(("cancelling pipeline due to a %ums stall - depth %d\n",
-             PR_IntervalToMilliseconds(delta), pipelineDepth));
-
-        nsHttpPipeline *pipeline = mTransaction->QueryPipeline();
-        MOZ_ASSERT(pipeline, "pipelinedepth > 1 without pipeline");
-        // code this defensively for the moment and check for null in opt build
-        // This will reschedule blocked members of the pipeline, but the
-        // blocking transaction (i.e. response 0) will not be changed.
-        if (pipeline) {
-            pipeline->CancelPipeline(NS_ERROR_NET_TIMEOUT);
-            LOG(("Rescheduling the head of line blocked members of a pipeline "
-                 "because reschedule-timeout idle interval exceeded"));
-        }
-    }
-
-    if (delta < gHttpHandler->GetPipelineTimeout())
-        return nextTickAfter;
-
-    if (pipelineDepth <= 1 && !mTransaction->PipelinePosition())
-        return nextTickAfter;
-
-    // nothing has transpired on this pipelined socket for many
-    // seconds. Call that a total stall and close the transaction.
-    // There is a chance the transaction will be restarted again
-    // depending on its state.. that will come back araound
-    // without pipelining on, so this won't loop.
-
-    LOG(("canceling transaction stalled for %ums on a pipeline "
-         "of depth %d and scheduled originally at pos %d\n",
-         PR_IntervalToMilliseconds(delta),
-         pipelineDepth, mTransaction->PipelinePosition()));
-
-    // This will also close the connection
-    CloseTransaction(mTransaction, NS_ERROR_NET_TIMEOUT);
-    return UINT32_MAX;
+    return nextTickAfter;
 }
 
 void
 nsHttpConnection::UpdateTCPKeepalive(nsITimer *aTimer, void *aClosure)
 {
     MOZ_ASSERT(aTimer);
     MOZ_ASSERT(aClosure);
 
@@ -1931,59 +1752,18 @@ nsHttpConnection::OnSocketReadable()
     if (mKeepAliveMask && (delta >= mMaxHangTime)) {
         LOG(("max hang time exceeded!\n"));
         // give the handler a chance to create a new persistent connection to
         // this host if we've been busy for too long.
         mKeepAliveMask = false;
         gHttpHandler->ProcessPendingQ(mConnInfo);
     }
 
-    // Look for data being sent in bursts with large pauses. If the pauses
-    // are caused by server bottlenecks such as think-time, disk i/o, or
-    // cpu exhaustion (as opposed to network latency) then we generate negative
-    // pipelining feedback to prevent head of line problems
-
     // Reduce the estimate of the time since last read by up to 1 RTT to
     // accommodate exhausted sender TCP congestion windows or minor I/O delays.
-
-    if (delta > mRtt)
-        delta -= mRtt;
-    else
-        delta = 0;
-
-    static const PRIntervalTime k400ms  = PR_MillisecondsToInterval(400);
-
-    if (delta >= (mRtt + gHttpHandler->GetPipelineRescheduleTimeout())) {
-        LOG(("Read delta ms of %u causing slow read major "
-             "event and pipeline cancellation",
-             PR_IntervalToMilliseconds(delta)));
-
-        gHttpHandler->ConnMgr()->PipelineFeedbackInfo(
-            mConnInfo, nsHttpConnectionMgr::BadSlowReadMajor, this, 0);
-
-        if (gHttpHandler->GetPipelineRescheduleOnTimeout() &&
-            mTransaction->PipelineDepth() > 1) {
-            nsHttpPipeline *pipeline = mTransaction->QueryPipeline();
-            MOZ_ASSERT(pipeline, "pipelinedepth > 1 without pipeline");
-            // code this defensively for the moment and check for null
-            // This will reschedule blocked members of the pipeline, but the
-            // blocking transaction (i.e. response 0) will not be changed.
-            if (pipeline) {
-                pipeline->CancelPipeline(NS_ERROR_NET_TIMEOUT);
-                LOG(("Rescheduling the head of line blocked members of a "
-                     "pipeline because reschedule-timeout idle interval "
-                     "exceeded"));
-            }
-        }
-    }
-    else if (delta > k400ms) {
-        gHttpHandler->ConnMgr()->PipelineFeedbackInfo(
-            mConnInfo, nsHttpConnectionMgr::BadSlowReadMinor, this, 0);
-    }
-
     mLastReadTime = now;
 
     nsresult rv;
     uint32_t n;
     bool again = true;
 
     do {
         if (!mProxyConnectInProgress && !mNPNComplete) {
--- a/netwerk/protocol/http/nsHttpConnection.h
+++ b/netwerk/protocol/http/nsHttpConnection.h
@@ -77,17 +77,16 @@ public:
     nsresult Activate(nsAHttpTransaction *, uint32_t caps, int32_t pri);
 
     // Close the underlying socket transport.
     void Close(nsresult reason, bool aIsShutdown = false);
 
     //-------------------------------------------------------------------------
     // XXX document when these are ok to call
 
-    bool SupportsPipelining();
     bool IsKeepAlive()
     {
         return mUsingSpdyVersion || (mKeepAliveMask && mKeepAlive);
     }
     bool CanReuse();   // can this connection be reused?
     bool CanDirectlyActivate();
 
     // Returns time in seconds for how long connection can be reused.
@@ -172,22 +171,16 @@ public:
     // other connections.
     uint32_t  ReadTimeoutTick(PRIntervalTime now);
 
     // For Active and Idle connections, this will be called when
     // mTCPKeepaliveTransitionTimer fires, to check if the TCP keepalive config
     // should move from short-lived (fast-detect) to long-lived.
     static void UpdateTCPKeepalive(nsITimer *aTimer, void *aClosure);
 
-    nsAHttpTransaction::Classifier Classification() { return mClassification; }
-    void Classify(nsAHttpTransaction::Classifier newclass)
-    {
-        mClassification = newclass;
-    }
-
     // When the connection is active this is called every second
     void  ReadTimeoutTick();
 
     int64_t BytesWritten() { return mTotalBytesWritten; } // includes TLS
     int64_t ContentBytesWritten() { return mContentBytesWritten; }
 
     void    SetSecurityCallbacks(nsIInterfaceRequestor* aCallbacks);
     void    PrintDiagnostics(nsCString &log);
@@ -233,17 +226,16 @@ private:
     nsresult OnTransactionDone(nsresult reason);
     nsresult OnSocketWritable();
     nsresult OnSocketReadable();
 
     nsresult SetupProxyConnect();
 
     PRIntervalTime IdleTime();
     bool     IsAlive();
-    bool     SupportsPipelining(nsHttpResponseHead *);
 
     // Makes certain the SSL handshake is complete and NPN negotiation
     // has had a chance to happen
     bool     EnsureNPNComplete(nsresult &aOut0RTTWriteHandshakeValue,
                                uint32_t &aOut0RTTBytesWritten);
     void     SetupSSL();
 
     // Start the Spdy transaction handler when NPN indicates spdy/*
@@ -303,17 +295,16 @@ private:
     RefPtr<nsIAsyncInputStream>   mInputOverflow;
 
     PRIntervalTime                  mRtt;
 
     bool                            mConnectedTransport;
     bool                            mKeepAlive;
     bool                            mKeepAliveMask;
     bool                            mDontReuse;
-    bool                            mSupportsPipelining;
     bool                            mIsReused;
     bool                            mCompletedProxyConnect;
     bool                            mLastTransactionExpectedNoContent;
     bool                            mIdleMonitoring;
     bool                            mProxyConnectInProgress;
     bool                            mExperienced;
     bool                            mInSpdyTunnel;
     bool                            mForcePlainText;
@@ -326,18 +317,16 @@ private:
     // excludes spdy transactions.
     uint32_t                        mHttp1xTransactionCount;
 
     // Keep-Alive: max="mRemainingConnectionUses" provides the number of future
     // transactions (including the current one) that the server expects to allow
     // on this persistent connection.
     uint32_t                        mRemainingConnectionUses;
 
-    nsAHttpTransaction::Classifier  mClassification;
-
     // SPDY related
     bool                            mNPNComplete;
     bool                            mSetupSSLCalled;
 
     // version level in use, 0 if unused
     uint8_t                         mUsingSpdyVersion;
 
     RefPtr<ASpdySession>            mSpdySession;
--- a/netwerk/protocol/http/nsHttpConnectionMgr.cpp
+++ b/netwerk/protocol/http/nsHttpConnectionMgr.cpp
@@ -9,17 +9,16 @@
 // Log on level :5, instead of default :4.
 #undef LOG
 #define LOG(args) LOG5(args)
 #undef LOG_ENABLED
 #define LOG_ENABLED() LOG5_ENABLED()
 
 #include "nsHttpConnectionMgr.h"
 #include "nsHttpConnection.h"
-#include "nsHttpPipeline.h"
 #include "nsHttpHandler.h"
 #include "nsIHttpChannelInternal.h"
 #include "nsNetCID.h"
 #include "nsCOMPtr.h"
 #include "nsNetUtil.h"
 #include "mozilla/net/DNS.h"
 #include "nsISocketTransport.h"
 #include "nsISSLSocketControl.h"
@@ -118,31 +117,27 @@ nsHttpConnectionMgr::EnsureSocketThreadT
 
     return rv;
 }
 
 nsresult
 nsHttpConnectionMgr::Init(uint16_t maxConns,
                           uint16_t maxPersistConnsPerHost,
                           uint16_t maxPersistConnsPerProxy,
-                          uint16_t maxRequestDelay,
-                          uint16_t maxPipelinedRequests,
-                          uint16_t maxOptimisticPipelinedRequests)
+                          uint16_t maxRequestDelay)
 {
     LOG(("nsHttpConnectionMgr::Init\n"));
 
     {
         ReentrantMonitorAutoEnter mon(mReentrantMonitor);
 
         mMaxConns = maxConns;
         mMaxPersistConnsPerHost = maxPersistConnsPerHost;
         mMaxPersistConnsPerProxy = maxPersistConnsPerProxy;
         mMaxRequestDelay = maxRequestDelay;
-        mMaxPipelinedRequests = maxPipelinedRequests;
-        mMaxOptimisticPipelinedRequests = maxOptimisticPipelinedRequests;
 
         mIsShuttingDown = false;
     }
 
     return EnsureSocketThreadTarget();
 }
 
 class BoolWrapper : public ARefBase
@@ -933,123 +928,16 @@ nsHttpConnectionMgr::ProcessPendingQForE
     MOZ_ASSERT(PR_GetCurrentThread() == gSocketThread);
 
     nsConnectionEntry *ent = mCT.Get(ci->HashKey());
     if (ent)
         return ProcessPendingQForEntry(ent, false);
     return false;
 }
 
-bool
-nsHttpConnectionMgr::SupportsPipelining(nsHttpConnectionInfo *ci)
-{
-    MOZ_ASSERT(PR_GetCurrentThread() == gSocketThread);
-
-    nsConnectionEntry *ent = mCT.Get(ci->HashKey());
-    if (ent)
-        return ent->SupportsPipelining();
-    return false;
-}
-
-// nsHttpPipelineFeedback used to hold references across events
-
-class nsHttpPipelineFeedback : public ARefBase
-{
-public:
-    nsHttpPipelineFeedback(nsHttpConnectionInfo *ci,
-                           nsHttpConnectionMgr::PipelineFeedbackInfoType info,
-                           nsHttpConnection *conn, uint32_t data)
-        : mConnInfo(ci)
-        , mConn(conn)
-        , mInfo(info)
-        , mData(data)
-        {
-        }
-
-
-    RefPtr<nsHttpConnectionInfo> mConnInfo;
-    RefPtr<nsHttpConnection> mConn;
-    nsHttpConnectionMgr::PipelineFeedbackInfoType mInfo;
-    uint32_t mData;
-private:
-    ~nsHttpPipelineFeedback() {}
-    NS_INLINE_DECL_THREADSAFE_REFCOUNTING(nsHttpPipelineFeedback)
-};
-
-void
-nsHttpConnectionMgr::PipelineFeedbackInfo(nsHttpConnectionInfo *ci,
-                                          PipelineFeedbackInfoType info,
-                                          nsHttpConnection *conn,
-                                          uint32_t data)
-{
-    if (!ci)
-        return;
-
-    // Post this to the socket thread if we are not running there already
-    if (PR_GetCurrentThread() != gSocketThread) {
-        RefPtr<nsHttpPipelineFeedback> fb =
-            new nsHttpPipelineFeedback(ci, info, conn, data);
-        PostEvent(&nsHttpConnectionMgr::OnMsgProcessFeedback, 0, fb);
-        return;
-    }
-
-    nsConnectionEntry *ent = mCT.Get(ci->HashKey());
-    if (ent)
-        ent->OnPipelineFeedbackInfo(info, conn, data);
-}
-
-void
-nsHttpConnectionMgr::ReportFailedToProcess(nsIURI *uri)
-{
-    MOZ_ASSERT(uri);
-
-    nsAutoCString host;
-    int32_t port = -1;
-    nsAutoCString username;
-    bool usingSSL = false;
-    bool isHttp = false;
-
-    nsresult rv = uri->SchemeIs("https", &usingSSL);
-    if (NS_SUCCEEDED(rv) && usingSSL)
-        isHttp = true;
-    if (NS_SUCCEEDED(rv) && !isHttp)
-        rv = uri->SchemeIs("http", &isHttp);
-    if (NS_SUCCEEDED(rv))
-        rv = uri->GetAsciiHost(host);
-    if (NS_SUCCEEDED(rv))
-        rv = uri->GetPort(&port);
-    if (NS_SUCCEEDED(rv))
-        uri->GetUsername(username);
-    if (NS_FAILED(rv) || !isHttp || host.IsEmpty())
-        return;
-
-    // report the event for all the permutations of anonymous and
-    // private versions of this host
-    RefPtr<nsHttpConnectionInfo> ci =
-        new nsHttpConnectionInfo(host, port, EmptyCString(), username, nullptr,
-                                 OriginAttributes(), usingSSL);
-    ci->SetAnonymous(false);
-    ci->SetPrivate(false);
-    PipelineFeedbackInfo(ci, RedCorruptedContent, nullptr, 0);
-
-    ci = ci->Clone();
-    ci->SetAnonymous(false);
-    ci->SetPrivate(true);
-    PipelineFeedbackInfo(ci, RedCorruptedContent, nullptr, 0);
-
-    ci = ci->Clone();
-    ci->SetAnonymous(true);
-    ci->SetPrivate(false);
-    PipelineFeedbackInfo(ci, RedCorruptedContent, nullptr, 0);
-
-    ci = ci->Clone();
-    ci->SetAnonymous(true);
-    ci->SetPrivate(true);
-    PipelineFeedbackInfo(ci, RedCorruptedContent, nullptr, 0);
-}
 
 // we're at the active connection limit if any one of the following conditions is true:
 //  (1) at max-connections
 //  (2) keep-alive enabled and at max-persistent-connections-per-server/proxy
 //  (3) keep-alive disabled and at max-connections-per-server
 bool
 nsHttpConnectionMgr::AtActiveConnectionLimit(nsConnectionEntry *ent, uint32_t caps)
 {
@@ -1302,150 +1190,16 @@ nsHttpConnectionMgr::MakeNewConnection(n
         if (rv == NS_ERROR_NOT_AVAILABLE)
             rv = NS_ERROR_FAILURE;
         return rv;
     }
 
     return NS_OK;
 }
 
-bool
-nsHttpConnectionMgr::AddToShortestPipeline(nsConnectionEntry *ent,
-                                           nsHttpTransaction *trans,
-                                           nsHttpTransaction::Classifier classification,
-                                           uint16_t depthLimit)
-{
-    if (classification == nsAHttpTransaction::CLASS_SOLO)
-        return false;
-
-    uint32_t maxdepth = ent->MaxPipelineDepth(classification);
-    if (maxdepth == 0) {
-        ent->CreditPenalty();
-        maxdepth = ent->MaxPipelineDepth(classification);
-    }
-
-    if (ent->PipelineState() == PS_RED)
-        return false;
-
-    if (ent->PipelineState() == PS_YELLOW && ent->mYellowConnection)
-        return false;
-
-    // The maximum depth of a pipeline in yellow is 1 pipeline of
-    // depth 2 for entire CI. When that transaction completes successfully
-    // we transition to green and that expands the allowed depth
-    // to any number of pipelines of up to depth 4.  When a transaction
-    // queued at position 3 or deeper succeeds we open it all the way
-    // up to depths limited only by configuration. The staggered start
-    // in green is simply because a successful yellow test of depth=2
-    // might really just be a race condition (i.e. depth=1 from the
-    // server's point of view), while depth=3 is a stronger indicator -
-    // keeping the pipelines to a modest depth during that period limits
-    // the damage if something is going to go wrong.
-
-    maxdepth = std::min<uint32_t>(maxdepth, depthLimit);
-
-    if (maxdepth < 2)
-        return false;
-
-    nsAHttpTransaction *activeTrans;
-
-    nsHttpConnection *bestConn = nullptr;
-    uint32_t activeCount = ent->mActiveConns.Length();
-    uint32_t bestConnLength = 0;
-    uint32_t connLength;
-
-    for (uint32_t i = 0; i < activeCount; ++i) {
-        nsHttpConnection *conn = ent->mActiveConns[i];
-        if (!conn->SupportsPipelining())
-            continue;
-
-        if (conn->Classification() != classification)
-            continue;
-
-        activeTrans = conn->Transaction();
-        if (!activeTrans ||
-            activeTrans->IsDone() ||
-            NS_FAILED(activeTrans->Status()))
-            continue;
-
-        connLength = activeTrans->PipelineDepth();
-
-        if (maxdepth <= connLength)
-            continue;
-
-        if (!bestConn || (connLength < bestConnLength)) {
-            bestConn = conn;
-            bestConnLength = connLength;
-        }
-    }
-
-    if (!bestConn)
-        return false;
-
-    activeTrans = bestConn->Transaction();
-    nsresult rv = activeTrans->AddTransaction(trans);
-    if (NS_FAILED(rv))
-        return false;
-
-    LOG(("   scheduling trans %p on pipeline at position %d\n",
-         trans, trans->PipelinePosition()));
-
-    if ((ent->PipelineState() == PS_YELLOW) && (trans->PipelinePosition() > 1))
-        ent->SetYellowConnection(bestConn);
-
-    if (!trans->GetPendingTime().IsNull()) {
-        if (trans->UsesPipelining())
-            AccumulateTimeDelta(
-                Telemetry::TRANSACTION_WAIT_TIME_HTTP_PIPELINES,
-                trans->GetPendingTime(), TimeStamp::Now());
-        else
-            AccumulateTimeDelta(
-                Telemetry::TRANSACTION_WAIT_TIME_HTTP,
-                trans->GetPendingTime(), TimeStamp::Now());
-        trans->SetPendingTime(false);
-    }
-    return true;
-}
-
-bool
-nsHttpConnectionMgr::IsUnderPressure(nsConnectionEntry *ent,
-                                   nsHttpTransaction::Classifier classification)
-{
-    // A connection entry is declared to be "under pressure" if most of the
-    // allowed parallel connections are already used up. In that case we want to
-    // favor existing pipelines over more parallelism so as to reserve any
-    // unused parallel connections for types that don't have existing pipelines.
-    //
-    // The definition of connection pressure is a pretty liberal one here - that
-    // is why we are using the more restrictive maxPersist* counters.
-    //
-    // Pipelines are also favored when the requested classification is already
-    // using 3 or more of the connections. Failure to do this could result in
-    // one class (e.g. images) establishing self replenishing queues on all the
-    // connections that would starve the other transaction types.
-
-    int32_t currentConns = ent->mActiveConns.Length();
-    int32_t maxConns =
-        (ent->mConnInfo->UsingHttpProxy() && !ent->mConnInfo->UsingConnect()) ?
-        mMaxPersistConnsPerProxy : mMaxPersistConnsPerHost;
-
-    // Leave room for at least 3 distinct types to operate concurrently,
-    // this satisfies the typical {html, js/css, img} page.
-    if (currentConns >= (maxConns - 2))
-        return true;                           /* prefer pipeline */
-
-    int32_t sameClass = 0;
-    for (int32_t i = 0; i < currentConns; ++i)
-        if (classification == ent->mActiveConns[i]->Classification())
-            if (++sameClass == 3)
-                return true;                   /* prefer pipeline */
-
-    return false;                              /* normal behavior */
-}
-
 // returns OK if a connection is found for the transaction
 //   and the transaction is started.
 // returns ERROR_NOT_AVAILABLE if no connection can be found and it
 //   should be queued until circumstances change
 // returns other ERROR when transaction has a hard failure and should
 //   not remain in the pending queue
 nsresult
 nsHttpConnectionMgr::TryDispatchTransaction(nsConnectionEntry *ent,
@@ -1456,38 +1210,32 @@ nsHttpConnectionMgr::TryDispatchTransact
     LOG(("nsHttpConnectionMgr::TryDispatchTransaction without conn "
          "[trans=%p ci=%p ci=%s caps=%x tunnelprovider=%p onlyreused=%d "
          "active=%" PRIuSIZE " idle=%" PRIuSIZE "]\n", trans,
          ent->mConnInfo.get(), ent->mConnInfo->HashKey().get(),
          uint32_t(trans->Caps()), trans->TunnelProvider(),
          onlyReusedConnection, ent->mActiveConns.Length(),
          ent->mIdleConns.Length()));
 
-    nsHttpTransaction::Classifier classification = trans->Classification();
     uint32_t caps = trans->Caps();
 
-    // no keep-alive means no pipelines either
-    if (!(caps & NS_HTTP_ALLOW_KEEPALIVE))
-        caps = caps & ~NS_HTTP_ALLOW_PIPELINING;
-
     // 0 - If this should use spdy then dispatch it post haste.
     // 1 - If there is connection pressure then see if we can pipeline this on
     //     a connection of a matching type instead of using a new conn
     // 2 - If there is an idle connection, use it!
     // 3 - if class == reval or script and there is an open conn of that type
     //     then pipeline onto shortest pipeline of that class if limits allow
     // 4 - If we aren't up against our connection limit,
     //     then open a new one
     // 5 - Try a pipeline if we haven't already - this will be unusual because
     //     it implies a low connection pressure situation where
     //     MakeNewConnection() failed.. that is possible, but unlikely, due to
     //     global limits
     // 6 - no connection is available - queue it
 
-    bool attemptedOptimisticPipeline = !(caps & NS_HTTP_ALLOW_PIPELINING);
     RefPtr<nsHttpConnection> unusedSpdyPersistentConnection;
 
     // step 0
     // look for existing spdy connection - that's always best because it is
     // essentially pipelining without head of line blocking
 
     if (!(caps & NS_HTTP_DISALLOW_SPDY) && gHttpHandler->IsSpdyEnabled()) {
         RefPtr<nsHttpConnection> conn = GetSpdyPreferredConn(ent);
@@ -1523,25 +1271,17 @@ nsHttpConnectionMgr::TryDispatchTransact
     } else {
         // Mark the transaction and its load group as blocking right now to prevent
         // other transactions from being reordered in the queue due to slow syns.
         trans->DispatchedAsBlocking();
     }
 
     // step 1
     // If connection pressure, then we want to favor pipelining of any kind
-    if (IsUnderPressure(ent, classification) && !attemptedOptimisticPipeline) {
-        attemptedOptimisticPipeline = true;
-        if (AddToShortestPipeline(ent, trans,
-                                  classification,
-                                  mMaxOptimisticPipelinedRequests)) {
-            LOG(("   dispatched step 1 trans=%p\n", trans));
-            return NS_OK;
-        }
-    }
+    // h1 pipelining has been removed
 
     // Subject most transactions at high parallelism to rate pacing.
     // It will only be actually submitted to the
     // token bucket once, and if possible it is granted admission synchronously.
     // It is important to leave a transaction in the pending queue when blocked by
     // pacing so it can be found on cancel if necessary.
     // Transactions that cause blocking or bypass it (e.g. js/css) are not rate
     // limited.
@@ -1595,28 +1335,17 @@ nsHttpConnectionMgr::TryDispatchTransact
             DispatchTransaction(ent, trans, conn);
             LOG(("   dispatched step 2 (idle) trans=%p\n", trans));
             return NS_OK;
         }
     }
 
     // step 3
     // consider pipelining scripts and revalidations
-    if (!attemptedOptimisticPipeline &&
-        (classification == nsHttpTransaction::CLASS_REVALIDATION ||
-         classification == nsHttpTransaction::CLASS_SCRIPT)) {
-        // Assignation kept here for documentation purpose; Never read after
-        attemptedOptimisticPipeline = true;
-        if (AddToShortestPipeline(ent, trans,
-                                  classification,
-                                  mMaxOptimisticPipelinedRequests)) {
-            LOG(("   dispatched step 3 (pipeline) trans=%p\n", trans));
-            return NS_OK;
-        }
-    }
+    // h1 pipelining has been removed
 
     // step 4
     if (!onlyReusedConnection) {
         nsresult rv = MakeNewConnection(ent, trans);
         if (NS_SUCCEEDED(rv)) {
             // this function returns NOT_AVAILABLE for asynchronous connects
             LOG(("   dispatched step 4 (async new conn) trans=%p\n", trans));
             return NS_ERROR_NOT_AVAILABLE;
@@ -1631,24 +1360,17 @@ nsHttpConnectionMgr::TryDispatchTransact
         }
     } else if (trans->TunnelProvider() && trans->TunnelProvider()->MaybeReTunnel(trans)) {
         LOG(("   sort of dispatched step 4a tunnel requeue trans=%p\n", trans));
         // the tunnel provider took responsibility for making a new tunnel
         return NS_OK;
     }
 
     // step 5
-    if (caps & NS_HTTP_ALLOW_PIPELINING) {
-        if (AddToShortestPipeline(ent, trans,
-                                  classification,
-                                  mMaxPipelinedRequests)) {
-            LOG(("   dispatched step 5 trans=%p\n", trans));
-            return NS_OK;
-        }
-    }
+    // previously pipelined anything here if allowed but h1 pipelining has been removed
 
     // step 6
     if (unusedSpdyPersistentConnection) {
         // to avoid deadlocks, we need to throw away this perfectly valid SPDY
         // connection to make room for a new one that can service a no KEEPALIVE
         // request
         unusedSpdyPersistentConnection->DontReuse();
     }
@@ -1667,17 +1389,17 @@ nsHttpConnectionMgr::DispatchTransaction
     nsresult rv;
 
     LOG(("nsHttpConnectionMgr::DispatchTransaction "
          "[ent-ci=%s %p trans=%p caps=%x conn=%p priority=%d]\n",
          ent->mConnInfo->HashKey().get(), ent, trans, caps, conn, priority));
 
     // It is possible for a rate-paced transaction to be dispatched independent
     // of the token bucket when the amount of parallelization has changed or
-    // when a muxed connection (e.g. spdy or pipelines) becomes available.
+    // when a muxed connection (e.g. h2) becomes available.
     trans->CancelPacing(NS_OK);
 
     if (conn->UsingSpdy()) {
         LOG(("Spdy Dispatch Transaction via Activate(). Transaction host = %s, "
              "Connection host = %s\n",
              trans->ConnectionInfo()->Origin(),
              conn->ConnectionInfo()->Origin()));
         rv = conn->Activate(trans, caps, priority);
@@ -1688,41 +1410,32 @@ nsHttpConnectionMgr::DispatchTransaction
             trans->SetPendingTime(false);
         }
         return rv;
     }
 
     MOZ_ASSERT(conn && !conn->Transaction(),
                "DispatchTranaction() on non spdy active connection");
 
-    if (!(caps & NS_HTTP_ALLOW_PIPELINING))
-        conn->Classify(nsAHttpTransaction::CLASS_SOLO);
-    else
-        conn->Classify(trans->Classification());
-
     rv = DispatchAbstractTransaction(ent, trans, caps, conn, priority);
 
     if (NS_SUCCEEDED(rv) && !trans->GetPendingTime().IsNull()) {
-        if (trans->UsesPipelining())
-            AccumulateTimeDelta(Telemetry::TRANSACTION_WAIT_TIME_HTTP_PIPELINES,
-                trans->GetPendingTime(), TimeStamp::Now());
-        else
-            AccumulateTimeDelta(Telemetry::TRANSACTION_WAIT_TIME_HTTP,
-                trans->GetPendingTime(), TimeStamp::Now());
+        AccumulateTimeDelta(Telemetry::TRANSACTION_WAIT_TIME_HTTP,
+                            trans->GetPendingTime(), TimeStamp::Now());
         trans->SetPendingTime(false);
     }
     return rv;
 }
 
 //-----------------------------------------------------------------------------
 // ConnectionHandle
 //
 // thin wrapper around a real connection, used to keep track of references
 // to the connection to determine when the connection may be reused.  the
-// transaction (or pipeline) owns a reference to this handle.  this extra
+// transaction owns a reference to this handle.  this extra
 // layer of indirection greatly simplifies consumer code, avoiding the
 // need for consumer code to know when to give the connection back to the
 // connection manager.
 //
 class ConnectionHandle : public nsAHttpConnection
 {
 public:
     NS_DECL_THREADSAFE_ISUPPORTS
@@ -1756,90 +1469,45 @@ NS_IMPL_ISUPPORTS0(ConnectionHandle)
 // concrete nsHttpTransaction
 nsresult
 nsHttpConnectionMgr::DispatchAbstractTransaction(nsConnectionEntry *ent,
                                                  nsAHttpTransaction *aTrans,
                                                  uint32_t caps,
                                                  nsHttpConnection *conn,
                                                  int32_t priority)
 {
+    nsresult rv;
     MOZ_ASSERT(!conn->UsingSpdy(),
                "Spdy Must Not Use DispatchAbstractTransaction");
     LOG(("nsHttpConnectionMgr::DispatchAbstractTransaction "
          "[ci=%s trans=%p caps=%x conn=%p]\n",
          ent->mConnInfo->HashKey().get(), aTrans, caps, conn));
 
-    /* Use pipeline datastructure even if connection does not currently qualify
-       to pipeline this transaction because a different pipeline-eligible
-       transaction might be placed on the active connection. Make an exception
-       for CLASS_SOLO as that connection will never pipeline until it goes
-       quiescent */
-
-    RefPtr<nsAHttpTransaction> transaction;
-    nsresult rv;
-    if (conn->Classification() != nsAHttpTransaction::CLASS_SOLO) {
-        LOG(("   using pipeline datastructure.\n"));
-        RefPtr<nsHttpPipeline> pipeline;
-        rv = BuildPipeline(ent, aTrans, getter_AddRefs(pipeline));
-        if (!NS_SUCCEEDED(rv))
-            return rv;
-        transaction = pipeline;
-    }
-    else {
-        LOG(("   not using pipeline datastructure due to class solo.\n"));
-        transaction = aTrans;
-    }
-
+    RefPtr<nsAHttpTransaction> transaction(aTrans);
     RefPtr<ConnectionHandle> handle = new ConnectionHandle(conn);
 
     // give the transaction the indirect reference to the connection.
     transaction->SetConnection(handle);
 
     rv = conn->Activate(transaction, caps, priority);
     if (NS_FAILED(rv)) {
       LOG(("  conn->Activate failed [rv=%" PRIx32 "]\n", static_cast<uint32_t>(rv)));
         ent->mActiveConns.RemoveElement(conn);
-        if (conn == ent->mYellowConnection)
-            ent->OnYellowComplete();
         DecrementActiveConnCount(conn);
         ConditionallyStopTimeoutTick();
 
         // sever back references to connection, and do so without triggering
         // a call to ReclaimConnection ;-)
         transaction->SetConnection(nullptr);
         handle->Reset(); // destroy the connection
     }
 
-    // As transaction goes out of scope it will drop the last refernece to the
-    // pipeline if activation failed, in which case this will destroy
-    // the pipeline, which will cause each the transactions owned by the
-    // pipeline to be restarted.
-
     return rv;
 }
 
-nsresult
-nsHttpConnectionMgr::BuildPipeline(nsConnectionEntry *ent,
-                                   nsAHttpTransaction *firstTrans,
-                                   nsHttpPipeline **result)
-{
-    MOZ_ASSERT(PR_GetCurrentThread() == gSocketThread);
-
-    /* form a pipeline here even if nothing is pending so that we
-       can stream-feed it as new transactions arrive */
-
-    /* the first transaction can go in unconditionally - 1 transaction
-       on a nsHttpPipeline object is not a real HTTP pipeline */
-
-    RefPtr<nsHttpPipeline> pipeline = new nsHttpPipeline();
-    pipeline->AddTransaction(firstTrans);
-    pipeline.forget(result);
-    return NS_OK;
-}
-
 void
 nsHttpConnectionMgr::ReportProxyTelemetry(nsConnectionEntry *ent)
 {
     enum { PROXY_NONE = 1, PROXY_HTTP = 2, PROXY_SOCKS = 3, PROXY_HTTPS = 4 };
 
     if (!ent->mConnInfo->UsingProxy())
         Telemetry::Accumulate(Telemetry::HTTP_PROXY_TYPE, PROXY_NONE);
     else if (ent->mConnInfo->UsingHttpsProxy())
@@ -2438,21 +2106,19 @@ nsHttpConnectionMgr::OnMsgPruneDeadConne
                 // happen after timeToNextExpire.
                 if (!mTimer || timeOfNextExpire < mTimeOfNextWakeUp) {
                     PruneDeadConnectionsAfter(timeToNextExpire);
                 }
             } else {
                 ConditionallyStopPruneDeadConnectionsTimer();
             }
 
-            // If this entry is empty, we have too many entries, and this
-            // doesn't represent some painfully determined red condition, then
-            // we can clean it up and restart from yellow.
-            if (ent->PipelineState()       != PS_RED &&
-                mCT.Count()                >  125 &&
+            // If this entry is empty, we have too many entries busy then
+            // we can clean it up and restart
+            if (mCT.Count()                >  125 &&
                 ent->mIdleConns.Length()   == 0 &&
                 ent->mActiveConns.Length() == 0 &&
                 ent->mHalfOpens.Length()   == 0 &&
                 ent->mPendingQ.Length()    == 0 &&
                 (!ent->mUsingSpdy || mCT.Count() > 300)) {
                 LOG(("    removing empty connection entry\n"));
                 iter.Remove();
                 continue;
@@ -2606,19 +2272,16 @@ nsHttpConnectionMgr::OnMsgReclaimConnect
     // a connection that still holds a reference to a transaction was
     // not closed naturally (i.e. it was reset or aborted) and is
     // therefore not something that should be reused.
     if (conn->Transaction()) {
         conn->DontReuse();
     }
 
     if (ent->mActiveConns.RemoveElement(conn)) {
-        if (conn == ent->mYellowConnection) {
-            ent->OnYellowComplete();
-        }
         DecrementActiveConnCount(conn);
         ConditionallyStopTimeoutTick();
     }
 
     if (conn->CanReuse()) {
         LOG(("  adding connection to idle list\n"));
         // Keep The idle connection list sorted with the connections that
         // have moved the largest data pipelines at the front because these
@@ -2691,42 +2354,28 @@ nsHttpConnectionMgr::OnMsgUpdateParam(in
         mMaxPersistConnsPerHost = value;
         break;
     case MAX_PERSISTENT_CONNECTIONS_PER_PROXY:
         mMaxPersistConnsPerProxy = value;
         break;
     case MAX_REQUEST_DELAY:
         mMaxRequestDelay = value;
         break;
-    case MAX_PIPELINED_REQUESTS:
-        mMaxPipelinedRequests = value;
-        break;
-    case MAX_OPTIMISTIC_PIPELINED_REQUESTS:
-        mMaxOptimisticPipelinedRequests = value;
-        break;
     default:
         NS_NOTREACHED("unexpected parameter name");
     }
 }
 
 // nsHttpConnectionMgr::nsConnectionEntry
 nsHttpConnectionMgr::nsConnectionEntry::~nsConnectionEntry()
 {
     MOZ_COUNT_DTOR(nsConnectionEntry);
     gHttpHandler->ConnMgr()->RemovePreferredHash(this);
 }
 
-void
-nsHttpConnectionMgr::OnMsgProcessFeedback(int32_t, ARefBase *param)
-{
-    MOZ_ASSERT(PR_GetCurrentThread() == gSocketThread);
-    nsHttpPipelineFeedback *fb = static_cast<nsHttpPipelineFeedback *>(param);
-    PipelineFeedbackInfo(fb->mConnInfo, fb->mInfo, fb->mConn, fb->mData);
-}
-
 // Read Timeout Tick handlers
 
 void
 nsHttpConnectionMgr::ActivateTimeoutTick()
 {
     MOZ_ASSERT(PR_GetCurrentThread() == gSocketThread);
     LOG(("nsHttpConnectionMgr::ActivateTimeoutTick() "
          "this=%p mTimeoutTick=%p\n", this, mTimeoutTick.get()));
@@ -3405,22 +3054,20 @@ nsHalfOpenSocket::OnOutputStreamReady(ns
             RefPtr<nsAHttpTransaction> trans;
             if (mTransaction->IsNullTransaction() && !mDispatchedMTransaction) {
                 // null transactions cannot be put in the entry queue, so that
                 // explains why it is not present.
                 mDispatchedMTransaction = true;
                 trans = mTransaction;
             } else {
                 trans = new NullHttpTransaction(mEnt->mConnInfo,
-                                                callbacks,
-                                                mCaps & ~NS_HTTP_ALLOW_PIPELINING);
+                                                callbacks, mCaps);
             }
 
             gHttpHandler->ConnMgr()->AddActiveConn(conn, mEnt);
-            conn->Classify(nsAHttpTransaction::CLASS_SOLO);
             rv = gHttpHandler->ConnMgr()->
                 DispatchAbstractTransaction(mEnt, trans, mCaps, conn, 0);
         } else {
             // otherwise just put this in the persistent connection pool
             LOG(("nsHalfOpenSocket::OnOutputStreamReady no transaction match "
                  "returning conn %p to pool\n", conn.get()));
             gHttpHandler->ConnMgr()->OnMsgReclaimConnection(0, conn);
         }
@@ -3540,304 +3187,43 @@ already_AddRefed<nsHttpConnection>
 ConnectionHandle::TakeHttpConnection()
 {
     // return our connection object to the caller and clear it internally
     // do not drop our reference - the caller now owns it.
     MOZ_ASSERT(mConn);
     return mConn.forget();
 }
 
-uint32_t
-ConnectionHandle::CancelPipeline(nsresult reason)
-{
-    // no pipeline to cancel
-    return 0;
-}
-
-nsAHttpTransaction::Classifier
-ConnectionHandle::Classification()
-{
-    if (mConn)
-        return mConn->Classification();
-
-    LOG(("ConnectionHandle::Classification this=%p "
-         "has null mConn using CLASS_SOLO default", this));
-    return nsAHttpTransaction::CLASS_SOLO;
-}
 
 // nsConnectionEntry
 
 nsHttpConnectionMgr::
 nsConnectionEntry::nsConnectionEntry(nsHttpConnectionInfo *ci)
     : mConnInfo(ci)
-    , mPipelineState(PS_YELLOW)
-    , mYellowGoodEvents(0)
-    , mYellowBadEvents(0)
-    , mYellowConnection(nullptr)
-    , mGreenDepth(kPipelineOpen)
-    , mPipeliningPenalty(0)
     , mUsingSpdy(false)
     , mInPreferredHash(false)
     , mPreferIPv4(false)
     , mPreferIPv6(false)
     , mUsedForConnection(false)
 {
     MOZ_COUNT_CTOR(nsConnectionEntry);
-    if (gHttpHandler->GetPipelineAggressive()) {
-        mGreenDepth = kPipelineUnlimited;
-        mPipelineState = PS_GREEN;
-    }
-    mInitialGreenDepth = mGreenDepth;
-    memset(mPipeliningClassPenalty, 0, sizeof(int16_t) * nsAHttpTransaction::CLASS_MAX);
 }
 
 bool
 nsHttpConnectionMgr::nsConnectionEntry::AvailableForDispatchNow()
 {
     if (mIdleConns.Length() && mIdleConns[0]->CanReuse()) {
         return true;
     }
 
     return gHttpHandler->ConnMgr()->
         GetSpdyPreferredConn(this) ? true : false;
 }
 
 bool
-nsHttpConnectionMgr::nsConnectionEntry::SupportsPipelining()
-{
-    return mPipelineState != nsHttpConnectionMgr::PS_RED;
-}
-
-nsHttpConnectionMgr::PipeliningState
-nsHttpConnectionMgr::nsConnectionEntry::PipelineState()
-{
-    return mPipelineState;
-}
-
-void
-nsHttpConnectionMgr::
-nsConnectionEntry::OnPipelineFeedbackInfo(
-    nsHttpConnectionMgr::PipelineFeedbackInfoType info,
-    nsHttpConnection *conn,
-    uint32_t data)
-{
-    MOZ_ASSERT(PR_GetCurrentThread() == gSocketThread);
-
-    if (mPipelineState == PS_YELLOW) {
-        if (info & kPipelineInfoTypeBad)
-            mYellowBadEvents++;
-        else if (info & (kPipelineInfoTypeNeutral | kPipelineInfoTypeGood))
-            mYellowGoodEvents++;
-    }
-
-    if (mPipelineState == PS_GREEN && info == GoodCompletedOK) {
-        int32_t depth = data;
-        LOG(("Transaction completed at pipeline depth of %d. Host = %s\n",
-             depth, mConnInfo->Origin()));
-
-        if (depth >= 3)
-            mGreenDepth = kPipelineUnlimited;
-    }
-
-    nsAHttpTransaction::Classifier classification;
-    if (conn)
-        classification = conn->Classification();
-    else if (info == BadInsufficientFraming ||
-             info == BadUnexpectedLarge)
-        classification = (nsAHttpTransaction::Classifier) data;
-    else
-        classification = nsAHttpTransaction::CLASS_SOLO;
-
-    if (gHttpHandler->GetPipelineAggressive() &&
-        info & kPipelineInfoTypeBad &&
-        info != BadExplicitClose &&
-        info != RedVersionTooLow &&
-        info != RedBannedServer &&
-        info != RedCorruptedContent &&
-        info != BadInsufficientFraming) {
-        LOG(("minor negative feedback ignored "
-             "because of pipeline aggressive mode"));
-    }
-    else if (info & kPipelineInfoTypeBad) {
-        if ((info & kPipelineInfoTypeRed) && (mPipelineState != PS_RED)) {
-            LOG(("transition to red from %d. Host = %s.\n",
-                 mPipelineState, mConnInfo->Origin()));
-            mPipelineState = PS_RED;
-            mPipeliningPenalty = 0;
-        }
-
-        if (mLastCreditTime.IsNull())
-            mLastCreditTime = TimeStamp::Now();
-
-        // Red* events impact the host globally via mPipeliningPenalty, while
-        // Bad* events impact the per class penalty.
-
-        // The individual penalties should be < 16bit-signed-maxint - 25000
-        // (approx 7500). Penalties are paid-off either when something promising
-        // happens (a successful transaction, or promising headers) or when
-        // time goes by at a rate of 1 penalty point every 16 seconds.
-
-        switch (info) {
-        case RedVersionTooLow:
-            mPipeliningPenalty += 1000;
-            break;
-        case RedBannedServer:
-            mPipeliningPenalty += 7000;
-            break;
-        case RedCorruptedContent:
-            mPipeliningPenalty += 7000;
-            break;
-        case RedCanceledPipeline:
-            mPipeliningPenalty += 60;
-            break;
-        case BadExplicitClose:
-            mPipeliningClassPenalty[classification] += 250;
-            break;
-        case BadSlowReadMinor:
-            mPipeliningClassPenalty[classification] += 5;
-            break;
-        case BadSlowReadMajor:
-            mPipeliningClassPenalty[classification] += 25;
-            break;
-        case BadInsufficientFraming:
-            mPipeliningClassPenalty[classification] += 7000;
-            break;
-        case BadUnexpectedLarge:
-            mPipeliningClassPenalty[classification] += 120;
-            break;
-
-        default:
-            MOZ_ASSERT(false, "Unknown Bad/Red Pipeline Feedback Event");
-        }
-
-        const int16_t kPenalty = 25000;
-        mPipeliningPenalty = std::min(mPipeliningPenalty, kPenalty);
-        mPipeliningClassPenalty[classification] =
-          std::min(mPipeliningClassPenalty[classification], kPenalty);
-
-        LOG(("Assessing red penalty to %s class %d for event %d. "
-             "Penalty now %d, throttle[%d] = %d\n", mConnInfo->Origin(),
-             classification, info, mPipeliningPenalty, classification,
-             mPipeliningClassPenalty[classification]));
-    }
-    else {
-        // hand out credits for neutral and good events such as
-        // "headers look ok" events
-
-        mPipeliningPenalty = std::max(mPipeliningPenalty - 1, 0);
-        mPipeliningClassPenalty[classification] = std::max(mPipeliningClassPenalty[classification] - 1, 0);
-    }
-
-    if (mPipelineState == PS_RED && !mPipeliningPenalty)
-    {
-        LOG(("transition %s to yellow\n", mConnInfo->Origin()));
-        mPipelineState = PS_YELLOW;
-        mYellowConnection = nullptr;
-    }
-}
-
-void
-nsHttpConnectionMgr::
-nsConnectionEntry::SetYellowConnection(nsHttpConnection *conn)
-{
-    MOZ_ASSERT(!mYellowConnection && mPipelineState == PS_YELLOW,
-               "yellow connection already set or state is not yellow");
-    mYellowConnection = conn;
-    mYellowGoodEvents = mYellowBadEvents = 0;
-}
-
-void
-nsHttpConnectionMgr::
-nsConnectionEntry::OnYellowComplete()
-{
-    if (mPipelineState == PS_YELLOW) {
-        if (mYellowGoodEvents && !mYellowBadEvents) {
-            LOG(("transition %s to green\n", mConnInfo->Origin()));
-            mPipelineState = PS_GREEN;
-            mGreenDepth = mInitialGreenDepth;
-        }
-        else {
-            // The purpose of the yellow state is to witness at least
-            // one successful pipelined transaction without seeing any
-            // kind of negative feedback before opening the flood gates.
-            // If we haven't confirmed that, then transfer back to red.
-            LOG(("transition %s to red from yellow return\n",
-                 mConnInfo->Origin()));
-            mPipelineState = PS_RED;
-        }
-    }
-
-    mYellowConnection = nullptr;
-}
-
-void
-nsHttpConnectionMgr::
-nsConnectionEntry::CreditPenalty()
-{
-    if (mLastCreditTime.IsNull())
-        return;
-
-    // Decrease penalty values by 1 for every 16 seconds
-    // (i.e 3.7 per minute, or 1000 every 4h20m)
-
-    TimeStamp now = TimeStamp::Now();
-    TimeDuration elapsedTime = now - mLastCreditTime;
-    uint32_t creditsEarned =
-        static_cast<uint32_t>(elapsedTime.ToSeconds()) >> 4;
-
-    bool failed = false;
-    if (creditsEarned > 0) {
-        mPipeliningPenalty =
-            std::max(int32_t(mPipeliningPenalty - creditsEarned), 0);
-        if (mPipeliningPenalty > 0)
-            failed = true;
-
-        for (int32_t i = 0; i < nsAHttpTransaction::CLASS_MAX; ++i) {
-            mPipeliningClassPenalty[i]  =
-                std::max(int32_t(mPipeliningClassPenalty[i] - creditsEarned), 0);
-            failed = failed || (mPipeliningClassPenalty[i] > 0);
-        }
-
-        // update last credit mark to reflect elapsed time
-        mLastCreditTime += TimeDuration::FromSeconds(creditsEarned << 4);
-    }
-    else {
-        failed = true;                         /* just assume this */
-    }
-
-    // If we are no longer red then clear the credit counter - you only
-    // get credits for time spent in the red state
-    if (!failed)
-        mLastCreditTime = TimeStamp();    /* reset to null timestamp */
-
-    if (mPipelineState == PS_RED && !mPipeliningPenalty)
-    {
-        LOG(("transition %s to yellow based on time credit\n",
-             mConnInfo->Origin()));
-        mPipelineState = PS_YELLOW;
-        mYellowConnection = nullptr;
-    }
-}
-
-uint32_t
-nsHttpConnectionMgr::
-nsConnectionEntry::MaxPipelineDepth(nsAHttpTransaction::Classifier aClass)
-{
-    // Still subject to configuration limit no matter return value
-
-    if ((mPipelineState == PS_RED) || (mPipeliningClassPenalty[aClass] > 0))
-        return 0;
-
-    if (mPipelineState == PS_YELLOW)
-        return kPipelineRestricted;
-
-    return mGreenDepth;
-}
-
-bool
 nsHttpConnectionMgr::GetConnectionData(nsTArray<HttpRetParams> *aArg)
 {
     for (auto iter = mCT.Iter(); !iter.Done(); iter.Next()) {
         nsAutoPtr<nsConnectionEntry>& ent = iter.Data();
 
         if (ent->mConnInfo->GetPrivate()) {
             continue;
         }
--- a/netwerk/protocol/http/nsHttpConnectionMgr.h
+++ b/netwerk/protocol/http/nsHttpConnectionMgr.h
@@ -43,33 +43,29 @@ public:
     NS_DECL_THREADSAFE_ISUPPORTS
     NS_DECL_NSIOBSERVER
 
     // parameter names
     enum nsParamName {
         MAX_CONNECTIONS,
         MAX_PERSISTENT_CONNECTIONS_PER_HOST,
         MAX_PERSISTENT_CONNECTIONS_PER_PROXY,
-        MAX_REQUEST_DELAY,
-        MAX_PIPELINED_REQUESTS,
-        MAX_OPTIMISTIC_PIPELINED_REQUESTS
+        MAX_REQUEST_DELAY
     };
 
     //-------------------------------------------------------------------------
     // NOTE: functions below may only be called on the main thread.
     //-------------------------------------------------------------------------
 
     nsHttpConnectionMgr();
 
     nsresult Init(uint16_t maxConnections,
                   uint16_t maxPersistentConnectionsPerHost,
                   uint16_t maxPersistentConnectionsPerProxy,
-                  uint16_t maxRequestDelay,
-                  uint16_t maxPipelinedRequests,
-                  uint16_t maxOptimisticPipelinedRequests);
+                  uint16_t maxRequestDelay);
     nsresult Shutdown();
 
     //-------------------------------------------------------------------------
     // NOTE: functions below may be called on any thread.
     //-------------------------------------------------------------------------
 
     // Schedules next pruning of dead connection to happen after
     // given time.
@@ -144,80 +140,16 @@ public:
 
     // called from main thread to post a new request token bucket
     // to the socket thread
     nsresult UpdateRequestTokenBucket(EventTokenBucket *aBucket);
 
     // clears the connection history mCT
     nsresult ClearConnectionHistory();
 
-    // Pipielining Interfaces and Datatypes
-
-    const static uint32_t kPipelineInfoTypeMask = 0xffff0000;
-    const static uint32_t kPipelineInfoIDMask   = ~kPipelineInfoTypeMask;
-
-    const static uint32_t kPipelineInfoTypeRed     = 0x00010000;
-    const static uint32_t kPipelineInfoTypeBad     = 0x00020000;
-    const static uint32_t kPipelineInfoTypeNeutral = 0x00040000;
-    const static uint32_t kPipelineInfoTypeGood    = 0x00080000;
-
-    enum PipelineFeedbackInfoType
-    {
-        // Used when an HTTP response less than 1.1 is received
-        RedVersionTooLow = kPipelineInfoTypeRed | kPipelineInfoTypeBad | 0x0001,
-
-        // Used when a HTTP Server response header that is on the banned from
-        // pipelining list is received
-        RedBannedServer = kPipelineInfoTypeRed | kPipelineInfoTypeBad | 0x0002,
-
-        // Used when a response is terminated early, when it fails an
-        // integrity check such as assoc-req or when a 304 contained a Last-Modified
-        // differnet than the entry being validated.
-        RedCorruptedContent = kPipelineInfoTypeRed | kPipelineInfoTypeBad | 0x0004,
-
-        // Used when a pipeline is only partly satisfied - for instance if the
-        // server closed the connection after responding to the first
-        // request but left some requests unprocessed.
-        RedCanceledPipeline = kPipelineInfoTypeRed | kPipelineInfoTypeBad | 0x0005,
-
-        // Used when a connection that we expected to stay persistently open
-        // was closed by the server. Not used when simply timed out.
-        BadExplicitClose = kPipelineInfoTypeBad | 0x0003,
-
-        // Used when there is a gap of around 400 - 1200ms in between data being
-        // read from the server
-        BadSlowReadMinor = kPipelineInfoTypeBad | 0x0006,
-
-        // Used when there is a gap of > 1200ms in between data being
-        // read from the server
-        BadSlowReadMajor = kPipelineInfoTypeBad | 0x0007,
-
-        // Used when a response is received that is not framed with either chunked
-        // encoding or a complete content length.
-        BadInsufficientFraming = kPipelineInfoTypeBad | 0x0008,
-
-        // Used when a very large response is recevied in a potential pipelining
-        // context. Large responses cause head of line blocking.
-        BadUnexpectedLarge = kPipelineInfoTypeBad | 0x000B,
-
-        // Used when a response is received that has headers that appear to support
-        // pipelining.
-        NeutralExpectedOK = kPipelineInfoTypeNeutral | 0x0009,
-
-        // Used when a response is received successfully to a pipelined request.
-        GoodCompletedOK = kPipelineInfoTypeGood | 0x000A
-    };
-
-    // called to provide information relevant to the pipelining manager
-    // may be called from any thread
-    void     PipelineFeedbackInfo(nsHttpConnectionInfo *,
-                                  PipelineFeedbackInfoType info,
-                                  nsHttpConnection *,
-                                  uint32_t);
-
     void ReportFailedToProcess(nsIURI *uri);
 
     // Causes a large amount of connection diagnostic information to be
     // printed to the javascript console
     void PrintDiagnostics();
 
     //-------------------------------------------------------------------------
     // NOTE: functions below may be called only on the socket thread.
@@ -242,47 +174,28 @@ public:
     // that the network peer has closed the transport.
     nsresult CloseIdleConnection(nsHttpConnection *);
 
     // The connection manager needs to know when a normal HTTP connection has been
     // upgraded to SPDY because the dispatch and idle semantics are a little
     // bit different.
     void ReportSpdyConnection(nsHttpConnection *, bool usingSpdy);
 
-    bool     SupportsPipelining(nsHttpConnectionInfo *);
-
     bool GetConnectionData(nsTArray<HttpRetParams> *);
 
     void ResetIPFamilyPreference(nsHttpConnectionInfo *);
 
     uint16_t MaxRequestDelay() { return mMaxRequestDelay; }
 
     // public, so that the SPDY/http2 seesions can activate
     void ActivateTimeoutTick();
 
 private:
     virtual ~nsHttpConnectionMgr();
 
-    enum PipeliningState {
-        // Host has proven itself pipeline capable through past experience and
-        // large pipeline depths are allowed on multiple connections.
-        PS_GREEN,
-
-        // Not enough information is available yet with this host to be certain
-        // of pipeline capability. Small pipelines on a single connection are
-        // allowed in order to decide whether or not to proceed to green.
-        PS_YELLOW,
-
-        // One or more bad events has happened that indicate that pipelining
-        // to this host (or a particular type of transaction with this host)
-        // is a bad idea. Pipelining is not currently allowed, but time and
-        // other positive experiences will eventually allow it to try again.
-        PS_RED
-    };
-
     class nsHalfOpenSocket;
 
     // nsConnectionEntry
     //
     // mCT maps connection info hash key to nsConnectionEntry object, which
     // contains list of active and idle connections as well as the list of
     // pending transactions.
     //
@@ -302,64 +215,16 @@ private:
 
         // calculate the number of half open sockets that have not had at least 1
         // connection complete
         uint32_t UnconnectedHalfOpens();
 
         // Remove a particular half open socket from the mHalfOpens array
         void RemoveHalfOpen(nsHalfOpenSocket *);
 
-        // Pipeline depths for various states
-        const static uint32_t kPipelineUnlimited  = 1024; // fully open - extended green
-        const static uint32_t kPipelineOpen       = 6;    // 6 on each conn - normal green
-        const static uint32_t kPipelineRestricted = 2;    // 2 on just 1 conn in yellow
-
-        nsHttpConnectionMgr::PipeliningState PipelineState();
-        void OnPipelineFeedbackInfo(
-            nsHttpConnectionMgr::PipelineFeedbackInfoType info,
-            nsHttpConnection *, uint32_t);
-        bool SupportsPipelining();
-        uint32_t MaxPipelineDepth(nsAHttpTransaction::Classifier classification);
-        void CreditPenalty();
-
-        nsHttpConnectionMgr::PipeliningState mPipelineState;
-
-        void SetYellowConnection(nsHttpConnection *);
-        void OnYellowComplete();
-        uint32_t                  mYellowGoodEvents;
-        uint32_t                  mYellowBadEvents;
-        nsHttpConnection         *mYellowConnection;
-
-        // initialGreenDepth is the max depth of a pipeline when you first
-        // transition to green. Normally this is kPipelineOpen, but it can
-        // be kPipelineUnlimited in aggressive mode.
-        uint32_t                  mInitialGreenDepth;
-
-        // greenDepth is the current max allowed depth of a pipeline when
-        // in the green state. Normally this starts as kPipelineOpen and
-        // grows to kPipelineUnlimited after a pipeline of depth 3 has been
-        // successfully transacted.
-        uint32_t                  mGreenDepth;
-
-        // pipeliningPenalty is the current amount of penalty points this host
-        // entry has earned for participating in events that are not conducive
-        // to good pipelines - such as head of line blocking, canceled pipelines,
-        // etc.. penalties are paid back either through elapsed time or simply
-        // healthy transactions. Having penalty points means that this host is
-        // not currently eligible for pipelines.
-        int16_t                   mPipeliningPenalty;
-
-        // some penalty points only apply to particular classifications of
-        // transactions - this allows a server that perhaps has head of line
-        // blocking problems on CGI queries to still serve JS pipelined.
-        int16_t                   mPipeliningClassPenalty[nsAHttpTransaction::CLASS_MAX];
-
-        // for calculating penalty repair credits
-        TimeStamp        mLastCreditTime;
-
         // Spdy sometimes resolves the address in the socket manager in order
         // to re-coalesce sharded HTTP hosts. The dotted decimal address is
         // combined with the Anonymous flag from the connection information
         // to build the hash key for hosts in the same ip pool.
         //
         // When a set of hosts are coalesced together one of them is marked
         // mSpdyPreferred. The mapping is maintained in the connection mananger
         // mSpdyPreferred hash.
@@ -494,42 +359,35 @@ private:
     ReentrantMonitor    mReentrantMonitor;
     nsCOMPtr<nsIEventTarget>     mSocketThreadTarget;
 
     // connection limits
     uint16_t mMaxConns;
     uint16_t mMaxPersistConnsPerHost;
     uint16_t mMaxPersistConnsPerProxy;
     uint16_t mMaxRequestDelay; // in seconds
-    uint16_t mMaxPipelinedRequests;
-    uint16_t mMaxOptimisticPipelinedRequests;
     Atomic<bool, mozilla::Relaxed> mIsShuttingDown;
 
     //-------------------------------------------------------------------------
     // NOTE: these members are only accessed on the socket transport thread
     //-------------------------------------------------------------------------
 
     bool     ProcessPendingQForEntry(nsConnectionEntry *, bool considerAll);
-    bool     IsUnderPressure(nsConnectionEntry *ent,
-                             nsHttpTransaction::Classifier classification);
     bool     AtActiveConnectionLimit(nsConnectionEntry *, uint32_t caps);
     nsresult TryDispatchTransaction(nsConnectionEntry *ent,
                                     bool onlyReusedConnection,
                                     nsHttpTransaction *trans);
     nsresult DispatchTransaction(nsConnectionEntry *,
                                  nsHttpTransaction *,
                                  nsHttpConnection *);
     nsresult DispatchAbstractTransaction(nsConnectionEntry *,
                                          nsAHttpTransaction *,
                                          uint32_t,
                                          nsHttpConnection *,
                                          int32_t);
-    nsresult BuildPipeline(nsConnectionEntry *,
-                           nsAHttpTransaction *,
-                           nsHttpPipeline **);
     bool     RestrictConnections(nsConnectionEntry *);
     nsresult ProcessNewTransaction(nsHttpTransaction *);
     nsresult EnsureSocketThreadTarget();
     void     ClosePersistentConnections(nsConnectionEntry *ent);
     void     ReportProxyTelemetry(nsConnectionEntry *ent);
     nsresult CreateTransport(nsConnectionEntry *, nsAHttpTransaction *,
                              uint32_t, bool, bool, bool);
     void     AddActiveConn(nsHttpConnection *, nsConnectionEntry *);
@@ -537,20 +395,16 @@ private:
     void     StartedConnect();
     void     RecvdConnect();
 
     nsConnectionEntry *GetOrCreateConnectionEntry(nsHttpConnectionInfo *,
                                                   bool allowWildCard);
 
     nsresult MakeNewConnection(nsConnectionEntry *ent,
                                nsHttpTransaction *trans);
-    bool     AddToShortestPipeline(nsConnectionEntry *ent,
-                                   nsHttpTransaction *trans,
-                                   nsHttpTransaction::Classifier classification,
-                                   uint16_t depthLimit);
 
     // Manage the preferred spdy connection entry for this address
     nsConnectionEntry *GetSpdyPreferredEnt(nsConnectionEntry *aOriginalEntry);
     nsConnectionEntry *LookupPreferredHash(nsConnectionEntry *ent);
     void               StorePreferredHash(nsConnectionEntry *ent);
     void               RemovePreferredHash(nsConnectionEntry *ent);
     nsHttpConnection  *GetSpdyPreferredConn(nsConnectionEntry *ent);
     nsDataHashtable<nsCStringHashKey, nsConnectionEntry *>   mSpdyPreferredHash;
--- a/netwerk/protocol/http/nsHttpHandler.cpp
+++ b/netwerk/protocol/http/nsHttpHandler.cpp
@@ -36,17 +36,16 @@
 #include "ASpdySession.h"
 #include "EventTokenBucket.h"
 #include "Tickler.h"
 #include "nsIXULAppInfo.h"
 #include "nsICookieService.h"
 #include "nsIObserverService.h"
 #include "nsISiteSecurityService.h"
 #include "nsIStreamConverterService.h"
-#include "nsITimer.h"
 #include "nsCRT.h"
 #include "nsIMemoryReporter.h"
 #include "nsIParentalControlsService.h"
 #include "nsPIDOMWindow.h"
 #include "nsINetworkLinkService.h"
 #include "nsHttpChannelAuthProvider.h"
 #include "nsServiceManagerUtils.h"
 #include "nsComponentManagerUtils.h"
@@ -169,41 +168,31 @@ nsHttpHandler::nsHttpHandler()
     , mCapabilities(NS_HTTP_ALLOW_KEEPALIVE)
     , mReferrerLevel(0xff) // by default we always send a referrer
     , mSpoofReferrerSource(false)
     , mHideOnionReferrerSource(false)
     , mReferrerTrimmingPolicy(0)
     , mReferrerXOriginTrimmingPolicy(0)
     , mReferrerXOriginPolicy(0)
     , mFastFallbackToIPv4(false)
-    , mProxyPipelining(true)
     , mIdleTimeout(PR_SecondsToInterval(10))
     , mSpdyTimeout(PR_SecondsToInterval(180))
     , mResponseTimeout(PR_SecondsToInterval(300))
     , mResponseTimeoutEnabled(false)
     , mNetworkChangedTimeout(5000)
     , mMaxRequestAttempts(6)
     , mMaxRequestDelay(10)
     , mIdleSynTimeout(250)
     , mH2MandatorySuiteEnabled(false)
-    , mPipeliningEnabled(false)
     , mMaxConnections(24)
     , mMaxPersistentConnectionsPerServer(2)
     , mMaxPersistentConnectionsPerProxy(4)
-    , mMaxPipelinedRequests(32)
-    , mMaxOptimisticPipelinedRequests(4)
-    , mPipelineAggressive(false)
-    , mMaxPipelineObjectSize(300000)
-    , mPipelineRescheduleOnTimeout(true)
-    , mPipelineRescheduleTimeout(PR_MillisecondsToInterval(1500))
-    , mPipelineReadTimeout(PR_MillisecondsToInterval(30000))
     , mRedirectionLimit(10)
     , mPhishyUserPassLength(1)
     , mQoSBits(0x00)
-    , mPipeliningOverSSL(false)
     , mEnforceAssocReq(false)
     , mLastUniqueID(NowInSeconds())
     , mSessionStartTime(0)
     , mLegacyAppName("Mozilla")
     , mLegacyAppVersion("5.0")
     , mProduct("Gecko")
     , mCompatFirefoxEnabled(false)
     , mUserAgentIsDirty(true)
@@ -264,21 +253,16 @@ nsHttpHandler::~nsHttpHandler()
         mConnMgr->Shutdown();
         mConnMgr = nullptr;
     }
 
     // Note: don't call NeckoChild::DestroyNeckoChild() here, as it's too late
     // and it'll segfault.  NeckoChild will get cleaned up by process exit.
 
     nsHttp::DestroyAtomTable();
-    if (mPipelineTestTimer) {
-        mPipelineTestTimer->Cancel();
-        mPipelineTestTimer = nullptr;
-    }
-
     gHttpHandler = nullptr;
 }
 
 nsresult
 nsHttpHandler::Init()
 {
     nsresult rv;
 
@@ -389,21 +373,23 @@ nsHttpHandler::Init()
         // about shutdown ordering.
         obsService->AddObserver(this, "profile-change-net-teardown", true);
         obsService->AddObserver(this, "profile-change-net-restore", true);
         obsService->AddObserver(this, NS_XPCOM_SHUTDOWN_OBSERVER_ID, true);
         obsService->AddObserver(this, "net:clear-active-logins", true);
         obsService->AddObserver(this, "net:prune-dead-connections", true);
         // Sent by the TorButton add-on in the Tor Browser
         obsService->AddObserver(this, "net:prune-all-connections", true);
-        obsService->AddObserver(this, "net:failed-to-process-uri-content", true);
         obsService->AddObserver(this, "last-pb-context-exited", true);
         obsService->AddObserver(this, "browser:purge-session-history", true);
         obsService->AddObserver(this, NS_NETWORK_LINK_TOPIC, true);
         obsService->AddObserver(this, "application-background", true);
+
+        // disabled as its a nop right now
+        // obsService->AddObserver(this, "net:failed-to-process-uri-content", true);
     }
 
     MakeNewRequestTokenBucket();
     mWifiTickler = new Tickler();
     if (NS_FAILED(mWifiTickler->Init()))
         mWifiTickler = nullptr;
 
     nsCOMPtr<nsIParentalControlsService> pc = do_CreateInstance("@mozilla.org/parental-controls-service;1");
@@ -438,19 +424,17 @@ nsHttpHandler::InitConnectionMgr()
 
     if (!mConnMgr) {
         mConnMgr = new nsHttpConnectionMgr();
     }
 
     rv = mConnMgr->Init(mMaxConnections,
                         mMaxPersistentConnectionsPerServer,
                         mMaxPersistentConnectionsPerProxy,
-                        mMaxRequestDelay,
-                        mMaxPipelinedRequests,
-                        mMaxOptimisticPipelinedRequests);
+                        mMaxRequestDelay);
     return rv;
 }
 
 nsresult
 nsHttpHandler::AddStandardRequestHeaders(nsHttpRequestHead *request, bool isSecure)
 {
     nsresult rv;
 
@@ -1152,106 +1136,16 @@ nsHttpHandler::PrefsChanged(nsIPrefBranc
             if (!PL_strcmp(httpVersion, "1.1"))
                 mProxyHttpVersion = NS_HTTP_VERSION_1_1;
             else
                 mProxyHttpVersion = NS_HTTP_VERSION_1_0;
             // it does not make sense to issue a HTTP/0.9 request to a proxy server
         }
     }
 
-    if (PREF_CHANGED(HTTP_PREF("pipelining"))) {
-        rv = prefs->GetBoolPref(HTTP_PREF("pipelining"), &cVar);
-        if (NS_SUCCEEDED(rv)) {
-            if (cVar)
-                mCapabilities |=  NS_HTTP_ALLOW_PIPELINING;
-            else
-                mCapabilities &= ~NS_HTTP_ALLOW_PIPELINING;
-            mPipeliningEnabled = cVar;
-        }
-    }
-
-    if (PREF_CHANGED(HTTP_PREF("pipelining.maxrequests"))) {
-        rv = prefs->GetIntPref(HTTP_PREF("pipelining.maxrequests"), &val);
-        if (NS_SUCCEEDED(rv)) {
-            mMaxPipelinedRequests = clamped(val, 1, 0xffff);
-            if (mConnMgr)
-                mConnMgr->UpdateParam(nsHttpConnectionMgr::MAX_PIPELINED_REQUESTS,
-                                      mMaxPipelinedRequests);
-        }
-    }
-
-    if (PREF_CHANGED(HTTP_PREF("pipelining.max-optimistic-requests"))) {
-        rv = prefs->
-            GetIntPref(HTTP_PREF("pipelining.max-optimistic-requests"), &val);
-        if (NS_SUCCEEDED(rv)) {
-            mMaxOptimisticPipelinedRequests = clamped(val, 1, 0xffff);
-            if (mConnMgr)
-                mConnMgr->UpdateParam
-                    (nsHttpConnectionMgr::MAX_OPTIMISTIC_PIPELINED_REQUESTS,
-                     mMaxOptimisticPipelinedRequests);
-        }
-    }
-
-    if (PREF_CHANGED(HTTP_PREF("pipelining.aggressive"))) {
-        rv = prefs->GetBoolPref(HTTP_PREF("pipelining.aggressive"), &cVar);
-        if (NS_SUCCEEDED(rv))
-            mPipelineAggressive = cVar;
-    }
-
-    if (PREF_CHANGED(HTTP_PREF("pipelining.maxsize"))) {
-        rv = prefs->GetIntPref(HTTP_PREF("pipelining.maxsize"), &val);
-        if (NS_SUCCEEDED(rv)) {
-            mMaxPipelineObjectSize =
-                static_cast<int64_t>(clamped(val, 1000, 100000000));
-        }
-    }
-
-    // Determines whether or not to actually reschedule after the
-    // reschedule-timeout has expired
-    if (PREF_CHANGED(HTTP_PREF("pipelining.reschedule-on-timeout"))) {
-        rv = prefs->GetBoolPref(HTTP_PREF("pipelining.reschedule-on-timeout"),
-                                &cVar);
-        if (NS_SUCCEEDED(rv))
-            mPipelineRescheduleOnTimeout = cVar;
-    }
-
-    // The amount of time head of line blocking is allowed (in ms)
-    // before the blocked transactions are moved to another pipeline
-    if (PREF_CHANGED(HTTP_PREF("pipelining.reschedule-timeout"))) {
-        rv = prefs->GetIntPref(HTTP_PREF("pipelining.reschedule-timeout"),
-                               &val);
-        if (NS_SUCCEEDED(rv)) {
-            mPipelineRescheduleTimeout =
-                PR_MillisecondsToInterval((uint16_t) clamped(val, 500, 0xffff));
-        }
-    }
-
-    // The amount of time a pipelined transaction is allowed to wait before
-    // being canceled and retried in a non-pipeline connection
-    if (PREF_CHANGED(HTTP_PREF("pipelining.read-timeout"))) {
-        rv = prefs->GetIntPref(HTTP_PREF("pipelining.read-timeout"), &val);
-        if (NS_SUCCEEDED(rv)) {
-            mPipelineReadTimeout =
-                PR_MillisecondsToInterval((uint16_t) clamped(val, 5000,
-                                                             0xffff));
-        }
-    }
-
-    if (PREF_CHANGED(HTTP_PREF("pipelining.ssl"))) {
-        rv = prefs->GetBoolPref(HTTP_PREF("pipelining.ssl"), &cVar);
-        if (NS_SUCCEEDED(rv))
-            mPipeliningOverSSL = cVar;
-    }
-
-    if (PREF_CHANGED(HTTP_PREF("proxy.pipelining"))) {
-        rv = prefs->GetBoolPref(HTTP_PREF("proxy.pipelining"), &cVar);
-        if (NS_SUCCEEDED(rv))
-            mProxyPipelining = cVar;
-    }
-
     if (PREF_CHANGED(HTTP_PREF("qos"))) {
         rv = prefs->GetIntPref(HTTP_PREF("qos"), &val);
         if (NS_SUCCEEDED(rv))
             mQoSBits = (uint8_t) clamped(val, 0, 0xff);
     }
 
     if (PREF_CHANGED(HTTP_PREF("accept.default"))) {
         nsXPIDLCString accept;
@@ -1575,47 +1469,16 @@ nsHttpHandler::PrefsChanged(nsIPrefBranc
     if (PREF_CHANGED("network.http.debug-observations")) {
         cVar = false;
         rv = prefs->GetBoolPref("network.http.debug-observations", &cVar);
         if (NS_SUCCEEDED(rv)) {
             mDebugObservations = cVar;
         }
     }
 
-    //
-    // Test HTTP Pipelining (bug796192)
-    // If experiments are allowed and pipelining is Off,
-    // turn it On for just 10 minutes
-    //
-    if (mAllowExperiments && !mPipeliningEnabled &&
-        PREF_CHANGED(HTTP_PREF("pipelining.abtest"))) {
-        rv = prefs->GetBoolPref(HTTP_PREF("pipelining.abtest"), &cVar);
-        if (NS_SUCCEEDED(rv)) {
-            // If option is enabled, only test for ~1% of sessions
-            if (cVar && !(rand() % 128)) {
-                mCapabilities |=  NS_HTTP_ALLOW_PIPELINING;
-                if (mPipelineTestTimer)
-                    mPipelineTestTimer->Cancel();
-                mPipelineTestTimer =
-                    do_CreateInstance("@mozilla.org/timer;1", &rv);
-                if (NS_SUCCEEDED(rv)) {
-                    rv = mPipelineTestTimer->InitWithFuncCallback(
-                        TimerCallback, this, 10*60*1000, // 10 minutes
-                        nsITimer::TYPE_ONE_SHOT);
-                }
-            } else {
-                mCapabilities &= ~NS_HTTP_ALLOW_PIPELINING;
-                if (mPipelineTestTimer) {
-                    mPipelineTestTimer->Cancel();
-                    mPipelineTestTimer = nullptr;
-                }
-            }
-        }
-    }
-
     if (PREF_CHANGED(HTTP_PREF("pacing.requests.enabled"))) {
         rv = prefs->GetBoolPref(HTTP_PREF("pacing.requests.enabled"), &cVar);
         if (NS_SUCCEEDED(rv)) {
             mRequestTokenBucketEnabled = cVar;
             requestTokenBucketUpdated = true;
         }
     }
     if (PREF_CHANGED(HTTP_PREF("pacing.requests.min-parallelism"))) {
@@ -1732,27 +1595,16 @@ nsHttpHandler::PrefsChanged(nsIPrefBranc
                               !mTCPKeepaliveLongLivedEnabled;
 
 #undef PREF_CHANGED
 #undef MULTI_PREF_CHANGED
 }
 
 
 /**
- * Static method called by mPipelineTestTimer when it expires.
- */
-void
-nsHttpHandler::TimerCallback(nsITimer * aTimer, void * aClosure)
-{
-    RefPtr<nsHttpHandler> thisObject = static_cast<nsHttpHandler*>(aClosure);
-    if (!thisObject->mPipeliningEnabled)
-        thisObject->mCapabilities &= ~NS_HTTP_ALLOW_PIPELINING;
-}
-
-/**
  * Currently, only regularizes the case of subtags.
  */
 static void
 CanonicalizeLanguageTag(char *languageTag)
 {
     char *s = languageTag;
     while (*s != '\0') {
         *s = nsCRT::ToLower(*s);
@@ -2043,22 +1895,16 @@ nsHttpHandler::NewProxiedChannel2(nsIURI
     if (IsNeckoChild()) {
         httpChannel = new HttpChannelChild();
     } else {
         httpChannel = new nsHttpChannel();
     }
 
     uint32_t caps = mCapabilities;
 
-    if (https) {
-        // enable pipelining over SSL if requested
-        if (mPipeliningOverSSL)
-            caps |= NS_HTTP_ALLOW_PIPELINING;
-    }
-
     if (!IsNeckoChild()) {
         // HACK: make sure PSM gets initialized on the main thread.
         net_EnsurePSMInit();
     }
 
     nsID channelId;
     rv = NewChannelId(&channelId);
     NS_ENSURE_SUCCESS(rv, rv);
@@ -2186,21 +2032,22 @@ nsHttpHandler::Observe(nsISupports *subj
         if (mConnMgr) {
             mConnMgr->PruneDeadConnections();
         }
     } else if (!strcmp(topic, "net:prune-all-connections")) {
         if (mConnMgr) {
             mConnMgr->DoShiftReloadConnectionCleanup(nullptr);
             mConnMgr->PruneDeadConnections();
         }
+#if 0
     } else if (!strcmp(topic, "net:failed-to-process-uri-content")) {
-        nsCOMPtr<nsIURI> uri = do_QueryInterface(subject);
-        if (uri && mConnMgr) {
-            mConnMgr->ReportFailedToProcess(uri);
-        }
+         // nop right now - we used to cancel h1 pipelines based on this,
+         // but those are no longer implemented
+         nsCOMPtr<nsIURI> uri = do_QueryInterface(subject);
+#endif
     } else if (!strcmp(topic, "last-pb-context-exited")) {
         mPrivateAuthCache.ClearAll();
         if (mConnMgr) {
             mConnMgr->ClearAltServiceMappings();
         }
     } else if (!strcmp(topic, "browser:purge-session-history")) {
         if (mConnMgr) {
             if (gSocketTransportService) {
--- a/netwerk/protocol/http/nsHttpHandler.h
+++ b/netwerk/protocol/http/nsHttpHandler.h
@@ -23,17 +23,16 @@ class nsIHttpChannel;
 class nsIPrefBranch;
 class nsICancelable;
 class nsICookieService;
 class nsIIOService;
 class nsIRequestContextService;
 class nsISiteSecurityService;
 class nsIStreamConverterService;
 class nsIThrottlingService;
-class nsITimer;
 class nsIUUIDGenerator;
 
 
 namespace mozilla {
 namespace net {
 
 extern Atomic<PRThread*, Relaxed> gSocketThread;
 
@@ -97,17 +96,16 @@ public:
     PRIntervalTime ResponseTimeoutEnabled()  { return mResponseTimeoutEnabled; }
     uint32_t       NetworkChangedTimeout()   { return mNetworkChangedTimeout; }
     uint16_t       MaxRequestAttempts()      { return mMaxRequestAttempts; }
     const char    *DefaultSocketType()       { return mDefaultSocketType.get(); /* ok to return null */ }
     uint32_t       PhishyUserPassLength()    { return mPhishyUserPassLength; }
     uint8_t        GetQoSBits()              { return mQoSBits; }
     uint16_t       GetIdleSynTimeout()       { return mIdleSynTimeout; }
     bool           FastFallbackToIPv4()      { return mFastFallbackToIPv4; }
-    bool           ProxyPipelining()         { return mProxyPipelining; }
     uint32_t       MaxSocketCount();
     bool           EnforceAssocReq()         { return mEnforceAssocReq; }
 
     bool           IsPersistentHttpsCachingEnabled() { return mEnablePersistentHttpsCaching; }
     bool           IsTelemetryEnabled() { return mTelemetryEnabled; }
     bool           AllowExperiments() { return mTelemetryEnabled && mAllowExperiments; }
 
     bool           IsSpdyEnabled() { return mEnableSpdy; }
@@ -314,38 +312,16 @@ public:
         NotifyObservers(chan, NS_HTTP_ON_EXAMINE_CACHED_RESPONSE_TOPIC);
     }
 
     // Generates the host:port string for use in the Host: header as well as the
     // CONNECT line for proxies. This handles IPv6 literals correctly.
     static nsresult GenerateHostPort(const nsCString& host, int32_t port,
                                      nsACString& hostLine);
 
-    bool GetPipelineAggressive()     { return mPipelineAggressive; }
-    void GetMaxPipelineObjectSize(int64_t *outVal)
-    {
-        *outVal = mMaxPipelineObjectSize;
-    }
-
-    bool GetPipelineEnabled()
-    {
-        return mCapabilities & NS_HTTP_ALLOW_PIPELINING;
-    }
-
-    bool GetPipelineRescheduleOnTimeout()
-    {
-        return mPipelineRescheduleOnTimeout;
-    }
-
-    PRIntervalTime GetPipelineRescheduleTimeout()
-    {
-        return mPipelineRescheduleTimeout;
-    }
-
-    PRIntervalTime GetPipelineTimeout()   { return mPipelineReadTimeout; }
 
     SpdyInformation *SpdyInfo() { return &mSpdyInfo; }
     bool IsH2MandatorySuiteEnabled() { return mH2MandatorySuiteEnabled; }
 
     // Returns true if content-signature test pref is set such that they are
     // NOT enforced on remote newtabs.
     bool NewTabContentSignaturesDisabled()
     {
@@ -396,17 +372,16 @@ private:
     nsresult SetAccept(const char *);
     nsresult SetAcceptLanguages(const char *);
     nsresult SetAcceptEncodings(const char *, bool mIsSecure);
 
     nsresult InitConnectionMgr();
 
     void     NotifyObservers(nsIHttpChannel *chan, const char *event);
 
-    static void TimerCallback(nsITimer * aTimer, void * aClosure);
 private:
 
     // cached services
     nsMainThreadPtrHandle<nsIIOService>              mIOService;
     nsMainThreadPtrHandle<nsIStreamConverterService> mStreamConvSvc;
     nsMainThreadPtrHandle<nsICookieService>          mCookieService;
     nsMainThreadPtrHandle<nsISiteSecurityService>    mSSService;
     nsMainThreadPtrHandle<nsIThrottlingService>      mThrottlingService;
@@ -428,51 +403,40 @@ private:
     uint8_t  mReferrerLevel;
     uint8_t  mSpoofReferrerSource;
     uint8_t  mHideOnionReferrerSource;
     uint8_t  mReferrerTrimmingPolicy;
     uint8_t  mReferrerXOriginTrimmingPolicy;
     uint8_t  mReferrerXOriginPolicy;
 
     bool mFastFallbackToIPv4;
-    bool mProxyPipelining;
     PRIntervalTime mIdleTimeout;
     PRIntervalTime mSpdyTimeout;
     PRIntervalTime mResponseTimeout;
     bool mResponseTimeoutEnabled;
     uint32_t mNetworkChangedTimeout; // milliseconds
     uint16_t mMaxRequestAttempts;
     uint16_t mMaxRequestDelay;
     uint16_t mIdleSynTimeout;
 
     bool     mH2MandatorySuiteEnabled;
-    bool     mPipeliningEnabled;
     uint16_t mMaxConnections;
     uint8_t  mMaxPersistentConnectionsPerServer;
     uint8_t  mMaxPersistentConnectionsPerProxy;
-    uint16_t mMaxPipelinedRequests;
-    uint16_t mMaxOptimisticPipelinedRequests;
-    bool     mPipelineAggressive;
-    int64_t  mMaxPipelineObjectSize;
-    bool     mPipelineRescheduleOnTimeout;
-    PRIntervalTime mPipelineRescheduleTimeout;
-    PRIntervalTime mPipelineReadTimeout;
-    nsCOMPtr<nsITimer> mPipelineTestTimer;
 
     uint8_t  mRedirectionLimit;
 
     // we'll warn the user if we load an URL containing a userpass field
     // unless its length is less than this threshold.  this warning is
     // intended to protect the user against spoofing attempts that use
     // the userpass field of the URL to obscure the actual origin server.
     uint8_t  mPhishyUserPassLength;
 
     uint8_t  mQoSBits;
 
-    bool mPipeliningOverSSL;
     bool mEnforceAssocReq;
 
     nsCString mAccept;
     nsCString mAcceptLanguages;
     nsCString mHttpAcceptEncodings;
     nsCString mHttpsAcceptEncodings;
 
     nsXPIDLCString mDefaultSocketType;
deleted file mode 100644
--- a/netwerk/protocol/http/nsHttpPipeline.cpp
+++ /dev/null
@@ -1,912 +0,0 @@
-/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * 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/. */
-
-// HttpLog.h should generally be included first
-#include "HttpLog.h"
-
-#include "nsHttpPipeline.h"
-#include "nsHttpHandler.h"
-#include "nsIOService.h"
-#include "nsISocketTransport.h"
-#include "nsIPipe.h"
-#include "nsCOMPtr.h"
-#include "nsSocketTransportService2.h"
-#include <algorithm>
-
-#ifdef DEBUG
-#include "prthread.h"
-#endif
-
-namespace mozilla {
-namespace net {
-
-//-----------------------------------------------------------------------------
-// nsHttpPushBackWriter
-//-----------------------------------------------------------------------------
-
-class nsHttpPushBackWriter : public nsAHttpSegmentWriter
-{
-public:
-    nsHttpPushBackWriter(const char *buf, uint32_t bufLen)
-        : mBuf(buf)
-        , mBufLen(bufLen)
-        { }
-    virtual ~nsHttpPushBackWriter() {}
-
-    nsresult OnWriteSegment(char *buf, uint32_t count, uint32_t *countWritten)
-    {
-        if (mBufLen == 0)
-            return NS_BASE_STREAM_CLOSED;
-
-        if (count > mBufLen)
-            count = mBufLen;
-
-        memcpy(buf, mBuf, count);
-
-        mBuf += count;
-        mBufLen -= count;
-        *countWritten = count;
-        return NS_OK;
-    }
-
-private:
-    const char *mBuf;
-    uint32_t    mBufLen;
-};
-
-//-----------------------------------------------------------------------------
-// nsHttpPipeline <public>
-//-----------------------------------------------------------------------------
-
-nsHttpPipeline::nsHttpPipeline()
-    : mStatus(NS_OK)
-    , mRequestIsPartial(false)
-    , mResponseIsPartial(false)
-    , mClosed(false)
-    , mUtilizedPipeline(false)
-    , mPushBackBuf(nullptr)
-    , mPushBackLen(0)
-    , mPushBackMax(0)
-    , mHttp1xTransactionCount(0)
-    , mReceivingFromProgress(0)
-    , mSendingToProgress(0)
-    , mSuppressSendEvents(true)
-{
-}
-
-nsHttpPipeline::~nsHttpPipeline()
-{
-    // make sure we aren't still holding onto any transactions!
-    Close(NS_ERROR_ABORT);
-
-    if (mPushBackBuf)
-        free(mPushBackBuf);
-}
-
-nsresult
-nsHttpPipeline::AddTransaction(nsAHttpTransaction *trans)
-{
-    LOG(("nsHttpPipeline::AddTransaction [this=%p trans=%p]\n", this, trans));
-
-    if (mRequestQ.Length() || mResponseQ.Length())
-        mUtilizedPipeline = true;
-
-    // A reference to the actual transaction is held by the pipeline transaction
-    // in either the request or response queue
-    mRequestQ.AppendElement(trans);
-    uint32_t qlen = PipelineDepth();
-
-    if (qlen != 1) {
-        trans->SetPipelinePosition(qlen);
-    }
-    else {
-        // do it for this case in case an idempotent cancellation
-        // is being repeated and an old value needs to be cleared
-        trans->SetPipelinePosition(0);
-    }
-
-    // trans->SetConnection() needs to be updated to point back at
-    // the pipeline object.
-    trans->SetConnection(this);
-
-    if (mConnection && !mClosed && mRequestQ.Length() == 1)
-        mConnection->ResumeSend();
-
-    return NS_OK;
-}
-
-uint32_t
-nsHttpPipeline::PipelineDepth()
-{
-    return mRequestQ.Length() + mResponseQ.Length();
-}
-
-nsresult
-nsHttpPipeline::SetPipelinePosition(int32_t position)
-{
-    nsAHttpTransaction *trans = Response(0);
-    if (trans)
-        return trans->SetPipelinePosition(position);
-    return NS_OK;
-}
-
-int32_t
-nsHttpPipeline::PipelinePosition()
-{
-    nsAHttpTransaction *trans = Response(0);
-    if (trans)
-        return trans->PipelinePosition();
-
-    // The response queue is empty, so return oldest request
-    if (mRequestQ.Length())
-        return Request(mRequestQ.Length() - 1)->PipelinePosition();
-
-    // No transactions in the pipeline
-    return 0;
-}
-
-nsHttpPipeline *
-nsHttpPipeline::QueryPipeline()
-{
-    return this;
-}
-
-//-----------------------------------------------------------------------------
-// nsHttpPipeline::nsISupports
-//-----------------------------------------------------------------------------
-
-NS_IMPL_ADDREF(nsHttpPipeline)
-NS_IMPL_RELEASE(nsHttpPipeline)
-
-// multiple inheritance fun :-)
-NS_INTERFACE_MAP_BEGIN(nsHttpPipeline)
-    NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsAHttpConnection)
-NS_INTERFACE_MAP_END
-
-
-//-----------------------------------------------------------------------------
-// nsHttpPipeline::nsAHttpConnection
-//-----------------------------------------------------------------------------
-
-nsresult
-nsHttpPipeline::OnHeadersAvailable(nsAHttpTransaction *trans,
-                                   nsHttpRequestHead *requestHead,
-                                   nsHttpResponseHead *responseHead,
-                                   bool *reset)
-{
-    LOG(("nsHttpPipeline::OnHeadersAvailable [this=%p]\n", this));
-
-    MOZ_ASSERT(PR_GetCurrentThread() == gSocketThread);
-    MOZ_ASSERT(mConnection, "no connection");
-
-    RefPtr<nsHttpConnectionInfo> ci;
-    GetConnectionInfo(getter_AddRefs(ci));
-    MOZ_ASSERT(ci);
-
-    if (!ci) {
-        return NS_ERROR_UNEXPECTED;
-    }
-
-    bool pipeliningBefore = gHttpHandler->ConnMgr()->SupportsPipelining(ci);
-
-    // trans has now received its response headers; forward to the real connection
-    nsresult rv = mConnection->OnHeadersAvailable(trans,
-                                                  requestHead,
-                                                  responseHead,
-                                                  reset);
-
-    if (!pipeliningBefore && gHttpHandler->ConnMgr()->SupportsPipelining(ci)) {
-        // The received headers have expanded the eligible
-        // pipeline depth for this connection
-        gHttpHandler->ConnMgr()->ProcessPendingQForEntry(ci);
-    }
-
-    return rv;
-}
-
-void
-nsHttpPipeline::CloseTransaction(nsAHttpTransaction *aTrans, nsresult reason)
-{
-    LOG(("nsHttpPipeline::CloseTransaction [this=%p trans=%p reason=%" PRIx32 "]\n",
-         this, aTrans, static_cast<uint32_t>(reason)));
-
-    MOZ_ASSERT(PR_GetCurrentThread() == gSocketThread);
-    MOZ_ASSERT(NS_FAILED(reason), "expecting failure code");
-
-    // the specified transaction is to be closed with the given "reason"
-    RefPtr<nsAHttpTransaction> trans(aTrans);
-    int32_t index;
-    bool killPipeline = false;
-
-    if ((index = mRequestQ.IndexOf(trans)) >= 0) {
-        if (index == 0 && mRequestIsPartial) {
-            // the transaction is in the request queue.  check to see if any of
-            // its data has been written out yet.
-            killPipeline = true;
-        }
-        mRequestQ.RemoveElementAt(index);
-    } else if ((index = mResponseQ.IndexOf(trans)) >= 0) {
-        mResponseQ.RemoveElementAt(index);
-        // while we could avoid killing the pipeline if this transaction is the
-        // last transaction in the pipeline, there doesn't seem to be that much
-        // value in doing so.  most likely if this transaction is going away,
-        // the others will be shortly as well.
-        killPipeline = true;
-    }
-
-    // Marking this connection as non-reusable prevents other items from being
-    // added to it and causes it to be torn down soon.
-    DontReuse();
-
-    trans->Close(reason);
-    trans = nullptr;
-
-    if (killPipeline) {
-        // reschedule anything from this pipeline onto a different connection
-        CancelPipeline(reason);
-    }
-
-    // If all the transactions have been removed then we can close the connection
-    // right away.
-    if (!mRequestQ.Length() && !mResponseQ.Length() && mConnection)
-        mConnection->CloseTransaction(this, reason);
-}
-
-nsresult
-nsHttpPipeline::TakeTransport(nsISocketTransport  **aTransport,
-                              nsIAsyncInputStream **aInputStream,
-                              nsIAsyncOutputStream **aOutputStream)
-{
-    return mConnection->TakeTransport(aTransport, aInputStream, aOutputStream);
-}
-
-bool
-nsHttpPipeline::IsPersistent()
-{
-    return true; // pipelining requires this
-}
-
-bool
-nsHttpPipeline::IsReused()
-{
-    if (!mUtilizedPipeline && mConnection)
-        return mConnection->IsReused();
-    return true;
-}
-
-void
-nsHttpPipeline::DontReuse()
-{
-    if (mConnection)
-        mConnection->DontReuse();
-}
-
-nsresult
-nsHttpPipeline::PushBack(const char *data, uint32_t length)
-{
-    LOG(("nsHttpPipeline::PushBack [this=%p len=%u]\n", this, length));
-
-    MOZ_ASSERT(PR_GetCurrentThread() == gSocketThread);
-    MOZ_ASSERT(mPushBackLen == 0, "push back buffer already has data!");
-
-    // If we have no chance for a pipeline (e.g. due to an Upgrade)
-    // then push this data down to original connection
-    if (!mConnection->IsPersistent())
-        return mConnection->PushBack(data, length);
-
-    // PushBack is called recursively from WriteSegments
-
-    // XXX we have a design decision to make here.  either we buffer the data
-    // and process it when we return to WriteSegments, or we attempt to move
-    // onto the next transaction from here.  doing so adds complexity with the
-    // benefit of eliminating the extra buffer copy.  the buffer is at most
-    // 4096 bytes, so it is really unclear if there is any value in the added
-    // complexity.  besides simplicity, buffering this data has the advantage
-    // that we'll call close on the transaction sooner, which will wake up
-    // the HTTP channel sooner to continue with its work.
-
-    if (!mPushBackBuf) {
-        mPushBackMax = length;
-        mPushBackBuf = (char *) malloc(mPushBackMax);
-        if (!mPushBackBuf)
-            return NS_ERROR_OUT_OF_MEMORY;
-    }
-    else if (length > mPushBackMax) {
-        // grow push back buffer as necessary.
-        MOZ_ASSERT(length <= nsIOService::gDefaultSegmentSize, "too big");
-        mPushBackMax = length;
-        mPushBackBuf = (char *) realloc(mPushBackBuf, mPushBackMax);
-        if (!mPushBackBuf)
-            return NS_ERROR_OUT_OF_MEMORY;
-    }
-
-    memcpy(mPushBackBuf, data, length);
-    mPushBackLen = length;
-
-    return NS_OK;
-}
-
-already_AddRefed<nsHttpConnection>
-nsHttpPipeline::TakeHttpConnection()
-{
-    if (mConnection)
-        return mConnection->TakeHttpConnection();
-    return nullptr;
-}
-
-nsAHttpTransaction::Classifier
-nsHttpPipeline::Classification()
-{
-    if (mConnection)
-        return mConnection->Classification();
-
-    LOG(("nsHttpPipeline::Classification this=%p "
-         "has null mConnection using CLASS_SOLO default", this));
-    return nsAHttpTransaction::CLASS_SOLO;
-}
-
-void
-nsHttpPipeline::SetProxyConnectFailed()
-{
-    nsAHttpTransaction *trans = Request(0);
-
-    if (trans)
-        trans->SetProxyConnectFailed();
-}
-
-nsHttpRequestHead *
-nsHttpPipeline::RequestHead()
-{
-    nsAHttpTransaction *trans = Request(0);
-
-    if (trans)
-        return trans->RequestHead();
-    return nullptr;
-}
-
-uint32_t
-nsHttpPipeline::Http1xTransactionCount()
-{
-  return mHttp1xTransactionCount;
-}
-
-nsresult
-nsHttpPipeline::TakeSubTransactions(
-    nsTArray<RefPtr<nsAHttpTransaction> > &outTransactions)
-{
-    LOG(("nsHttpPipeline::TakeSubTransactions [this=%p]\n", this));
-
-    if (mResponseQ.Length() || mRequestIsPartial)
-        return NS_ERROR_ALREADY_OPENED;
-
-    int32_t i, count = mRequestQ.Length();
-    for (i = 0; i < count; ++i) {
-        nsAHttpTransaction *trans = Request(i);
-        // set the transaction connection object back to the underlying
-        // nsHttpConnectionHandle
-        trans->SetConnection(mConnection);
-        outTransactions.AppendElement(trans);
-    }
-    mRequestQ.Clear();
-
-    LOG(("   took %d\n", count));
-    return NS_OK;
-}
-
-//-----------------------------------------------------------------------------
-// nsHttpPipeline::nsAHttpTransaction
-//-----------------------------------------------------------------------------
-
-void
-nsHttpPipeline::SetConnection(nsAHttpConnection *conn)
-{
-    LOG(("nsHttpPipeline::SetConnection [this=%p conn=%p]\n", this, conn));
-
-    MOZ_ASSERT(PR_GetCurrentThread() == gSocketThread);
-    MOZ_ASSERT(!conn || !mConnection, "already have a connection");
-
-    mConnection = conn;
-}
-
-nsAHttpConnection *
-nsHttpPipeline::Connection()
-{
-    LOG(("nsHttpPipeline::Connection [this=%p conn=%p]\n", this, mConnection.get()));
-
-    MOZ_ASSERT(PR_GetCurrentThread() == gSocketThread);
-    return mConnection;
-}
-
-void
-nsHttpPipeline::GetSecurityCallbacks(nsIInterfaceRequestor **result)
-{
-    MOZ_ASSERT(PR_GetCurrentThread() == gSocketThread);
-
-    // depending on timing this could be either the request or the response
-    // that is needed - but they both go to the same host. A request for these
-    // callbacks directly in nsHttpTransaction would not make a distinction
-    // over whether the the request had been transmitted yet.
-    nsAHttpTransaction *trans = Request(0);
-    if (!trans)
-        trans = Response(0);
-    if (trans)
-        trans->GetSecurityCallbacks(result);
-    else {
-        *result = nullptr;
-    }
-}
-
-void
-nsHttpPipeline::OnTransportStatus(nsITransport* transport,
-                                  nsresult status, int64_t progress)
-{
-    LOG(("nsHttpPipeline::OnStatus [this=%p status=%" PRIx32 " progress=%" PRId64 "]\n",
-         this, static_cast<uint32_t>(status), progress));
-
-    MOZ_ASSERT(PR_GetCurrentThread() == gSocketThread);
-
-    nsAHttpTransaction *trans;
-    int32_t i, count;
-
-    switch (status) {
-
-    case NS_NET_STATUS_RESOLVING_HOST:
-    case NS_NET_STATUS_RESOLVED_HOST:
-    case NS_NET_STATUS_CONNECTING_TO:
-    case NS_NET_STATUS_CONNECTED_TO:
-        // These should only appear at most once per pipeline.
-        // Deliver to the first transaction.
-
-        trans = Request(0);
-        if (!trans)
-            trans = Response(0);
-        if (trans)
-            trans->OnTransportStatus(transport, status, progress);
-
-        break;
-
-    case NS_NET_STATUS_SENDING_TO:
-        // This is generated by the socket transport when (part) of
-        // a transaction is written out
-        //
-        // In pipelining this is generated out of FillSendBuf(), but it cannot do
-        // so until the connection is confirmed by CONNECTED_TO.
-        // See patch for bug 196827.
-        //
-
-        if (mSuppressSendEvents) {
-            mSuppressSendEvents = false;
-
-            // catch up by sending the event to all the transactions that have
-            // moved from request to response and any that have been partially
-            // sent. Also send WAITING_FOR to those that were completely sent
-            count = mResponseQ.Length();
-            for (i = 0; i < count; ++i) {
-                Response(i)->OnTransportStatus(transport,
-                                               NS_NET_STATUS_SENDING_TO,
-                                               progress);
-                Response(i)->OnTransportStatus(transport,
-                                               NS_NET_STATUS_WAITING_FOR,
-                                               progress);
-            }
-            if (mRequestIsPartial && Request(0))
-                Request(0)->OnTransportStatus(transport,
-                                              NS_NET_STATUS_SENDING_TO,
-                                              progress);
-            mSendingToProgress = progress;
-        }
-        // otherwise ignore it
-        break;
-
-    case NS_NET_STATUS_WAITING_FOR:
-        // Created by nsHttpConnection when request pipeline has been totally
-        // sent. Ignore it here because it is simulated in FillSendBuf() when
-        // a request is moved from request to response.
-
-        // ignore it
-        break;
-
-    case NS_NET_STATUS_RECEIVING_FROM:
-        // Forward this only to the transaction currently recieving data. It is
-        // normally generated by the socket transport, but can also
-        // be repeated by the pushbackwriter if necessary.
-        mReceivingFromProgress = progress;
-        if (Response(0))
-            Response(0)->OnTransportStatus(transport, status, progress);
-        break;
-
-    default:
-        // forward other notifications to all request transactions
-        count = mRequestQ.Length();
-        for (i = 0; i < count; ++i)
-            Request(i)->OnTransportStatus(transport, status, progress);
-        break;
-    }
-}
-
-nsHttpConnectionInfo *
-nsHttpPipeline::ConnectionInfo()
-{
-    nsAHttpTransaction *trans = Request(0) ? Request(0) : Response(0);
-    if (!trans) {
-        return nullptr;
-    }
-    return trans->ConnectionInfo();
-}
-
-bool
-nsHttpPipeline::IsDone()
-{
-    bool done = true;
-
-    uint32_t i, count = mRequestQ.Length();
-    for (i = 0; done && (i < count); i++)
-        done = Request(i)->IsDone();
-
-    count = mResponseQ.Length();
-    for (i = 0; done && (i < count); i++)
-        done = Response(i)->IsDone();
-
-    return done;
-}
-
-nsresult
-nsHttpPipeline::Status()
-{
-    return mStatus;
-}
-
-uint32_t
-nsHttpPipeline::Caps()
-{
-    nsAHttpTransaction *trans = Request(0);
-    if (!trans)
-        trans = Response(0);
-
-    return trans ? trans->Caps() : 0;
-}
-
-void
-nsHttpPipeline::SetDNSWasRefreshed()
-{
-    nsAHttpTransaction *trans = Request(0);
-    if (!trans)
-        trans = Response(0);
-
-    if (trans)
-      trans->SetDNSWasRefreshed();
-}
-
-uint64_t
-nsHttpPipeline::Available()
-{
-    uint64_t result = 0;
-
-    int32_t i, count = mRequestQ.Length();
-    for (i=0; i<count; ++i)
-        result += Request(i)->Available();
-    return result;
-}
-
-nsresult
-nsHttpPipeline::ReadFromPipe(nsIInputStream *stream,
-                             void *closure,
-                             const char *buf,
-                             uint32_t offset,
-                             uint32_t count,
-                             uint32_t *countRead)
-{
-    nsHttpPipeline *self = (nsHttpPipeline *) closure;
-    return self->mReader->OnReadSegment(buf, count, countRead);
-}
-
-nsresult
-nsHttpPipeline::ReadSegments(nsAHttpSegmentReader *reader,
-                             uint32_t count,
-                             uint32_t *countRead)
-{
-    LOG(("nsHttpPipeline::ReadSegments [this=%p count=%u]\n", this, count));
-
-    MOZ_ASSERT(PR_GetCurrentThread() == gSocketThread);
-
-    if (mClosed) {
-        *countRead = 0;
-        return mStatus;
-    }
-
-    nsresult rv;
-    uint64_t avail = 0;
-    if (mSendBufIn) {
-        rv = mSendBufIn->Available(&avail);
-        if (NS_FAILED(rv)) return rv;
-    }
-
-    if (avail == 0) {
-        rv = FillSendBuf();
-        if (NS_FAILED(rv)) return rv;
-
-        rv = mSendBufIn->Available(&avail);
-        if (NS_FAILED(rv)) return rv;
-
-        // return EOF if send buffer is empty
-        if (avail == 0) {
-            *countRead = 0;
-            return NS_OK;
-        }
-    }
-
-    // read no more than what was requested
-    if (avail > count)
-        avail = count;
-
-    mReader = reader;
-
-    // avail is under 4GB, so casting to uint32_t is safe
-    rv = mSendBufIn->ReadSegments(ReadFromPipe, this, (uint32_t)avail, countRead);
-
-    mReader = nullptr;
-    return rv;
-}
-
-nsresult
-nsHttpPipeline::WriteSegments(nsAHttpSegmentWriter *writer,
-                              uint32_t count,
-                              uint32_t *countWritten)
-{
-    LOG(("nsHttpPipeline::WriteSegments [this=%p count=%u]\n", this, count));
-
-    MOZ_ASSERT(PR_GetCurrentThread() == gSocketThread);
-
-    if (mClosed)
-        return NS_SUCCEEDED(mStatus) ? NS_BASE_STREAM_CLOSED : mStatus;
-
-    nsAHttpTransaction *trans;
-    nsresult rv;
-
-    trans = Response(0);
-    // This code deals with the establishment of a CONNECT tunnel through
-    // an HTTP proxy. It allows the connection to do the CONNECT/200
-    // HTTP transaction to establish a tunnel as a precursor to the
-    // actual pipeline of regular HTTP transactions.
-    if (!trans && mRequestQ.Length() &&
-        mConnection->IsProxyConnectInProgress()) {
-        LOG(("nsHttpPipeline::WriteSegments [this=%p] Forced Delegation\n",
-             this));
-        trans = Request(0);
-    }
-
-    if (!trans) {
-        if (mRequestQ.Length() > 0)
-            rv = NS_BASE_STREAM_WOULD_BLOCK;
-        else
-            rv = NS_BASE_STREAM_CLOSED;
-    } else {
-        //
-        // ask the transaction to consume data from the connection.
-        // PushBack may be called recursively.
-        //
-        rv = trans->WriteSegments(writer, count, countWritten);
-
-        if (rv == NS_BASE_STREAM_CLOSED || trans->IsDone()) {
-            trans->Close(NS_OK);
-
-            // Release the transaction if it is not IsProxyConnectInProgress()
-            if (trans == Response(0)) {
-                mResponseQ.RemoveElementAt(0);
-                mResponseIsPartial = false;
-                ++mHttp1xTransactionCount;
-            }
-
-            // ask the connection manager to add additional transactions
-            // to our pipeline.
-            RefPtr<nsHttpConnectionInfo> ci;
-            GetConnectionInfo(getter_AddRefs(ci));
-            if (ci)
-                gHttpHandler->ConnMgr()->ProcessPendingQForEntry(ci);
-        }
-        else
-            mResponseIsPartial = true;
-    }
-
-    if (mPushBackLen) {
-        nsHttpPushBackWriter pushBackWriter(mPushBackBuf, mPushBackLen);
-        uint32_t len = mPushBackLen, n;
-        mPushBackLen = 0;
-
-        // This progress notification has previously been sent from
-        // the socket transport code, but it was delivered to the
-        // previous transaction on the pipeline.
-        nsITransport *transport = Transport();
-        if (transport)
-            OnTransportStatus(transport, NS_NET_STATUS_RECEIVING_FROM,
-                              mReceivingFromProgress);
-
-        // the push back buffer is never larger than NS_HTTP_SEGMENT_SIZE,
-        // so we are guaranteed that the next response will eat the entire
-        // push back buffer (even though it might again call PushBack).
-        rv = WriteSegments(&pushBackWriter, len, &n);
-    }
-
-    return rv;
-}
-
-uint32_t
-nsHttpPipeline::CancelPipeline(nsresult originalReason)
-{
-    uint32_t i, reqLen, respLen, total;
-    nsAHttpTransaction *trans;
-
-    reqLen = mRequestQ.Length();
-    respLen = mResponseQ.Length();
-    total = reqLen + respLen;
-
-    // don't count the first response, if presnet
-    if (respLen)
-        total--;
-
-    if (!total)
-        return 0;
-
-    // any pending requests can ignore this error and be restarted
-    // unless it is during a CONNECT tunnel request
-    for (i = 0; i < reqLen; ++i) {
-        trans = Request(i);
-        if (mConnection && mConnection->IsProxyConnectInProgress())
-            trans->Close(originalReason);
-        else
-            trans->Close(NS_ERROR_NET_RESET);
-    }
-    mRequestQ.Clear();
-
-    // any pending responses can be restarted except for the first one,
-    // that we might want to finish on this pipeline or cancel individually.
-    // Higher levels of callers ensure that we don't process non-idempotent
-    // tranasction with the NS_HTTP_ALLOW_PIPELINING bit set
-    for (i = 1; i < respLen; ++i) {
-        trans = Response(i);
-        trans->Close(NS_ERROR_NET_RESET);
-    }
-
-    if (respLen > 1)
-        mResponseQ.TruncateLength(1);
-
-    DontReuse();
-    Classify(nsAHttpTransaction::CLASS_SOLO);
-
-    return total;
-}
-
-void
-nsHttpPipeline::Close(nsresult reason)
-{
-    LOG(("nsHttpPipeline::Close [this=%p reason=%" PRIx32 "]\n",
-         this, static_cast<uint32_t>(reason)));
-
-    if (mClosed) {
-        LOG(("  already closed\n"));
-        return;
-    }
-
-    // the connection is going away!
-    mStatus = reason;
-    mClosed = true;
-
-    RefPtr<nsHttpConnectionInfo> ci;
-    GetConnectionInfo(getter_AddRefs(ci));
-    uint32_t numRescheduled = CancelPipeline(reason);
-
-    // numRescheduled can be 0 if there is just a single response in the
-    // pipeline object. That isn't really a meaningful pipeline that
-    // has been forced to be rescheduled so it does not need to generate
-    // negative feedback.
-    if (ci && numRescheduled)
-        gHttpHandler->ConnMgr()->PipelineFeedbackInfo(
-            ci, nsHttpConnectionMgr::RedCanceledPipeline, nullptr, 0);
-
-    nsAHttpTransaction *trans = Response(0);
-    if (!trans)
-        return;
-
-    // The current transaction can be restarted via reset
-    // if the response has not started to arrive and the reason
-    // for failure is innocuous (e.g. not an SSL error)
-    if (!mResponseIsPartial &&
-        (reason == NS_ERROR_NET_RESET ||
-         reason == NS_OK ||
-         reason == NS_ERROR_NET_TIMEOUT ||
-         reason == NS_BASE_STREAM_CLOSED)) {
-        trans->Close(NS_ERROR_NET_RESET);
-    }
-    else {
-        trans->Close(reason);
-    }
-
-    mResponseQ.Clear();
-}
-
-nsresult
-nsHttpPipeline::OnReadSegment(const char *segment,
-                              uint32_t count,
-                              uint32_t *countRead)
-{
-    return mSendBufOut->Write(segment, count, countRead);
-}
-
-nsresult
-nsHttpPipeline::FillSendBuf()
-{
-    // reads from request queue, moving transactions to response queue
-    // when they have been completely read.
-
-    nsresult rv;
-
-    if (!mSendBufIn) {
-        // allocate a single-segment pipe
-        rv = NS_NewPipe(getter_AddRefs(mSendBufIn),
-                        getter_AddRefs(mSendBufOut),
-                        nsIOService::gDefaultSegmentSize,  /* segment size */
-                        nsIOService::gDefaultSegmentSize,  /* max size */
-                        true, true);
-        if (NS_FAILED(rv)) return rv;
-    }
-
-    uint32_t n;
-    uint64_t avail;
-    RefPtr<nsAHttpTransaction> trans;
-    nsITransport *transport = Transport();
-
-    while ((trans = Request(0)) != nullptr) {
-        avail = trans->Available();
-        if (avail) {
-            // if there is already a response in the responseq then this
-            // new data comprises a pipeline. Update the transaction in the
-            // response queue to reflect that if necessary. We are now sending
-            // out a request while we haven't received all responses.
-            nsAHttpTransaction *response = Response(0);
-            if (response && !response->PipelinePosition())
-                response->SetPipelinePosition(1);
-            rv = trans->ReadSegments(this, (uint32_t)std::min(avail, (uint64_t)UINT32_MAX), &n);
-            if (NS_FAILED(rv)) return rv;
-
-            if (n == 0) {
-                LOG(("send pipe is full"));
-                break;
-            }
-
-            mSendingToProgress += n;
-            if (!mSuppressSendEvents && transport) {
-                // Simulate a SENDING_TO event
-                trans->OnTransportStatus(transport,
-                                         NS_NET_STATUS_SENDING_TO,
-                                         mSendingToProgress);
-            }
-        }
-
-        avail = trans->Available();
-        if (avail == 0) {
-            // move transaction from request queue to response queue
-            mRequestQ.RemoveElementAt(0);
-            mResponseQ.AppendElement(trans);
-            mRequestIsPartial = false;
-
-            if (!mSuppressSendEvents && transport) {
-                // Simulate a WAITING_FOR event
-                trans->OnTransportStatus(transport,
-                                         NS_NET_STATUS_WAITING_FOR,
-                                         mSendingToProgress);
-            }
-
-            // It would be good to re-enable data read handlers via ResumeRecv()
-            // except the read handler code can be synchronously dispatched on
-            // the stack.
-        }
-        else
-            mRequestIsPartial = true;
-    }
-    return NS_OK;
-}
-
-} // namespace net
-} // namespace mozilla
deleted file mode 100644
--- a/netwerk/protocol/http/nsHttpPipeline.h
+++ /dev/null
@@ -1,105 +0,0 @@
-/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * 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 nsHttpPipeline_h__
-#define nsHttpPipeline_h__
-
-#include "nsAHttpConnection.h"
-#include "nsAHttpTransaction.h"
-#include "nsTArray.h"
-#include "nsCOMPtr.h"
-
-class nsIInputStream;
-class nsIOutputStream;
-
-namespace mozilla { namespace net {
-
-class nsHttpPipeline final : public nsAHttpConnection
-                           , public nsAHttpTransaction
-                           , public nsAHttpSegmentReader
-{
-public:
-    NS_DECL_THREADSAFE_ISUPPORTS
-    NS_DECL_NSAHTTPCONNECTION(mConnection)
-    NS_DECL_NSAHTTPTRANSACTION
-    NS_DECL_NSAHTTPSEGMENTREADER
-
-    nsHttpPipeline();
-
-  bool ResponseTimeoutEnabled() const override final {
-    return true;
-  }
-
-private:
-    virtual ~nsHttpPipeline();
-
-    nsresult FillSendBuf();
-
-    static nsresult ReadFromPipe(nsIInputStream *, void *, const char *,
-                                 uint32_t, uint32_t, uint32_t *);
-
-    // convenience functions
-    nsAHttpTransaction *Request(int32_t i)
-    {
-        if (mRequestQ.Length() == 0)
-            return nullptr;
-
-        return mRequestQ[i];
-    }
-    nsAHttpTransaction *Response(int32_t i)
-    {
-        if (mResponseQ.Length() == 0)
-            return nullptr;
-
-        return mResponseQ[i];
-    }
-
-    // overload of nsAHttpTransaction::QueryPipeline()
-    nsHttpPipeline *QueryPipeline() override;
-
-    RefPtr<nsAHttpConnection>   mConnection;
-    nsTArray<RefPtr<nsAHttpTransaction> > mRequestQ;
-    nsTArray<RefPtr<nsAHttpTransaction> > mResponseQ;
-    nsresult                      mStatus;
-
-    // these flags indicate whether or not the first request or response
-    // is partial.  a partial request means that Request(0) has been
-    // partially written out to the socket.  a partial response means
-    // that Response(0) has been partially read in from the socket.
-    bool mRequestIsPartial;
-    bool mResponseIsPartial;
-
-    // indicates whether or not the pipeline has been explicitly closed.
-    bool mClosed;
-
-    // indicates whether or not a true pipeline (more than 1 request without
-    // a synchronous response) has been formed.
-    bool mUtilizedPipeline;
-
-    // used when calling ReadSegments/WriteSegments on a transaction.
-    nsAHttpSegmentReader *mReader;
-
-    // send buffer
-    nsCOMPtr<nsIInputStream>  mSendBufIn;
-    nsCOMPtr<nsIOutputStream> mSendBufOut;
-
-    // the push back buffer.  not exceeding nsIOService::gDefaultSegmentSize bytes.
-    char     *mPushBackBuf;
-    uint32_t  mPushBackLen;
-    uint32_t  mPushBackMax;
-
-    // The number of transactions completed on this pipeline.
-    uint32_t  mHttp1xTransactionCount;
-
-    // For support of OnTransportStatus()
-    int64_t  mReceivingFromProgress;
-    int64_t  mSendingToProgress;
-    bool     mSuppressSendEvents;
-};
-
-} // namespace net
-} // namespace mozilla
-
-#endif // nsHttpPipeline_h__
--- a/netwerk/protocol/http/nsHttpTransaction.cpp
+++ b/netwerk/protocol/http/nsHttpTransaction.cpp
@@ -99,18 +99,16 @@ nsHttpTransaction::nsHttpTransaction()
     , mInvalidResponseBytesRead(0)
     , mPushedStream(nullptr)
     , mInitialRwin(0)
     , mChunkedDecoder(nullptr)
     , mStatus(NS_OK)
     , mPriority(0)
     , mRestartCount(0)
     , mCaps(0)
-    , mClassification(CLASS_GENERAL)
-    , mPipelinePosition(0)
     , mHttpVersion(NS_HTTP_VERSION_UNKNOWN)
     , mHttpResponseCode(0)
     , mCurrentHttpResponseHeaderSize(0)
     , mCapsToClear(0)
     , mResponseIsComplete(false)
     , mClosed(false)
     , mConnected(false)
     , mHaveStatusLine(false)
@@ -140,17 +138,16 @@ nsHttpTransaction::nsHttpTransaction()
     , mSubmittedRatePacing(false)
     , mPassedRatePacing(false)
     , mSynchronousRatePaceRequest(false)
     , mClassOfService(0)
     , m0RTTInProgress(false)
     , mTransportStatus(NS_OK)
 {
     LOG(("Creating nsHttpTransaction @%p\n", this));
-    gHttpHandler->GetMaxPipelineObjectSize(&mMaxPipelineObjectSize);
 
 #ifdef MOZ_VALGRIND
     memset(&mSelfAddr, 0, sizeof(NetAddr));
     memset(&mPeerAddr, 0, sizeof(NetAddr));
 #endif
     mSelfAddr.raw.family = PR_AF_UNSPEC;
     mPeerAddr.raw.family = PR_AF_UNSPEC;
 }
@@ -176,55 +173,16 @@ nsHttpTransaction::~nsHttpTransaction()
     mConnection = nullptr;
 
     delete mResponseHead;
     delete mForTakeResponseHead;
     delete mChunkedDecoder;
     ReleaseBlockingTransaction();
 }
 
-nsHttpTransaction::Classifier
-nsHttpTransaction::Classify()
-{
-    if (!(mCaps & NS_HTTP_ALLOW_PIPELINING))
-        return (mClassification = CLASS_SOLO);
-
-    if (mRequestHead->HasHeader(nsHttp::If_Modified_Since) ||
-        mRequestHead->HasHeader(nsHttp::If_None_Match))
-        return (mClassification = CLASS_REVALIDATION);
-
-    nsAutoCString accept;
-    bool hasAccept = NS_SUCCEEDED(mRequestHead->GetHeader(nsHttp::Accept, accept));
-    if (hasAccept && StringBeginsWith(accept, NS_LITERAL_CSTRING("image/"))) {
-        return (mClassification = CLASS_IMAGE);
-    }
-
-    if (hasAccept && StringBeginsWith(accept, NS_LITERAL_CSTRING("text/css"))) {
-        return (mClassification = CLASS_SCRIPT);
-    }
-
-    mClassification = CLASS_GENERAL;
-
-    nsAutoCString requestURI;
-    mRequestHead->RequestURI(requestURI);
-    int32_t queryPos = requestURI.FindChar('?');
-    if (queryPos == kNotFound) {
-        if (StringEndsWith(requestURI,
-                           NS_LITERAL_CSTRING(".js")))
-            mClassification = CLASS_SCRIPT;
-    }
-    else if (queryPos >= 3 &&
-             Substring(requestURI, queryPos - 3, 3).
-             EqualsLiteral(".js")) {
-        mClassification = CLASS_SCRIPT;
-    }
-
-    return mClassification;
-}
-
 nsresult
 nsHttpTransaction::Init(uint32_t caps,
                         nsHttpConnectionInfo *cinfo,
                         nsHttpRequestHead *requestHead,
                         nsIInputStream *requestBody,
                         bool requestBodyHasHeaders,
                         nsIEventTarget *target,
                         nsIInterfaceRequestor *callbacks,
@@ -410,18 +368,16 @@ nsHttpTransaction::Init(uint32_t caps,
     if (NS_FAILED(rv)) return rv;
 
 #ifdef WIN32 // bug 1153929
     MOZ_DIAGNOSTIC_ASSERT(mPipeOut);
     uint32_t * vtable = (uint32_t *) mPipeOut.get();
     MOZ_DIAGNOSTIC_ASSERT(*vtable != 0);
 #endif // WIN32
 
-    Classify();
-
     nsCOMPtr<nsIAsyncInputStream> tmp(mPipeIn);
     tmp.forget(responseBody);
     return NS_OK;
 }
 
 // This method should only be used on the socket thread
 nsAHttpConnection *
 nsHttpTransaction::Connection()
@@ -438,17 +394,17 @@ nsHttpTransaction::GetConnectionReferenc
     return connection.forget();
 }
 
 nsHttpResponseHead *
 nsHttpTransaction::TakeResponseHead()
 {
     MOZ_ASSERT(!mResponseHeadTaken, "TakeResponseHead called 2x");
 
-    // Lock RestartInProgress() and TakeResponseHead() against main thread
+    // Lock TakeResponseHead() against main thread
     MutexAutoLock lock(*nsHttp::GetLock());
 
     mResponseHeadTaken = true;
 
     // Prefer mForTakeResponseHead over mResponseHead. It is always a complete
     // set of headers.
     nsHttpResponseHead *head;
     if (mForTakeResponseHead) {
@@ -599,17 +555,19 @@ nsHttpTransaction::OnTransportStatus(nsI
     if (TimingEnabled() && GetRequestStart().IsNull()) {
         if (status == NS_NET_STATUS_RESOLVING_HOST) {
             SetDomainLookupStart(TimeStamp::Now(), true);
         } else if (status == NS_NET_STATUS_RESOLVED_HOST) {
             SetDomainLookupEnd(TimeStamp::Now());
         } else if (status == NS_NET_STATUS_CONNECTING_TO) {
             SetConnectStart(TimeStamp::Now());
         } else if (status == NS_NET_STATUS_CONNECTED_TO) {
-            SetConnectEnd(TimeStamp::Now());
+            SetConnectEnd(TimeStamp::Now(), true);
+        } else if (status == NS_NET_STATUS_TLS_HANDSHAKE_ENDED) {
+            SetConnectEnd(TimeStamp::Now(), false);
         }
     }
 
     if (!mTransportSink)
         return;
 
     MOZ_ASSERT(PR_GetCurrentThread() == gSocketThread);
 
@@ -621,26 +579,25 @@ nsHttpTransaction::OnTransportStatus(nsI
             (status == NS_NET_STATUS_WAITING_FOR))
             mActivityDistributor->ObserveActivity(
                 mChannel,
                 NS_HTTP_ACTIVITY_TYPE_HTTP_TRANSACTION,
                 NS_HTTP_ACTIVITY_SUBTYPE_REQUEST_BODY_SENT,
                 PR_Now(), 0, EmptyCString());
 
         // report the status and progress
-        if (!mRestartInProgressVerifier.IsDiscardingContent())
-            mActivityDistributor->ObserveActivity(
-                mChannel,
-                NS_HTTP_ACTIVITY_TYPE_SOCKET_TRANSPORT,
-                static_cast<uint32_t>(status),
-                PR_Now(),
-                progress,
-                EmptyCString());
+        mActivityDistributor->ObserveActivity(
+            mChannel,
+            NS_HTTP_ACTIVITY_TYPE_SOCKET_TRANSPORT,
+            static_cast<uint32_t>(status),
+            PR_Now(),
+            progress,
+            EmptyCString());
     }
-
+    
     // nsHttpChannel synthesizes progress events in OnDataAvailable
     if (status == NS_NET_STATUS_RECEIVING_FROM)
         return;
 
     int64_t progressMax;
 
     if (status == NS_NET_STATUS_SENDING_TO) {
         // suppress progress when only writing request headers
@@ -1024,34 +981,19 @@ nsHttpTransaction::Close(nsresult reason
 
         if (reason == psm::GetXPCOMFromNSSError(SSL_ERROR_DOWNGRADE_WITH_EARLY_DATA) ||
             (!mReceivedData &&
             ((mRequestHead && mRequestHead->IsSafeMethod()) ||
              !reallySentData || connReused))) {
             // if restarting fails, then we must proceed to close the pipe,
             // which will notify the channel that the transaction failed.
 
-            if (mPipelinePosition) {
-                gHttpHandler->ConnMgr()->PipelineFeedbackInfo(
-                    mConnInfo, nsHttpConnectionMgr::RedCanceledPipeline,
-                    nullptr, 0);
-            }
             if (NS_SUCCEEDED(Restart()))
                 return;
         }
-        else if (!mResponseIsComplete && mPipelinePosition &&
-                 reason == NS_ERROR_NET_RESET) {
-            // due to unhandled rst on a pipeline - safe to
-            // restart as only idempotent is found there
-
-            gHttpHandler->ConnMgr()->PipelineFeedbackInfo(
-                mConnInfo, nsHttpConnectionMgr::RedCorruptedContent, nullptr, 0);
-            if (NS_SUCCEEDED(RestartInProgress()))
-                return;
-        }
     }
 
     if ((mChunkedDecoder || (mContentLength >= int64_t(0))) &&
         (NS_SUCCEEDED(reason) && !mResponseIsComplete)) {
 
         NS_WARNING("Partial transfer, incomplete HTTP response received");
 
         if ((mHttpResponseCode / 100 == 2) &&
@@ -1072,30 +1014,16 @@ nsHttpTransaction::Close(nsresult reason
             // whether or not we generate an error for the transaction
             // bad framing means we don't want a pconn
             mConnection->DontReuse();
         }
     }
 
     bool relConn = true;
     if (NS_SUCCEEDED(reason)) {
-        if (!mResponseIsComplete) {
-            // The response has not been delimited with a high-confidence
-            // algorithm like Content-Length or Chunked Encoding. We
-            // need to use a strong framing mechanism to pipeline.
-            gHttpHandler->ConnMgr()->PipelineFeedbackInfo(
-                mConnInfo, nsHttpConnectionMgr::BadInsufficientFraming,
-                nullptr, mClassification);
-        }
-        else if (mPipelinePosition) {
-            // report this success as feedback
-            gHttpHandler->ConnMgr()->PipelineFeedbackInfo(
-                mConnInfo, nsHttpConnectionMgr::GoodCompletedOK,
-                nullptr, mPipelinePosition);
-        }
 
         // the server has not sent the final \r\n terminating the header
         // section, and there may still be a header line unparsed.  let's make
         // sure we parse the remaining header line, and then hopefully, the
         // response will be usable (see bug 88792).
         if (!mHaveAllHeaders) {
             char data = '\n';
             uint32_t unused;
@@ -1154,41 +1082,16 @@ nsHttpTransaction::Close(nsresult reason
 }
 
 nsHttpConnectionInfo *
 nsHttpTransaction::ConnectionInfo()
 {
     return mConnInfo.get();
 }
 
-nsresult
-nsHttpTransaction::AddTransaction(nsAHttpTransaction *trans)
-{
-    return NS_ERROR_NOT_IMPLEMENTED;
-}
-
-uint32_t
-nsHttpTransaction::PipelineDepth()
-{
-    return IsDone() ? 0 : 1;
-}
-
-nsresult
-nsHttpTransaction::SetPipelinePosition(int32_t position)
-{
-    mPipelinePosition = position;
-    return NS_OK;
-}
-
-int32_t
-nsHttpTransaction::PipelinePosition()
-{
-    return mPipelinePosition;
-}
-
 bool // NOTE BASE CLASS
 nsAHttpTransaction::ResponseTimeoutEnabled() const
 {
     return false;
 }
 
 PRIntervalTime // NOTE BASE CLASS
 nsAHttpTransaction::ResponseTimeout()
@@ -1202,81 +1105,16 @@ nsHttpTransaction::ResponseTimeoutEnable
     return mResponseTimeoutEnabled;
 }
 
 //-----------------------------------------------------------------------------
 // nsHttpTransaction <private>
 //-----------------------------------------------------------------------------
 
 nsresult
-nsHttpTransaction::RestartInProgress()
-{
-    MOZ_ASSERT(PR_GetCurrentThread() == gSocketThread);
-
-    if ((mRestartCount + 1) >= gHttpHandler->MaxRequestAttempts()) {
-        LOG(("nsHttpTransaction::RestartInProgress() "
-             "reached max request attempts, failing transaction %p\n", this));
-        return NS_ERROR_NET_RESET;
-    }
-
-    // Lock RestartInProgress() and TakeResponseHead() against main thread
-    MutexAutoLock lock(*nsHttp::GetLock());
-
-    // Don't try and RestartInProgress() things that haven't gotten a response
-    // header yet. Those should be handled under the normal restart() path if
-    // they are eligible.
-    if (!mHaveAllHeaders)
-        return NS_ERROR_NET_RESET;
-
-    if (mCaps & NS_HTTP_STICKY_CONNECTION) {
-        return NS_ERROR_NET_RESET;
-    }
-
-    // don't try and restart 0.9 or non 200/Get HTTP/1
-    if (!mRestartInProgressVerifier.IsSetup())
-        return NS_ERROR_NET_RESET;
-
-    LOG(("Will restart transaction %p and skip first %" PRId64 " bytes, "
-         "old Content-Length %" PRId64,
-         this, mContentRead, mContentLength));
-
-    mRestartInProgressVerifier.SetAlreadyProcessed(
-        std::max(mRestartInProgressVerifier.AlreadyProcessed(), mContentRead));
-
-    if (!mResponseHeadTaken && !mForTakeResponseHead) {
-        // TakeResponseHeader() has not been called yet and this
-        // is the first restart. Store the resp headers exclusively
-        // for TakeResponseHead() which is called from the main thread and
-        // could happen at any time - so we can't continue to modify those
-        // headers (which restarting will effectively do)
-        mForTakeResponseHead = mResponseHead;
-        mResponseHead = nullptr;
-    }
-
-    if (mResponseHead) {
-        mResponseHead->Reset();
-    }
-
-    mContentRead = 0;
-    mContentLength = -1;
-    delete mChunkedDecoder;
-    mChunkedDecoder = nullptr;
-    mHaveStatusLine = false;
-    mHaveAllHeaders = false;
-    mHttpResponseMatched = false;
-    mResponseIsComplete = false;
-    mDidContentStart = false;
-    mNoContent = false;
-    mSentData = false;
-    mReceivedData = false;
-
-    return Restart();
-}
-
-nsresult
 nsHttpTransaction::Restart()
 {
     MOZ_ASSERT(PR_GetCurrentThread() == gSocketThread);
 
     // limit the number of restart attempts - bug 92224
     if (++mRestartCount >= gHttpHandler->MaxRequestAttempts()) {
         LOG(("reached max request attempts, failing transaction @%p\n", this));
         return NS_ERROR_NET_RESET;
@@ -1299,22 +1137,16 @@ nsHttpTransaction::Restart()
         MutexAutoLock lock(mLock);
         mConnection = nullptr;
     }
 
     // Reset this to our default state, since this may change from one restart
     // to the next
     mReuseOnRestart = false;
 
-    // disable pipelining for the next attempt in case pipelining caused the
-    // reset.  this is being overly cautious since we don't know if pipelining
-    // was the problem here.
-    mCaps &= ~NS_HTTP_ALLOW_PIPELINING;
-    SetPipelinePosition(0);
-
     if (!mConnInfo->GetRoutedHost().IsEmpty()) {
         MutexAutoLock lock(*nsHttp::GetLock());
         RefPtr<nsHttpConnectionInfo> ci;
          mConnInfo->CloneAsDirectRoute(getter_AddRefs(ci));
          mConnInfo = ci;
         if (mRequestHead) {
             mRequestHead->SetHeader(nsHttp::Alternate_Service_Used, NS_LITERAL_CSTRING("0"));
         }
@@ -1434,19 +1266,16 @@ nsHttpTransaction::ParseLineSegment(char
         // not a continuation of the previous or if we haven't
         // parsed the status line yet, then parse the contents
         // of mLineBuf.
         mLineBuf.Truncate(mLineBuf.Length() - 1);
         if (!mHaveStatusLine || (*segment != ' ' && *segment != '\t')) {
             nsresult rv = ParseLine(mLineBuf);
             mLineBuf.Truncate();
             if (NS_FAILED(rv)) {
-                gHttpHandler->ConnMgr()->PipelineFeedbackInfo(
-                    mConnInfo, nsHttpConnectionMgr::RedCorruptedContent,
-                    nullptr, 0);
                 return rv;
             }
         }
     }
 
     // append segment to mLineBuf...
     mLineBuf.Append(segment, len);
 
@@ -1615,18 +1444,17 @@ nsHttpTransaction::HandleContentStart()
 
         // Save http version, mResponseHead isn't available anymore after
         // TakeResponseHead() is called
         mHttpVersion = mResponseHead->Version();
         mHttpResponseCode = mResponseHead->Status();
 
         // notify the connection, give it a chance to cause a reset.
         bool reset = false;
-        if (!mRestartInProgressVerifier.IsSetup())
-            mConnection->OnHeadersAvailable(this, mRequestHead, mResponseHead, &reset);
+        mConnection->OnHeadersAvailable(this, mRequestHead, mResponseHead, &reset);
 
         // looks like we should ignore this response, resetting...
         if (reset) {
             LOG(("resetting transaction's response head\n"));
             mHaveAllHeaders = false;
             mHaveStatusLine = false;
             mReceivedData = false;
             mSentData = false;
@@ -1661,31 +1489,23 @@ nsHttpTransaction::HandleContentStart()
         }
 
         if (mResponseHead->Status() == 200 &&
             mConnection->IsProxyConnectInProgress()) {
             // successful CONNECTs do not have response bodies
             mNoContent = true;
         }
         mConnection->SetLastTransactionExpectedNoContent(mNoContent);
-        if (mInvalidResponseBytesRead)
-            gHttpHandler->ConnMgr()->PipelineFeedbackInfo(
-                mConnInfo, nsHttpConnectionMgr::BadInsufficientFraming,
-                nullptr, mClassification);
 
-        if (mNoContent)
+        if (mNoContent) {
             mContentLength = 0;
-        else {
+        } else {
             // grab the content-length from the response headers
             mContentLength = mResponseHead->ContentLength();
 
-            if ((mClassification != CLASS_SOLO) &&
-                (mContentLength > mMaxPipelineObjectSize))
-                CancelPipeline(nsHttpConnectionMgr::BadUnexpectedLarge);
-
             // handle chunked encoding here, so we'll know immediately when
             // we're done with the socket.  please note that _all_ other
             // decoding is done when the channel receives the content data
             // so as not to block the socket transport thread too much.
             if (mResponseHead->Version() >= NS_HTTP_VERSION_1_0 &&
                 mResponseHead->HasHeaderValue(nsHttp::Transfer_Encoding, "chunked")) {
                 // we only support the "chunked" transfer encoding right now.
                 mChunkedDecoder = new nsHttpChunkedDecoder();
@@ -1697,30 +1517,19 @@ nsHttpTransaction::HandleContentStart()
                     if (mConnection) {
                         mConnection->DontReuse();
                     }
                 }
             }
             else if (mContentLength == int64_t(-1))
                 LOG(("waiting for the server to close the connection.\n"));
         }
-        if (mRestartInProgressVerifier.IsSetup() &&
-            !mRestartInProgressVerifier.Verify(mContentLength, mResponseHead)) {
-            LOG(("Restart in progress subsequent transaction failed to match"));
-            return NS_ERROR_ABORT;
-        }
     }
 
     mDidContentStart = true;
-
-    // The verifier only initializes itself once (from the first iteration of
-    // a transaction that gets far enough to have response headers)
-    if (mRequestHead->IsGet())
-        mRestartInProgressVerifier.Set(mContentLength, mResponseHead);
-
     return NS_OK;
 }
 
 // called on the socket thread
 nsresult
 nsHttpTransaction::HandleContent(char *buf,
                                  uint32_t count,
                                  uint32_t *contentRead,
@@ -1771,48 +1580,24 @@ nsHttpTransaction::HandleContent(char *b
         }
     }
     else {
         // when we are just waiting for the server to close the connection...
         // (no explicit content-length given)
         *contentRead = count;
     }
 
-    int64_t toReadBeforeRestart =
-        mRestartInProgressVerifier.ToReadBeforeRestart();
-
-    if (toReadBeforeRestart && *contentRead) {
-        uint32_t ignore =
-            static_cast<uint32_t>(std::min<int64_t>(toReadBeforeRestart, UINT32_MAX));
-        ignore = std::min(*contentRead, ignore);
-        LOG(("Due To Restart ignoring %d of remaining %" PRId64,
-             ignore, toReadBeforeRestart));
-        *contentRead -= ignore;
-        mContentRead += ignore;
-        mRestartInProgressVerifier.HaveReadBeforeRestart(ignore);
-        memmove(buf, buf + ignore, *contentRead + *contentRemaining);
-    }
-
     if (*contentRead) {
         // update count of content bytes read and report progress...
         mContentRead += *contentRead;
     }
 
     LOG(("nsHttpTransaction::HandleContent [this=%p count=%u read=%u mContentRead=%" PRId64 " mContentLength=%" PRId64 "]\n",
         this, count, *contentRead, mContentRead, mContentLength));
 
-    // Check the size of chunked responses. If we exceed the max pipeline size
-    // for this response reschedule the pipeline
-    if ((mClassification != CLASS_SOLO) &&
-        mChunkedDecoder &&
-        ((mContentRead + mChunkedDecoder->GetChunkRemaining()) >
-         mMaxPipelineObjectSize)) {
-        CancelPipeline(nsHttpConnectionMgr::BadUnexpectedLarge);
-    }
-
     // check for end-of-file
     if ((mContentRead == mContentLength) ||
         (mChunkedDecoder && mChunkedDecoder->ReachedEOF())) {
         // the transaction is done with a complete response.
         mTransactionDone = true;
         mResponseIsComplete = true;
         ReleaseBlockingTransaction();
 
@@ -1895,17 +1680,17 @@ nsHttpTransaction::ProcessData(char *buf
         // buf layout:
         //
         // +--------------------------------------+----------------+-----+
         // |              countRead               | countRemaining |     |
         // +--------------------------------------+----------------+-----+
         //
         // count          : bytes read from the socket
         // countRead      : bytes corresponding to this transaction
-        // countRemaining : bytes corresponding to next pipelined transaction
+        // countRemaining : bytes corresponding to next transaction on conn
         //
         // NOTE:
         // count > countRead + countRemaining <==> chunked transfer encoding
         //
         rv = HandleContent(buf, count, countRead, &countRemaining);
         if (NS_FAILED(rv)) return rv;
         // we may have read more than our share, in which case we must give
         // the excess bytes back to the connection
@@ -1920,43 +1705,25 @@ nsHttpTransaction::ProcessData(char *buf
             mContentDecodingCheck = true;
         }
     }
 
     return NS_OK;
 }
 
 void
-nsHttpTransaction::CancelPipeline(uint32_t reason)
-{
-    // reason is casted through a uint to avoid compiler header deps
-    gHttpHandler->ConnMgr()->PipelineFeedbackInfo(
-        mConnInfo,
-        static_cast<nsHttpConnectionMgr::PipelineFeedbackInfoType>(reason),
-        nullptr, mClassification);
-
-    mConnection->CancelPipeline(NS_ERROR_ABORT);
-
-    // Avoid pipelining this transaction on restart by classifying it as solo.
-    // This also prevents BadUnexpectedLarge from being reported more
-    // than one time per transaction.
-    mClassification = CLASS_SOLO;
-}
-
-
-void
 nsHttpTransaction::SetRequestContext(nsIRequestContext *aRequestContext)
 {
     LOG(("nsHttpTransaction %p SetRequestContext %p\n", this, aRequestContext));
     mRequestContext = aRequestContext;
 }
 
 // Called when the transaction marked for blocking is associated with a connection
-// (i.e. added to a new h1 conn, an idle http connection, or placed into
-// a http pipeline). It is safe to call this multiple times with it only
+// (i.e. added to a new h1 conn, an idle http connection, etc..)
+// It is safe to call this multiple times with it only
 // having an effect once.
 void
 nsHttpTransaction::DispatchedAsBlocking()
 {
     if (mDispatchedAsBlocking)
         return;
 
     LOG(("nsHttpTransaction %p dispatched as blocking\n", this));
@@ -2322,105 +2089,16 @@ nsHttpTransaction::OnOutputStreamReady(n
         mConnection->TransactionHasDataToRecv(this);
         nsresult rv = mConnection->ResumeRecv();
         if (NS_FAILED(rv))
             NS_ERROR("ResumeRecv failed");
     }
     return NS_OK;
 }
 
-// nsHttpTransaction::RestartVerifier
-
-static bool
-matchOld(nsHttpResponseHead *newHead, nsCString &old,
-         nsHttpAtom headerAtom)
-{
-    nsAutoCString val;
-
-    newHead->GetHeader(headerAtom, val);
-    if (!val.IsEmpty() && old.IsEmpty())
-        return false;
-    if (val.IsEmpty() && !old.IsEmpty())
-        return false;
-    if (!val.IsEmpty() && !old.Equals(val))
-        return false;
-    return true;
-}
-
-bool
-nsHttpTransaction::RestartVerifier::Verify(int64_t contentLength,
-                                           nsHttpResponseHead *newHead)
-{
-    if (mContentLength != contentLength)
-        return false;
-
-    if (newHead->Status() != 200)
-        return false;
-
-    if (!matchOld(newHead, mContentRange, nsHttp::Content_Range))
-        return false;
-
-    if (!matchOld(newHead, mLastModified, nsHttp::Last_Modified))
-        return false;
-
-    if (!matchOld(newHead, mETag, nsHttp::ETag))
-        return false;
-
-    if (!matchOld(newHead, mContentEncoding, nsHttp::Content_Encoding))
-        return false;
-
-    if (!matchOld(newHead, mTransferEncoding, nsHttp::Transfer_Encoding))
-        return false;
-
-    return true;
-}
-
-void
-nsHttpTransaction::RestartVerifier::Set(int64_t contentLength,
-                                        nsHttpResponseHead *head)
-{
-    if (mSetup)
-        return;
-
-    // If mSetup does not transition to true RestartInPogress() is later
-    // forbidden
-
-    // Only RestartInProgress with 200 response code
-    if (!head || (head->Status() != 200)) {
-        return;
-    }
-
-    mContentLength = contentLength;
-
-    nsAutoCString val;
-    if (NS_SUCCEEDED(head->GetHeader(nsHttp::ETag, val))) {
-        mETag = val;
-    }
-    if (NS_SUCCEEDED(head->GetHeader(nsHttp::Last_Modified, val))) {
-        mLastModified = val;
-    }
-    if (NS_SUCCEEDED(head->GetHeader(nsHttp::Content_Range, val))) {
-        mContentRange = val;
-    }
-    if (NS_SUCCEEDED(head->GetHeader(nsHttp::Content_Encoding, val))) {
-        mContentEncoding = val;
-    }
-    if (NS_SUCCEEDED(head->GetHeader(nsHttp::Transfer_Encoding, val))) {
-        mTransferEncoding = val;
-    }
-
-    // We can only restart with any confidence if we have a stored etag or
-    // last-modified header
-    if (mETag.IsEmpty() && mLastModified.IsEmpty()) {
-        return;
-    }
-
-    mSetup = true;
-}
-
 void
 nsHttpTransaction::GetNetworkAddresses(NetAddr &self, NetAddr &peer)
 {
     MutexAutoLock lock(mLock);
     self = mSelfAddr;
     peer = mPeerAddr;
 }
 
--- a/netwerk/protocol/http/nsHttpTransaction.h
+++ b/netwerk/protocol/http/nsHttpTransaction.h
@@ -114,24 +114,21 @@ public:
 
     void EnableKeepAlive() { mCaps |= NS_HTTP_ALLOW_KEEPALIVE; }
     void MakeSticky() { mCaps |= NS_HTTP_STICKY_CONNECTION; }
 
     // SetPriority() may only be used by the connection manager.
     void    SetPriority(int32_t priority) { mPriority = priority; }
     int32_t    Priority()                 { return mPriority; }
 
-    enum Classifier Classification() { return mClassification; }
-
     void PrintDiagnostics(nsCString &log);
 
     // Sets mPendingTime to the current time stamp or to a null time stamp (if now is false)
     void SetPendingTime(bool now = true) { mPendingTime = now ? TimeStamp::Now() : TimeStamp(); }
     const TimeStamp GetPendingTime() { return mPendingTime; }
-    bool UsesPipelining() const { return mCaps & NS_HTTP_ALLOW_PIPELINING; }
 
     // overload of nsAHttpTransaction::RequestContext()
     nsIRequestContext *RequestContext() override { return mRequestContext.get(); }
     void SetRequestContext(nsIRequestContext *aRequestContext);
     void DispatchedAsBlocking();
     void RemoveDispatchedAsBlocking();
 
     nsHttpTransaction *QueryHttpTransaction() override { return this; }
@@ -169,31 +166,27 @@ public:
 
     bool Do0RTT() override;
     nsresult Finish0RTT(bool aRestart, bool aAlpnChanged /* ignored */) override;
 private:
     friend class DeleteHttpTransaction;
     virtual ~nsHttpTransaction();
 
     nsresult Restart();
-    nsresult RestartInProgress();
     char    *LocateHttpStart(char *buf, uint32_t len,
                              bool aAllowPartialMatch);
     nsresult ParseLine(nsACString &line);
     nsresult ParseLineSegment(char *seg, uint32_t len);
     nsresult ParseHead(char *, uint32_t count, uint32_t *countRead);
     nsresult HandleContentStart();
     nsresult HandleContent(char *, uint32_t count, uint32_t *contentRead, uint32_t *contentRemaining);
     nsresult ProcessData(char *, uint32_t, uint32_t *);
     void     DeleteSelfOnConsumerThread();
     void     ReleaseBlockingTransaction();
 
-    Classifier Classify();
-    void       CancelPipeline(uint32_t reason);
-
     static nsresult ReadRequestSegment(nsIInputStream *, void *, const char *,
                                        uint32_t, uint32_t, uint32_t *);
     static nsresult WritePipeSegment(nsIOutputStream *, void *, char *,
                                      uint32_t, uint32_t, uint32_t *);
 
     bool TimingEnabled() const { return mCaps & NS_HTTP_TIMING_ENABLED; }
 
     bool ResponseTimeoutEnabled() const final;
@@ -274,19 +267,16 @@ private:
     TimingStruct                    mTimings;
 
     nsresult                        mStatus;
 
     int16_t                         mPriority;
 
     uint16_t                        mRestartCount;        // the number of times this transaction has been restarted
     uint32_t                        mCaps;
-    enum Classifier                 mClassification;
-    int32_t                         mPipelinePosition;
-    int64_t                         mMaxPipelineObjectSize;
 
     nsHttpVersion                   mHttpVersion;
     uint16_t                        mHttpResponseCode;
 
     uint32_t                        mCurrentHttpResponseHeaderSize;
 
     // mCapsToClear holds flags that should be cleared in mCaps, e.g. unset
     // NS_HTTP_REFRESH_DNS when DNS refresh request has completed to avoid
@@ -333,78 +323,16 @@ private:
 
     // protected by nsHttp::GetLock()
     nsHttpResponseHead             *mForTakeResponseHead;
     bool                            mResponseHeadTaken;
 
     // The time when the transaction was submitted to the Connection Manager
     TimeStamp                       mPendingTime;
 
-    class RestartVerifier
-    {
-
-        // When a idemptotent transaction has received part of its response body
-        // and incurs an error it can be restarted. To do this we mark the place
-        // where we stopped feeding the body to the consumer and start the
-        // network call over again. If everything we track (headers, length, etc..)
-        // matches up to the place where we left off then the consumer starts being
-        // fed data again with the new information. This can be done N times up
-        // to the normal restart (i.e. with no response info) limit.
-
-    public:
-        RestartVerifier()
-            : mContentLength(-1)
-            , mAlreadyProcessed(0)
-            , mToReadBeforeRestart(0)
-            , mSetup(false)
-        {}
-        ~RestartVerifier() {}
-
-        void Set(int64_t contentLength, nsHttpResponseHead *head);
-        bool Verify(int64_t contentLength, nsHttpResponseHead *head);
-        bool IsDiscardingContent() { return mToReadBeforeRestart != 0; }
-        bool IsSetup() { return mSetup; }
-        int64_t AlreadyProcessed() { return mAlreadyProcessed; }
-        void SetAlreadyProcessed(int64_t val) {
-            mAlreadyProcessed = val;
-            mToReadBeforeRestart = val;
-        }
-        int64_t ToReadBeforeRestart() { return mToReadBeforeRestart; }
-        void HaveReadBeforeRestart(uint32_t amt)
-        {
-            MOZ_ASSERT(amt <= mToReadBeforeRestart,
-                       "too large of a HaveReadBeforeRestart deduction");
-            mToReadBeforeRestart -= amt;
-        }
-
-    private:
-        // This is the data from the first complete response header
-        // used to make sure that all subsequent response headers match
-
-        int64_t                         mContentLength;
-        nsCString                       mETag;
-        nsCString                       mLastModified;
-        nsCString                       mContentRange;
-        nsCString                       mContentEncoding;
-        nsCString                       mTransferEncoding;
-
-        // This is the amount of data that has been passed to the channel
-        // from previous iterations of the transaction and must therefore
-        // be skipped in the new one.
-        int64_t                         mAlreadyProcessed;
-
-        // The amount of data that must be discarded in the current iteration
-        // (where iteration > 0) to reach the mAlreadyProcessed high water
-        // mark.
-        int64_t                         mToReadBeforeRestart;
-
-        // true when ::Set has been called with a response header
-        bool                            mSetup;
-    } mRestartInProgressVerifier;
-
 // For Rate Pacing via an EventTokenBucket
 public:
     // called by the connection manager to run this transaction through the
     // token bucket. If the token bucket admits the transaction immediately it
     // returns true. The function is called repeatedly until it returns true.
     bool TryToRunPacedRequest();
 
     // ATokenBucketEvent pure virtual implementation. Called by the token bucket
--- a/netwerk/protocol/http/nsIHttpChannel.idl
+++ b/netwerk/protocol/http/nsIHttpChannel.idl
@@ -201,26 +201,17 @@ interface nsIHttpChannel : nsIChannel
      * behavior. Don't do it!
      *
      * @param aVisitor
      *        the header visitor instance.
      */
     void visitNonDefaultRequestHeaders(in nsIHttpHeaderVisitor aVisitor);
 
     /**
-     * This attribute is a hint to the channel to indicate whether or not
-     * the underlying HTTP transaction should be allowed to be pipelined
-     * with other transactions.  This should be set to FALSE, for example,
-     * if the application knows that the corresponding document is likely
-     * to be very large.
-     *
-     * This attribute is true by default, though other factors may prevent
-     * pipelining.
-     *
-     * This attribute may only be set before the channel is opened.
+     * This attribute no longer has any effect, it remains for backwards compat
      *
      * @throws NS_ERROR_FAILURE if set after the channel has been opened.
      */
     attribute boolean allowPipelining;
 
     /**
      * This attribute of the channel indicates whether or not
      * the underlying HTTP transaction should be honor stored Strict Transport
deleted file mode 100644
--- a/netwerk/test/unit/test_assoc.js
+++ /dev/null
@@ -1,102 +0,0 @@
-Cu.import("resource://testing-common/httpd.js");
-Cu.import("resource://gre/modules/NetUtil.jsm");
-
-var httpserver = new HttpServer();
-var currentTestIndex = 0;
-
-XPCOMUtils.defineLazyGetter(this, "port", function() {
-    return httpserver.identity.primaryPort;
-});
-
-XPCOMUtils.defineLazyGetter(this, "tests", function() {
-    return [
-            // this is valid
-            {url: "/assoc/assoctest?valid",
-             responseheader: ["Assoc-Req: GET http://localhost:" + port +
-                              "/assoc/assoctest?valid",
-                              "Pragma: X-Verify-Assoc-Req"],
-             flags: 0},
-
-            // this is invalid because the method is wrong
-            {url: "/assoc/assoctest?invalid",
-             responseheader: ["Assoc-Req: POST http://localhost:" + port +
-                              "/assoc/assoctest?invalid",
-                              "Pragma: X-Verify-Assoc-Req"],
-             flags: CL_EXPECT_LATE_FAILURE},
-
-            // this is invalid because the url is wrong
-            {url: "/assoc/assoctest?notvalid",
-             responseheader: ["Assoc-Req: GET http://localhost:" + port +
-                              "/wrongpath/assoc/assoctest?notvalid",
-                              "Pragma: X-Verify-Assoc-Req"],
-             flags: CL_EXPECT_LATE_FAILURE},
-
-             // this is invalid because the space between method and URL is missing
-            {url: "/assoc/assoctest?invalid2",
-             responseheader: ["Assoc-Req: GEThttp://localhost:" + port +
-                              "/assoc/assoctest?invalid2",
-                              "Pragma: X-Verify-Assoc-Req"],
-             flags: CL_EXPECT_LATE_FAILURE},
-    ];
-});
-
-var oldPrefVal;
-var domBranch;
-
-function setupChannel(url)
-{
-  return NetUtil.newChannel({
-    uri: "http://localhost:" + port + url,
-    loadUsingSystemPrincipal: true
-  });
-}
-
-function startIter()
-{
-    var channel = setupChannel(tests[currentTestIndex].url);
-    channel.asyncOpen2(new ChannelListener(completeIter,
-                                          channel, tests[currentTestIndex].flags));
-}
-
-function completeIter(request, data, ctx)
-{
-    if (++currentTestIndex < tests.length ) {
-        startIter();
-    } else {
-        domBranch.setBoolPref("enforce", oldPrefVal);
-        httpserver.stop(do_test_finished);
-    }
-}
-
-function run_test()
-{
-    var prefService =
-        Components.classes["@mozilla.org/preferences-service;1"]
-        .getService(Components.interfaces.nsIPrefService);
-    domBranch = prefService.getBranch("network.http.assoc-req.");
-    oldPrefVal = domBranch.getBoolPref("enforce");
-    domBranch.setBoolPref("enforce", true);
-
-    httpserver.registerPathHandler("/assoc/assoctest", handler);
-    httpserver.start(-1);
-
-    startIter();
-    do_test_pending();
-}
-
-function handler(metadata, response)
-{
-    var body = "thequickbrownfox";
-    response.setHeader("Content-Type", "text/plain", false);
-
-    var header = tests[currentTestIndex].responseheader;
-    if (header != undefined) {
-        for (var i = 0; i < header.length; i++) {
-            var splitHdr = header[i].split(": ");
-            response.setHeader(splitHdr[0], splitHdr[1], false);
-        }
-    }
-    
-    response.setStatusLine(metadata.httpVersion, 200, "OK");
-    response.bodyOutputStream.write(body, body.length);
-}
--- a/netwerk/test/unit/xpcshell.ini
+++ b/netwerk/test/unit/xpcshell.ini
@@ -85,17 +85,16 @@ skip-if = true
 [test_NetUtil.js]
 [test_URIs.js]
 # Intermittent time-outs on Android, bug 1285020
 requesttimeoutfactor = 2
 [test_URIs2.js]
 # Intermittent time-outs on Android, bug 1285020
 requesttimeoutfactor = 2
 [test_aboutblank.js]
-[test_assoc.js]
 [test_auth_jar.js]
 [test_auth_proxy.js]
 [test_authentication.js]
 [test_authpromptwrapper.js]
 [test_auth_dialog_permission.js]
 [test_backgroundfilesaver.js]
 # Runs for a long time, causing intermittent time-outs on Android, bug 995686
 requesttimeoutfactor = 2
--- a/security/manager/ssl/StaticHPKPins.h
+++ b/security/manager/ssl/StaticHPKPins.h
@@ -1152,9 +1152,9 @@ static const TransportSecurityPreload kP
   { "za.search.yahoo.com", false, true, false, -1, &kPinset_yahoo },
   { "zh.search.yahoo.com", false, true, false, -1, &kPinset_yahoo },
 };
 
 // Pinning Preload List Length = 477;
 
 static const int32_t kUnknownId = -1;
 
-static const PRTime kPreloadPKPinsExpirationTime = INT64_C(1496850035698000);
+static const PRTime kPreloadPKPinsExpirationTime = INT64_C(1496936394193000);
--- a/security/manager/ssl/nsSTSPreloadList.errors
+++ b/security/manager/ssl/nsSTSPreloadList.errors
@@ -48,19 +48,17 @@ 3click-loan.com: could not connect to ho
 3sreporting.com: did not receive HSTS header
 3yearloans.com: max-age too low: 0
 404.sh: max-age too low: 0
 420dongstorm.com: could not connect to host
 42ms.org: could not connect to host
 4455software.com: did not receive HSTS header
 4679.space: could not connect to host
 47ronin.com: did not receive HSTS header
-491mhz.net: could not connect to host
 4cclothing.com: could not connect to host
-4d2.xyz: could not connect to host
 4elements.com: did not receive HSTS header
 4eyes.ch: did not receive HSTS header
 4mm.org: did not receive HSTS header
 4ourty2.org: could not connect to host
 4sqsu.eu: could not connect to host
 50millionablaze.org: did not receive HSTS header
 540.co: did not receive HSTS header
 56ct.com: could not connect to host
@@ -110,17 +108,16 @@ actu-medias.com: did not receive HSTS he
 actualite-videos.com: [Exception... "Component returned failure code: 0x80004005 (NS_ERROR_FAILURE) [nsISiteSecurityService.processHeader]"  nsresult: "0x80004005 (NS_ERROR_FAILURE)"  location: "JS frame :: /builds/slave/m-cen-l64-periodicupdate-00000/getHSTSPreloadList.js :: processStsHeader :: line 121"  data: no]
 acuve.jp: could not connect to host
 ada.is: max-age too low: 2592000
 adams.net: max-age too low: 0
 adamwk.com: did not receive HSTS header
 addaxpetroleum.com: could not connect to host
 addvocate.com: could not connect to host
 adelevie.com: could not connect to host
-adequatetechnology.com: could not connect to host
 aderal.io: could not connect to host
 adfa-1.com: did not receive HSTS header
 adhs-chaoten.net: did not receive HSTS header
 admin.google.com: did not receive HSTS header (error ignored - included regardless)
 admitcard.co.in: did not receive HSTS header
 admsel.ec: could not connect to host
 adopteunsiteflash.com: did not receive HSTS header
 adquisitio.co.uk: could not connect to host
@@ -139,16 +136,17 @@ aemoria.com: could not connect to host
 aerialmediapro.net: could not connect to host
 aes256.ru: could not connect to host
 aether.pw: could not connect to host
 aevpn.net: could not connect to host
 aficotroceni.ro: did not receive HSTS header
 afp548.tk: could not connect to host
 agalaxyfarfaraway.co.uk: could not connect to host
 agbremen.de: did not receive HSTS header
+ageg.ca: could not connect to host
 agentseeker.ca: did not receive HSTS header
 agonswim.com: could not connect to host
 agrimap.com: did not receive HSTS header
 agrios.de: did not receive HSTS header
 agro-id.gov.ua: could not connect to host
 ahabingo.com: did not receive HSTS header
 ahmedabadflowermall.com: did not receive HSTS header
 ahoynetwork.com: could not connect to host
@@ -156,16 +154,17 @@ ahri.ovh: could not connect to host
 aidanwoods.com: did not receive HSTS header
 airbnb.com: did not receive HSTS header
 aircomms.com: did not receive HSTS header
 airproto.com: did not receive HSTS header
 aishnair.com: could not connect to host
 aiticon.de: did not receive HSTS header
 aiw-thkoeln.online: could not connect to host
 ajmahal.com: could not connect to host
+akboy.pw: could not connect to host
 akclinics.org: did not receive HSTS header
 akerek.hu: did not receive HSTS header
 akombakom.net: did not receive HSTS header
 akselimedia.fi: did not receive HSTS header
 al-shami.net: could not connect to host
 aladdin.ie: did not receive HSTS header
 alainwolf.net: could not connect to host
 alanlee.net: could not connect to host
@@ -176,28 +175,31 @@ albertopimienta.com: did not receive HST
 albion2.org: did not receive HSTS header
 alcazaar.com: could not connect to host
 alecvannoten.be: did not receive HSTS header
 alenan.org: could not connect to host
 alessandro.pw: did not receive HSTS header
 alethearose.com: did not receive HSTS header
 alexandre.sh: did not receive HSTS header
 alexisabarca.com: did not receive HSTS header
+alexpavel.com: could not connect to host
 alexsergeyev.com: could not connect to host
+alextsang.net: could not connect to host
 alfa24.pro: could not connect to host
 alittlebitcheeky.com: did not receive HSTS header
 aljaspod.com: [Exception... "Component returned failure code: 0x80004005 (NS_ERROR_FAILURE) [nsISiteSecurityService.processHeader]"  nsresult: "0x80004005 (NS_ERROR_FAILURE)"  location: "JS frame :: /builds/slave/m-cen-l64-periodicupdate-00000/getHSTSPreloadList.js :: processStsHeader :: line 121"  data: no]
 alkami.com: did not receive HSTS header
 all-subtitles.com: did not receive HSTS header
 all.tf: did not receive HSTS header
 alldaymonitoring.com: could not connect to host
 allforyou.at: could not connect to host
 allinnote.com: could not connect to host
 allmbw.com: could not connect to host
 allstarswithus.com: could not connect to host
+alltheducks.com: could not connect to host
 alpha.irccloud.com: could not connect to host
 alphabit-secure.com: could not connect to host
 alphabuild.io: did not receive HSTS header
 alphalabs.xyz: could not connect to host
 alt33c3.org: could not connect to host
 alterbaum.net: did not receive HSTS header
 altfire.ca: could not connect to host
 altmv.com: max-age too low: 7776000
@@ -226,16 +228,17 @@ ancientkarma.com: could not connect to h
 andere-gedanken.net: max-age too low: 10
 andiplusben.com: could not connect to host
 andreasbreitenlohner.de: did not receive HSTS header
 andreasolsson.se: could not connect to host
 andreastoneman.com: could not connect to host
 andreigec.net: did not receive HSTS header
 andrewbroekman.com: could not connect to host
 andrewmichaud.beer: could not connect to host
+andrewregan.me: could not connect to host
 andreypopp.com: could not connect to host
 androoz.se: could not connect to host
 andymartin.cc: did not receive HSTS header
 anfsanchezo.co: did not receive HSTS header
 anfsanchezo.me: could not connect to host
 anghami.com: did not receive HSTS header
 animeday.ml: could not connect to host
 animesfusion.com.br: could not connect to host
@@ -267,16 +270,17 @@ apeasternpower.com: could not connect to
 api.mega.co.nz: could not connect to host
 apibot.de: could not connect to host
 apis.google.com: did not receive HSTS header (error ignored - included regardless)
 apis.world: did not receive HSTS header
 apmg-certified.com: did not receive HSTS header
 apmg-cyber.com: did not receive HSTS header
 apnakliyat.com: did not receive HSTS header
 aponkralsunucu.com: could not connect to host
+app-arena.com: did not receive HSTS header
 app.lookout.com: did not receive HSTS header
 app.manilla.com: could not connect to host
 appart.ninja: could not connect to host
 appengine.google.com: did not receive HSTS header (error ignored - included regardless)
 applez.xyz: could not connect to host
 applic8.com: did not receive HSTS header
 appraisal-comps.com: could not connect to host
 appreciationkards.com: could not connect to host
@@ -343,17 +347,16 @@ atlex.nl: did not receive HSTS header
 atomik.pro: could not connect to host
 atop.io: could not connect to host
 attimidesigns.com: did not receive HSTS header
 au.search.yahoo.com: max-age too low: 172800
 aubiosales.com: did not receive HSTS header
 aucubin.moe: could not connect to host
 audiovisualdevices.com.au: did not receive HSTS header
 aufmerksamkeitsstudie.com: could not connect to host
-augiero.it: could not connect to host
 aujapan.ru: could not connect to host
 aurainfosec.com: did not receive HSTS header
 aurainfosec.com.au: could not connect to host
 auraredeye.com: did not receive HSTS header
 auraredshield.com: did not receive HSTS header
 auroratownshipfd.org: could not connect to host
 ausnah.me: could not connect to host
 ausoptic.com.au: max-age too low: 2592000
@@ -372,22 +375,20 @@ auverbox.ovh: could not connect to host
 auxiliumincrementum.co.uk: could not connect to host
 avec-ou-sans-ordonnance.fr: could not connect to host
 avenelequinehospital.com.au: did not receive HSTS header
 avepol.cz: did not receive HSTS header
 avepol.eu: did not receive HSTS header
 aviacao.pt: did not receive HSTS header
 avinet.com: max-age too low: 0
 avqueen.cn: did not receive HSTS header
-avril4th.com: could not connect to host
 avus-automobile.com: did not receive HSTS header
 awg-mode.de: did not receive HSTS header
 axado.com.br: did not receive HSTS header
 axeny.com: did not receive HSTS header
-aymerick.fr: could not connect to host
 az.search.yahoo.com: did not receive HSTS header
 azprep.us: could not connect to host
 azuxul.fr: could not connect to host
 b3orion.com: max-age too low: 0
 b64.club: could not connect to host
 babelfisch.eu: could not connect to host
 baby-click.de: did not receive HSTS header
 babybic.hu: did not receive HSTS header
@@ -424,20 +425,22 @@ bazarstupava.sk: could not connect to ho
 bcbsmagentprofile.com: could not connect to host
 bcchack.com: could not connect to host
 bccx.com: could not connect to host
 bckp.de: did not receive HSTS header
 bcm.com.au: max-age too low: 0
 bcnx.de: max-age too low: 0
 bcsytv.com: could not connect to host
 bcweightlifting.ca: could not connect to host
+bde-epitech.fr: did not receive HSTS header
 be.search.yahoo.com: did not receive HSTS header
 beach-inspector.com: did not receive HSTS header
 beachi.es: could not connect to host
 beaglewatch.com: could not connect to host
+beamitapp.com: could not connect to host
 beardydave.com: did not receive HSTS header
 beastowner.com: did not receive HSTS header
 beavers.io: could not connect to host
 bebesurdoue.com: could not connect to host
 bedabox.com: max-age too low: 0
 bedeta.de: could not connect to host
 bedreid.dk: did not receive HSTS header
 bedrijvenadministratie.nl: did not receive HSTS header
@@ -498,16 +501,17 @@ bisterfeldt.com: could not connect to ho
 bitchan.it: could not connect to host
 bitcoinprivacy.net: did not receive HSTS header
 bitcoinworld.me: could not connect to host
 bitconcepts.co.uk: could not connect to host
 bitf.ly: could not connect to host
 bitfactory.ws: could not connect to host
 bitfarm-archiv.com: did not receive HSTS header
 bitfarm-archiv.de: did not receive HSTS header
+bitgo.com: max-age too low: 0
 bitheus.com: could not connect to host
 bithosting.io: did not receive HSTS header
 bitnet.io: did not receive HSTS header
 bitsafe.systems: did not receive HSTS header
 bittmann.me: could not connect to host
 bitvigor.com: could not connect to host
 bityes.org: could not connect to host
 bivsi.com: could not connect to host
@@ -529,16 +533,17 @@ blindsexdate.nl: could not connect to ho
 blitzprog.org: could not connect to host
 blocksatz-medien.de: did not receive HSTS header
 blog-ritaline.com: could not connect to host
 blog.cyveillance.com: did not receive HSTS header
 blog.lookout.com: did not receive HSTS header
 bloglikepro.com: could not connect to host
 blubbablasen.de: could not connect to host
 blucas.org: did not receive HSTS header
+blue-labs.org: could not connect to host
 blueglobalmedia.com: could not connect to host
 blueliv.com: did not receive HSTS header
 bluescloud.xyz: could not connect to host
 bluetenmeer.com: did not receive HSTS header
 blupig.net: did not receive HSTS header
 bluserv.net: did not receive HSTS header
 bm-trading.nl: did not receive HSTS header
 bngsecure.com: [Exception... "Component returned failure code: 0x80004005 (NS_ERROR_FAILURE) [nsISiteSecurityService.processHeader]"  nsresult: "0x80004005 (NS_ERROR_FAILURE)"  location: "JS frame :: /builds/slave/m-cen-l64-periodicupdate-00000/getHSTSPreloadList.js :: processStsHeader :: line 121"  data: no]
@@ -579,17 +584,16 @@ branchtrack.com: did not receive HSTS he
 branchzero.com: did not receive HSTS header
 brandnewdays.nl: could not connect to host
 brandon.so: could not connect to host
 brandred.net: could not connect to host
 brandspray.com: did not receive HSTS header
 bravz.de: could not connect to host
 brettabel.com: did not receive HSTS header
 brickoo.com: could not connect to host
-brilliantbuilders.co.uk: could not connect to host
 britzer-toner.de: did not receive HSTS header
 brks.xyz: could not connect to host
 broken-oak.com: could not connect to host
 brookechase.com: did not receive HSTS header
 browserid.org: did not receive HSTS header
 brunix.net: did not receive HSTS header
 brunosouza.org: could not connect to host
 bsagan.fr: could not connect to host
@@ -600,19 +604,17 @@ buchheld.at: did not receive HSTS header
 bucket.tk: could not connect to host
 budgetthostels.nl: did not receive HSTS header
 budskap.eu: could not connect to host
 bugtrack.io: did not receive HSTS header
 buhler.pro: did not receive HSTS header
 buildci.asia: could not connect to host
 buildsaver.co.za: did not receive HSTS header
 built.by: did not receive HSTS header
-builtritetrailerplans.com: did not receive HSTS header
 bulletpoint.cz: could not connect to host
-bulmafox.com: could not connect to host
 bumarkamoda.com: could not connect to host
 bunaken.asia: could not connect to host
 burian-server.cz: could not connect to host
 burpsuite.site: could not connect to host
 burrow.ovh: could not connect to host
 burtrum.me: could not connect to host
 burtrum.top: could not connect to host
 business.lookout.com: could not connect to host
@@ -658,16 +660,17 @@ calvin.me: max-age too low: 2592000
 calvinallen.net: did not receive HSTS header
 calyxinstitute.org: [Exception... "Component returned failure code: 0x80004005 (NS_ERROR_FAILURE) [nsISiteSecurityService.processHeader]"  nsresult: "0x80004005 (NS_ERROR_FAILURE)"  location: "JS frame :: /builds/slave/m-cen-l64-periodicupdate-00000/getHSTSPreloadList.js :: processStsHeader :: line 121"  data: no]
 camolist.com: could not connect to host
 canadiangamblingchoice.com: did not receive HSTS header
 cancelmyprofile.com: did not receive HSTS header
 candicontrols.com: did not receive HSTS header
 candratech.com: could not connect to host
 candylion.rocks: could not connect to host
+canfly.org: could not connect to host
 cannyfoxx.me: could not connect to host
 canyonshoa.com: did not receive HSTS header
 capecycles.co.za: did not receive HSTS header
 capeyorkfire.com.au: did not receive HSTS header
 captchatheprize.com: could not connect to host
 capturethepen.co.uk: could not connect to host
 car-navi.ph: did not receive HSTS header
 carano-service.de: did not receive HSTS header
@@ -748,17 +751,16 @@ chejianer.cn: did not receive HSTS heade
 chensir.net: could not connect to host
 cherysunzhang.com: max-age too low: 7776000
 chicolawfirm.com: did not receive HSTS header
 chihiro.xyz: could not connect to host
 chijiokeindustries.co.uk: could not connect to host
 childcaresolutionscny.org: did not receive HSTS header
 chinacdn.org: could not connect to host
 chinawhale.com: did not receive HSTS header
-chinternet.xyz: could not connect to host
 chirgui.eu: could not connect to host
 chm.vn: did not receive HSTS header
 chontalpa.pw: could not connect to host
 chopperforums.com: did not receive HSTS header
 chotu.net: could not connect to host
 chris-web.info: could not connect to host
 chrisandsarahinasia.com: did not receive HSTS header
 chrisfaber.com: could not connect to host
@@ -844,36 +846,35 @@ codabix.net: could not connect to host
 code.google.com: did not receive HSTS header (error ignored - included regardless)
 codeco.pw: could not connect to host
 codecontrollers.de: could not connect to host
 codeforce.io: could not connect to host
 codeforhakodate.org: could not connect to host
 codelayer.ca: could not connect to host
 codemonkeyrawks.net: did not receive HSTS header
 codepoet.de: could not connect to host
-codepult.com: could not connect to host
 codepx.com: did not receive HSTS header
 codewiththepros.org: could not connect to host
 codiva.io: max-age too low: 2592000
 coffeeetc.co.uk: did not receive HSTS header
 coffeestrategies.com: max-age too low: 2592000
 coiffeurschnittstelle.ch: did not receive HSTS header
 coindam.com: could not connect to host
 coldlostsick.net: could not connect to host
 colinwolff.com: could not connect to host
 colisfrais.com: did not receive HSTS header
 collies.eu: did not receive HSTS header
 collins.kg: did not receive HSTS header
 collins.press: did not receive HSTS header
 colmexpro.com: did not receive HSTS header
 colognegaming.net: could not connect to host
 coloradocomputernetworking.net: could not connect to host
+combron.nl: did not receive HSTS header
 comfortdom.ua: did not receive HSTS header
 comfortticket.de: did not receive HSTS header
-comfy.moe: could not connect to host
 comicspines.com: could not connect to host
 comotalk.com: could not connect to host
 compalytics.com: could not connect to host
 comparejewelleryprices.co.uk: could not connect to host
 completeid.com: max-age too low: 86400
 completionist.audio: could not connect to host
 compraneta.com: could not connect to host
 compucorner.com.mx: could not connect to host
@@ -896,16 +897,17 @@ continuumgaming.com: could not connect t
 controlcenter.gigahost.dk: did not receive HSTS header
 coolchevy.org.ua: did not receive HSTS header
 cor-ser.es: could not connect to host
 coralproject.net: did not receive HSTS header
 cordial-restaurant.com: did not receive HSTS header
 core.mx: could not connect to host
 core4system.de: could not connect to host
 corenetworking.de: could not connect to host
+corgi.party: could not connect to host
 cormactagging.ie: could not connect to host
 cormilu.com.br: did not receive HSTS header
 correctpaardbatterijnietje.nl: did not receive HSTS header
 corruption-mc.net: could not connect to host
 corruption-rsps.net: could not connect to host
 corruption-server.net: could not connect to host
 count.sh: could not connect to host
 couragewhispers.ca: did not receive HSTS header
@@ -979,30 +981,27 @@ curveweb.co.uk: did not receive HSTS hea
 custe.rs: could not connect to host
 cuvva.insure: did not receive HSTS header
 cyanogenmod.xxx: could not connect to host
 cyberpunk.ca: could not connect to host
 cybershambles.com: could not connect to host
 cycleluxembourg.lu: did not receive HSTS header
 cydia-search.io: could not connect to host
 cyphertite.com: could not connect to host
-d42.no: could not connect to host
 dad256.tk: could not connect to host
 dadtheimpaler.com: could not connect to host
-dag-konsult.com: did not receive HSTS header
 dah5.com: did not receive HSTS header
 dailystormerpodcasts.com: did not receive HSTS header
 daimadi.com: could not connect to host
 dakrib.net: could not connect to host
 daku.gdn: did not receive HSTS header
 dalfiume.it: [Exception... "Component returned failure code: 0x80004005 (NS_ERROR_FAILURE) [nsISiteSecurityService.processHeader]"  nsresult: "0x80004005 (NS_ERROR_FAILURE)"  location: "JS frame :: /builds/slave/m-cen-l64-periodicupdate-00000/getHSTSPreloadList.js :: processStsHeader :: line 121"  data: no]
 dalingk.co: could not connect to host
 damedrogy.cz: could not connect to host
 damianuv-blog.cz: did not receive HSTS header
-dango.in: could not connect to host
 daniel-steuer.de: could not connect to host
 danielcowie.me: could not connect to host
 danieldk.eu: did not receive HSTS header
 danieliancu.com: could not connect to host
 danielvoogsgerd.nl: could not connect to host
 danielworthy.com: did not receive HSTS header
 danijobs.com: could not connect to host
 danrl.de: could not connect to host
@@ -1027,16 +1026,17 @@ dataretention.solutions: could not conne
 datatekniikka.com: could not connect to host
 datenkeks.de: did not receive HSTS header
 dateno1.com: max-age too low: 0
 datenreiter.cf: could not connect to host
 datenreiter.gq: could not connect to host
 datenreiter.ml: could not connect to host
 datenreiter.tk: could not connect to host
 datewon.net: did not receive HSTS header
+datorb.com: could not connect to host
 davidglidden.eu: could not connect to host
 davidgrudl.com: [Exception... "Component returned failure code: 0x80004005 (NS_ERROR_FAILURE) [nsISiteSecurityService.processHeader]"  nsresult: "0x80004005 (NS_ERROR_FAILURE)"  location: "JS frame :: /builds/slave/m-cen-l64-periodicupdate-00000/getHSTSPreloadList.js :: processStsHeader :: line 121"  data: no]
 davidhunter.scot: did not receive HSTS header
 davidnoren.com: did not receive HSTS header
 davidreinhardt.de: could not connect to host
 davidscherzer.at: could not connect to host
 daylightcompany.com: did not receive HSTS header
 daytonaseaside.com: did not receive HSTS header
@@ -1073,17 +1073,16 @@ deltaconcepts.de: did not receive HSTS h
 deltanet-production.de: max-age too low: 0
 delvj.org: could not connect to host
 demdis.org: could not connect to host
 demilitarized.ninja: could not connect to host
 democracychronicles.com: did not receive HSTS header
 demotops.com: did not receive HSTS header
 denh.am: did not receive HSTS header
 denisjean.fr: could not connect to host
-dennisdoes.net: could not connect to host
 dentaldomain.org: did not receive HSTS header
 dentaldomain.ph: could not connect to host
 depeche-mode.moscow: max-age too low: 7200
 depijl-mz.nl: did not receive HSTS header
 depixion.agency: could not connect to host
 dequehablamos.es: could not connect to host
 derevtsov.com: did not receive HSTS header
 derhil.de: did not receive HSTS header
@@ -1142,16 +1141,17 @@ do.search.yahoo.com: did not receive HST
 dobet.in: could not connect to host
 docid.io: could not connect to host
 docket.news: could not connect to host
 docs.google.com: did not receive HSTS header (error ignored - included regardless)
 docset.io: could not connect to host
 docufiel.com: could not connect to host
 doeswindowssuckforeveryoneorjustme.com: could not connect to host
 dogbox.se: did not receive HSTS header
+doggieholic.net: could not connect to host
 dohosting.ru: could not connect to host
 dokan.online: did not receive HSTS header
 dollarstore24.com: could not connect to host
 dollywiki.co.uk: could not connect to host
 dolphin-cloud.com: could not connect to host
 dolphincorp.co.uk: could not connect to host
 domaris.de: did not receive HSTS header
 dominicpratt.de: did not receive HSTS header
@@ -1163,30 +1163,28 @@ donzelot.co.uk: max-age too low: 3600
 dooku.cz: could not connect to host
 doomleika.com: could not connect to host
 dopost.it: could not connect to host
 doridian.com: could not connect to host
 doridian.de: could not connect to host
 doridian.net: did not receive HSTS header
 doridian.org: could not connect to host
 dossplumbing.co.za: did not receive HSTS header
-dot42.no: could not connect to host
 dotadata.me: could not connect to host
 doublefun.net: could not connect to host
 dovecotadmin.org: could not connect to host
 dovetailnow.com: could not connect to host
 download.jitsi.org: did not receive HSTS header
 downsouthweddings.com.au: did not receive HSTS header
 doyoucheck.com: did not receive HSTS header
 dpratt.de: did not receive HSTS header
 dpsg-roden.de: could not connect to host
 dragonisles.net: could not connect to host
 dragons-of-highlands.cz: could not connect to host
 dragontrainingmobilezoo.com.au: max-age too low: 0
-drakeanddragon.com: [Exception... "Component returned failure code: 0x80004005 (NS_ERROR_FAILURE) [nsISiteSecurityService.processHeader]"  nsresult: "0x80004005 (NS_ERROR_FAILURE)"  location: "JS frame :: /builds/slave/m-cen-l64-periodicupdate-00000/getHSTSPreloadList.js :: processStsHeader :: line 121"  data: no]
 drakefortreasurer.sexy: could not connect to host
 draw.uy: could not connect to host
 drdevil.ru: could not connect to host
 dreadbyte.com: could not connect to host
 drhopeson.com: could not connect to host
 drishti.guru: could not connect to host
 drive.google.com: did not receive HSTS header (error ignored - included regardless)
 drkmtrx.xyz: could not connect to host
@@ -1203,25 +1201,25 @@ duesee.org: could not connect to host
 dullsir.com: did not receive HSTS header
 dutchessuganda.com: did not receive HSTS header
 dutchrank.com: could not connect to host
 dwhd.org: [Exception... "Component returned failure code: 0x80004005 (NS_ERROR_FAILURE) [nsISiteSecurityService.processHeader]"  nsresult: "0x80004005 (NS_ERROR_FAILURE)"  location: "JS frame :: /builds/slave/m-cen-l64-periodicupdate-00000/getHSTSPreloadList.js :: processStsHeader :: line 121"  data: no]
 dworzak.ch: could not connect to host
 dycontrol.de: could not connect to host
 dylanscott.com.au: did not receive HSTS header
 dymersion.com: did not receive HSTS header
+dyn.im: could not connect to host
 dynamic-innovations.net: could not connect to host
 dzimejl.sk: did not receive HSTS header
 dzlibs.io: could not connect to host
 dzndk.org: could not connect to host
 e-aut.net: did not receive HSTS header
 e-deca2.org: did not receive HSTS header
 e-sa.com: did not receive HSTS header
 e3amn2l.com: could not connect to host
-eagle-yard.de: did not receive HSTS header
 earga.sm: could not connect to host
 earlybirdsnacks.com: could not connect to host
 earthrise16.com: could not connect to host
 easychiller.org: could not connect to host
 easyhaul.com: could not connect to host
 eatlowcarb.de: did not receive HSTS header
 eauclairecommerce.com: could not connect to host
 ebankcbt.com: could not connect to host
@@ -1236,17 +1234,16 @@ ecfs.link: could not connect to host
 ecg.fr: could not connect to host
 echipstore.com: did not receive HSTS header
 echosystem.fr: did not receive HSTS header
 ecogen.net.au: could not connect to host
 ecole-en-danger.fr: could not connect to host
 ecole-maternelle-saint-joseph.be: could not connect to host
 ecomparemo.com: did not receive HSTS header
 ecorus.eu: did not receive HSTS header
-ectora.com: could not connect to host
 edcphenix.tk: could not connect to host
 edelsteincosmetic.com: did not receive HSTS header
 edissecurity.sk: did not receive HSTS header
 edix.ru: could not connect to host
 edk.com.tr: did not receive HSTS header
 edmodo.com: did not receive HSTS header
 edp-collaborative.com: max-age too low: 2500
 eduvance.in: did not receive HSTS header
@@ -1302,17 +1299,16 @@ encoder.pw: could not connect to host
 encontrebarato.com.br: did not receive HSTS header
 encrypted.google.com: did not receive HSTS header (error ignored - included regardless)
 end.pp.ua: could not connect to host
 endlessdark.net: max-age too low: 600
 endlesstone.com: did not receive HSTS header
 enefan.jp: could not connect to host
 enersec.co.uk: could not connect to host
 engelwerbung.com: [Exception... "Component returned failure code: 0x80004005 (NS_ERROR_FAILURE) [nsISiteSecurityService.processHeader]"  nsresult: "0x80004005 (NS_ERROR_FAILURE)"  location: "JS frame :: /builds/slave/m-cen-l64-periodicupdate-00000/getHSTSPreloadList.js :: processStsHeader :: line 121"  data: no]
-engineeryourmarketing.com: could not connect to host
 enigmacpt.com: did not receive HSTS header
 enigmail.net: did not receive HSTS header
 enjoy-nepal.de: max-age too low: 0
 enskat.de: could not connect to host
 enskatson-sippe.de: could not connect to host
 enteente.club: could not connect to host
 enteente.space: could not connect to host
 enteente.xyz: could not connect to host
@@ -1337,47 +1333,46 @@ eressea.xyz: could not connect to host
 eridanus.uk: could not connect to host
 ernaehrungsberatung-rapperswil.ch: [Exception... "Component returned failure code: 0x80004005 (NS_ERROR_FAILURE) [nsISiteSecurityService.processHeader]"  nsresult: "0x80004005 (NS_ERROR_FAILURE)"  location: "JS frame :: /builds/slave/m-cen-l64-periodicupdate-00000/getHSTSPreloadList.js :: processStsHeader :: line 121"  data: no]
 ernaehrungsberatung-zurich.ch: could not connect to host
 ernesto.at: could not connect to host
 eromixx.com: did not receive HSTS header
 erotalia.es: could not connect to host
 eroticen.com: did not receive HSTS header
 erotische-aanbiedingen.nl: could not connect to host
-errlytics.com: [Exception... "Component returned failure code: 0x80004005 (NS_ERROR_FAILURE) [nsISiteSecurityService.processHeader]"  nsresult: "0x80004005 (NS_ERROR_FAILURE)"  location: "JS frame :: /builds/slave/m-cen-l64-periodicupdate-00000/getHSTSPreloadList.js :: processStsHeader :: line 121"  data: no]
 errolz.com: could not connect to host
 errors.zenpayroll.com: could not connect to host
 ersindemirtas.com: did not receive HSTS header
 escotour.com: did not receive HSTS header
 esec.rs: did not receive HSTS header
 esko.bar: could not connect to host
 esln.org: did not receive HSTS header
 esoterikerforum.de: did not receive HSTS header
 espra.com: could not connect to host
 esquonic.com: could not connect to host
 essexcosmeticdentists.co.uk: did not receive HSTS header
 essexghosthunters.co.uk: did not receive HSTS header
 estilosapeca.com: could not connect to host
 et-buchholz.de: could not connect to host
 etdonline.co.uk: could not connect to host
 eternitylove.us: could not connect to host
-eth9.net: could not connect to host
+eth9.net: max-age too low: 0
 ethicalexploiting.com: could not connect to host
 etsysecure.com: could not connect to host
 etula.ga: could not connect to host
 etula.me: could not connect to host
 euanbaines.com: did not receive HSTS header
 eucl3d.com: did not receive HSTS header
 eulerpi.io: could not connect to host
 eupho.me: could not connect to host
 euroshop24.net: could not connect to host
 evafojtova.cz: did not receive HSTS header
 evantage.org: could not connect to host
 evdenevenakliyatankara.pw: did not receive HSTS header
-everybooks.com: could not connect to host
+everybooks.com: max-age too low: 60
 everylab.org: could not connect to host
 everything.place: could not connect to host
 evin.ml: could not connect to host
 evites.me: could not connect to host
 evomon.com: could not connect to host
 evossd.tk: could not connect to host
 ewuchuan.com: could not connect to host
 excelgum.ca: did not receive HSTS header
@@ -1399,17 +1394,17 @@ ezmod.org: could not connect to host
 eztv.ch: did not receive HSTS header
 f-s-u.co.uk: could not connect to host
 f00.ca: did not receive HSTS header
 fabhub.io: could not connect to host
 fabianasantiago.com: could not connect to host
 fabianfischer.de: did not receive HSTS header
 factorable.net: did not receive HSTS header
 factorygw.com: did not receive HSTS header
-fadilus.com: could not connect to host
+fadilus.com: did not receive HSTS header
 faesser.com: did not receive HSTS header
 fail4free.de: did not receive HSTS header
 failforward.org: did not receive HSTS header
 fairlyoddtreasures.com: did not receive HSTS header
 faizan.net: did not receive HSTS header
 faizan.xyz: could not connect to host
 fakeletters.org: did not receive HSTS header
 faktura.pl: did not receive HSTS header
@@ -1425,21 +1420,23 @@ fanyl.cn: could not connect to host
 farhadexchange.com: did not receive HSTS header
 fashioncare.cz: did not receive HSTS header
 fasset.jp: could not connect to host
 fastograph.com: could not connect to host
 fastopen.ml: could not connect to host
 fatgeekflix.net: could not connect to host
 fatherhood.gov: did not receive HSTS header
 fatlossguide.xyz: could not connect to host
+fatwin.pw: could not connect to host
 fayolle.info: [Exception... "Component returned failure code: 0x80004005 (NS_ERROR_FAILURE) [nsISiteSecurityService.processHeader]"  nsresult: "0x80004005 (NS_ERROR_FAILURE)"  location: "JS frame :: /builds/slave/m-cen-l64-periodicupdate-00000/getHSTSPreloadList.js :: processStsHeader :: line 121"  data: no]
 fbox.li: could not connect to host
 fdj.im: could not connect to host
 feard.space: could not connect to host
 feastr.de: did not receive HSTS header
+fedrtc.org: could not connect to host
 fedux.com.ar: could not connect to host
 feezmodo.com: max-age too low: 0
 felisslovakia.sk: [Exception... "Component returned failure code: 0x80004005 (NS_ERROR_FAILURE) [nsISiteSecurityService.processHeader]"  nsresult: "0x80004005 (NS_ERROR_FAILURE)"  location: "JS frame :: /builds/slave/m-cen-l64-periodicupdate-00000/getHSTSPreloadList.js :: processStsHeader :: line 121"  data: no]
 feliwyn.fr: did not receive HSTS header
 feminists.co: could not connect to host
 fenteo.com: could not connect to host
 feragon.net: did not receive HSTS header
 fernseher-kauf.de: could not connect to host
@@ -1456,17 +1453,16 @@ fightr.co: could not connect to host
 fikt.space: could not connect to host
 filmipop.com: max-age too low: 0
 finalgear.com: did not receive HSTS header
 financieringsportaal.nl: did not receive HSTS header
 finanzkontor.net: could not connect to host
 findtutorsnearme.com: did not receive HSTS header
 finfev.de: could not connect to host
 finiteheap.com: did not receive HSTS header
-finneas.net: could not connect to host
 finpt.com: could not connect to host
 firebaseio-demo.com: could not connect to host
 firebaseio.com: could not connect to host (error ignored - included regardless)
 firefall.rocks: could not connect to host
 firemail.io: could not connect to host
 fireorbit.de: did not receive HSTS header
 firstdogonthemoon.com.au: did not receive HSTS header
 firstforex.co.uk: did not receive HSTS header
@@ -1482,30 +1478,30 @@ fixingdns.com: did not receive HSTS head
 fj.search.yahoo.com: did not receive HSTS header
 fjruiz.es: did not receive HSTS header
 flags.ninja: could not connect to host
 flamewall.net: could not connect to host
 flareon.net: could not connect to host
 flawcheck.com: did not receive HSTS header
 fleurette.me: max-age too low: 0
 fliexer.com: could not connect to host
+flipneus.net: could not connect to host
 flirchi.com: did not receive HSTS header
 floless.co.uk: did not receive HSTS header
 florian-lillpopp.de: max-age too low: 10
 florianlillpopp.de: max-age too low: 10
 floridaescapes.co.uk: did not receive HSTS header
 flouartistique.ch: could not connect to host
 flow.pe: could not connect to host
 flow.su: could not connect to host
 flowersandclouds.com: could not connect to host
 flowlo.me: could not connect to host
-fluffycloud.de: did not receive HSTS header
 flushstudios.com: did not receive HSTS header
-fly.moe: could not connect to host
 flyaces.com: did not receive HSTS header
+flyserver.co.il: could not connect to host
 fm83.nl: could not connect to host
 fndout.com: did not receive HSTS header
 fnvsecurity.com: could not connect to host
 fojtova.cz: did not receive HSTS header
 fojtovi.cz: did not receive HSTS header
 fonetiq.io: could not connect to host
 food4health.guide: could not connect to host
 foodievenues.com: could not connect to host
@@ -1528,16 +1524,17 @@ fotopasja.info: could not connect to hos
 fourchin.net: did not receive HSTS header
 foxdev.io: could not connect to host
 foxelbox.com: [Exception... "Component returned failure code: 0x80004005 (NS_ERROR_FAILURE) [nsISiteSecurityService.processHeader]"  nsresult: "0x80004005 (NS_ERROR_FAILURE)"  location: "JS frame :: /builds/slave/m-cen-l64-periodicupdate-00000/getHSTSPreloadList.js :: processStsHeader :: line 121"  data: no]
 foxley-farm.co.uk: did not receive HSTS header
 foxley-seeds.co.uk: did not receive HSTS header
 foxleyseeds.co.uk: could not connect to host
 foxtrot.pw: could not connect to host
 fr33d0m.link: could not connect to host
+fragmentspuren.de: could not connect to host
 francevpn.xyz: could not connect to host
 frangor.info: did not receive HSTS header
 frankwei.xyz: did not receive HSTS header
 franta.biz: did not receive HSTS header
 franta.email: did not receive HSTS header
 franzt.de: could not connect to host
 frasys.io: max-age too low: 7776000
 fredvoyage.fr: did not receive HSTS header
@@ -1551,21 +1548,21 @@ freesounding.ru: could not connect to ho
 freethought.org.au: could not connect to host
 freeutopia.org: did not receive HSTS header
 frenzel.dk: could not connect to host
 freqlabs.com: could not connect to host
 freshfind.xyz: could not connect to host
 freshlymind.com: did not receive HSTS header
 frforms.com: did not receive HSTS header
 friendica.ch: could not connect to host
+friendlyfiregameshow.com: could not connect to host
 frizo.com: did not receive HSTS header
 froggstack.de: could not connect to host
 frontisme.nl: could not connect to host
 frontmin.com: did not receive HSTS header
-froot.se: could not connect to host
 frost-ci.xyz: could not connect to host
 frowin-stemmer.de: could not connect to host
 fruitusers.com: could not connect to host
 frusky.de: did not receive HSTS header
 frusky.net: could not connect to host
 fspphoto.com: could not connect to host
 ftctele.com: did not receive HSTS header
 fuckbilibili.com: did not receive HSTS header
@@ -1614,17 +1611,17 @@ gamenected.com: could not connect to hos
 gamenected.de: could not connect to host
 gameofpwnz.com: did not receive HSTS header
 gamepader.com: could not connect to host
 gameparade.de: could not connect to host
 gamepiece.com: could not connect to host
 gamerslair.org: did not receive HSTS header
 gamesdepartment.co.uk: did not receive HSTS header
 gameserver-sponsor.de: could not connect to host
-gamingmedia.eu: did not receive HSTS header
+gamingmedia.eu: could not connect to host
 gampenhof.de: did not receive HSTS header
 gaptek.id: did not receive HSTS header
 garciamartin.me: could not connect to host
 garden-life.org: could not connect to host
 gatapro.net: could not connect to host
 gatilagata.com.br: could not connect to host
 gatorsa.es: could not connect to host
 gdpventure.com: max-age too low: 0
@@ -1635,16 +1632,17 @@ geli-graphics.com: did not receive HSTS 
 gem-indonesia.net: could not connect to host
 gendrin.com: could not connect to host
 genuu.com: could not connect to host
 genuxation.com: could not connect to host
 genyaa.com: could not connect to host
 genyhitch.com: did not receive HSTS header
 geofox.org: did not receive HSTS header
 georgesonarthurs.com.au: did not receive HSTS header
+georgmayer.eu: could not connect to host
 gerencianet.com.br: did not receive HSTS header
 gersting.net: could not connect to host
 gesiwista.net: could not connect to host
 get.zenpayroll.com: did not receive HSTS header
 getable.com: did not receive HSTS header
 getblys.com.au: did not receive HSTS header
 getbooks.co.il: did not receive HSTS header
 getcarefirst.com: did not receive HSTS header
@@ -1666,16 +1664,17 @@ getlolaccount.com: could not connect to 
 getmassage.com.ng: could not connect to host
 getremembrall.com: could not connect to host
 getsello.com: could not connect to host
 getwashdaddy.com: could not connect to host
 gfm.tech: could not connect to host
 gfournier.ca: could not connect to host
 gfwsb.ml: could not connect to host
 gglks.com: did not receive HSTS header
+ggss.ml: could not connect to host
 gh16.com.ar: could not connect to host
 gheorghesarcov.ga: could not connect to host
 gheorghesarcov.tk: could not connect to host
 giakki.eu: could not connect to host
 gietvloergarant.nl: did not receive HSTS header
 gigacloud.org: max-age too low: 0
 gilgaz.com: did not receive HSTS header
 gilly.berlin: did not receive HSTS header
@@ -1685,18 +1684,20 @@ giogadesign.com: did not receive HSTS he
 gipsamsfashion.com: could not connect to host
 gipsic.com: did not receive HSTS header
 gistfy.com: could not connect to host
 github.party: could not connect to host
 givemyanswer.com: did not receive HSTS header
 gizzo.sk: could not connect to host
 gkralik.eu: [Exception... "Component returned failure code: 0x80004005 (NS_ERROR_FAILURE) [nsISiteSecurityService.processHeader]"  nsresult: "0x80004005 (NS_ERROR_FAILURE)"  location: "JS frame :: /builds/slave/m-cen-l64-periodicupdate-00000/getHSTSPreloadList.js :: processStsHeader :: line 121"  data: no]
 gl.search.yahoo.com: did not receive HSTS header
+glasfaser-im-hanseviertel.de: could not connect to host
 glass.google.com: did not receive HSTS header (error ignored - included regardless)
 glentakahashi.com: max-age too low: 0
+glitchsys.com: could not connect to host
 glitzmirror.com: could not connect to host
 global-adult-webcams.com: did not receive HSTS header
 globalado.com: could not connect to host
 globalexpert.co.nz: could not connect to host
 globalittech.com: could not connect to host
 globalmusic.ga: could not connect to host
 globalsites.nl: did not receive HSTS header
 gloomyvancouver.com: could not connect to host
@@ -1737,16 +1738,17 @@ gotowned.org: did not receive HSTS heade
 gotspot.com: could not connect to host
 gottcode.org: did not receive HSTS header
 gov.ax: could not connect to host
 govillemo.ca: did not receive HSTS header
 gozel.com.tr: did not receive HSTS header
 gparent.org: did not receive HSTS header
 gpsfix.cz: could not connect to host
 gpstuner.com: did not receive HSTS header
+grabi.ga: could not connect to host
 gracesofgrief.com: max-age too low: 86400
 gradienthosting.co.uk: did not receive HSTS header
 grandmascookieblog.com: did not receive HSTS header
 grantedby.me: could not connect to host
 graph.no: did not receive HSTS header