Merge mozilla-central to autoland a=merge on a CLOSED TREE
authorCoroiu Cristina <ccoroiu@mozilla.com>
Tue, 08 May 2018 18:54:28 +0300
changeset 417334 c34bb5938be6a8d542efd3ae82bbf7fdf5a996d6
parent 417333 3cd1fcae55debedd74333804b355b4aa20d1b58b (current diff)
parent 417305 7c83ceac4be6d055bebd870a82b78b76de14b9d7 (diff)
child 417335 97fd777d726a26276af59d8cca1abe7c84a3c41d
push id33966
push useraciure@mozilla.com
push dateTue, 08 May 2018 22:55:45 +0000
treeherdermozilla-central@ecbcf736a436 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmerge
milestone62.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Merge mozilla-central to autoland a=merge on a CLOSED TREE
Cargo.lock
layout/generic/nsBulletFrame.cpp
layout/generic/nsHTMLCanvasFrame.cpp
layout/painting/nsDisplayList.cpp
rdf/base/moz.build
rdf/base/nsCompositeDataSource.cpp
rdf/base/nsContainerEnumerator.cpp
rdf/base/nsDefaultResourceFactory.cpp
rdf/base/nsIRDFCompositeDataSource.idl
rdf/base/nsIRDFContainer.idl
rdf/base/nsIRDFContainerUtils.idl
rdf/base/nsIRDFContentSink.h
rdf/base/nsIRDFDataSource.idl
rdf/base/nsIRDFDelegateFactory.idl
rdf/base/nsIRDFInMemoryDataSource.idl
rdf/base/nsIRDFInferDataSource.idl
rdf/base/nsIRDFLiteral.idl
rdf/base/nsIRDFNode.idl
rdf/base/nsIRDFObserver.idl
rdf/base/nsIRDFPropagatableDataSource.idl
rdf/base/nsIRDFPurgeableDataSource.idl
rdf/base/nsIRDFRemoteDataSource.idl
rdf/base/nsIRDFResource.idl
rdf/base/nsIRDFService.idl
rdf/base/nsIRDFXMLParser.idl
rdf/base/nsIRDFXMLSerializer.idl
rdf/base/nsIRDFXMLSink.idl
rdf/base/nsIRDFXMLSource.idl
rdf/base/nsInMemoryDataSource.cpp
rdf/base/nsNameSpaceMap.cpp
rdf/base/nsNameSpaceMap.h
rdf/base/nsRDFBaseDataSources.h
rdf/base/nsRDFContainer.cpp
rdf/base/nsRDFContainerUtils.cpp
rdf/base/nsRDFContentSink.cpp
rdf/base/nsRDFResource.cpp
rdf/base/nsRDFResource.h
rdf/base/nsRDFService.cpp
rdf/base/nsRDFService.h
rdf/base/nsRDFXMLDataSource.cpp
rdf/base/nsRDFXMLParser.cpp
rdf/base/nsRDFXMLParser.h
rdf/base/nsRDFXMLSerializer.cpp
rdf/base/nsRDFXMLSerializer.h
rdf/base/rdf.h
rdf/base/rdfIDataSource.idl
rdf/base/rdfITripleVisitor.idl
rdf/base/rdfutil.cpp
rdf/base/rdfutil.h
rdf/build/moz.build
rdf/build/nsRDFCID.h
rdf/build/nsRDFModule.cpp
rdf/datasource/moz.build
rdf/datasource/nsILocalStore.h
rdf/datasource/nsIRDFFTP.h
rdf/datasource/nsLocalStore.cpp
rdf/datasource/nsRDFBuiltInDataSources.h
rdf/moz.build
rdf/tests/moz.build
rdf/tests/unit/sample.rdf
rdf/tests/unit/test_rdfredirect.js
rdf/tests/unit/xpcshell.ini
third_party/rust/core-foundation-0.5.1/.cargo-checksum.json
third_party/rust/core-foundation-0.5.1/Cargo.toml
third_party/rust/core-foundation-0.5.1/src/array.rs
third_party/rust/core-foundation-0.5.1/src/base.rs
third_party/rust/core-foundation-0.5.1/src/bundle.rs
third_party/rust/core-foundation-0.5.1/src/dictionary.rs
third_party/rust/core-foundation-0.5.1/src/filedescriptor.rs
third_party/rust/core-foundation-0.5.1/src/lib.rs
third_party/rust/core-foundation-0.5.1/src/propertylist.rs
third_party/rust/core-foundation-0.5.1/src/runloop.rs
third_party/rust/core-foundation-0.5.1/src/set.rs
third_party/rust/core-foundation-0.5.1/tests/use_macro_outside_crate.rs
third_party/rust/core-foundation-sys-0.5.1/.cargo-checksum.json
third_party/rust/core-foundation-sys-0.5.1/Cargo.toml
third_party/rust/core-foundation-sys-0.5.1/src/array.rs
third_party/rust/core-foundation-sys-0.5.1/src/base.rs
third_party/rust/core-foundation-sys-0.5.1/src/bundle.rs
third_party/rust/core-foundation-sys-0.5.1/src/data.rs
third_party/rust/core-foundation-sys-0.5.1/src/date.rs
third_party/rust/core-foundation-sys-0.5.1/src/dictionary.rs
third_party/rust/core-foundation-sys-0.5.1/src/error.rs
third_party/rust/core-foundation-sys-0.5.1/src/filedescriptor.rs
third_party/rust/core-foundation-sys-0.5.1/src/lib.rs
third_party/rust/core-foundation-sys-0.5.1/src/messageport.rs
third_party/rust/core-foundation-sys-0.5.1/src/number.rs
third_party/rust/core-foundation-sys-0.5.1/src/propertylist.rs
third_party/rust/core-foundation-sys-0.5.1/src/runloop.rs
third_party/rust/core-foundation-sys-0.5.1/src/set.rs
third_party/rust/core-foundation-sys-0.5.1/src/string.rs
third_party/rust/core-foundation-sys-0.5.1/src/timezone.rs
third_party/rust/core-foundation-sys-0.5.1/src/url.rs
third_party/rust/core-foundation-sys-0.5.1/src/uuid.rs
toolkit/mozapps/extensions/internal/RDFManifestConverter.jsm
toolkit/mozapps/extensions/internal/UpdateRDFConverter.jsm
widget/windows/nsWindow.cpp
xpfe/components/build/moz.build
xpfe/components/build/nsModule.cpp
xpfe/components/directory/moz.build
xpfe/components/directory/nsDirectoryViewer.cpp
xpfe/components/directory/nsDirectoryViewer.h
xpfe/components/directory/nsIHTTPIndex.idl
xpfe/components/moz.build
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -334,24 +334,38 @@ name = "core-foundation"
 version = "0.5.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "core-foundation-sys 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "libc 0.2.39 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
+name = "core-foundation"
+version = "0.6.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "core-foundation-sys 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.39 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
 name = "core-foundation-sys"
 version = "0.5.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "libc 0.2.39 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
+name = "core-foundation-sys"
+version = "0.6.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
+[[package]]
 name = "core-graphics"
 version = "0.13.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "bitflags 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "core-foundation 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "foreign-types 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "libc 0.2.39 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -2120,17 +2134,18 @@ version = "0.1.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
 name = "u2fhid"
 version = "0.1.0"
 dependencies = [
  "bitflags 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "boxfnonce 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
- "core-foundation-sys 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "core-foundation 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "core-foundation-sys 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "libc 0.2.39 (registry+https://github.com/rust-lang/crates.io-index)",
  "libudev 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "rand 0.3.18 (registry+https://github.com/rust-lang/crates.io-index)",
  "runloop 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
@@ -2484,17 +2499,19 @@ dependencies = [
 "checksum cexpr 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "393a5f0088efbe41f9d1fcd062f24e83c278608420e62109feb2c8abee07de7d"
 "checksum cfg-if 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "d4c819a1287eb618df47cc647173c5c4c66ba19d888a6e50d605672aed3140de"
 "checksum chrono 0.2.25 (registry+https://github.com/rust-lang/crates.io-index)" = "9213f7cd7c27e95c2b57c49f0e69b1ea65b27138da84a170133fd21b07659c00"
 "checksum clang-sys 0.22.0 (registry+https://github.com/rust-lang/crates.io-index)" = "939a1a34310b120d26eba35c29475933128b0ec58e24b43327f8dbe6036fc538"
 "checksum clap 2.29.0 (registry+https://github.com/rust-lang/crates.io-index)" = "110d43e343eb29f4f51c1db31beb879d546db27998577e5715270a54bcf41d3f"
 "checksum cmake 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)" = "56d741ea7a69e577f6d06b36b7dff4738f680593dc27a701ffa8506b73ce28bb"
 "checksum cookie 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)" = "746858cae4eae40fff37e1998320068df317bc247dc91a67c6cfa053afdc2abb"
 "checksum core-foundation 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "286e0b41c3a20da26536c6000a280585d519fd07b3956b43aed8a79e9edce980"
+"checksum core-foundation 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c7caa6cb9e76ddddbea09a03266d6b3bc98cd41e9fb9b017c473e7cca593ec25"
 "checksum core-foundation-sys 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "716c271e8613ace48344f723b60b900a93150271e5be206212d052bbc0883efa"
+"checksum core-foundation-sys 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b2a53cce0ddcf7e7e1f998738d757d5a3bf08bf799a180e50ebe50d298f52f5a"
 "checksum core-graphics 0.13.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fb0ed45fdc32f9ab426238fba9407dfead7bacd7900c9b4dd3f396f46eafdae3"
 "checksum core-text 9.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2bd581c37283d0c23311d179aefbb891f2324ee0405da58a26e8594ab76e5748"
 "checksum cose 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "72fa26cb151d3ae4b70f63d67d0fed57ce04220feafafbae7f503bef7aae590d"
 "checksum cose-c 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "49726015ab0ca765144fcca61e4a7a543a16b795a777fa53f554da2fffff9a94"
 "checksum crc 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bd5d02c0aac6bd68393ed69e00bbc2457f3e89075c6349db7189618dc4ddc1d7"
 "checksum crossbeam-deque 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f739f8c5363aca78cfb059edf753d8f0d36908c348f3d8d1503f03d8b75d9cf3"
 "checksum crossbeam-epoch 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "927121f5407de9956180ff5e936fe3cf4324279280001cd56b669d28ee7e9150"
 "checksum crossbeam-utils 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "2760899e32a1d58d5abb31129f8fae5de75220bc2176e77ff7c627ae45c918d9"
--- a/accessible/base/FocusManager.cpp
+++ b/accessible/base/FocusManager.cpp
@@ -234,17 +234,17 @@ FocusManager::ForceFocusEvent()
     }
   }
 }
 
 void
 FocusManager::DispatchFocusEvent(DocAccessible* aDocument,
                                  Accessible* aTarget)
 {
-  NS_PRECONDITION(aDocument, "No document for focused accessible!");
+  MOZ_ASSERT(aDocument, "No document for focused accessible!");
   if (aDocument) {
     RefPtr<AccEvent> event =
       new AccEvent(nsIAccessibleEvent::EVENT_FOCUS, aTarget,
                    eAutoDetect, AccEvent::eCoalesceOfSameType);
     aDocument->FireDelayedEvent(event);
 
 #ifdef A11Y_LOG
     if (logging::IsEnabled(logging::eFocus))
@@ -287,18 +287,18 @@ FocusManager::ProcessDOMFocus(nsINode* a
 
     DispatchFocusEvent(document, target);
   }
 }
 
 void
 FocusManager::ProcessFocusEvent(AccEvent* aEvent)
 {
-  NS_PRECONDITION(aEvent->GetEventType() == nsIAccessibleEvent::EVENT_FOCUS,
-                  "Focus event is expected!");
+  MOZ_ASSERT(aEvent->GetEventType() == nsIAccessibleEvent::EVENT_FOCUS,
+             "Focus event is expected!");
 
   // Emit focus event if event target is the active item. Otherwise then check
   // if it's still focused and then update active item and emit focus event.
   Accessible* target = aEvent->GetAccessible();
   if (target != mActiveItem) {
 
     // Check if still focused. Otherwise we can end up with storing the active
     // item for control that isn't focused anymore.
--- a/accessible/base/TextAttrs.cpp
+++ b/accessible/base/TextAttrs.cpp
@@ -32,23 +32,23 @@ TextAttrsMgr::GetAttributes(nsIPersisten
                             uint32_t* aEndOffset)
 {
   // 1. Hyper text accessible must be specified always.
   // 2. Offset accessible and result hyper text offsets must be specified in
   // the case of text attributes.
   // 3. Offset accessible and result hyper text offsets must not be specified
   // but include default text attributes flag and attributes list must be
   // specified in the case of default text attributes.
-  NS_PRECONDITION(mHyperTextAcc &&
-                  ((mOffsetAcc && mOffsetAccIdx != -1 &&
-                    aStartOffset && aEndOffset) ||
-                  (!mOffsetAcc && mOffsetAccIdx == -1 &&
-                    !aStartOffset && !aEndOffset &&
-                   mIncludeDefAttrs && aAttributes)),
-                  "Wrong usage of TextAttrsMgr!");
+  MOZ_ASSERT(mHyperTextAcc &&
+             ((mOffsetAcc && mOffsetAccIdx != -1 &&
+               aStartOffset && aEndOffset) ||
+             (!mOffsetAcc && mOffsetAccIdx == -1 &&
+               !aStartOffset && !aEndOffset &&
+              mIncludeDefAttrs && aAttributes)),
+             "Wrong usage of TextAttrsMgr!");
 
   // Embedded objects are combined into own range with empty attributes set.
   if (mOffsetAcc && !mOffsetAcc->IsText()) {
     for (int32_t childIdx = mOffsetAccIdx - 1; childIdx >= 0; childIdx--) {
       Accessible* currAcc = mHyperTextAcc->GetChildAt(childIdx);
       if (currAcc->IsText())
         break;
 
--- a/accessible/generic/Accessible.cpp
+++ b/accessible/generic/Accessible.cpp
@@ -2351,49 +2351,49 @@ Accessible::IsLink() const
   // Every embedded accessible within hypertext accessible implements
   // hyperlink interface.
   return mParent && mParent->IsHyperText() && !IsText();
 }
 
 uint32_t
 Accessible::StartOffset()
 {
-  NS_PRECONDITION(IsLink(), "StartOffset is called not on hyper link!");
+  MOZ_ASSERT(IsLink(), "StartOffset is called not on hyper link!");
 
   HyperTextAccessible* hyperText = mParent ? mParent->AsHyperText() : nullptr;
   return hyperText ? hyperText->GetChildOffset(this) : 0;
 }
 
 uint32_t
 Accessible::EndOffset()
 {
-  NS_PRECONDITION(IsLink(), "EndOffset is called on not hyper link!");
+  MOZ_ASSERT(IsLink(), "EndOffset is called on not hyper link!");
 
   HyperTextAccessible* hyperText = mParent ? mParent->AsHyperText() : nullptr;
   return hyperText ? (hyperText->GetChildOffset(this) + 1) : 0;
 }
 
 uint32_t
 Accessible::AnchorCount()
 {
-  NS_PRECONDITION(IsLink(), "AnchorCount is called on not hyper link!");
+  MOZ_ASSERT(IsLink(), "AnchorCount is called on not hyper link!");
   return 1;
 }
 
 Accessible*
 Accessible::AnchorAt(uint32_t aAnchorIndex)
 {
-  NS_PRECONDITION(IsLink(), "GetAnchor is called on not hyper link!");
+  MOZ_ASSERT(IsLink(), "GetAnchor is called on not hyper link!");
   return aAnchorIndex == 0 ? this : nullptr;
 }
 
 already_AddRefed<nsIURI>
 Accessible::AnchorURIAt(uint32_t aAnchorIndex)
 {
-  NS_PRECONDITION(IsLink(), "AnchorURIAt is called on not hyper link!");
+  MOZ_ASSERT(IsLink(), "AnchorURIAt is called on not hyper link!");
   return nullptr;
 }
 
 void
 Accessible::ToTextPoint(HyperTextAccessible** aContainer, int32_t* aOffset,
                         bool aIsBefore) const
 {
   if (IsHyperText()) {
--- a/accessible/generic/Accessible.h
+++ b/accessible/generic/Accessible.h
@@ -738,17 +738,17 @@ public:
    */
   virtual uint32_t EndOffset();
 
   /**
    * Return true if the link is valid (e. g. points to a valid URL).
    */
   inline bool IsLinkValid()
   {
-    NS_PRECONDITION(IsLink(), "IsLinkValid is called on not hyper link!");
+    MOZ_ASSERT(IsLink(), "IsLinkValid is called on not hyper link!");
 
     // XXX In order to implement this we would need to follow every link
     // Perhaps we can get information about invalid links from the cache
     // In the mean time authors can use role="link" aria-invalid="true"
     // to force it for links they internally know to be invalid
     return (0 == (State() & mozilla::a11y::states::INVALID));
   }
 
--- a/accessible/mac/mozTextAccessible.mm
+++ b/accessible/mac/mozTextAccessible.mm
@@ -12,17 +12,17 @@
 
 #import "mozTextAccessible.h"
 
 using namespace mozilla::a11y;
 
 inline bool
 ToNSRange(id aValue, NSRange* aRange)
 {
-  NS_PRECONDITION(aRange, "aRange is nil");
+  MOZ_ASSERT(aRange, "aRange is nil");
 
   if ([aValue isKindOfClass:[NSValue class]] &&
       strcmp([(NSValue*)aValue objCType], @encode(NSRange)) == 0) {
     *aRange = [aValue rangeValue];
     return true;
   }
 
   return false;
@@ -542,17 +542,17 @@ ToNSString(id aValue)
 - (void)selectedTextDidChange
 {
   NSAccessibilityPostNotification(GetObjectOrRepresentedView(self),
                                   NSAccessibilitySelectedTextChangedNotification);
 }
 
 - (NSString*)stringFromRange:(NSRange*)range
 {
-  NS_PRECONDITION(range, "no range");
+  MOZ_ASSERT(range, "no range");
 
   AccessibleWrap* accWrap = [self getGeckoAccessible];
   ProxyAccessible* proxy = [self getProxyAccessible];
   HyperTextAccessible* textAcc = accWrap? accWrap->AsHyperText() : nullptr;
   if (!textAcc && !proxy)
     return nil;
 
   nsAutoString text;
--- a/accessible/xpcom/xpcAccessibleSelectable.cpp
+++ b/accessible/xpcom/xpcAccessibleSelectable.cpp
@@ -14,17 +14,17 @@ using namespace mozilla::a11y;
 NS_IMETHODIMP
 xpcAccessibleSelectable::GetSelectedItems(nsIArray** aSelectedItems)
 {
   NS_ENSURE_ARG_POINTER(aSelectedItems);
   *aSelectedItems = nullptr;
 
   if (!Intl())
     return NS_ERROR_FAILURE;
-  NS_PRECONDITION(Intl()->IsSelect(), "Called on non selectable widget!");
+  MOZ_ASSERT(Intl()->IsSelect(), "Called on non selectable widget!");
 
   AutoTArray<Accessible*, 10> items;
   Intl()->SelectedItems(&items);
 
   uint32_t itemCount = items.Length();
   if (itemCount == 0)
     return NS_OK;
 
@@ -43,32 +43,32 @@ xpcAccessibleSelectable::GetSelectedItem
 NS_IMETHODIMP
 xpcAccessibleSelectable::GetSelectedItemCount(uint32_t* aSelectionCount)
 {
   NS_ENSURE_ARG_POINTER(aSelectionCount);
   *aSelectionCount = 0;
 
   if (!Intl())
     return NS_ERROR_FAILURE;
-  NS_PRECONDITION(Intl()->IsSelect(), "Called on non selectable widget!");
+  MOZ_ASSERT(Intl()->IsSelect(), "Called on non selectable widget!");
 
   *aSelectionCount = Intl()->SelectedItemCount();
   return NS_OK;
 }
 
 NS_IMETHODIMP
 xpcAccessibleSelectable::GetSelectedItemAt(uint32_t aIndex,
                                            nsIAccessible** aSelected)
 {
   NS_ENSURE_ARG_POINTER(aSelected);
   *aSelected = nullptr;
 
   if (!Intl())
     return NS_ERROR_FAILURE;
-  NS_PRECONDITION(Intl()->IsSelect(), "Called on non selectable widget!");
+  MOZ_ASSERT(Intl()->IsSelect(), "Called on non selectable widget!");
 
   *aSelected = ToXPC(Intl()->GetSelectedItem(aIndex));
   if (*aSelected) {
     NS_ADDREF(*aSelected);
     return NS_OK;
   }
 
   return NS_ERROR_INVALID_ARG;
@@ -77,58 +77,58 @@ xpcAccessibleSelectable::GetSelectedItem
 NS_IMETHODIMP
 xpcAccessibleSelectable::IsItemSelected(uint32_t aIndex, bool* aIsSelected)
 {
   NS_ENSURE_ARG_POINTER(aIsSelected);
   *aIsSelected = false;
 
   if (!Intl())
     return NS_ERROR_FAILURE;
-  NS_PRECONDITION(Intl()->IsSelect(), "Called on non selectable widget!");
+  MOZ_ASSERT(Intl()->IsSelect(), "Called on non selectable widget!");
 
   *aIsSelected = Intl()->IsItemSelected(aIndex);
   return NS_OK;
 }
 
 NS_IMETHODIMP
 xpcAccessibleSelectable::AddItemToSelection(uint32_t aIndex)
 {
   if (!Intl())
     return NS_ERROR_FAILURE;
-  NS_PRECONDITION(Intl()->IsSelect(), "Called on non selectable widget!");
+  MOZ_ASSERT(Intl()->IsSelect(), "Called on non selectable widget!");
 
   return Intl()->AddItemToSelection(aIndex) ? NS_OK : NS_ERROR_INVALID_ARG;
 }
 
 NS_IMETHODIMP
 xpcAccessibleSelectable::RemoveItemFromSelection(uint32_t aIndex)
 {
   if (!Intl())
     return NS_ERROR_FAILURE;
-  NS_PRECONDITION(Intl()->IsSelect(), "Called on non selectable widget!");
+  MOZ_ASSERT(Intl()->IsSelect(), "Called on non selectable widget!");
 
   return Intl()->RemoveItemFromSelection(aIndex) ? NS_OK : NS_ERROR_INVALID_ARG;
 }
 
 NS_IMETHODIMP
 xpcAccessibleSelectable::SelectAll(bool* aIsMultiSelect)
 {
   NS_ENSURE_ARG_POINTER(aIsMultiSelect);
   *aIsMultiSelect = false;
 
   if (!Intl())
     return NS_ERROR_FAILURE;
-  NS_PRECONDITION(Intl()->IsSelect(), "Called on non selectable widget!");
+  MOZ_ASSERT(Intl()->IsSelect(), "Called on non selectable widget!");
 
   *aIsMultiSelect = Intl()->SelectAll();
   return NS_OK;
 }
 
 NS_IMETHODIMP
 xpcAccessibleSelectable::UnselectAll()
 {
   if (!Intl())
     return NS_ERROR_FAILURE;
-  NS_PRECONDITION(Intl()->IsSelect(), "Called on non selectable widget!");
+  MOZ_ASSERT(Intl()->IsSelect(), "Called on non selectable widget!");
 
   Intl()->UnselectAll();
   return NS_OK;
 }
--- a/accessible/xul/XULTreeGridAccessible.cpp
+++ b/accessible/xul/XULTreeGridAccessible.cpp
@@ -366,17 +366,17 @@ XULTreeGridRowAccessible::ChildCount() c
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 // XULTreeGridRowAccessible: XULTreeItemAccessibleBase implementation
 
 XULTreeGridCellAccessible*
 XULTreeGridRowAccessible::GetCellAccessible(nsITreeColumn* aColumn) const
 {
-  NS_PRECONDITION(aColumn, "No tree column!");
+  MOZ_ASSERT(aColumn, "No tree column!");
 
   void* key = static_cast<void*>(aColumn);
   XULTreeGridCellAccessible* cachedCell = mAccessibleCache.GetWeak(key);
   if (cachedCell)
     return cachedCell;
 
   RefPtr<XULTreeGridCellAccessible> cell =
     new XULTreeGridCellAccessibleWrap(mContent, mDoc,
--- a/browser/components/build/nsModule.cpp
+++ b/browser/components/build/nsModule.cpp
@@ -15,17 +15,16 @@
 #elif defined(MOZ_WIDGET_GTK)
 #include "nsGNOMEShellService.h"
 #endif
 
 #if defined(XP_WIN)
 #include "nsIEHistoryEnumerator.h"
 #endif
 
-#include "rdf.h"
 #include "nsFeedSniffer.h"
 #include "AboutRedirector.h"
 #include "nsIAboutModule.h"
 
 #include "nsNetCID.h"
 
 using namespace mozilla::browser;
 
--- a/caps/ContentPrincipal.cpp
+++ b/caps/ContentPrincipal.cpp
@@ -325,17 +325,17 @@ ContentPrincipal::MayLoadInternal(nsIURI
   }
 
   return false;
 }
 
 NS_IMETHODIMP
 ContentPrincipal::GetHashValue(uint32_t* aValue)
 {
-  NS_PRECONDITION(mCodebase, "Need a codebase");
+  MOZ_ASSERT(mCodebase, "Need a codebase");
 
   *aValue = nsScriptSecurityManager::HashPrincipalByOrigin(this);
   return NS_OK;
 }
 
 NS_IMETHODIMP
 ContentPrincipal::GetDomain(nsIURI** aDomain)
 {
--- a/caps/nsJSPrincipals.cpp
+++ b/caps/nsJSPrincipals.cpp
@@ -23,27 +23,27 @@
 
 using namespace mozilla;
 using namespace mozilla::ipc;
 
 NS_IMETHODIMP_(MozExternalRefCountType)
 nsJSPrincipals::AddRef()
 {
   MOZ_ASSERT(NS_IsMainThread());
-  NS_PRECONDITION(int32_t(refcount) >= 0, "illegal refcnt");
+  MOZ_ASSERT(int32_t(refcount) >= 0, "illegal refcnt");
   nsrefcnt count = ++refcount;
   NS_LOG_ADDREF(this, count, "nsJSPrincipals", sizeof(*this));
   return count;
 }
 
 NS_IMETHODIMP_(MozExternalRefCountType)
 nsJSPrincipals::Release()
 {
   MOZ_ASSERT(NS_IsMainThread());
-  NS_PRECONDITION(0 != refcount, "dup release");
+  MOZ_ASSERT(0 != refcount, "dup release");
   nsrefcnt count = --refcount;
   NS_LOG_RELEASE(this, count, "nsJSPrincipals");
   if (count == 0) {
     delete this;
   }
 
   return count;
 }
--- a/caps/nsScriptSecurityManager.cpp
+++ b/caps/nsScriptSecurityManager.cpp
@@ -72,20 +72,86 @@
 
 // This should be probably defined on some other place... but I couldn't find it
 #define WEBAPPS_PERM_NAME "webapps-manage"
 
 using namespace mozilla;
 using namespace mozilla::dom;
 
 nsIIOService    *nsScriptSecurityManager::sIOService = nullptr;
-nsIStringBundle *nsScriptSecurityManager::sStrBundle = nullptr;
 JSContext       *nsScriptSecurityManager::sContext   = nullptr;
 bool nsScriptSecurityManager::sStrictFileOriginPolicy = true;
 
+namespace {
+
+class BundleHelper
+{
+public:
+  NS_INLINE_DECL_REFCOUNTING(BundleHelper)
+
+  static nsIStringBundle*
+  GetOrCreate()
+  {
+    MOZ_ASSERT(!sShutdown);
+
+    // Already shutting down. Nothing should require the use of the string
+    // bundle when shutting down.
+    if (sShutdown) {
+      return nullptr;
+    }
+
+    if (!sSelf) {
+      sSelf = new BundleHelper();
+    }
+
+    return sSelf->GetOrCreateInternal();
+  }
+
+  static void
+  Shutdown()
+  {
+    sSelf = nullptr;
+    sShutdown = true;
+  }
+
+private:
+  ~BundleHelper() = default;
+
+  nsIStringBundle*
+  GetOrCreateInternal()
+  {
+    if (!mBundle) {
+      nsCOMPtr<nsIStringBundleService> bundleService =
+          mozilla::services::GetStringBundleService();
+      if (NS_WARN_IF(!bundleService)) {
+        return nullptr;
+      }
+
+      nsresult rv =
+        bundleService->CreateBundle("chrome://global/locale/security/caps.properties",
+                                    getter_AddRefs(mBundle));
+      if (NS_WARN_IF(NS_FAILED(rv))) {
+        return nullptr;
+      }
+    }
+
+    return mBundle;
+  }
+
+  nsCOMPtr<nsIStringBundle> mBundle;
+
+  static StaticRefPtr<BundleHelper> sSelf;
+  static bool sShutdown;
+};
+
+StaticRefPtr<BundleHelper> BundleHelper::sSelf;
+bool BundleHelper::sShutdown = false;
+
+} // anonymous
+
 ///////////////////////////
 // Convenience Functions //
 ///////////////////////////
 
 class nsAutoInPrincipalDomainOriginSetter {
 public:
     nsAutoInPrincipalDomainOriginSetter() {
         ++sInPrincipalDomainOrigin;
@@ -255,17 +321,18 @@ InheritAndSetCSPOnPrincipalIfNeeded(nsIC
   aPrincipal->SetCsp(originalCSP);
 }
 
 nsresult
 nsScriptSecurityManager::GetChannelResultPrincipal(nsIChannel* aChannel,
                                                    nsIPrincipal** aPrincipal,
                                                    bool aIgnoreSandboxing)
 {
-  NS_PRECONDITION(aChannel, "Must have channel!");
+  MOZ_ASSERT(aChannel, "Must have channel!");
+
   // Check whether we have an nsILoadInfo that says what we should do.
   nsCOMPtr<nsILoadInfo> loadInfo = aChannel->GetLoadInfo();
   if (loadInfo && loadInfo->GetForceInheritPrincipalOverruleOwner()) {
     nsCOMPtr<nsIPrincipal> principalToInherit =
       loadInfo->FindPrincipalToInherit(aChannel);
     principalToInherit.forget(aPrincipal);
     return NS_OK;
   }
@@ -344,17 +411,17 @@ nsScriptSecurityManager::GetChannelResul
  * sandboxed or when the load could be a blob or data uri (i.e even when
  * you encounter loads that may or may not be sandboxed and loads
  * that may or may not inherit)."
  */
 NS_IMETHODIMP
 nsScriptSecurityManager::GetChannelURIPrincipal(nsIChannel* aChannel,
                                                 nsIPrincipal** aPrincipal)
 {
-    NS_PRECONDITION(aChannel, "Must have channel!");
+    MOZ_ASSERT(aChannel, "Must have channel!");
 
     // Get the principal from the URI.  Make sure this does the same thing
     // as nsDocument::Reset and XULDocument::StartDocumentLoad.
     nsCOMPtr<nsIURI> uri;
     nsresult rv = NS_GetFinalChannelURI(aChannel, getter_AddRefs(uri));
     NS_ENSURE_SUCCESS(rv, rv);
 
     nsCOMPtr<nsILoadInfo> loadInfo;
@@ -512,17 +579,17 @@ nsScriptSecurityManager::CheckLoadURIFro
  * Helper method to handle cases where a flag passed to
  * CheckLoadURIWithPrincipal means denying loading if the given URI has certain
  * nsIProtocolHandler flags set.
  * @return if success, access is allowed. Otherwise, deny access
  */
 static nsresult
 DenyAccessIfURIHasFlags(nsIURI* aURI, uint32_t aURIFlags)
 {
-    NS_PRECONDITION(aURI, "Must have URI!");
+    MOZ_ASSERT(aURI, "Must have URI!");
 
     bool uriHasFlags;
     nsresult rv =
         NS_URIChainHasFlags(aURI, aURIFlags, &uriHasFlags);
     NS_ENSURE_SUCCESS(rv, rv);
 
     if (uriHasFlags) {
         return NS_ERROR_DOM_BAD_URI;
@@ -560,17 +627,18 @@ EqualOrSubdomain(nsIURI* aProbeArg, nsIU
     }
 }
 
 NS_IMETHODIMP
 nsScriptSecurityManager::CheckLoadURIWithPrincipal(nsIPrincipal* aPrincipal,
                                                    nsIURI *aTargetURI,
                                                    uint32_t aFlags)
 {
-    NS_PRECONDITION(aPrincipal, "CheckLoadURIWithPrincipal must have a principal");
+    MOZ_ASSERT(aPrincipal, "CheckLoadURIWithPrincipal must have a principal");
+
     // If someone passes a flag that we don't understand, we should
     // fail, because they may need a security check that we don't
     // provide.
     NS_ENSURE_FALSE(aFlags & ~(nsIScriptSecurityManager::LOAD_IS_AUTOMATIC_DOCUMENT_REPLACEMENT |
                                nsIScriptSecurityManager::ALLOW_CHROME |
                                nsIScriptSecurityManager::DISALLOW_SCRIPT |
                                nsIScriptSecurityManager::DISALLOW_INHERIT_PRINCIPAL |
                                nsIScriptSecurityManager::DONT_REPORT_ERRORS),
@@ -974,30 +1042,32 @@ nsScriptSecurityManager::CheckLoadURIFla
     // and none of the rest of the nested chain of URIs for aTargetURI
     // prohibits the load, so avoid warning in that case:
     bool hasSubsumersFlag = false;
     rv = NS_URIChainHasFlags(aTargetBaseURI,
                              nsIProtocolHandler::URI_LOADABLE_BY_SUBSUMERS,
                              &hasSubsumersFlag);
     NS_ENSURE_SUCCESS(rv, rv);
     if (!hasFlags && !hasSubsumersFlag) {
-        nsAutoString message;
-        NS_ConvertASCIItoUTF16 ucsTargetScheme(targetScheme);
-        const char16_t* formatStrings[] = { ucsTargetScheme.get() };
-        rv = sStrBundle->
-            FormatStringFromName("ProtocolFlagError",
-                                 formatStrings,
-                                 ArrayLength(formatStrings),
-                                 message);
-        if (NS_SUCCEEDED(rv)) {
-            nsCOMPtr<nsIConsoleService> console(
-              do_GetService("@mozilla.org/consoleservice;1"));
-            NS_ENSURE_TRUE(console, NS_ERROR_FAILURE);
+        nsCOMPtr<nsIStringBundle> bundle = BundleHelper::GetOrCreate();
+        if (bundle) {
+            nsAutoString message;
+            NS_ConvertASCIItoUTF16 ucsTargetScheme(targetScheme);
+            const char16_t* formatStrings[] = { ucsTargetScheme.get() };
+            rv = bundle->FormatStringFromName("ProtocolFlagError",
+                                              formatStrings,
+                                              ArrayLength(formatStrings),
+                                              message);
+            if (NS_SUCCEEDED(rv)) {
+                nsCOMPtr<nsIConsoleService> console(
+                  do_GetService("@mozilla.org/consoleservice;1"));
+                NS_ENSURE_TRUE(console, NS_ERROR_FAILURE);
 
-            console->LogStringMessage(message.get());
+                console->LogStringMessage(message.get());
+            }
         }
     }
 
     return NS_OK;
 }
 
 nsresult
 nsScriptSecurityManager::ReportError(JSContext* cx, const char* aMessageTag,
@@ -1011,25 +1081,30 @@ nsScriptSecurityManager::ReportError(JSC
     rv = aSource->GetAsciiSpec(sourceSpec);
     NS_ENSURE_SUCCESS(rv, rv);
 
     // Get the target URL spec
     nsAutoCString targetSpec;
     rv = aTarget->GetAsciiSpec(targetSpec);
     NS_ENSURE_SUCCESS(rv, rv);
 
+    nsCOMPtr<nsIStringBundle> bundle = BundleHelper::GetOrCreate();
+    if (NS_WARN_IF(!bundle)) {
+      return NS_OK;
+    }
+
     // Localize the error message
     nsAutoString message;
     NS_ConvertASCIItoUTF16 ucsSourceSpec(sourceSpec);
     NS_ConvertASCIItoUTF16 ucsTargetSpec(targetSpec);
     const char16_t *formatStrings[] = { ucsSourceSpec.get(), ucsTargetSpec.get() };
-    rv = sStrBundle->FormatStringFromName(aMessageTag,
-                                          formatStrings,
-                                          ArrayLength(formatStrings),
-                                          message);
+    rv = bundle->FormatStringFromName(aMessageTag,
+                                      formatStrings,
+                                      ArrayLength(formatStrings),
+                                      message);
     NS_ENSURE_SUCCESS(rv, rv);
 
     // If a JS context was passed in, set a JS exception.
     // Otherwise, print the error message directly to the JS console
     // and to standard output
     if (cx)
     {
         SetPendingException(cx, message.get());
@@ -1230,32 +1305,38 @@ nsScriptSecurityManager::CanCreateWrappe
     NS_ConvertUTF8toUTF16 originUTF16(originUTF8);
     nsAutoCString classInfoNameUTF8;
     if (aClassInfo) {
       aClassInfo->GetClassDescription(classInfoNameUTF8);
     }
     if (classInfoNameUTF8.IsEmpty()) {
       classInfoNameUTF8.AssignLiteral("UnnamedClass");
     }
+
+    nsCOMPtr<nsIStringBundle> bundle = BundleHelper::GetOrCreate();
+    if (NS_WARN_IF(!bundle)) {
+      return NS_OK;
+    }
+
     NS_ConvertUTF8toUTF16 classInfoUTF16(classInfoNameUTF8);
     nsresult rv;
     nsAutoString errorMsg;
     if (originUTF16.IsEmpty()) {
         const char16_t* formatStrings[] = { classInfoUTF16.get() };
-        rv = sStrBundle->FormatStringFromName("CreateWrapperDenied",
-                                              formatStrings,
-                                              1,
-                                              errorMsg);
+        rv = bundle->FormatStringFromName("CreateWrapperDenied",
+                                          formatStrings,
+                                          1,
+                                          errorMsg);
     } else {
         const char16_t* formatStrings[] = { classInfoUTF16.get(),
                                             originUTF16.get() };
-        rv = sStrBundle->FormatStringFromName("CreateWrapperDeniedForOrigin",
-                                              formatStrings,
-                                              2,
-                                              errorMsg);
+        rv = bundle->FormatStringFromName("CreateWrapperDeniedForOrigin",
+                                          formatStrings,
+                                          2,
+                                          errorMsg);
     }
     NS_ENSURE_SUCCESS(rv, rv);
 
     SetPendingException(cx, errorMsg.get());
     return NS_ERROR_DOM_XPCONNECT_ACCESS_DENIED;
 }
 
 NS_IMETHODIMP
@@ -1329,24 +1410,16 @@ nsScriptSecurityManager::nsScriptSecurit
 
 nsresult nsScriptSecurityManager::Init()
 {
     nsresult rv = CallGetService(NS_IOSERVICE_CONTRACTID, &sIOService);
     NS_ENSURE_SUCCESS(rv, rv);
 
     InitPrefs();
 
-    nsCOMPtr<nsIStringBundleService> bundleService =
-        mozilla::services::GetStringBundleService();
-    if (!bundleService)
-        return NS_ERROR_FAILURE;
-
-    rv = bundleService->CreateBundle("chrome://global/locale/security/caps.properties", &sStrBundle);
-    NS_ENSURE_SUCCESS(rv, rv);
-
     // Create our system principal singleton
     RefPtr<SystemPrincipal> system = SystemPrincipal::Create();
 
     mSystemPrincipal = system;
 
     //-- Register security check callback in the JS engine
     //   Currently this is used to control access to function.caller
     sContext = danger::GetJSContext();
@@ -1385,17 +1458,17 @@ nsScriptSecurityManager::Shutdown()
 {
     if (sContext) {
         JS_SetSecurityCallbacks(sContext, nullptr);
         JS_SetTrustedPrincipals(sContext, nullptr);
         sContext = nullptr;
     }
 
     NS_IF_RELEASE(sIOService);
-    NS_IF_RELEASE(sStrBundle);
+    BundleHelper::Shutdown();
 }
 
 nsScriptSecurityManager *
 nsScriptSecurityManager::GetScriptSecurityManager()
 {
     return gScriptSecMan;
 }
 
--- a/chrome/nsChromeProtocolHandler.cpp
+++ b/chrome/nsChromeProtocolHandler.cpp
@@ -108,17 +108,17 @@ nsChromeProtocolHandler::NewChannel2(nsI
                                      nsILoadInfo* aLoadInfo,
                                      nsIChannel** aResult)
 {
     nsresult rv;
 
     NS_ENSURE_ARG_POINTER(aURI);
     NS_ENSURE_ARG_POINTER(aLoadInfo);
 
-    NS_PRECONDITION(aResult, "Null out param");
+    MOZ_ASSERT(aResult, "Null out param");
 
 #ifdef DEBUG
     // Check that the uri we got is already canonified
     nsresult debug_rv;
     nsCOMPtr<nsIURI> debugURL = aURI;
     debug_rv = nsChromeRegistry::Canonify(debugURL);
     if (NS_SUCCEEDED(debug_rv)) {
         bool same;
--- a/docshell/base/nsDSURIContentListener.cpp
+++ b/docshell/base/nsDSURIContentListener.cpp
@@ -256,17 +256,17 @@ nsDSURIContentListener::IsPreferred(cons
 }
 
 NS_IMETHODIMP
 nsDSURIContentListener::CanHandleContent(const char* aContentType,
                                          bool aIsContentPreferred,
                                          char** aDesiredContentType,
                                          bool* aCanHandleContent)
 {
-  NS_PRECONDITION(aCanHandleContent, "Null out param?");
+  MOZ_ASSERT(aCanHandleContent, "Null out param?");
   NS_ENSURE_ARG_POINTER(aDesiredContentType);
 
   *aCanHandleContent = false;
   *aDesiredContentType = nullptr;
 
   nsresult rv = NS_OK;
   if (aContentType) {
     uint32_t canHandle = nsIWebNavigationInfo::UNSUPPORTED;
--- a/docshell/base/nsDocShell.cpp
+++ b/docshell/base/nsDocShell.cpp
@@ -532,17 +532,17 @@ NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(
   NS_INTERFACE_MAP_ENTRY_CONDITIONAL(nsINetworkInterceptController,
                                      mInterceptController)
   NS_INTERFACE_MAP_ENTRY(nsIDeprecationWarner)
 NS_INTERFACE_MAP_END_INHERITING(nsDocLoader)
 
 NS_IMETHODIMP
 nsDocShell::GetInterface(const nsIID& aIID, void** aSink)
 {
-  NS_PRECONDITION(aSink, "null out param");
+  MOZ_ASSERT(aSink, "null out param");
 
   *aSink = nullptr;
 
   if (aIID.Equals(NS_GET_IID(nsICommandManager))) {
     NS_ENSURE_SUCCESS(EnsureCommandHandler(), NS_ERROR_FAILURE);
     *aSink = mCommandManager;
   } else if (aIID.Equals(NS_GET_IID(nsIURIContentListener))) {
     *aSink = mContentListener;
@@ -663,19 +663,19 @@ nsDocShell::GetInterface(const nsIID& aI
 }
 
 NS_IMETHODIMP
 nsDocShell::LoadURI(nsIURI* aURI,
                     nsIDocShellLoadInfo* aLoadInfo,
                     uint32_t aLoadFlags,
                     bool aFirstParty)
 {
-  NS_PRECONDITION(aLoadInfo || (aLoadFlags & EXTRA_LOAD_FLAGS) == 0,
-                  "Unexpected flags");
-  NS_PRECONDITION((aLoadFlags & 0xf) == 0, "Should not have these flags set");
+  MOZ_ASSERT(aLoadInfo || (aLoadFlags & EXTRA_LOAD_FLAGS) == 0,
+             "Unexpected flags");
+  MOZ_ASSERT((aLoadFlags & 0xf) == 0, "Should not have these flags set");
 
   // Note: we allow loads to get through here even if mFiredUnloadEvent is
   // true; that case will get handled in LoadInternal or LoadHistoryEntry,
   // so we pass false as the second parameter to IsNavigationAllowed.
   // However, we don't allow the page to change location *in the middle of*
   // firing beforeunload, so we do need to check if *beforeunload* is currently
   // firing, so we call IsNavigationAllowed rather than just IsPrintingOrPP.
   if (!IsNavigationAllowed(true, false)) {
@@ -3122,17 +3122,17 @@ nsDocShell::GetSameTypeRootTreeItemIgnor
 }
 
 /* static */
 bool
 nsDocShell::CanAccessItem(nsIDocShellTreeItem* aTargetItem,
                           nsIDocShellTreeItem* aAccessingItem,
                           bool aConsiderOpener)
 {
-  NS_PRECONDITION(aTargetItem, "Must have target item!");
+  MOZ_ASSERT(aTargetItem, "Must have target item!");
 
   if (!gValidateOrigin || !aAccessingItem) {
     // Good to go
     return true;
   }
 
   // XXXbz should we care if aAccessingItem or the document therein is
   // chrome?  Should those get extra privileges?
@@ -5286,17 +5286,17 @@ nsDocShell::LoadPage(nsISupports* aPageD
 
   rv = LoadHistoryEntry(shEntry, LOAD_HISTORY);
   return rv;
 }
 
 NS_IMETHODIMP
 nsDocShell::GetCurrentDescriptor(nsISupports** aPageDescriptor)
 {
-  NS_PRECONDITION(aPageDescriptor, "Null out param?");
+  MOZ_ASSERT(aPageDescriptor, "Null out param?");
 
   *aPageDescriptor = nullptr;
 
   nsISHEntry* src = mOSHE ? mOSHE : mLSHE;
   if (src) {
     nsCOMPtr<nsISHEntry> dest;
 
     nsresult rv = src->Clone(getter_AddRefs(dest));
@@ -6340,17 +6340,17 @@ nsDocShell::RefreshURI(nsIURI* aURI, nsI
 
 nsresult
 nsDocShell::ForceRefreshURIFromTimer(nsIURI* aURI,
                                      nsIPrincipal* aPrincipal,
                                      int32_t aDelay,
                                      bool aMetaRefresh,
                                      nsITimer* aTimer)
 {
-  NS_PRECONDITION(aTimer, "Must have a timer here");
+  MOZ_ASSERT(aTimer, "Must have a timer here");
 
   // Remove aTimer from mRefreshURIList if needed
   if (mRefreshURIList) {
     uint32_t n = 0;
     mRefreshURIList->GetLength(&n);
 
     for (uint32_t i = 0; i < n; ++i) {
       nsCOMPtr<nsITimer> timer = do_QueryElementAt(mRefreshURIList, i);
@@ -9753,18 +9753,18 @@ nsDocShell::InternalLoad(nsIURI* aURI,
 
   rv = CheckLoadingPermissions();
   if (NS_FAILED(rv)) {
     return rv;
   }
 
   if (mFiredUnloadEvent) {
     if (IsOKToLoadURI(aURI)) {
-      NS_PRECONDITION(aWindowTarget.IsEmpty(),
-                      "Shouldn't have a window target here!");
+      MOZ_ASSERT(aWindowTarget.IsEmpty(),
+                 "Shouldn't have a window target here!");
 
       // If this is a replace load, make whatever load triggered
       // the unload event also a replace load, so we don't
       // create extra history entries.
       if (LOAD_TYPE_HAS_FLAGS(aLoadType, LOAD_FLAGS_REPLACE_HISTORY)) {
         mLoadType = LOAD_NORMAL_REPLACE;
       }
 
@@ -11335,18 +11335,18 @@ nsDocShell::SetupReferrerFromChannel(nsI
 
 bool
 nsDocShell::OnNewURI(nsIURI* aURI, nsIChannel* aChannel,
                      nsIPrincipal* aTriggeringPrincipal,
                      nsIPrincipal* aPrincipalToInherit,
                      uint32_t aLoadType, bool aFireOnLocationChange,
                      bool aAddToGlobalHistory, bool aCloneSHChildren)
 {
-  NS_PRECONDITION(aURI, "uri is null");
-  NS_PRECONDITION(!aChannel || !aTriggeringPrincipal, "Shouldn't have both set");
+  MOZ_ASSERT(aURI, "uri is null");
+  MOZ_ASSERT(!aChannel || !aTriggeringPrincipal, "Shouldn't have both set");
 
   MOZ_ASSERT(!aPrincipalToInherit || (aPrincipalToInherit && aTriggeringPrincipal));
 
 #if defined(DEBUG)
   if (MOZ_LOG_TEST(gDocShellLog, LogLevel::Debug)) {
     nsAutoCString chanName;
     if (aChannel) {
       aChannel->GetName(chanName);
@@ -11987,18 +11987,18 @@ nsDocShell::ShouldAddToSessionHistory(ns
 
 nsresult
 nsDocShell::AddToSessionHistory(nsIURI* aURI, nsIChannel* aChannel,
                                 nsIPrincipal* aTriggeringPrincipal,
                                 nsIPrincipal* aPrincipalToInherit,
                                 bool aCloneChildren,
                                 nsISHEntry** aNewEntry)
 {
-  NS_PRECONDITION(aURI, "uri is null");
-  NS_PRECONDITION(!aChannel || !aTriggeringPrincipal, "Shouldn't have both set");
+  MOZ_ASSERT(aURI, "uri is null");
+  MOZ_ASSERT(!aChannel || !aTriggeringPrincipal, "Shouldn't have both set");
 
 #if defined(DEBUG)
   if (MOZ_LOG_TEST(gDocShellLog, LogLevel::Debug)) {
     nsAutoCString chanName;
     if (aChannel) {
       aChannel->GetName(chanName);
     } else {
       chanName.AssignLiteral("<no channel>");
@@ -13148,17 +13148,17 @@ nsDocShell::GetIsContent(bool* aIsConten
 {
   *aIsContent = (mItemType == typeContent);
   return NS_OK;
 }
 
 bool
 nsDocShell::IsOKToLoadURI(nsIURI* aURI)
 {
-  NS_PRECONDITION(aURI, "Must have a URI!");
+  MOZ_ASSERT(aURI, "Must have a URI!");
 
   if (!mFiredUnloadEvent) {
     return true;
   }
 
   if (!mLoadingURI) {
     return false;
   }
--- a/docshell/base/nsWebNavigationInfo.cpp
+++ b/docshell/base/nsWebNavigationInfo.cpp
@@ -26,17 +26,17 @@ nsWebNavigationInfo::Init()
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsWebNavigationInfo::IsTypeSupported(const nsACString& aType,
                                      nsIWebNavigation* aWebNav,
                                      uint32_t* aIsTypeSupported)
 {
-  NS_PRECONDITION(aIsTypeSupported, "null out param?");
+  MOZ_ASSERT(aIsTypeSupported, "null out param?");
 
   // Note to self: aWebNav could be an nsWebBrowser or an nsDocShell here (or
   // an nsSHistory, but not much we can do with that).  So if we start using
   // it here, we need to be careful to get to the docshell correctly.
 
   // For now just report what the Gecko-Content-Viewers category has
   // to say for itself.
   *aIsTypeSupported = nsIWebNavigationInfo::UNSUPPORTED;
@@ -89,17 +89,17 @@ nsWebNavigationInfo::IsTypeSupported(con
 
   return NS_OK;
 }
 
 nsresult
 nsWebNavigationInfo::IsTypeSupportedInternal(const nsCString& aType,
                                              uint32_t* aIsSupported)
 {
-  NS_PRECONDITION(aIsSupported, "Null out param?");
+  MOZ_ASSERT(aIsSupported, "Null out param?");
 
   nsContentUtils::ContentViewerType vtype = nsContentUtils::TYPE_UNSUPPORTED;
 
   nsCOMPtr<nsIDocumentLoaderFactory> docLoaderFactory =
     nsContentUtils::FindInternalContentViewer(aType, &vtype);
 
   switch (vtype) {
     case nsContentUtils::TYPE_UNSUPPORTED:
--- a/docshell/build/nsDocShellModule.cpp
+++ b/docshell/build/nsDocShellModule.cpp
@@ -48,17 +48,17 @@
 using mozilla::dom::ContentHandlerService;
 
 static bool gInitialized = false;
 
 // The one time initialization for this module
 static nsresult
 Initialize()
 {
-  NS_PRECONDITION(!gInitialized, "docshell module already initialized");
+  MOZ_ASSERT(!gInitialized, "docshell module already initialized");
   if (gInitialized) {
     return NS_OK;
   }
   gInitialized = true;
 
   nsresult rv = nsSHistory::Startup();
   NS_ENSURE_SUCCESS(rv, rv);
 
--- a/docshell/shistory/nsSHEntryShared.cpp
+++ b/docshell/shistory/nsSHEntryShared.cpp
@@ -134,18 +134,18 @@ nsSHEntryShared::DropPresentationState()
   mChildShells.Clear();
   mRefreshURIList = nullptr;
   mEditorData = nullptr;
 }
 
 nsresult
 nsSHEntryShared::SetContentViewer(nsIContentViewer* aViewer)
 {
-  NS_PRECONDITION(!aViewer || !mContentViewer,
-                  "SHEntryShared already contains viewer");
+  MOZ_ASSERT(!aViewer || !mContentViewer,
+             "SHEntryShared already contains viewer");
 
   if (mContentViewer || !aViewer) {
     DropPresentationState();
   }
 
   // If we're setting mContentViewer to null, state should already be cleared
   // in the DropPresentationState() call above; If we're setting it to a
   // non-null content viewer, the entry shouldn't have been tracked either.
--- a/docshell/shistory/nsSHistory.cpp
+++ b/docshell/shistory/nsSHistory.cpp
@@ -684,26 +684,26 @@ nsSHistory::GetCount(int32_t* aResult)
   *aResult = mLength;
   return NS_OK;
 }
 
 /* Get index of the history list */
 NS_IMETHODIMP
 nsSHistory::GetIndex(int32_t* aResult)
 {
-  NS_PRECONDITION(aResult, "null out param?");
+  MOZ_ASSERT(aResult, "null out param?");
   *aResult = mIndex;
   return NS_OK;
 }
 
 /* Get the requestedIndex */
 NS_IMETHODIMP
 nsSHistory::GetRequestedIndex(int32_t* aResult)
 {
-  NS_PRECONDITION(aResult, "null out param?");
+  MOZ_ASSERT(aResult, "null out param?");
   *aResult = mRequestedIndex;
   return NS_OK;
 }
 
 /* Get the entry at a given index */
 NS_IMETHODIMP
 nsSHistory::GetEntryAtIndex(int32_t aIndex, bool aModifyIndex,
                             nsISHEntry** aResult)
--- a/dom/base/CharacterData.cpp
+++ b/dom/base/CharacterData.cpp
@@ -61,18 +61,18 @@ CharacterData::CharacterData(already_Add
              mNodeInfo->NodeType() == COMMENT_NODE ||
              mNodeInfo->NodeType() == PROCESSING_INSTRUCTION_NODE ||
              mNodeInfo->NodeType() == DOCUMENT_TYPE_NODE,
              "Bad NodeType in aNodeInfo");
 }
 
 CharacterData::~CharacterData()
 {
-  NS_PRECONDITION(!IsInUncomposedDoc(),
-                  "Please remove this from the document properly");
+  MOZ_ASSERT(!IsInUncomposedDoc(),
+             "Please remove this from the document properly");
   if (GetParent()) {
     NS_RELEASE(mParent);
   }
 }
 
 NS_IMPL_CYCLE_COLLECTION_CLASS(CharacterData)
 
 NS_IMPL_CYCLE_COLLECTION_TRACE_WRAPPERCACHE(CharacterData)
@@ -241,18 +241,18 @@ CharacterData::ReplaceData(uint32_t aOff
 }
 
 nsresult
 CharacterData::SetTextInternal(uint32_t aOffset, uint32_t aCount,
                                const char16_t* aBuffer,
                                uint32_t aLength, bool aNotify,
                                CharacterDataChangeInfo::Details* aDetails)
 {
-  NS_PRECONDITION(aBuffer || !aLength,
-                  "Null buffer passed to SetTextInternal!");
+  MOZ_ASSERT(aBuffer || !aLength,
+             "Null buffer passed to SetTextInternal!");
 
   // sanitize arguments
   uint32_t textLength = mText.GetLength();
   if (aOffset > textLength) {
     return NS_ERROR_DOM_INDEX_SIZE_ERR;
   }
 
   if (aCount > textLength - aOffset) {
@@ -441,38 +441,38 @@ CharacterData::ToCString(nsAString& aBuf
 #endif
 
 
 nsresult
 CharacterData::BindToTree(nsIDocument* aDocument, nsIContent* aParent,
                           nsIContent* aBindingParent,
                           bool aCompileEventHandlers)
 {
-  NS_PRECONDITION(aParent || aDocument, "Must have document if no parent!");
-  NS_PRECONDITION(NODE_FROM(aParent, aDocument)->OwnerDoc() == OwnerDoc(),
-                  "Must have the same owner document");
-  NS_PRECONDITION(!aParent || aDocument == aParent->GetUncomposedDoc(),
-                  "aDocument must be current doc of aParent");
-  NS_PRECONDITION(!GetUncomposedDoc() && !IsInUncomposedDoc(),
-                  "Already have a document.  Unbind first!");
+  MOZ_ASSERT(aParent || aDocument, "Must have document if no parent!");
+  MOZ_ASSERT(NODE_FROM(aParent, aDocument)->OwnerDoc() == OwnerDoc(),
+             "Must have the same owner document");
+  MOZ_ASSERT(!aParent || aDocument == aParent->GetUncomposedDoc(),
+             "aDocument must be current doc of aParent");
+  MOZ_ASSERT(!GetUncomposedDoc() && !IsInUncomposedDoc(),
+             "Already have a document.  Unbind first!");
   // Note that as we recurse into the kids, they'll have a non-null parent.  So
   // only assert if our parent is _changing_ while we have a parent.
-  NS_PRECONDITION(!GetParent() || aParent == GetParent(),
-                  "Already have a parent.  Unbind first!");
-  NS_PRECONDITION(!GetBindingParent() ||
-                  aBindingParent == GetBindingParent() ||
-                  (!aBindingParent && aParent &&
-                   aParent->GetBindingParent() == GetBindingParent()),
-                  "Already have a binding parent.  Unbind first!");
-  NS_PRECONDITION(aBindingParent != this,
-                  "Content must not be its own binding parent");
-  NS_PRECONDITION(!IsRootOfNativeAnonymousSubtree() ||
-                  aBindingParent == aParent,
-                  "Native anonymous content must have its parent as its "
-                  "own binding parent");
+  MOZ_ASSERT(!GetParent() || aParent == GetParent(),
+             "Already have a parent.  Unbind first!");
+  MOZ_ASSERT(!GetBindingParent() ||
+             aBindingParent == GetBindingParent() ||
+             (!aBindingParent && aParent &&
+              aParent->GetBindingParent() == GetBindingParent()),
+             "Already have a binding parent.  Unbind first!");
+  MOZ_ASSERT(aBindingParent != this,
+             "Content must not be its own binding parent");
+  MOZ_ASSERT(!IsRootOfNativeAnonymousSubtree() ||
+             aBindingParent == aParent,
+             "Native anonymous content must have its parent as its "
+             "own binding parent");
 
   if (!aBindingParent && aParent) {
     aBindingParent = aParent->GetBindingParent();
   }
 
   // First set the binding parent
   if (aBindingParent) {
     NS_ASSERTION(IsRootOfNativeAnonymousSubtree() ||
--- a/dom/base/Element.cpp
+++ b/dom/base/Element.cpp
@@ -1529,40 +1529,40 @@ EditableInclusiveDescendantCount(nsICont
   return aContent->EditableDescendantCount();
 }
 
 nsresult
 Element::BindToTree(nsIDocument* aDocument, nsIContent* aParent,
                     nsIContent* aBindingParent,
                     bool aCompileEventHandlers)
 {
-  NS_PRECONDITION(aParent || aDocument, "Must have document if no parent!");
-  NS_PRECONDITION((NODE_FROM(aParent, aDocument)->OwnerDoc() == OwnerDoc()),
-                  "Must have the same owner document");
-  NS_PRECONDITION(!aParent || aDocument == aParent->GetUncomposedDoc(),
-                  "aDocument must be current doc of aParent");
-  NS_PRECONDITION(!GetUncomposedDoc(), "Already have a document.  Unbind first!");
+  MOZ_ASSERT(aParent || aDocument, "Must have document if no parent!");
+  MOZ_ASSERT((NODE_FROM(aParent, aDocument)->OwnerDoc() == OwnerDoc()),
+             "Must have the same owner document");
+  MOZ_ASSERT(!aParent || aDocument == aParent->GetUncomposedDoc(),
+             "aDocument must be current doc of aParent");
+  MOZ_ASSERT(!GetUncomposedDoc(), "Already have a document.  Unbind first!");
   // Note that as we recurse into the kids, they'll have a non-null parent.  So
   // only assert if our parent is _changing_ while we have a parent.
-  NS_PRECONDITION(!GetParent() || aParent == GetParent(),
-                  "Already have a parent.  Unbind first!");
-  NS_PRECONDITION(!GetBindingParent() ||
-                  aBindingParent == GetBindingParent() ||
-                  (!aBindingParent && aParent &&
-                   aParent->GetBindingParent() == GetBindingParent()),
-                  "Already have a binding parent.  Unbind first!");
-  NS_PRECONDITION(aBindingParent != this,
-                  "Content must not be its own binding parent");
-  NS_PRECONDITION(!IsRootOfNativeAnonymousSubtree() ||
-                  aBindingParent == aParent,
-                  "Native anonymous content must have its parent as its "
-                  "own binding parent");
-  NS_PRECONDITION(aBindingParent || !aParent ||
-                  aBindingParent == aParent->GetBindingParent(),
-                  "We should be passed the right binding parent");
+  MOZ_ASSERT(!GetParent() || aParent == GetParent(),
+             "Already have a parent.  Unbind first!");
+  MOZ_ASSERT(!GetBindingParent() ||
+             aBindingParent == GetBindingParent() ||
+             (!aBindingParent && aParent &&
+              aParent->GetBindingParent() == GetBindingParent()),
+             "Already have a binding parent.  Unbind first!");
+  MOZ_ASSERT(aBindingParent != this,
+             "Content must not be its own binding parent");
+  MOZ_ASSERT(!IsRootOfNativeAnonymousSubtree() ||
+             aBindingParent == aParent,
+             "Native anonymous content must have its parent as its "
+             "own binding parent");
+  MOZ_ASSERT(aBindingParent || !aParent ||
+             aBindingParent == aParent->GetBindingParent(),
+             "We should be passed the right binding parent");
 
 #ifdef MOZ_XUL
   // First set the binding parent
   nsXULElement* xulElem = nsXULElement::FromNode(this);
   if (xulElem) {
     xulElem->SetXULBindingParent(aBindingParent);
   }
   else
@@ -1836,17 +1836,17 @@ RemoveFromBindingManagerRunnable::Run()
 
   return NS_OK;
 }
 
 
 void
 Element::UnbindFromTree(bool aDeep, bool aNullParent)
 {
-  NS_PRECONDITION(aDeep || (!GetUncomposedDoc() && !GetBindingParent()),
+  MOZ_ASSERT(aDeep || (!GetUncomposedDoc() && !GetBindingParent()),
                   "Shallow unbind won't clear document and binding parent on "
                   "kids!");
 
   RemoveFromIdTable();
 
   // Make sure to unbind this node before doing the kids
   nsIDocument* document = GetComposedDoc();
 
@@ -2213,19 +2213,19 @@ Element::IsNodeOfType(uint32_t aFlags) c
 /* static */
 nsresult
 Element::DispatchEvent(nsPresContext* aPresContext,
                        WidgetEvent* aEvent,
                        nsIContent* aTarget,
                        bool aFullDispatch,
                        nsEventStatus* aStatus)
 {
-  NS_PRECONDITION(aTarget, "Must have target");
-  NS_PRECONDITION(aEvent, "Must have source event");
-  NS_PRECONDITION(aStatus, "Null out param?");
+  MOZ_ASSERT(aTarget, "Must have target");
+  MOZ_ASSERT(aEvent, "Must have source event");
+  MOZ_ASSERT(aStatus, "Null out param?");
 
   if (!aPresContext) {
     return NS_OK;
   }
 
   nsCOMPtr<nsIPresShell> shell = aPresContext->GetPresShell();
   if (!shell) {
     return NS_OK;
@@ -2242,19 +2242,19 @@ Element::DispatchEvent(nsPresContext* aP
 nsresult
 Element::DispatchClickEvent(nsPresContext* aPresContext,
                             WidgetInputEvent* aSourceEvent,
                             nsIContent* aTarget,
                             bool aFullDispatch,
                             const EventFlags* aExtraEventFlags,
                             nsEventStatus* aStatus)
 {
-  NS_PRECONDITION(aTarget, "Must have target");
-  NS_PRECONDITION(aSourceEvent, "Must have source event");
-  NS_PRECONDITION(aStatus, "Null out param?");
+  MOZ_ASSERT(aTarget, "Must have target");
+  MOZ_ASSERT(aSourceEvent, "Must have source event");
+  MOZ_ASSERT(aStatus, "Null out param?");
 
   WidgetMouseEvent event(aSourceEvent->IsTrusted(), eMouseClick,
                          aSourceEvent->mWidget, WidgetMouseEvent::eReal);
   event.mRefPoint = aSourceEvent->mRefPoint;
   uint32_t clickCount = 1;
   float pressure = 0;
   uint32_t pointerId = 0; // Use the default value here.
   uint16_t inputSource = 0;
@@ -2317,17 +2317,17 @@ Element::SetEventHandler(nsAtom* aEventN
 {
   nsIDocument *ownerDoc = OwnerDoc();
   if (ownerDoc->IsLoadedAsData()) {
     // Make this a no-op rather than throwing an error to avoid
     // the error causing problems setting the attribute.
     return NS_OK;
   }
 
-  NS_PRECONDITION(aEventName, "Must have event name!");
+  MOZ_ASSERT(aEventName, "Must have event name!");
   bool defer = true;
   EventListenerManager* manager =
     GetEventListenerManagerForAttr(aEventName, &defer);
   if (!manager) {
     return NS_OK;
   }
 
   defer = defer && aDefer; // only defer if everyone agrees...
--- a/dom/base/Element.h
+++ b/dom/base/Element.h
@@ -598,32 +598,32 @@ private:
 
 protected:
   // Methods for the ESM, nsGlobalWindow and focus manager to manage state bits.
   // These will handle setting up script blockers when they notify, so no need
   // to do it in the callers unless desired.  States passed here must only be
   // those in EXTERNALLY_MANAGED_STATES.
   virtual void AddStates(EventStates aStates)
   {
-    NS_PRECONDITION(!aStates.HasAtLeastOneOfStates(INTRINSIC_STATES),
-                    "Should only be adding externally-managed states here");
+    MOZ_ASSERT(!aStates.HasAtLeastOneOfStates(INTRINSIC_STATES),
+               "Should only be adding externally-managed states here");
     AddStatesSilently(aStates);
     NotifyStateChange(aStates);
   }
   virtual void RemoveStates(EventStates aStates)
   {
-    NS_PRECONDITION(!aStates.HasAtLeastOneOfStates(INTRINSIC_STATES),
-                    "Should only be removing externally-managed states here");
+    MOZ_ASSERT(!aStates.HasAtLeastOneOfStates(INTRINSIC_STATES),
+               "Should only be removing externally-managed states here");
     RemoveStatesSilently(aStates);
     NotifyStateChange(aStates);
   }
   virtual void ToggleStates(EventStates aStates, bool aNotify)
   {
-    NS_PRECONDITION(!aStates.HasAtLeastOneOfStates(INTRINSIC_STATES),
-                    "Should only be removing externally-managed states here");
+    MOZ_ASSERT(!aStates.HasAtLeastOneOfStates(INTRINSIC_STATES),
+               "Should only be removing externally-managed states here");
     mState ^= aStates;
     if (aNotify) {
       NotifyStateChange(aStates);
     }
   }
 
 public:
   // Public methods to manage state bits in MANUALLY_MANAGED_STATES.
--- a/dom/base/EventSource.cpp
+++ b/dom/base/EventSource.cpp
@@ -830,22 +830,22 @@ EventSourceImpl::AsyncOnChannelRedirect(
                                         uint32_t aFlags,
                                         nsIAsyncVerifyRedirectCallback* aCallback)
 {
   AssertIsOnMainThread();
   if (IsClosed()) {
     return NS_ERROR_ABORT;
   }
   nsCOMPtr<nsIRequest> aOldRequest = do_QueryInterface(aOldChannel);
-  NS_PRECONDITION(aOldRequest, "Redirect from a null request?");
+  MOZ_ASSERT(aOldRequest, "Redirect from a null request?");
 
   nsresult rv = CheckHealthOfRequestCallback(aOldRequest);
   NS_ENSURE_SUCCESS(rv, rv);
 
-  NS_PRECONDITION(aNewChannel, "Redirect without a channel?");
+  MOZ_ASSERT(aNewChannel, "Redirect without a channel?");
 
   nsCOMPtr<nsIURI> newURI;
   rv = NS_GetFinalChannelURI(aNewChannel, getter_AddRefs(newURI));
   NS_ENSURE_SUCCESS(rv, rv);
 
   bool isValidScheme =
     (NS_SUCCEEDED(newURI->SchemeIs("http", &isValidScheme)) && isValidScheme) ||
     (NS_SUCCEEDED(newURI->SchemeIs("https", &isValidScheme)) && isValidScheme);
@@ -1368,18 +1368,17 @@ EventSourceImpl::TimerCallback(nsITimer*
 {
   AssertIsOnMainThread();
   RefPtr<EventSourceImpl> thisObject = static_cast<EventSourceImpl*>(aClosure);
 
   if (thisObject->IsClosed()) {
     return;
   }
 
-  NS_PRECONDITION(!thisObject->mHttpChannel,
-                  "the channel hasn't been cancelled!!");
+  MOZ_ASSERT(!thisObject->mHttpChannel, "the channel hasn't been cancelled!!");
 
   if (!thisObject->IsFrozen()) {
     nsresult rv = thisObject->InitChannelAndRequestEventSource();
     if (NS_FAILED(rv)) {
       NS_WARNING("thisObject->InitChannelAndRequestEventSource() failed");
       return;
     }
   }
--- a/dom/base/FragmentOrElement.cpp
+++ b/dom/base/FragmentOrElement.cpp
@@ -809,18 +809,18 @@ FragmentOrElement::FragmentOrElement(alr
 
 FragmentOrElement::FragmentOrElement(already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo)
   : nsIContent(aNodeInfo)
 {
 }
 
 FragmentOrElement::~FragmentOrElement()
 {
-  NS_PRECONDITION(!IsInUncomposedDoc(),
-                  "Please remove this from the document properly");
+  MOZ_ASSERT(!IsInUncomposedDoc(),
+             "Please remove this from the document properly");
   if (GetParent()) {
     NS_RELEASE(mParent);
   }
 }
 
 already_AddRefed<nsINodeList>
 FragmentOrElement::GetChildren(uint32_t aFilter)
 {
@@ -1182,30 +1182,30 @@ nsIContent::SetXBLInsertionPoint(nsICont
   }
 }
 
 nsresult
 FragmentOrElement::InsertChildBefore(nsIContent* aKid,
                                      nsIContent* aBeforeThis,
                                      bool aNotify)
 {
-  NS_PRECONDITION(aKid, "null ptr");
+  MOZ_ASSERT(aKid, "null ptr");
 
   int32_t index = aBeforeThis ? ComputeIndexOf(aBeforeThis) : GetChildCount();
   MOZ_ASSERT(index >= 0);
 
   return doInsertChildAt(aKid, index, aNotify, mAttrsAndChildren);
 }
 
 nsresult
 FragmentOrElement::InsertChildAt_Deprecated(nsIContent* aKid,
                                             uint32_t aIndex,
                                             bool aNotify)
 {
-  NS_PRECONDITION(aKid, "null ptr");
+  MOZ_ASSERT(aKid, "null ptr");
 
   return doInsertChildAt(aKid, aIndex, aNotify, mAttrsAndChildren);
 }
 
 void
 FragmentOrElement::RemoveChildAt_Deprecated(uint32_t aIndex, bool aNotify)
 {
   nsCOMPtr<nsIContent> oldKid = mAttrsAndChildren.GetSafeChildAt(aIndex);
--- a/dom/base/IDTracker.h
+++ b/dom/base/IDTracker.h
@@ -117,17 +117,17 @@ private:
   public:
     virtual void SetTo(Element* aTo) = 0;
     virtual void Clear() { mTarget = nullptr; }
     virtual ~Notification() {}
   protected:
     explicit Notification(IDTracker* aTarget)
       : mTarget(aTarget)
     {
-      NS_PRECONDITION(aTarget, "Must have a target");
+      MOZ_ASSERT(aTarget, "Must have a target");
     }
     IDTracker* mTarget;
   };
 
   class ChangeNotification : public mozilla::Runnable,
                              public Notification
   {
   public:
--- a/dom/base/Selection.cpp
+++ b/dom/base/Selection.cpp
@@ -2117,17 +2117,17 @@ Selection::SetTextRangeStyle(nsRange* aR
   }
   return NS_OK;
 }
 
 nsresult
 Selection::StartAutoScrollTimer(nsIFrame* aFrame, const nsPoint& aPoint,
                                 uint32_t aDelay)
 {
-  NS_PRECONDITION(aFrame, "Need a frame");
+  MOZ_ASSERT(aFrame, "Need a frame");
 
   nsresult result;
   if (!mFrameSelection) {
     return NS_OK;//nothing to do
   }
 
   if (!mAutoScrollTimer) {
     mAutoScrollTimer = new nsAutoScrollTimer();
@@ -2155,17 +2155,17 @@ Selection::StopAutoScrollTimer()
     return mAutoScrollTimer->Stop();
   }
   return NS_OK;
 }
 
 nsresult
 Selection::DoAutoScroll(nsIFrame* aFrame, nsPoint aPoint)
 {
-  NS_PRECONDITION(aFrame, "Need a frame");
+  MOZ_ASSERT(aFrame, "Need a frame");
 
   if (mAutoScrollTimer) {
     (void)mAutoScrollTimer->Stop();
   }
 
   nsPresContext* presContext = aFrame->PresContext();
   nsCOMPtr<nsIPresShell> shell = presContext->PresShell();
   nsRootPresContext* rootPC = presContext->GetRootPresContext();
--- a/dom/base/nsAttrAndChildArray.cpp
+++ b/dom/base/nsAttrAndChildArray.cpp
@@ -609,17 +609,17 @@ nsAttrAndChildArray::SetAndSwapMappedAtt
   mapped->SetAndSwapAttr(aLocalName, aValue, aHadValue);
 
   return MakeMappedUnique(mapped);
 }
 
 nsresult
 nsAttrAndChildArray::DoSetMappedAttrStyleSheet(nsHTMLStyleSheet* aSheet)
 {
-  NS_PRECONDITION(mImpl && mImpl->mMappedAttrs,
+  MOZ_ASSERT(mImpl && mImpl->mMappedAttrs,
                   "Should have mapped attrs here!");
   if (aSheet == mImpl->mMappedAttrs->GetStyleSheet()) {
     return NS_OK;
   }
 
   RefPtr<nsMappedAttributes> mapped =
     GetModifiableMapped(nullptr, nullptr, false);
 
@@ -795,17 +795,17 @@ const nsMappedAttributes*
 nsAttrAndChildArray::GetMapped() const
 {
   return mImpl ? mImpl->mMappedAttrs : nullptr;
 }
 
 nsresult nsAttrAndChildArray::EnsureCapacityToClone(const nsAttrAndChildArray& aOther,
                                                     bool aAllocateChildren)
 {
-  NS_PRECONDITION(!mImpl, "nsAttrAndChildArray::EnsureCapacityToClone requires the array be empty when called");
+  MOZ_ASSERT(!mImpl, "nsAttrAndChildArray::EnsureCapacityToClone requires the array be empty when called");
 
   uint32_t attrCount = aOther.NonMappedAttrCount();
   uint32_t childCount = 0;
   if (aAllocateChildren) {
     childCount = aOther.ChildCount();
   }
 
   if (attrCount == 0 && childCount == 0) {
@@ -925,18 +925,18 @@ nsAttrAndChildArray::AddAttrSlot()
 
   return true;
 }
 
 inline void
 nsAttrAndChildArray::SetChildAtPos(void** aPos, nsIContent* aChild,
                                    uint32_t aIndex, uint32_t aChildCount)
 {
-  NS_PRECONDITION(!aChild->GetNextSibling(), "aChild with next sibling?");
-  NS_PRECONDITION(!aChild->GetPreviousSibling(), "aChild with prev sibling?");
+  MOZ_ASSERT(!aChild->GetNextSibling(), "aChild with next sibling?");
+  MOZ_ASSERT(!aChild->GetPreviousSibling(), "aChild with prev sibling?");
 
   *aPos = aChild;
   NS_ADDREF(aChild);
   if (aIndex != 0) {
     nsIContent* previous = static_cast<nsIContent*>(*(aPos - 1));
     aChild->mPreviousSibling = previous;
     previous->mNextSibling = aChild;
   }
@@ -960,9 +960,8 @@ nsAttrAndChildArray::SizeOfExcludingThis
     for (uint32_t i = 0; i < slotCount && AttrSlotIsTaken(i); ++i) {
       nsAttrValue* value = &ATTRS(mImpl)[i].mValue;
       n += value->SizeOfExcludingThis(aMallocSizeOf);
     }
   }
 
   return n;
 }
-
--- a/dom/base/nsAttrAndChildArray.h
+++ b/dom/base/nsAttrAndChildArray.h
@@ -179,17 +179,17 @@ private:
 
   uint32_t AttrSlotCount() const
   {
     return mImpl ? mImpl->mAttrAndChildCount & ATTRCHILD_ARRAY_ATTR_SLOTS_COUNT_MASK : 0;
   }
 
   bool AttrSlotIsTaken(uint32_t aSlot) const
   {
-    NS_PRECONDITION(aSlot < AttrSlotCount(), "out-of-bounds");
+    MOZ_ASSERT(aSlot < AttrSlotCount(), "out-of-bounds");
     return mImpl->mBuffer[aSlot * ATTRSIZE];
   }
 
   void SetChildCount(uint32_t aCount)
   {
     mImpl->mAttrAndChildCount =
         (mImpl->mAttrAndChildCount & ATTRCHILD_ARRAY_ATTR_SLOTS_COUNT_MASK) |
         (aCount << ATTRCHILD_ARRAY_ATTR_SLOTS_BITS);
--- a/dom/base/nsAttrValue.cpp
+++ b/dom/base/nsAttrValue.cpp
@@ -732,17 +732,17 @@ nsAttrValue::GetAsAtom() const
         return NS_AtomizeMainThread(val);
       }
   }
 }
 
 const nsCheapString
 nsAttrValue::GetStringValue() const
 {
-  NS_PRECONDITION(Type() == eString, "wrong type");
+  MOZ_ASSERT(Type() == eString, "wrong type");
 
   return nsCheapString(static_cast<nsStringBuffer*>(GetPtr()));
 }
 
 bool
 nsAttrValue::GetColorValue(nscolor& aColor) const
 {
   if (Type() != eColor) {
@@ -753,17 +753,17 @@ nsAttrValue::GetColorValue(nscolor& aCol
 
   aColor = GetMiscContainer()->mValue.mColor;
   return true;
 }
 
 void
 nsAttrValue::GetEnumString(nsAString& aResult, bool aRealTag) const
 {
-  NS_PRECONDITION(Type() == eEnum, "wrong type");
+  MOZ_ASSERT(Type() == eEnum, "wrong type");
 
   uint32_t allEnumBits =
     (BaseType() == eIntegerBase) ? static_cast<uint32_t>(GetIntInternal())
                                    : GetMiscContainer()->mValue.mEnumValue;
   int16_t val = allEnumBits >> NS_ATTRVALUE_ENUMTABLEINDEX_BITS;
   const EnumTable* table = sEnumTableArray->
     ElementAt(allEnumBits & NS_ATTRVALUE_ENUMTABLEINDEX_MASK);
 
@@ -795,18 +795,18 @@ nsAttrValue::GetAtomCount() const
   }
 
   return 0;
 }
 
 nsAtom*
 nsAttrValue::AtomAt(int32_t aIndex) const
 {
-  NS_PRECONDITION(aIndex >= 0, "Index must not be negative");
-  NS_PRECONDITION(GetAtomCount() > uint32_t(aIndex), "aIndex out of range");
+  MOZ_ASSERT(aIndex >= 0, "Index must not be negative");
+  MOZ_ASSERT(GetAtomCount() > uint32_t(aIndex), "aIndex out of range");
 
   if (BaseType() == eAtomBase) {
     return GetAtomValue();
   }
 
   NS_ASSERTION(Type() == eAtomArray, "GetAtomCount must be confused");
 
   return GetAtomArrayValue()->ElementAt(aIndex);
@@ -1395,18 +1395,18 @@ nsAttrValue::ParseEnumValue(const nsAStr
                    "failed to store enum properly");
 
       return true;
     }
     tableEntry++;
   }
 
   if (aDefaultValue) {
-    NS_PRECONDITION(aTable <= aDefaultValue && aDefaultValue < tableEntry,
-                    "aDefaultValue not inside aTable?");
+    MOZ_ASSERT(aTable <= aDefaultValue && aDefaultValue < tableEntry,
+               "aDefaultValue not inside aTable?");
     SetIntValueAndType(EnumTableEntryToValue(aTable, aDefaultValue),
                        eEnum, &aValue);
     return true;
   }
 
   return false;
 }
 
@@ -1438,17 +1438,17 @@ nsAttrValue::ParseSpecialIntValue(const 
                      nonStrict ? &aString : nullptr);
   return true;
 }
 
 bool
 nsAttrValue::ParseIntWithBounds(const nsAString& aString,
                                 int32_t aMin, int32_t aMax)
 {
-  NS_PRECONDITION(aMin < aMax, "bad boundaries");
+  MOZ_ASSERT(aMin < aMax, "bad boundaries");
 
   ResetIfSet();
 
   nsContentUtils::ParseHTMLIntegerResultFlags result;
   int32_t originalVal = nsContentUtils::ParseHTMLInteger(aString, &result);
   if (result & nsContentUtils::eParseHTMLInteger_Error) {
     return false;
   }
@@ -1960,9 +1960,8 @@ nsAttrValue::SizeOfExcludingThis(MallocS
     }
     case eAtomBase:    // Atoms are counted separately.
     case eIntegerBase: // The value is in mBits, nothing to do.
       break;
   }
 
   return n;
 }
-
--- a/dom/base/nsAttrValueInlines.h
+++ b/dom/base/nsAttrValueInlines.h
@@ -123,77 +123,77 @@ public:
 
 /**
  * Implementation of inline methods
  */
 
 inline int32_t
 nsAttrValue::GetIntegerValue() const
 {
-  NS_PRECONDITION(Type() == eInteger, "wrong type");
+  MOZ_ASSERT(Type() == eInteger, "wrong type");
   return (BaseType() == eIntegerBase)
          ? GetIntInternal()
          : GetMiscContainer()->mValue.mInteger;
 }
 
 inline int16_t
 nsAttrValue::GetEnumValue() const
 {
-  NS_PRECONDITION(Type() == eEnum, "wrong type");
+  MOZ_ASSERT(Type() == eEnum, "wrong type");
   // We don't need to worry about sign extension here since we're
   // returning an int16_t which will cut away the top bits.
   return static_cast<int16_t>((
     (BaseType() == eIntegerBase)
     ? static_cast<uint32_t>(GetIntInternal())
     : GetMiscContainer()->mValue.mEnumValue)
       >> NS_ATTRVALUE_ENUMTABLEINDEX_BITS);
 }
 
 inline float
 nsAttrValue::GetPercentValue() const
 {
-  NS_PRECONDITION(Type() == ePercent, "wrong type");
+  MOZ_ASSERT(Type() == ePercent, "wrong type");
   return ((BaseType() == eIntegerBase)
           ? GetIntInternal()
           : GetMiscContainer()->mValue.mPercent)
             / 100.0f;
 }
 
 inline mozilla::AtomArray*
 nsAttrValue::GetAtomArrayValue() const
 {
-  NS_PRECONDITION(Type() == eAtomArray, "wrong type");
+  MOZ_ASSERT(Type() == eAtomArray, "wrong type");
   return GetMiscContainer()->mValue.mAtomArray;
 }
 
 inline mozilla::DeclarationBlock*
 nsAttrValue::GetCSSDeclarationValue() const
 {
-  NS_PRECONDITION(Type() == eCSSDeclaration, "wrong type");
+  MOZ_ASSERT(Type() == eCSSDeclaration, "wrong type");
   return GetMiscContainer()->mValue.mCSSDeclaration;
 }
 
 inline nsIURI*
 nsAttrValue::GetURLValue() const
 {
-  NS_PRECONDITION(Type() == eURL, "wrong type");
+  MOZ_ASSERT(Type() == eURL, "wrong type");
   return GetMiscContainer()->mValue.mURL;
 }
 
 inline double
 nsAttrValue::GetDoubleValue() const
 {
-  NS_PRECONDITION(Type() == eDoubleValue, "wrong type");
+  MOZ_ASSERT(Type() == eDoubleValue, "wrong type");
   return GetMiscContainer()->mDoubleValue;
 }
 
 inline bool
 nsAttrValue::GetIntMarginValue(nsIntMargin& aMargin) const
 {
-  NS_PRECONDITION(Type() == eIntMarginValue, "wrong type");
+  MOZ_ASSERT(Type() == eIntMarginValue, "wrong type");
   nsIntMargin* m = GetMiscContainer()->mValue.mIntMargin;
   if (!m)
     return false;
   aMargin = *m;
   return true;
 }
 
 inline bool
@@ -264,17 +264,17 @@ nsAttrValue::Type() const
       return static_cast<ValueType>(static_cast<uint16_t>(BaseType()));
     }
   }
 }
 
 inline nsAtom*
 nsAttrValue::GetAtomValue() const
 {
-  NS_PRECONDITION(Type() == eAtom, "wrong type");
+  MOZ_ASSERT(Type() == eAtom, "wrong type");
   return reinterpret_cast<nsAtom*>(GetPtr());
 }
 
 inline void
 nsAttrValue::ToString(mozilla::dom::DOMString& aResult) const
 {
   switch (Type()) {
     case eString:
--- a/dom/base/nsContentAreaDragDrop.cpp
+++ b/dom/base/nsContentAreaDragDrop.cpp
@@ -537,18 +537,18 @@ DragDataProducer::GetImageData(imgIConta
 
 nsresult
 DragDataProducer::Produce(DataTransfer* aDataTransfer,
                           bool* aCanDrag,
                           nsISelection** aSelection,
                           nsIContent** aDragNode,
                           nsACString& aPrincipalURISpec)
 {
-  NS_PRECONDITION(aCanDrag && aSelection && aDataTransfer && aDragNode,
-                  "null pointer passed to Produce");
+  MOZ_ASSERT(aCanDrag && aSelection && aDataTransfer && aDragNode,
+             "null pointer passed to Produce");
   NS_ASSERTION(mWindow, "window not set");
   NS_ASSERTION(mSelectionTargetNode, "selection target node should have been set");
 
   *aDragNode = nullptr;
 
   nsresult rv;
   nsIContent* dragNode = nullptr;
   *aSelection = nullptr;
--- a/dom/base/nsContentList.cpp
+++ b/dom/base/nsContentList.cpp
@@ -623,17 +623,17 @@ nsContentList::Item(uint32_t aIndex)
 
 void
 nsContentList::AttributeChanged(Element* aElement,
                                 int32_t aNameSpaceID,
                                 nsAtom* aAttribute,
                                 int32_t aModType,
                                 const nsAttrValue* aOldValue)
 {
-  NS_PRECONDITION(aElement, "Must have a content node to work with");
+  MOZ_ASSERT(aElement, "Must have a content node to work with");
 
   if (!mFunc || !mFuncMayDependOnAttr || mState == LIST_DIRTY ||
       !MayContainRelevantNodes(aElement->GetParentNode()) ||
       !nsContentUtils::IsInSameAnonymousTree(mRootNode, aElement)) {
     // Either we're already dirty or this notification doesn't affect
     // whether we might match aElement.
     return;
   }
@@ -653,17 +653,17 @@ nsContentList::AttributeChanged(Element*
     mElements.RemoveElement(aElement);
   }
 }
 
 void
 nsContentList::ContentAppended(nsIContent* aFirstNewContent)
 {
   nsIContent* container = aFirstNewContent->GetParent();
-  NS_PRECONDITION(container, "Can't get at the new content if no container!");
+  MOZ_ASSERT(container, "Can't get at the new content if no container!");
 
   /*
    * If the state is LIST_DIRTY then we have no useful information in our list
    * and we want to put off doing work as much as possible.
    *
    * Also, if container is anonymous from our point of view, we know that we
    * can't possibly be matching any of the kids.
    *
@@ -822,19 +822,19 @@ nsContentList::Match(Element *aElement)
 
   return matchHTML ? ni->Equals(mHTMLMatchAtom, mMatchNameSpaceId) :
                      ni->Equals(mXMLMatchAtom, mMatchNameSpaceId);
 }
 
 bool
 nsContentList::MatchSelf(nsIContent *aContent)
 {
-  NS_PRECONDITION(aContent, "Can't match null stuff, you know");
-  NS_PRECONDITION(mDeep || aContent->GetParentNode() == mRootNode,
-                  "MatchSelf called on a node that we can't possibly match");
+  MOZ_ASSERT(aContent, "Can't match null stuff, you know");
+  MOZ_ASSERT(mDeep || aContent->GetParentNode() == mRootNode,
+             "MatchSelf called on a node that we can't possibly match");
 
   if (!aContent->IsElement()) {
     return false;
   }
 
   if (Match(aContent->AsElement()))
     return true;
 
--- a/dom/base/nsContentList.h
+++ b/dom/base/nsContentList.h
@@ -382,18 +382,18 @@ public:
   }
 
   bool MatchesKey(const nsContentListKey& aKey) const
   {
     // The root node is most commonly the same: the document.  And the
     // most common namespace id is kNameSpaceID_Unknown.  So check the
     // string first.  Cases in which whether our root's ownerDocument
     // is HTML changes are extremely rare, so check those last.
-    NS_PRECONDITION(mXMLMatchAtom,
-                    "How did we get here with a null match atom on our list?");
+    MOZ_ASSERT(mXMLMatchAtom,
+               "How did we get here with a null match atom on our list?");
     return
       mXMLMatchAtom->Equals(aKey.mTagname) &&
       mRootNode == aKey.mRootNode &&
       mMatchNameSpaceId == aKey.mMatchNameSpaceId &&
       mIsHTMLDocument == aKey.mIsHTMLDocument;
   }
 
   /**
--- a/dom/base/nsContentPolicy.cpp
+++ b/dom/base/nsContentPolicy.cpp
@@ -83,17 +83,17 @@ nsContentPolicy::CheckPolicy(CPMethod   
     nsCOMPtr<nsIPrincipal> requestPrincipal = loadInfo->TriggeringPrincipal();
     nsCOMPtr<nsIURI> requestingLocation;
     nsCOMPtr<nsIPrincipal> loadingPrincipal = loadInfo->LoadingPrincipal();
     if (loadingPrincipal) {
       loadingPrincipal->GetURI(getter_AddRefs(requestingLocation));
     }
 
     //sanity-check passed-through parameters
-    NS_PRECONDITION(decision, "Null out pointer");
+    MOZ_ASSERT(decision, "Null out pointer");
     WARN_IF_URI_UNINITIALIZED(contentLocation, "Request URI");
     WARN_IF_URI_UNINITIALIZED(requestingLocation, "Requesting URI");
 
 #ifdef DEBUG
     {
         nsCOMPtr<nsIDOMNode> node(do_QueryInterface(requestingContext));
         nsCOMPtr<nsIDOMWindow> window(do_QueryInterface(requestingContext));
         nsCOMPtr<nsITabChild> tabChild(do_QueryInterface(requestingContext));
@@ -203,17 +203,17 @@ nsContentPolicy::CheckPolicy(CPMethod   
 
 NS_IMETHODIMP
 nsContentPolicy::ShouldLoad(nsIURI           *contentLocation,
                             nsILoadInfo      *loadInfo,
                             const nsACString &mimeType,
                             int16_t          *decision)
 {
     // ShouldProcess does not need a content location, but we do
-    NS_PRECONDITION(contentLocation, "Must provide request location");
+    MOZ_ASSERT(contentLocation, "Must provide request location");
     nsresult rv = CheckPolicy(&nsIContentPolicy::ShouldLoad,
                               contentLocation, loadInfo,
                               mimeType, decision);
     LOG_CHECK("ShouldLoad");
 
     return rv;
 }
 
--- a/dom/base/nsContentSink.cpp
+++ b/dom/base/nsContentSink.cpp
@@ -51,16 +51,17 @@
 #include "mozilla/dom/ServiceWorkerDescriptor.h"
 #include "mozilla/dom/ScriptLoader.h"
 #include "nsParserConstants.h"
 #include "nsSandboxFlags.h"
 #include "Link.h"
 #include "HTMLLinkElement.h"
 
 using namespace mozilla;
+using namespace mozilla::css;
 using namespace mozilla::dom;
 
 LazyLogModule gContentSinkLogModuleInfo("nscontentsink");
 
 NS_IMPL_CYCLE_COLLECTING_ADDREF(nsContentSink)
 NS_IMPL_CYCLE_COLLECTING_RELEASE(nsContentSink)
 
 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsContentSink)
@@ -190,18 +191,18 @@ nsContentSink::InitializeStatics()
 }
 
 nsresult
 nsContentSink::Init(nsIDocument* aDoc,
                     nsIURI* aURI,
                     nsISupports* aContainer,
                     nsIChannel* aChannel)
 {
-  NS_PRECONDITION(aDoc, "null ptr");
-  NS_PRECONDITION(aURI, "null ptr");
+  MOZ_ASSERT(aDoc, "null ptr");
+  MOZ_ASSERT(aURI, "null ptr");
 
   if (!aDoc || !aURI) {
     return NS_ERROR_NULL_POINTER;
   }
 
   mDocument = aDoc;
 
   mDocumentURI = aURI;
@@ -778,28 +779,32 @@ nsContentSink::ProcessStyleLinkFromHeade
   nsresult rv = NS_NewURI(getter_AddRefs(url), aHref, nullptr,
                           mDocument->GetDocBaseURI());
 
   if (NS_FAILED(rv)) {
     // The URI is bad, move along, don't propagate the error (for now)
     return NS_OK;
   }
 
-  mozilla::net::ReferrerPolicy referrerPolicy =
-    mozilla::net::AttributeReferrerPolicyFromString(aReferrerPolicy);
-  if (referrerPolicy == net::RP_Unset) {
-    referrerPolicy = mDocument->GetReferrerPolicy();
-  }
-  // If this is a fragment parser, we don't want to observe.
-  // We don't support CORS for processing instructions
+
+  Loader::SheetInfo info {
+    *mDocument,
+    nullptr,
+    url.forget(),
+    nullptr,
+    net::AttributeReferrerPolicyFromString(aReferrerPolicy),
+    CORS_NONE,
+    aTitle,
+    aMedia,
+    aAlternate ? Loader::HasAlternateRel::Yes : Loader::HasAlternateRel::No,
+    Loader::IsInline::No,
+  };
+
   auto loadResultOrErr =
-    mCSSLoader->LoadStyleLink(nullptr, url, nullptr, aTitle, aMedia, aAlternate,
-                              CORS_NONE, referrerPolicy,
-                              /* integrity = */ EmptyString(),
-                              mRunsToCompletion ? nullptr : this);
+    mCSSLoader->LoadStyleLink(info, mRunsToCompletion ? nullptr : this);
   if (loadResultOrErr.isErr()) {
     return loadResultOrErr.unwrapErr();
   }
 
   if (loadResultOrErr.unwrap().ShouldBlock() && !mRunsToCompletion) {
     ++mPendingSheetCount;
     mScriptLoader->AddParserBlockingScriptExecutionBlocker();
   }
--- a/dom/base/nsContentUtils.cpp
+++ b/dom/base/nsContentUtils.cpp
@@ -765,17 +765,17 @@ nsContentUtils::Init()
   return NS_OK;
 }
 
 nsresult nsContentUtils::RemoveWyciwygScheme(nsIURI* aURI, nsIURI** aReturn)
 {
 #ifdef DEBUG
   bool isWyciwyg = false;
   aURI->SchemeIs("wyciwyg", &isWyciwyg);
-  NS_PRECONDITION(isWyciwyg, "Scheme should be wyciwyg");
+  MOZ_ASSERT(isWyciwyg, "Scheme should be wyciwyg");
 #endif
   nsAutoCString path;
   nsresult rv = aURI->GetPathQueryRef(path);
   NS_ENSURE_SUCCESS(rv, rv);
 
   uint32_t pathLength = path.Length();
   if (pathLength <= 2) {
     return NS_ERROR_FAILURE;
@@ -1056,17 +1056,17 @@ nsContentUtils::Atob(const nsAString& aA
     return NS_ERROR_DOM_INVALID_CHARACTER_ERR;
   }
   return rv;
 }
 
 bool
 nsContentUtils::IsAutocompleteEnabled(mozilla::dom::HTMLInputElement* aInput)
 {
-  NS_PRECONDITION(aInput, "aInput should not be null!");
+  MOZ_ASSERT(aInput, "aInput should not be null!");
 
   nsAutoString autocomplete;
   aInput->GetAutocomplete(autocomplete);
 
   if (autocomplete.IsEmpty()) {
     auto* form = aInput->GetForm();
     if (!form) {
       return true;
@@ -2188,17 +2188,17 @@ nsContentUtils::IsAbsoluteURL(const nsAC
 
   return false;
 }
 
 //static
 bool
 nsContentUtils::InProlog(nsINode *aNode)
 {
-  NS_PRECONDITION(aNode, "missing node to nsContentUtils::InProlog");
+  MOZ_ASSERT(aNode, "missing node to nsContentUtils::InProlog");
 
   nsINode* parent = aNode->GetParentNode();
   if (!parent || !parent->IsDocument()) {
     return false;
   }
 
   nsIDocument* doc = parent->AsDocument();
   nsIContent* root = doc->GetRootElement();
@@ -2386,17 +2386,17 @@ nsContentUtils::LookupBindingMember(JSCo
     return true;
   return binding->LookupMember(aCx, aId, aDesc);
 }
 
 // static
 nsINode*
 nsContentUtils::GetCrossDocParentNode(nsINode* aChild)
 {
-  NS_PRECONDITION(aChild, "The child is null!");
+  MOZ_ASSERT(aChild, "The child is null!");
 
   nsINode* parent = aChild->GetParentNode();
   if (parent && parent->IsContent() && aChild->IsContent()) {
     parent = aChild->AsContent()->GetFlattenedTreeParent();
   }
 
   if (parent || !aChild->IsDocument()) {
     return parent;
@@ -2407,34 +2407,34 @@ nsContentUtils::GetCrossDocParentNode(ns
   return parentDoc ? parentDoc->FindContentForSubDocument(doc) : nullptr;
 }
 
 // static
 bool
 nsContentUtils::ContentIsDescendantOf(const nsINode* aPossibleDescendant,
                                       const nsINode* aPossibleAncestor)
 {
-  NS_PRECONDITION(aPossibleDescendant, "The possible descendant is null!");
-  NS_PRECONDITION(aPossibleAncestor, "The possible ancestor is null!");
+  MOZ_ASSERT(aPossibleDescendant, "The possible descendant is null!");
+  MOZ_ASSERT(aPossibleAncestor, "The possible ancestor is null!");
 
   do {
     if (aPossibleDescendant == aPossibleAncestor)
       return true;
     aPossibleDescendant = aPossibleDescendant->GetParentNode();
   } while (aPossibleDescendant);
 
   return false;
 }
 
 bool
 nsContentUtils::ContentIsHostIncludingDescendantOf(
   const nsINode* aPossibleDescendant, const nsINode* aPossibleAncestor)
 {
-  NS_PRECONDITION(aPossibleDescendant, "The possible descendant is null!");
-  NS_PRECONDITION(aPossibleAncestor, "The possible ancestor is null!");
+  MOZ_ASSERT(aPossibleDescendant, "The possible descendant is null!");
+  MOZ_ASSERT(aPossibleAncestor, "The possible ancestor is null!");
 
   do {
     if (aPossibleDescendant == aPossibleAncestor)
       return true;
     if (aPossibleDescendant->IsDocumentFragment()) {
       aPossibleDescendant =
         aPossibleDescendant->AsDocumentFragment()->GetHost();
     } else {
@@ -2473,18 +2473,18 @@ nsContentUtils::ContentIsShadowIncluding
   return false;
 }
 
 // static
 bool
 nsContentUtils::ContentIsCrossDocDescendantOf(nsINode* aPossibleDescendant,
                                               nsINode* aPossibleAncestor)
 {
-  NS_PRECONDITION(aPossibleDescendant, "The possible descendant is null!");
-  NS_PRECONDITION(aPossibleAncestor, "The possible ancestor is null!");
+  MOZ_ASSERT(aPossibleDescendant, "The possible descendant is null!");
+  MOZ_ASSERT(aPossibleAncestor, "The possible ancestor is null!");
 
   do {
     if (aPossibleDescendant == aPossibleAncestor)
       return true;
 
     aPossibleDescendant = GetCrossDocParentNode(aPossibleDescendant);
   } while (aPossibleDescendant);
 
@@ -2492,18 +2492,18 @@ nsContentUtils::ContentIsCrossDocDescend
 }
 
 // static
 bool
 nsContentUtils::ContentIsFlattenedTreeDescendantOf(
   const nsINode* aPossibleDescendant,
   const nsINode* aPossibleAncestor)
 {
-  NS_PRECONDITION(aPossibleDescendant, "The possible descendant is null!");
-  NS_PRECONDITION(aPossibleAncestor, "The possible ancestor is null!");
+  MOZ_ASSERT(aPossibleDescendant, "The possible descendant is null!");
+  MOZ_ASSERT(aPossibleAncestor, "The possible ancestor is null!");
 
   do {
     if (aPossibleDescendant == aPossibleAncestor) {
       return true;
     }
     aPossibleDescendant = aPossibleDescendant->GetFlattenedTreeParentNode();
   } while (aPossibleDescendant);
 
@@ -2511,18 +2511,18 @@ nsContentUtils::ContentIsFlattenedTreeDe
 }
 
 // static
 bool
 nsContentUtils::ContentIsFlattenedTreeDescendantOfForStyle(
   const nsINode* aPossibleDescendant,
   const nsINode* aPossibleAncestor)
 {
-  NS_PRECONDITION(aPossibleDescendant, "The possible descendant is null!");
-  NS_PRECONDITION(aPossibleAncestor, "The possible ancestor is null!");
+  MOZ_ASSERT(aPossibleDescendant, "The possible descendant is null!");
+  MOZ_ASSERT(aPossibleAncestor, "The possible ancestor is null!");
 
   do {
     if (aPossibleDescendant == aPossibleAncestor) {
       return true;
     }
     aPossibleDescendant =
       aPossibleDescendant->GetFlattenedTreeParentNodeForStyle();
   } while (aPossibleDescendant);
@@ -3446,19 +3446,19 @@ nsContentUtils::GetContextForContent(con
 // static
 bool
 nsContentUtils::CanLoadImage(nsIURI* aURI, nsINode* aNode,
                              nsIDocument* aLoadingDocument,
                              nsIPrincipal* aLoadingPrincipal,
                              int16_t* aImageBlockingStatus,
                              uint32_t aContentType)
 {
-  NS_PRECONDITION(aURI, "Must have a URI");
-  NS_PRECONDITION(aLoadingDocument, "Must have a document");
-  NS_PRECONDITION(aLoadingPrincipal, "Must have a loading principal");
+  MOZ_ASSERT(aURI, "Must have a URI");
+  MOZ_ASSERT(aLoadingDocument, "Must have a document");
+  MOZ_ASSERT(aLoadingPrincipal, "Must have a loading principal");
 
   nsresult rv;
 
   uint32_t appType = nsIDocShell::APP_TYPE_UNKNOWN;
 
   {
     nsCOMPtr<nsIDocShellTreeItem> docShellTreeItem = aLoadingDocument->GetDocShell();
     if (docShellTreeItem) {
@@ -3671,21 +3671,21 @@ nsContentUtils::LoadImage(nsIURI* aURI, 
                           nsIURI* aReferrer,
                           net::ReferrerPolicy aReferrerPolicy,
                           imgINotificationObserver* aObserver, int32_t aLoadFlags,
                           const nsAString& initiatorType,
                           imgRequestProxy** aRequest,
                           uint32_t aContentPolicyType,
                           bool aUseUrgentStartForChannel)
 {
-  NS_PRECONDITION(aURI, "Must have a URI");
-  NS_PRECONDITION(aContext, "Must have a context");
-  NS_PRECONDITION(aLoadingDocument, "Must have a document");
-  NS_PRECONDITION(aLoadingPrincipal, "Must have a principal");
-  NS_PRECONDITION(aRequest, "Null out param");
+  MOZ_ASSERT(aURI, "Must have a URI");
+  MOZ_ASSERT(aContext, "Must have a context");
+  MOZ_ASSERT(aLoadingDocument, "Must have a document");
+  MOZ_ASSERT(aLoadingPrincipal, "Must have a principal");
+  MOZ_ASSERT(aRequest, "Null out param");
 
   imgLoader* imgLoader = GetImgLoaderForDocument(aLoadingDocument);
   if (!imgLoader) {
     // nothing we can do here
     return NS_ERROR_FAILURE;
   }
 
   nsCOMPtr<nsILoadGroup> loadGroup = aLoadingDocument->GetDocumentLoadGroup();
@@ -3783,17 +3783,17 @@ nsContentUtils::ContentIsDraggable(nsICo
   // special handling for content area image and link dragging
   return IsDraggableImage(aContent) || IsDraggableLink(aContent);
 }
 
 // static
 bool
 nsContentUtils::IsDraggableImage(nsIContent* aContent)
 {
-  NS_PRECONDITION(aContent, "Must have content node to test");
+  MOZ_ASSERT(aContent, "Must have content node to test");
 
   nsCOMPtr<nsIImageLoadingContent> imageContent(do_QueryInterface(aContent));
   if (!imageContent) {
     return false;
   }
 
   nsCOMPtr<imgIRequest> imgRequest;
   imageContent->GetRequest(nsIImageLoadingContent::CURRENT_REQUEST,
@@ -4585,17 +4585,17 @@ nsContentUtils::MatchElementId(nsIConten
 
   return nullptr;
 }
 
 /* static */
 Element *
 nsContentUtils::MatchElementId(nsIContent *aContent, const nsAString& aId)
 {
-  NS_PRECONDITION(!aId.IsEmpty(), "Will match random elements");
+  MOZ_ASSERT(!aId.IsEmpty(), "Will match random elements");
 
   // ID attrs are generally stored as atoms, so just atomize this up front
   RefPtr<nsAtom> id(NS_Atomize(aId));
   if (!id) {
     // OOM, so just bail
     return nullptr;
   }
 
@@ -4732,19 +4732,19 @@ nsContentUtils::HasMutationListeners(nsI
   // all mutation bits when there is a listener for DOMSubtreeModified event.
   return !window || window->HasMutationListeners(aType);
 }
 
 void
 nsContentUtils::MaybeFireNodeRemoved(nsINode* aChild, nsINode* aParent,
                                      nsIDocument* aOwnerDoc)
 {
-  NS_PRECONDITION(aChild, "Missing child");
-  NS_PRECONDITION(aChild->GetParentNode() == aParent, "Wrong parent");
-  NS_PRECONDITION(aChild->OwnerDoc() == aOwnerDoc, "Wrong owner-doc");
+  MOZ_ASSERT(aChild, "Missing child");
+  MOZ_ASSERT(aChild->GetParentNode() == aParent, "Wrong parent");
+  MOZ_ASSERT(aChild->OwnerDoc() == aOwnerDoc, "Wrong owner-doc");
 
   // Having an explicit check here since it's an easy mistake to fall into,
   // and there might be existing code with problems. We'd rather be safe
   // than fire DOMNodeRemoved in all corner cases. We also rely on it for
   // nsAutoScriptBlockerSuppressNodeRemoved.
   if (!IsSafeToRunScript()) {
     // This checks that IsSafeToRunScript is true since we don't want to fire
     // events when that is false. We can't rely on EventDispatcher to assert
@@ -5402,20 +5402,18 @@ nsContentUtils::HasNonEmptyTextContent(n
   return false;
 }
 
 /* static */
 bool
 nsContentUtils::IsInSameAnonymousTree(const nsINode* aNode,
                                       const nsIContent* aContent)
 {
-  NS_PRECONDITION(aNode,
-                  "Must have a node to work with");
-  NS_PRECONDITION(aContent,
-                  "Must have a content to work with");
+  MOZ_ASSERT(aNode, "Must have a node to work with");
+  MOZ_ASSERT(aContent, "Must have a content to work with");
 
   if (!aNode->IsContent()) {
     /**
      * The root isn't an nsIContent, so it's a document or attribute.  The only
      * nodes in the same anonymous subtree as it will have a null
      * bindingParent.
      *
      * XXXbz strictly speaking, that's not true for attribute nodes.
@@ -5489,17 +5487,17 @@ nsContentUtils::CombineResourcePrincipal
 
 /* static */
 void
 nsContentUtils::TriggerLink(nsIContent *aContent, nsPresContext *aPresContext,
                             nsIURI *aLinkURI, const nsString &aTargetSpec,
                             bool aClick, bool aIsTrusted)
 {
   NS_ASSERTION(aPresContext, "Need a nsPresContext");
-  NS_PRECONDITION(aLinkURI, "No link URI");
+  MOZ_ASSERT(aLinkURI, "No link URI");
 
   if (aContent->IsEditable()) {
     return;
   }
 
   nsILinkHandler *handler = aPresContext->GetLinkHandler();
   if (!handler) {
     return;
@@ -6274,17 +6272,17 @@ NS_IMPL_ISUPPORTS(SameOriginCheckerImpl,
                   nsIInterfaceRequestor)
 
 NS_IMETHODIMP
 SameOriginCheckerImpl::AsyncOnChannelRedirect(nsIChannel* aOldChannel,
                                               nsIChannel* aNewChannel,
                                               uint32_t aFlags,
                                               nsIAsyncVerifyRedirectCallback* cb)
 {
-  NS_PRECONDITION(aNewChannel, "Redirecting to null channel?");
+  MOZ_ASSERT(aNewChannel, "Redirecting to null channel?");
 
   nsresult rv = nsContentUtils::CheckSameOrigin(aOldChannel, aNewChannel);
   if (NS_SUCCEEDED(rv)) {
     cb->OnRedirectVerifyCallback(NS_OK);
   }
 
   return rv;
 }
@@ -6294,17 +6292,17 @@ SameOriginCheckerImpl::GetInterface(cons
 {
   return QueryInterface(aIID, aResult);
 }
 
 /* static */
 nsresult
 nsContentUtils::GetASCIIOrigin(nsIPrincipal* aPrincipal, nsACString& aOrigin)
 {
-  NS_PRECONDITION(aPrincipal, "missing principal");
+  MOZ_ASSERT(aPrincipal, "missing principal");
 
   aOrigin.Truncate();
 
   nsCOMPtr<nsIURI> uri;
   nsresult rv = aPrincipal->GetURI(getter_AddRefs(uri));
   NS_ENSURE_SUCCESS(rv, rv);
 
   if (uri) {
@@ -6315,17 +6313,17 @@ nsContentUtils::GetASCIIOrigin(nsIPrinci
 
   return NS_OK;
 }
 
 /* static */
 nsresult
 nsContentUtils::GetASCIIOrigin(nsIURI* aURI, nsACString& aOrigin)
 {
-  NS_PRECONDITION(aURI, "missing uri");
+  MOZ_ASSERT(aURI, "missing uri");
 
   // For Blob URI we have to return the origin of page using its principal.
   nsCOMPtr<nsIURIWithPrincipal> uriWithPrincipal = do_QueryInterface(aURI);
   if (uriWithPrincipal) {
     nsCOMPtr<nsIPrincipal> principal;
     uriWithPrincipal->GetPrincipal(getter_AddRefs(principal));
 
     if (principal) {
@@ -6369,17 +6367,17 @@ nsContentUtils::GetASCIIOrigin(nsIURI* a
 
   return NS_OK;
 }
 
 /* static */
 nsresult
 nsContentUtils::GetUTFOrigin(nsIPrincipal* aPrincipal, nsAString& aOrigin)
 {
-  NS_PRECONDITION(aPrincipal, "missing principal");
+  MOZ_ASSERT(aPrincipal, "missing principal");
 
   aOrigin.Truncate();
 
   nsCOMPtr<nsIURI> uri;
   nsresult rv = aPrincipal->GetURI(getter_AddRefs(uri));
   NS_ENSURE_SUCCESS(rv, rv);
 
   if (uri) {
@@ -6390,17 +6388,17 @@ nsContentUtils::GetUTFOrigin(nsIPrincipa
 
   return NS_OK;
 }
 
 /* static */
 nsresult
 nsContentUtils::GetUTFOrigin(nsIURI* aURI, nsAString& aOrigin)
 {
-  NS_PRECONDITION(aURI, "missing uri");
+  MOZ_ASSERT(aURI, "missing uri");
 
   bool isBlobURL = false;
   nsresult rv = aURI->SchemeIs(BLOBURI_SCHEME, &isBlobURL);
   NS_ENSURE_SUCCESS(rv, rv);
 
   // For Blob URI, the path is the URL of the owning page.
   if (isBlobURL) {
     nsAutoCString path;
--- a/dom/base/nsContentUtils.h
+++ b/dom/base/nsContentUtils.h
@@ -2186,17 +2186,17 @@ public:
 
   /**
    * Utility method for getElementsByClassName.  aRootNode is the node (either
    * document or element), which getElementsByClassName was called on.
    */
   static already_AddRefed<nsContentList>
   GetElementsByClassName(nsINode* aRootNode, const nsAString& aClasses)
   {
-    NS_PRECONDITION(aRootNode, "Must have root node");
+    MOZ_ASSERT(aRootNode, "Must have root node");
 
     return GetFuncStringContentList<nsCacheableFuncStringHTMLCollection>(aRootNode,
                                                                          MatchClassNames,
                                                                          DestroyClassNameArray,
                                                                          AllocClassMatchingInfo,
                                                                          aClasses);
   }
 
--- a/dom/base/nsDocument.cpp
+++ b/dom/base/nsDocument.cpp
@@ -500,18 +500,18 @@ struct PositionComparator
   }
 };
 
 } // namespace
 
 bool
 nsIdentifierMapEntry::AddIdElement(Element* aElement)
 {
-  NS_PRECONDITION(aElement, "Must have element");
-  NS_PRECONDITION(!mIdContentList.Contains(nullptr),
+  MOZ_ASSERT(aElement, "Must have element");
+  MOZ_ASSERT(!mIdContentList.Contains(nullptr),
                   "Why is null in our list?");
 
 #ifdef DEBUG
   Element* currentElement = mIdContentList.SafeElementAt(0);
 #endif
 
   // Common case
   if (mIdContentList.IsEmpty()) {
@@ -544,17 +544,17 @@ nsIdentifierMapEntry::AddIdElement(Eleme
     FireChangeCallbacks(oldElement, aElement);
   }
   return true;
 }
 
 void
 nsIdentifierMapEntry::RemoveIdElement(Element* aElement)
 {
-  NS_PRECONDITION(aElement, "Missing element");
+  MOZ_ASSERT(aElement, "Missing element");
 
   // This should only be called while the document is in an update.
   // Assertions near the call to this method guarantee this.
 
   // This could fire in OOM situations
   // Only assert this in HTML documents for now as XUL does all sorts of weird
   // crap.
   NS_ASSERTION(!aElement->OwnerDoc()->IsHTMLDocument() ||
@@ -815,18 +815,18 @@ nsIDocument*
 nsExternalResourceMap::RequestResource(nsIURI* aURI,
                                        nsINode* aRequestingNode,
                                        nsIDocument* aDisplayDocument,
                                        ExternalResourceLoad** aPendingLoad)
 {
   // If we ever start allowing non-same-origin loads here, we might need to do
   // something interesting with aRequestingPrincipal even for the hashtable
   // gets.
-  NS_PRECONDITION(aURI, "Must have a URI");
-  NS_PRECONDITION(aRequestingNode, "Must have a node");
+  MOZ_ASSERT(aURI, "Must have a URI");
+  MOZ_ASSERT(aRequestingNode, "Must have a node");
   *aPendingLoad = nullptr;
   if (mHaveShutDown) {
     return nullptr;
   }
 
   // First, make sure we strip the ref from aURI.
   nsCOMPtr<nsIURI> clone;
   nsresult rv = aURI->CloneIgnoringRef(getter_AddRefs(clone));
@@ -953,19 +953,19 @@ TransferShowingState(nsIDocument* aFromD
 }
 
 nsresult
 nsExternalResourceMap::AddExternalResource(nsIURI* aURI,
                                            nsIContentViewer* aViewer,
                                            nsILoadGroup* aLoadGroup,
                                            nsIDocument* aDisplayDocument)
 {
-  NS_PRECONDITION(aURI, "Unexpected call");
-  NS_PRECONDITION((aViewer && aLoadGroup) || (!aViewer && !aLoadGroup),
-                  "Must have both or neither");
+  MOZ_ASSERT(aURI, "Unexpected call");
+  MOZ_ASSERT((aViewer && aLoadGroup) || (!aViewer && !aLoadGroup),
+             "Must have both or neither");
 
   RefPtr<PendingLoad> load;
   mPendingLoads.Remove(aURI, getter_AddRefs(load));
 
   nsresult rv = NS_OK;
 
   nsCOMPtr<nsIDocument> doc;
   if (aViewer) {
@@ -1045,17 +1045,17 @@ nsExternalResourceMap::PendingLoad::OnSt
   return mTargetListener->OnStartRequest(aRequest, aContext);
 }
 
 nsresult
 nsExternalResourceMap::PendingLoad::SetupViewer(nsIRequest* aRequest,
                                                 nsIContentViewer** aViewer,
                                                 nsILoadGroup** aLoadGroup)
 {
-  NS_PRECONDITION(!mTargetListener, "Unexpected call to OnStartRequest");
+  MOZ_ASSERT(!mTargetListener, "Unexpected call to OnStartRequest");
   *aViewer = nullptr;
   *aLoadGroup = nullptr;
 
   nsCOMPtr<nsIChannel> chan(do_QueryInterface(aRequest));
   NS_ENSURE_TRUE(chan, NS_ERROR_UNEXPECTED);
 
   nsCOMPtr<nsIHttpChannel> httpChannel(do_QueryInterface(aRequest));
   if (httpChannel) {
@@ -1156,18 +1156,18 @@ nsExternalResourceMap::PendingLoad::OnSt
 
   return NS_OK;
 }
 
 nsresult
 nsExternalResourceMap::PendingLoad::StartLoad(nsIURI* aURI,
                                               nsINode* aRequestingNode)
 {
-  NS_PRECONDITION(aURI, "Must have a URI");
-  NS_PRECONDITION(aRequestingNode, "Must have a node");
+  MOZ_ASSERT(aURI, "Must have a URI");
+  MOZ_ASSERT(aRequestingNode, "Must have a node");
 
   nsCOMPtr<nsILoadGroup> loadGroup =
     aRequestingNode->OwnerDoc()->GetDocumentLoadGroup();
 
   nsresult rv = NS_OK;
   nsCOMPtr<nsIChannel> channel;
   rv = NS_NewChannel(getter_AddRefs(channel),
                      aURI,
@@ -1749,17 +1749,17 @@ NS_INTERFACE_TABLE_HEAD(nsDocument)
   NS_INTERFACE_TABLE_TO_MAP_SEGUE_CYCLE_COLLECTION(nsDocument)
 NS_INTERFACE_MAP_END
 
 
 NS_IMPL_CYCLE_COLLECTING_ADDREF(nsDocument)
 NS_IMETHODIMP_(MozExternalRefCountType)
 nsDocument::Release()
 {
-  NS_PRECONDITION(0 != mRefCnt, "dup release");
+  MOZ_ASSERT(0 != mRefCnt, "dup release");
   NS_ASSERT_OWNINGTHREAD(nsDocument);
   nsISupports* base = NS_CYCLE_COLLECTION_CLASSNAME(nsDocument)::Upcast(this);
   bool shouldDelete = false;
   nsrefcnt count = mRefCnt.decr(base, &shouldDelete);
   NS_LOG_RELEASE(this, count, "nsDocument");
   if (count == 0) {
     if (mStackRefCnt && !mNeedsReleaseAfterStackRefCntRelease) {
       mNeedsReleaseAfterStackRefCntRelease = true;
@@ -2224,17 +2224,17 @@ nsIDocument::Reset(nsIChannel* aChannel,
   mChannel = aChannel;
 }
 
 void
 nsIDocument::ResetToURI(nsIURI* aURI,
                         nsILoadGroup* aLoadGroup,
                         nsIPrincipal* aPrincipal)
 {
-  NS_PRECONDITION(aURI, "Null URI passed to ResetToURI");
+  MOZ_ASSERT(aURI, "Null URI passed to ResetToURI");
 
   MOZ_LOG(gDocumentLeakPRLog, LogLevel::Debug,
           ("DOCUMENT %p ResetToURI %s", this, aURI->GetSpecOrDefault().get()));
 
   mSecurityInfo = nullptr;
 
   mDocumentLoadGroup = nullptr;
 
@@ -2527,19 +2527,19 @@ AppendSheetsToStyleSet(ServoStyleSet* aS
     aStyleSet->AppendStyleSheet(aType, sheet);
   }
 }
 
 
 void
 nsIDocument::FillStyleSet(ServoStyleSet* aStyleSet)
 {
-  NS_PRECONDITION(aStyleSet, "Must have a style set");
-  NS_PRECONDITION(aStyleSet->SheetCount(SheetType::Doc) == 0,
-                  "Style set already has document sheets?");
+  MOZ_ASSERT(aStyleSet, "Must have a style set");
+  MOZ_ASSERT(aStyleSet->SheetCount(SheetType::Doc) == 0,
+             "Style set already has document sheets?");
 
   MOZ_ASSERT(!mStyleSetFilled);
 
   for (StyleSheet* sheet : Reversed(mStyleSheets)) {
     if (sheet->IsApplicable()) {
       aStyleSet->AddDocStyleSheet(sheet, this);
     }
   }
@@ -4370,17 +4370,17 @@ nsIDocument::RemoveStyleSheetFromStyleSe
   if (shell) {
     shell->StyleSet()->RemoveDocStyleSheet(aSheet);
   }
 }
 
 void
 nsIDocument::RemoveStyleSheet(StyleSheet* aSheet)
 {
-  NS_PRECONDITION(aSheet, "null arg");
+  MOZ_ASSERT(aSheet, "null arg");
   RefPtr<StyleSheet> sheet = aSheet; // hold ref so it won't die too soon
 
   if (!mStyleSheets.RemoveElement(aSheet)) {
     NS_ASSERTION(mInUnlinkOrDeletion, "stylesheet not found");
     return;
   }
 
   if (!mIsGoingAway) {
@@ -4396,18 +4396,18 @@ nsIDocument::RemoveStyleSheet(StyleSheet
 
 void
 nsIDocument::UpdateStyleSheets(nsTArray<RefPtr<StyleSheet>>& aOldSheets,
                                nsTArray<RefPtr<StyleSheet>>& aNewSheets)
 {
   BeginUpdate(UPDATE_STYLE);
 
   // XXX Need to set the sheet on the ownernode, if any
-  NS_PRECONDITION(aOldSheets.Length() == aNewSheets.Length(),
-                  "The lists must be the same length!");
+  MOZ_ASSERT(aOldSheets.Length() == aNewSheets.Length(),
+             "The lists must be the same length!");
   int32_t count = aOldSheets.Length();
 
   RefPtr<StyleSheet> oldSheet;
   int32_t i;
   for (i = 0; i < count; ++i) {
     oldSheet = aOldSheets[i];
 
     // First remove the old sheet.
@@ -4448,17 +4448,17 @@ nsIDocument::InsertStyleSheetAt(StyleShe
 
   NotifyStyleSheetAdded(aSheet, true);
 }
 
 
 void
 nsIDocument::SetStyleSheetApplicableState(StyleSheet* aSheet, bool aApplicable)
 {
-  NS_PRECONDITION(aSheet, "null arg");
+  MOZ_ASSERT(aSheet, "null arg");
 
   // If we're actually in the document style sheet list
   if (mStyleSheets.IndexOf(aSheet) != mStyleSheets.NoIndex) {
     if (aApplicable) {
       AddStyleSheetToStyleSets(aSheet);
     } else {
       RemoveStyleSheetFromStyleSets(aSheet);
     }
@@ -4532,17 +4532,17 @@ FindSheet(const nsTArray<RefPtr<StyleShe
 
   return -1;
 }
 
 nsresult
 nsIDocument::LoadAdditionalStyleSheet(additionalSheetType aType,
                                       nsIURI* aSheetURI)
 {
-  NS_PRECONDITION(aSheetURI, "null arg");
+  MOZ_ASSERT(aSheetURI, "null arg");
 
   // Checking if we have loaded this one already.
   if (FindSheet(mAdditionalSheets[aType], aSheetURI) >= 0)
     return NS_ERROR_INVALID_ARG;
 
   // Loading the sheet sync.
   RefPtr<css::Loader> loader = new css::Loader(GetDocGroup());
 
@@ -5467,18 +5467,18 @@ nsIDocument::UnblockDOMContentLoaded()
   } else {
     DispatchContentLoadedEvents();
   }
 }
 
 void
 nsIDocument::ContentStateChanged(nsIContent* aContent, EventStates aStateMask)
 {
-  NS_PRECONDITION(!nsContentUtils::IsSafeToRunScript(),
-                  "Someone forgot a scriptblocker");
+  MOZ_ASSERT(!nsContentUtils::IsSafeToRunScript(),
+             "Someone forgot a scriptblocker");
   NS_DOCUMENT_NOTIFY_OBSERVERS(ContentStateChanged,
                                (this, aContent, aStateMask));
 }
 
 void
 nsIDocument::DocumentStatesChanged(EventStates aStateMask)
 {
   UpdateDocumentStates(aStateMask);
@@ -6735,18 +6735,18 @@ nsIDocument::TryCancelFrameLoaderInitial
   }
 }
 
 nsIDocument*
 nsIDocument::RequestExternalResource(nsIURI* aURI,
                                      nsINode* aRequestingNode,
                                      ExternalResourceLoad** aPendingLoad)
 {
-  NS_PRECONDITION(aURI, "Must have a URI");
-  NS_PRECONDITION(aRequestingNode, "Must have a node");
+  MOZ_ASSERT(aURI, "Must have a URI");
+  MOZ_ASSERT(aRequestingNode, "Must have a node");
   if (mDisplayDocument) {
     return mDisplayDocument->RequestExternalResource(aURI,
                                                      aRequestingNode,
                                                      aPendingLoad);
   }
 
   return mExternalResourceMap.RequestResource(aURI, aRequestingNode,
                                               this, aPendingLoad);
@@ -6910,17 +6910,17 @@ nsIDocument::Anchors()
   return mAnchors;
 }
 
 /* static */
 bool
 nsIDocument::MatchNameAttribute(Element* aElement, int32_t aNamespaceID,
                                 nsAtom* aAtom, void* aData)
 {
-  NS_PRECONDITION(aElement, "Must have element to work with!");
+  MOZ_ASSERT(aElement, "Must have element to work with!");
 
   if (!aElement->HasName()) {
     return false;
   }
 
   nsString* elementName = static_cast<nsString*>(aData);
   return
     aElement->GetNameSpaceID() == kNameSpaceID_XHTML &&
@@ -8381,21 +8381,21 @@ nsIDocument::PostUnblockOnloadEvent()
   } else {
     NS_WARNING("failed to dispatch nsUnblockOnloadEvent");
   }
 }
 
 void
 nsIDocument::DoUnblockOnload()
 {
-  NS_PRECONDITION(!mDisplayDocument,
+  MOZ_ASSERT(!mDisplayDocument,
                   "Shouldn't get here for resource document");
-  NS_PRECONDITION(mOnloadBlockCount != 0,
-                  "Shouldn't have a count of zero here, since we stabilized in "
-                  "PostUnblockOnloadEvent");
+  MOZ_ASSERT(mOnloadBlockCount != 0,
+             "Shouldn't have a count of zero here, since we stabilized in "
+             "PostUnblockOnloadEvent");
 
   --mOnloadBlockCount;
 
   if (mOnloadBlockCount != 0) {
     // We blocked again after the last unblock.  Nothing to do here.  We'll
     // post a new event when we unblock again.
     return;
   }
--- a/dom/base/nsDocumentEncoder.cpp
+++ b/dom/base/nsDocumentEncoder.cpp
@@ -94,17 +94,17 @@ protected:
   {
     return -1;
   }
 
   nsresult FlushText(nsAString& aString, bool aForce);
 
   bool IsVisibleNode(nsINode* aNode)
   {
-    NS_PRECONDITION(aNode, "");
+    MOZ_ASSERT(aNode, "null node");
 
     if (mFlags & SkipInvisibleContent) {
       // Treat the visibility of the ShadowRoot as if it were
       // the host content.
       //
       // FIXME(emilio): I suspect instead of this a bunch of the GetParent()
       // calls here should be doing GetFlattenedTreeParent, then this condition
       // should be unreachable...
@@ -1749,17 +1749,17 @@ nsCOMPtr<nsINode>
 nsHTMLCopyEncoder::GetChildAt(nsINode *aParent, int32_t aOffset)
 {
   nsCOMPtr<nsINode> resultNode;
 
   if (!aParent)
     return resultNode;
 
   nsCOMPtr<nsIContent> content = do_QueryInterface(aParent);
-  NS_PRECONDITION(content, "null content in nsHTMLCopyEncoder::GetChildAt");
+  MOZ_ASSERT(content, "null content in nsHTMLCopyEncoder::GetChildAt");
 
   resultNode = content->GetChildAt_Deprecated(aOffset);
 
   return resultNode;
 }
 
 bool
 nsHTMLCopyEncoder::IsMozBR(nsIDOMNode* aNode)
--- a/dom/base/nsFocusManager.cpp
+++ b/dom/base/nsFocusManager.cpp
@@ -1558,18 +1558,18 @@ nsFocusManager::IsWindowVisible(nsPIDOMW
   bool visible = false;
   baseWin->GetVisibility(&visible);
   return visible;
 }
 
 bool
 nsFocusManager::IsNonFocusableRoot(nsIContent* aContent)
 {
-  NS_PRECONDITION(aContent, "aContent must not be NULL");
-  NS_PRECONDITION(aContent->IsInComposedDoc(), "aContent must be in a document");
+  MOZ_ASSERT(aContent, "aContent must not be NULL");
+  MOZ_ASSERT(aContent->IsInComposedDoc(), "aContent must be in a document");
 
   // If aContent is in designMode, the root element is not focusable.
   // NOTE: in designMode, most elements are not focusable, just the document is
   //       focusable.
   // Also, if aContent is not editable but it isn't in designMode, it's not
   // focusable.
   // And in userfocusignored context nothing is focusable.
   nsIDocument* doc = aContent->GetComposedDoc();
--- a/dom/base/nsFrameLoader.cpp
+++ b/dom/base/nsFrameLoader.cpp
@@ -625,17 +625,17 @@ nsFrameLoader::GetDocShell(ErrorResult& 
   return mDocShell;
 }
 
 static void
 SetTreeOwnerAndChromeEventHandlerOnDocshellTree(nsIDocShellTreeItem* aItem,
                                                 nsIDocShellTreeOwner* aOwner,
                                                 EventTarget* aHandler)
 {
-  NS_PRECONDITION(aItem, "Must have item");
+  MOZ_ASSERT(aItem, "Must have item");
 
   aItem->SetTreeOwner(aOwner);
 
   int32_t childCount = 0;
   aItem->GetChildCount(&childCount);
   for (int32_t i = 0; i < childCount; ++i) {
     nsCOMPtr<nsIDocShellTreeItem> item;
     aItem->GetChildAt(i, getter_AddRefs(item));
@@ -657,18 +657,18 @@ SetTreeOwnerAndChromeEventHandlerOnDocsh
  * @return whether aItem is top-level content
  */
 bool
 nsFrameLoader::AddTreeItemToTreeOwner(nsIDocShellTreeItem* aItem,
                                       nsIDocShellTreeOwner* aOwner,
                                       int32_t aParentType,
                                       nsIDocShell* aParentNode)
 {
-  NS_PRECONDITION(aItem, "Must have docshell treeitem");
-  NS_PRECONDITION(mOwnerContent, "Must have owning content");
+  MOZ_ASSERT(aItem, "Must have docshell treeitem");
+  MOZ_ASSERT(mOwnerContent, "Must have owning content");
 
   nsAutoString value;
   bool isContent = mOwnerContent->AttrValueIs(
     kNameSpaceID_None, TypeAttrName(), nsGkAtoms::content, eIgnoreCase);
 
   // Force mozbrowser frames to always be typeContent, even if the
   // mozbrowser interfaces are disabled.
   nsCOMPtr<nsIDOMMozBrowserFrame> mozbrowser =
--- a/dom/base/nsGenConImageContent.cpp
+++ b/dom/base/nsGenConImageContent.cpp
@@ -86,17 +86,17 @@ NS_IMPL_ISUPPORTS_INHERITED(nsGenConImag
 NS_IMPL_ELEMENT_CLONE(nsGenConImageContent)
 
 namespace mozilla {
 namespace dom {
 
 already_AddRefed<nsIContent>
 CreateGenConImageContent(nsIDocument* aDocument, imgRequestProxy* aImageRequest)
 {
-  NS_PRECONDITION(aImageRequest, "Must have request!");
+  MOZ_ASSERT(aImageRequest, "Must have request!");
   RefPtr<NodeInfo> nodeInfo =
     aDocument->NodeInfoManager()->
       GetNodeInfo(nsGkAtoms::mozgeneratedcontentimage,
                   nullptr,
                   kNameSpaceID_XHTML,
                   nsINode::ELEMENT_NODE);
   // Work around not being able to bind a non-const lvalue reference
   // to an rvalue of non-reference type by just creating an rvalue
--- a/dom/base/nsGlobalWindowInner.cpp
+++ b/dom/base/nsGlobalWindowInner.cpp
@@ -1662,18 +1662,18 @@ nsGlobalWindowInner::GetPopupControlStat
   return nsContentUtils::GetPopupControlState();
 }
 
 nsresult
 nsGlobalWindowInner::SetNewDocument(nsIDocument* aDocument,
                                     nsISupports* aState,
                                     bool aForceReuseInnerWindow)
 {
-  NS_PRECONDITION(mDocumentPrincipal == nullptr,
-                  "mDocumentPrincipal prematurely set!");
+  MOZ_ASSERT(mDocumentPrincipal == nullptr,
+             "mDocumentPrincipal prematurely set!");
   MOZ_ASSERT(aDocument);
 
   if (!mOuterWindow) {
     return NS_ERROR_NOT_INITIALIZED;
   }
 
   // Refuse to set a new document if the call came from an inner
   // window that's not the current inner window.
@@ -4775,17 +4775,17 @@ public:
   {
     MOZ_ASSERT(mWindow);
     mOldURL.Assign(aOldURL);
     mNewURL.Assign(aNewURL);
   }
 
   NS_IMETHOD Run() override
   {
-    NS_PRECONDITION(NS_IsMainThread(), "Should be called on the main thread.");
+    MOZ_ASSERT(NS_IsMainThread(), "Should be called on the main thread.");
     return mWindow->FireHashchange(mOldURL, mNewURL);
   }
 
 private:
   nsString mOldURL;
   nsString mNewURL;
   RefPtr<nsGlobalWindowInner> mWindow;
 };
--- a/dom/base/nsGlobalWindowOuter.cpp
+++ b/dom/base/nsGlobalWindowOuter.cpp
@@ -1410,17 +1410,17 @@ protected:
 };
 
 NS_DEFINE_STATIC_IID_ACCESSOR(WindowStateHolder, WINDOWSTATEHOLDER_IID)
 
 WindowStateHolder::WindowStateHolder(nsGlobalWindowInner* aWindow)
   : mInnerWindow(aWindow),
     mInnerWindowReflector(RootingCx(), aWindow->GetWrapper())
 {
-  NS_PRECONDITION(aWindow, "null window");
+  MOZ_ASSERT(aWindow, "null window");
 
   aWindow->Suspend();
 
   // When a global goes into the bfcache, we disable script.
   xpc::Scriptability::Get(mInnerWindowReflector).SetDocShellAllowsScript(false);
 }
 
 WindowStateHolder::~WindowStateHolder()
@@ -1635,17 +1635,17 @@ CreateNativeGlobalForInner(JSContext* aC
   return NS_OK;
 }
 
 nsresult
 nsGlobalWindowOuter::SetNewDocument(nsIDocument* aDocument,
                                     nsISupports* aState,
                                     bool aForceReuseInnerWindow)
 {
-  NS_PRECONDITION(mDocumentPrincipal == nullptr,
+  MOZ_ASSERT(mDocumentPrincipal == nullptr,
                   "mDocumentPrincipal prematurely set!");
   MOZ_ASSERT(aDocument);
 
   // Bail out early if we're in process of closing down the window.
   NS_ENSURE_STATE(!mCleanedUp);
 
   NS_ASSERTION(!GetCurrentInnerWindow() ||
                GetCurrentInnerWindow()->GetExtantDoc() == mDoc,
@@ -3845,17 +3845,17 @@ GetCallerDocShellTreeItem()
   return callerItem.forget();
 }
 
 bool
 nsGlobalWindowOuter::WindowExists(const nsAString& aName,
                                   bool aForceNoOpener,
                                   bool aLookForCallerOnJSStack)
 {
-  NS_PRECONDITION(mDocShell, "Must have docshell");
+  MOZ_ASSERT(mDocShell, "Must have docshell");
 
   if (aForceNoOpener) {
     return aName.LowerCaseEqualsLiteral("_self") ||
            aName.LowerCaseEqualsLiteral("_top") ||
            aName.LowerCaseEqualsLiteral("_parent");
   }
 
   nsCOMPtr<nsIDocShellTreeItem> caller;
@@ -6896,20 +6896,21 @@ nsGlobalWindowOuter::OpenInternal(const 
                                   bool aForceNoOpener,
                                   nsPIDOMWindowOuter **aReturn)
 {
 #ifdef DEBUG
   uint32_t argc = 0;
   if (argv)
       argv->GetLength(&argc);
 #endif
-  NS_PRECONDITION(!aExtraArgument || (!argv && argc == 0),
-                  "Can't pass in arguments both ways");
-  NS_PRECONDITION(!aCalledNoScript || (!argv && argc == 0),
-                  "Can't pass JS args when called via the noscript methods");
+
+  MOZ_ASSERT(!aExtraArgument || (!argv && argc == 0),
+             "Can't pass in arguments both ways");
+  MOZ_ASSERT(!aCalledNoScript || (!argv && argc == 0),
+             "Can't pass JS args when called via the noscript methods");
 
   mozilla::Maybe<AutoUnblockScriptClosing> closeUnblocker;
 
   // Calls to window.open from script should navigate.
   MOZ_ASSERT(aCalledNoScript || aNavigate);
 
   *aReturn = nullptr;
 
@@ -7726,9 +7727,8 @@ nsAutoPopupStatePusherInternal::nsAutoPo
   : mOldState(nsContentUtils::PushPopupControlState(aState, aForce))
 {
 }
 
 nsAutoPopupStatePusherInternal::~nsAutoPopupStatePusherInternal()
 {
   nsContentUtils::PopPopupControlState(mOldState);
 }
-
--- a/dom/base/nsIContentInlines.h
+++ b/dom/base/nsIContentInlines.h
@@ -28,18 +28,20 @@ nsIContent::IsInChromeDocument() const
 {
   return nsContentUtils::IsChromeDoc(OwnerDoc());
 }
 
 inline void
 nsIContent::SetPrimaryFrame(nsIFrame* aFrame)
 {
   MOZ_ASSERT(IsInUncomposedDoc() || IsInShadowTree(), "This will end badly!");
-  NS_PRECONDITION(!aFrame || !mPrimaryFrame || aFrame == mPrimaryFrame,
-                  "Losing track of existing primary frame");
+
+  // FIXME bug 749326
+  NS_ASSERTION(!aFrame || !mPrimaryFrame || aFrame == mPrimaryFrame,
+               "Losing track of existing primary frame");
 
   if (aFrame) {
     if (MOZ_LIKELY(!IsHTMLElement(nsGkAtoms::area)) ||
         aFrame->GetContent() == this) {
       aFrame->SetIsPrimaryFrame(true);
     }
   } else if (nsIFrame* currentPrimaryFrame = GetPrimaryFrame()) {
     if (MOZ_LIKELY(!IsHTMLElement(nsGkAtoms::area)) ||
--- a/dom/base/nsIStyleSheetLinkingElement.h
+++ b/dom/base/nsIStyleSheetLinkingElement.h
@@ -6,41 +6,55 @@
 #ifndef nsIStyleSheetLinkingElement_h__
 #define nsIStyleSheetLinkingElement_h__
 
 
 #include "nsISupports.h"
 #include "mozilla/StyleSheet.h"
 #include "mozilla/Result.h"
 
+class nsIContent;
 class nsICSSLoaderObserver;
+class nsIPrincipal;
 class nsIURI;
 
 #define NS_ISTYLESHEETLINKINGELEMENT_IID          \
 { 0xa8b79f3b, 0x9d18, 0x4f9c, \
   { 0xb1, 0xaa, 0x8c, 0x9b, 0x1b, 0xaa, 0xac, 0xad } }
 
 class nsIStyleSheetLinkingElement : public nsISupports {
 public:
   enum class ForceUpdate
   {
     Yes,
     No,
   };
 
+  enum class Completed
+  {
+    Yes,
+    No,
+  };
+
+  enum class HasAlternateRel
+  {
+    Yes,
+    No
+  };
+
   enum class IsAlternate
   {
     Yes,
     No,
   };
 
-  enum class Completed
+  enum class IsInline
   {
     Yes,
-    No,
+    No
   };
 
   enum class MediaMatched
   {
     Yes,
     No,
   };
 
@@ -74,16 +88,49 @@ public:
       if (!mWillNotify) {
         return false;
       }
 
       return !mIsAlternate && mMediaMatched;
     }
   };
 
+  struct MOZ_STACK_CLASS SheetInfo
+  {
+    nsIContent* mContent;
+    // FIXME(emilio): do these really need to be strong refs?
+    nsCOMPtr<nsIURI> mURI;
+
+    // The principal of the scripted caller that initiated the load, if
+    // available. Otherwise null.
+    nsCOMPtr<nsIPrincipal> mTriggeringPrincipal;
+    mozilla::net::ReferrerPolicy mReferrerPolicy;
+    mozilla::CORSMode mCORSMode;
+    nsString mTitle;
+    nsString mMedia;
+    nsString mIntegrity;
+
+    bool mHasAlternateRel;
+    bool mIsInline;
+
+    SheetInfo(const nsIDocument&,
+              nsIContent*,
+              already_AddRefed<nsIURI> aURI,
+              already_AddRefed<nsIPrincipal> aTriggeringPrincipal,
+              mozilla::net::ReferrerPolicy aReferrerPolicy,
+              mozilla::CORSMode aCORSMode,
+              const nsAString& aTitle,
+              const nsAString& aMedia,
+              HasAlternateRel aHasAlternateRel,
+              IsInline aIsInline);
+
+    ~SheetInfo();
+  };
+
+
   NS_DECLARE_STATIC_IID_ACCESSOR(NS_ISTYLESHEETLINKINGELEMENT_IID)
 
   /**
    * Used to make the association between a style sheet and
    * the element that linked it to the document.
    *
    * @param aStyleSheet the style sheet associated with this
    *                    element.
--- a/dom/base/nsImageLoadingContent.cpp
+++ b/dom/base/nsImageLoadingContent.cpp
@@ -143,18 +143,18 @@ nsImageLoadingContent::Notify(imgIReques
     OnUnlockedDraw();
     return NS_OK;
   }
 
   if (aType == imgINotificationObserver::LOAD_COMPLETE) {
     // We should definitely have a request here
     MOZ_ASSERT(aRequest, "no request?");
 
-    NS_PRECONDITION(aRequest == mCurrentRequest || aRequest == mPendingRequest,
-                    "Unknown request");
+    MOZ_ASSERT(aRequest == mCurrentRequest || aRequest == mPendingRequest,
+               "Unknown request");
   }
 
   {
     // Calling Notify on observers can modify the list of observers so make
     // a local copy.
     AutoTArray<nsCOMPtr<imgINotificationObserver>, 2> observers;
     for (ImageObserver* observer = &mObserverList, *next; observer;
          observer = next) {
@@ -337,17 +337,17 @@ nsImageLoadingContent::SetLoadingEnabled
   if (nsContentUtils::GetImgLoaderForChannel(nullptr, nullptr)) {
     mLoadingEnabled = aLoadingEnabled;
   }
 }
 
 NS_IMETHODIMP
 nsImageLoadingContent::GetImageBlockingStatus(int16_t* aStatus)
 {
-  NS_PRECONDITION(aStatus, "Null out param");
+  MOZ_ASSERT(aStatus, "Null out param");
   *aStatus = ImageBlockingStatus();
   return NS_OK;
 }
 
 static void
 ReplayImageStatus(imgIRequest* aRequest, imgINotificationObserver* aObserver)
 {
   if (!aRequest) {
@@ -714,17 +714,17 @@ nsImageLoadingContent::GetRequestType(im
   aError.Throw(NS_ERROR_UNEXPECTED);
   return UNKNOWN_REQUEST;
 }
 
 NS_IMETHODIMP
 nsImageLoadingContent::GetRequestType(imgIRequest* aRequest,
                                       int32_t* aRequestType)
 {
-  NS_PRECONDITION(aRequestType, "Null out param");
+  MOZ_ASSERT(aRequestType, "Null out param");
 
   ErrorResult result;
   *aRequestType = GetRequestType(aRequest, result);
   return result.StealNSResult();
 }
 
 already_AddRefed<nsIURI>
 nsImageLoadingContent::GetCurrentURI(ErrorResult& aError)
@@ -1234,18 +1234,18 @@ nsPresContext* nsImageLoadingContent::Ge
   return frame->PresContext();
 }
 
 nsresult
 nsImageLoadingContent::StringToURI(const nsAString& aSpec,
                                    nsIDocument* aDocument,
                                    nsIURI** aURI)
 {
-  NS_PRECONDITION(aDocument, "Must have a document");
-  NS_PRECONDITION(aURI, "Null out param");
+  MOZ_ASSERT(aDocument, "Must have a document");
+  MOZ_ASSERT(aURI, "Null out param");
 
   // (1) Get the base URI
   nsIContent* thisContent = AsContent();
   nsCOMPtr<nsIURI> baseURL = thisContent->GetBaseURI();
 
   // (2) Get the charset
   auto encoding = aDocument->GetDocumentCharacterSet();
 
@@ -1743,9 +1743,9 @@ nsImageLoadingContent::ScriptedImageObse
 }
 
 // Only HTMLInputElement.h overrides this for <img> tags
 // all other subclasses use this one, i.e. ignore referrer attributes
 mozilla::net::ReferrerPolicy
 nsImageLoadingContent::GetImageReferrerPolicy()
 {
   return mozilla::net::RP_Unset;
-};
+}
--- a/dom/base/nsJSEnvironment.cpp
+++ b/dom/base/nsJSEnvironment.cpp
@@ -809,17 +809,17 @@ nsJSContext::ConvertSupportsTojsvals(nsI
   }
   return rv;
 }
 
 // This really should go into xpconnect somewhere...
 nsresult
 nsJSContext::AddSupportsPrimitiveTojsvals(nsISupports *aArg, JS::Value *aArgv)
 {
-  NS_PRECONDITION(aArg, "Empty arg");
+  MOZ_ASSERT(aArg, "Empty arg");
 
   nsCOMPtr<nsISupportsPrimitive> argPrimitive(do_QueryInterface(aArg));
   if (!argPrimitive)
     return NS_ERROR_NO_INTERFACE;
 
   AutoJSContext cx;
   uint16_t type;
   argPrimitive->GetType(&type);
--- a/dom/base/nsMappedAttributes.cpp
+++ b/dom/base/nsMappedAttributes.cpp
@@ -147,17 +147,17 @@ nsMappedAttributes::LastRelease()
   delete this;
 }
 
 
 void
 nsMappedAttributes::SetAndSwapAttr(nsAtom* aAttrName, nsAttrValue& aValue,
                                    bool* aValueWasSet)
 {
-  NS_PRECONDITION(aAttrName, "null name");
+  MOZ_ASSERT(aAttrName, "null name");
   *aValueWasSet = false;
   uint32_t i;
   for (i = 0; i < mAttrCount && !Attrs()[i].mName.IsSmaller(aAttrName); ++i) {
     if (Attrs()[i].mName.Equals(aAttrName)) {
       Attrs()[i].mValue.SwapValueWith(aValue);
       *aValueWasSet = true;
       return;
     }
@@ -173,17 +173,17 @@ nsMappedAttributes::SetAndSwapAttr(nsAto
   new (&Attrs()[i].mValue) nsAttrValue();
   Attrs()[i].mValue.SwapValueWith(aValue);
   ++mAttrCount;
 }
 
 const nsAttrValue*
 nsMappedAttributes::GetAttr(nsAtom* aAttrName) const
 {
-  NS_PRECONDITION(aAttrName, "null name");
+  MOZ_ASSERT(aAttrName, "null name");
 
   for (uint32_t i = 0; i < mAttrCount; ++i) {
     if (Attrs()[i].mName.Equals(aAttrName)) {
       return &Attrs()[i].mValue;
     }
   }
 
   return nullptr;
--- a/dom/base/nsNameSpaceManager.cpp
+++ b/dom/base/nsNameSpaceManager.cpp
@@ -121,17 +121,17 @@ nsNameSpaceManager::RegisterNameSpace(al
   MOZ_ASSERT(aNameSpaceID >= -1, "Bogus namespace ID");
 
   return rv;
 }
 
 nsresult
 nsNameSpaceManager::GetNameSpaceURI(int32_t aNameSpaceID, nsAString& aURI)
 {
-  NS_PRECONDITION(aNameSpaceID >= 0, "Bogus namespace ID");
+  MOZ_ASSERT(aNameSpaceID >= 0, "Bogus namespace ID");
 
   // We have historically treated GetNameSpaceURI calls for kNameSpaceID_None
   // as erroneous.
   if (aNameSpaceID <= 0 || aNameSpaceID >= int32_t(mURIArray.Length())) {
     aURI.Truncate();
 
     return NS_ERROR_ILLEGAL_VALUE;
   }
--- a/dom/base/nsNodeInfoManager.cpp
+++ b/dom/base/nsNodeInfoManager.cpp
@@ -102,17 +102,17 @@ NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_THIS_B
   if (tmp->mDocument) {
     return NS_CYCLE_COLLECTION_PARTICIPANT(nsDocument)->CanSkipThis(tmp->mDocument);
   }
 NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_THIS_END
 
 nsresult
 nsNodeInfoManager::Init(nsIDocument *aDocument)
 {
-  NS_PRECONDITION(!mPrincipal,
+  MOZ_ASSERT(!mPrincipal,
                   "Being inited when we already have a principal?");
 
   mPrincipal = NullPrincipal::CreateWithoutOriginAttributes();
 
   if (aDocument) {
     mBindingManager = new nsBindingManager(aDocument);
   }
 
@@ -314,17 +314,17 @@ nsNodeInfoManager::SetDocumentPrincipal(
                         "Documents shouldn't have an expanded principal");
 
   mPrincipal = aPrincipal;
 }
 
 void
 nsNodeInfoManager::RemoveNodeInfo(NodeInfo *aNodeInfo)
 {
-  NS_PRECONDITION(aNodeInfo, "Trying to remove null nodeinfo from manager!");
+  MOZ_ASSERT(aNodeInfo, "Trying to remove null nodeinfo from manager!");
 
   if (aNodeInfo == mDocumentNodeInfo) {
     mDocumentNodeInfo = nullptr;
     mDocument = nullptr;
   } else {
     if (--mNonDocumentNodeInfos == 0) {
       if (mDocument) {
         // Note, whoever calls this method should keep NodeInfoManager alive,
--- a/dom/base/nsNodeUtils.cpp
+++ b/dom/base/nsNodeUtils.cpp
@@ -205,30 +205,30 @@ nsNodeUtils::NativeAnonymousChildListCha
                             (aContent, aIsRemove),
                             isRemove);
 }
 
 void
 nsNodeUtils::ContentInserted(nsINode* aContainer,
                              nsIContent* aChild)
 {
-  NS_PRECONDITION(aContainer->IsContent() || aContainer->IsDocument(),
-                  "container must be an nsIContent or an nsIDocument");
+  MOZ_ASSERT(aContainer->IsContent() || aContainer->IsDocument(),
+             "container must be an nsIContent or an nsIDocument");
   nsIDocument* doc = aContainer->OwnerDoc();
   IMPL_MUTATION_NOTIFICATION(ContentInserted, aContainer, (aChild),
                              IsRemoveNotification::No);
 }
 
 void
 nsNodeUtils::ContentRemoved(nsINode* aContainer,
                             nsIContent* aChild,
                             nsIContent* aPreviousSibling)
 {
-  NS_PRECONDITION(aContainer->IsContent() || aContainer->IsDocument(),
-                  "container must be an nsIContent or an nsIDocument");
+  MOZ_ASSERT(aContainer->IsContent() || aContainer->IsDocument(),
+             "container must be an nsIContent or an nsIDocument");
   nsIDocument* doc = aContainer->OwnerDoc();
   MOZ_ASSERT(aChild->GetParentNode() == aContainer,
              "We expect the parent link to be still around at this point");
   IMPL_MUTATION_NOTIFICATION(ContentRemoved, aContainer,
                              (aChild, aPreviousSibling),
                              IsRemoveNotification::Yes);
 }
 
@@ -378,21 +378,20 @@ nsNodeUtils::CloneNodeImpl(nsINode *aNod
 /* static */
 already_AddRefed<nsINode>
 nsNodeUtils::CloneAndAdopt(nsINode *aNode, bool aClone, bool aDeep,
                            nsNodeInfoManager *aNewNodeInfoManager,
                            JS::Handle<JSObject*> aReparentScope,
                            nsCOMArray<nsINode> *aNodesWithProperties,
                            nsINode* aParent, ErrorResult& aError)
 {
-  NS_PRECONDITION((!aClone && aNewNodeInfoManager) || !aReparentScope,
-                  "If cloning or not getting a new nodeinfo we shouldn't "
-                  "rewrap");
-  NS_PRECONDITION(!aParent || aNode->IsContent(),
-                  "Can't insert document or attribute nodes into a parent");
+  MOZ_ASSERT((!aClone && aNewNodeInfoManager) || !aReparentScope,
+              "If cloning or not getting a new nodeinfo we shouldn't rewrap");
+  MOZ_ASSERT(!aParent || aNode->IsContent(),
+             "Can't insert document or attribute nodes into a parent");
 
   // First deal with aNode and walk its attributes (and their children). Then,
   // if aDeep is true, deal with aNode's children (and recurse into their
   // attributes and children).
 
   nsAutoScriptBlocker scriptBlocker;
 
   nsNodeInfoManager *nodeInfoManager = aNewNodeInfoManager;
@@ -708,9 +707,8 @@ nsNodeUtils::GetFirstChildOfTemplateOrNo
   if (nsNodeUtils::IsTemplateElement(aNode)) {
     DocumentFragment* frag =
       static_cast<HTMLTemplateElement*>(aNode)->Content();
     return frag->GetFirstChild();
   }
 
   return aNode->GetFirstChild();
 }
-
--- a/dom/base/nsPropertyTable.cpp
+++ b/dom/base/nsPropertyTable.cpp
@@ -135,17 +135,17 @@ nsPropertyTable::EnumerateAll(NSProperty
 }
 
 void*
 nsPropertyTable::GetPropertyInternal(nsPropertyOwner aObject,
                                      nsAtom* aPropertyName,
                                      bool aRemove,
                                      nsresult* aResult)
 {
-  NS_PRECONDITION(aPropertyName && aObject, "unexpected null param");
+  MOZ_ASSERT(aPropertyName && aObject, "unexpected null param");
   nsresult rv = NS_PROPTABLE_PROP_NOT_THERE;
   void *propValue = nullptr;
 
   PropertyList* propertyList = GetPropertyListFor(aPropertyName);
   if (propertyList) {
     auto entry = static_cast<PropertyListMapEntry*>
                             (propertyList->mObjectValueMap.Search(aObject));
     if (entry) {
@@ -167,17 +167,17 @@ nsPropertyTable::GetPropertyInternal(nsP
 nsresult
 nsPropertyTable::SetPropertyInternal(nsPropertyOwner aObject,
                                      nsAtom* aPropertyName,
                                      void* aPropertyValue,
                                      NSPropertyDtorFunc aPropDtorFunc,
                                      void* aPropDtorData,
                                      bool aTransfer)
 {
-  NS_PRECONDITION(aPropertyName && aObject, "unexpected null param");
+  MOZ_ASSERT(aPropertyName && aObject, "unexpected null param");
 
   PropertyList* propertyList = GetPropertyListFor(aPropertyName);
 
   if (propertyList) {
     // Make sure the dtor function and data and the transfer flag match
     if (aPropDtorFunc != propertyList->mDtorFunc ||
         aPropDtorData != propertyList->mDtorData ||
         aTransfer != propertyList->mTransfer) {
@@ -213,17 +213,17 @@ nsPropertyTable::SetPropertyInternal(nsP
 
   return result;
 }
 
 nsresult
 nsPropertyTable::DeleteProperty(nsPropertyOwner aObject,
                                 nsAtom* aPropertyName)
 {
-  NS_PRECONDITION(aPropertyName && aObject, "unexpected null param");
+  MOZ_ASSERT(aPropertyName && aObject, "unexpected null param");
 
   PropertyList* propertyList = GetPropertyListFor(aPropertyName);
   if (propertyList) {
     if (propertyList->DeletePropertyFor(aObject))
       return NS_OK;
   }
 
   return NS_PROPTABLE_PROP_NOT_THERE;
--- a/dom/base/nsRange.cpp
+++ b/dom/base/nsRange.cpp
@@ -55,17 +55,17 @@ nsRange::GetDocGroup() const
 }
 
 /******************************************************
  * stack based utilty class for managing monitor
  ******************************************************/
 
 static void InvalidateAllFrames(nsINode* aNode)
 {
-  NS_PRECONDITION(aNode, "bad arg");
+  MOZ_ASSERT(aNode, "bad arg");
 
   nsIFrame* frame = nullptr;
   switch (aNode->NodeType()) {
     case nsINode::TEXT_NODE:
     case nsINode::ELEMENT_NODE:
     {
       nsIContent* content = static_cast<nsIContent*>(aNode);
       frame = content->GetPrimaryFrame();
@@ -194,17 +194,17 @@ struct IsItemInRangeComparator
     return -1;
   }
 };
 
 /* static */ bool
 nsRange::IsNodeSelected(nsINode* aNode, uint32_t aStartOffset,
                         uint32_t aEndOffset)
 {
-  NS_PRECONDITION(aNode, "bad arg");
+  MOZ_ASSERT(aNode, "bad arg");
 
   nsINode* n = GetNextRangeCommonAncestor(aNode);
   NS_ASSERTION(n || !aNode->IsSelectionDescendant(),
                "orphan selection descendant");
 
   // Collect the selection objects for potential ranges.
   nsTHashtable<nsPtrHashKey<Selection>> ancestorSelections;
   Selection* prevSelection = nullptr;
@@ -456,17 +456,17 @@ static void UnmarkDescendants(nsINode* a
       }
     }
   }
 }
 
 void
 nsRange::RegisterCommonAncestor(nsINode* aNode)
 {
-  NS_PRECONDITION(aNode, "bad arg");
+  MOZ_ASSERT(aNode, "bad arg");
 
   MOZ_DIAGNOSTIC_ASSERT(IsInSelection(), "registering range not in selection");
 
   mRegisteredCommonAncestor = aNode;
 
   MarkDescendants(aNode);
 
   UniquePtr<LinkedList<nsRange>>& ranges = aNode->GetCommonAncestorRangesPtr();
@@ -477,17 +477,17 @@ nsRange::RegisterCommonAncestor(nsINode*
   MOZ_DIAGNOSTIC_ASSERT(!isInList());
   ranges->insertBack(this);
   aNode->SetCommonAncestorForRangeInSelection();
 }
 
 void
 nsRange::UnregisterCommonAncestor(nsINode* aNode, bool aIsUnlinking)
 {
-  NS_PRECONDITION(aNode, "bad arg");
+  MOZ_ASSERT(aNode, "bad arg");
   NS_ASSERTION(aNode->IsCommonAncestorForRangeInSelection(), "wrong node");
   MOZ_DIAGNOSTIC_ASSERT(aNode == mRegisteredCommonAncestor, "wrong node");
   LinkedList<nsRange>* ranges = aNode->GetExistingCommonAncestorRanges();
   MOZ_ASSERT(ranges);
 
   mRegisteredCommonAncestor = nullptr;
 
 #ifdef DEBUG
@@ -959,39 +959,42 @@ nsRange::NotifySelectionListenersAfterRa
 // for content notification of range ownership.
 // Calling DoSetRange with either parent argument null will collapse
 // the range to have both endpoints point to the other node
 void
 nsRange::DoSetRange(const RawRangeBoundary& aStart,
                     const RawRangeBoundary& aEnd,
                     nsINode* aRoot, bool aNotInsertedYet)
 {
-  NS_PRECONDITION((aStart.IsSet() && aEnd.IsSet() && aRoot) ||
-                  (!aStart.IsSet() && !aEnd.IsSet() && !aRoot),
-                  "Set all or none");
-  NS_PRECONDITION(!aRoot || aNotInsertedYet ||
-                  (nsContentUtils::ContentIsDescendantOf(aStart.Container(), aRoot) &&
-                   nsContentUtils::ContentIsDescendantOf(aEnd.Container(), aRoot) &&
-                   aRoot == IsValidBoundary(aStart.Container()) &&
-                   aRoot == IsValidBoundary(aEnd.Container())),
-                  "Wrong root");
-  NS_PRECONDITION(!aRoot ||
-                  (aStart.Container()->IsContent() &&
-                   aEnd.Container()->IsContent() &&
-                   aRoot ==
-                    static_cast<nsIContent*>(aStart.Container())->GetBindingParent() &&
-                   aRoot ==
-                    static_cast<nsIContent*>(aEnd.Container())->GetBindingParent()) ||
-                  (!aRoot->GetParentNode() &&
-                   (aRoot->IsDocument() ||
-                    aRoot->IsAttr() ||
-                    aRoot->IsDocumentFragment() ||
-                     /*For backward compatibility*/
-                    aRoot->IsContent())),
-                  "Bad root");
+  MOZ_ASSERT((aStart.IsSet() && aEnd.IsSet() && aRoot) ||
+             (!aStart.IsSet() && !aEnd.IsSet() && !aRoot),
+             "Set all or none");
+
+  MOZ_ASSERT(!aRoot || aNotInsertedYet ||
+             (nsContentUtils::ContentIsDescendantOf(aStart.Container(), aRoot) &&
+              nsContentUtils::ContentIsDescendantOf(aEnd.Container(), aRoot) &&
+              aRoot == IsValidBoundary(aStart.Container()) &&
+              aRoot == IsValidBoundary(aEnd.Container())),
+             "Wrong root");
+
+  MOZ_ASSERT(!aRoot ||
+             (aStart.Container()->IsContent() &&
+              aEnd.Container()->IsContent() &&
+              aRoot ==
+               static_cast<nsIContent*>(aStart.Container())->GetBindingParent() &&
+              aRoot ==
+               static_cast<nsIContent*>(aEnd.Container())->GetBindingParent()) ||
+             (!aRoot->GetParentNode() &&
+              (aRoot->IsDocument() ||
+               aRoot->IsAttr() ||
+               aRoot->IsDocumentFragment() ||
+                /*For backward compatibility*/
+               aRoot->IsContent())),
+             "Bad root");
+
   if (mRoot != aRoot) {
     if (mRoot) {
       mRoot->RemoveMutationObserver(this);
     }
     if (aRoot) {
       aRoot->AddMutationObserver(this);
     }
   }
--- a/dom/base/nsStyleLinkElement.cpp
+++ b/dom/base/nsStyleLinkElement.cpp
@@ -30,16 +30,54 @@
 #include "nsUnicharInputStream.h"
 #include "nsContentUtils.h"
 #include "nsStyleUtil.h"
 #include "nsQueryObject.h"
 
 using namespace mozilla;
 using namespace mozilla::dom;
 
+nsStyleLinkElement::SheetInfo::SheetInfo(
+  const nsIDocument& aDocument,
+  nsIContent* aContent,
+  already_AddRefed<nsIURI> aURI,
+  already_AddRefed<nsIPrincipal> aTriggeringPrincipal,
+  mozilla::net::ReferrerPolicy aReferrerPolicy,
+  mozilla::CORSMode aCORSMode,
+  const nsAString& aTitle,
+  const nsAString& aMedia,
+  HasAlternateRel aHasAlternateRel,
+  IsInline aIsInline
+)
+  : mContent(aContent)
+  , mURI(aURI)
+  , mTriggeringPrincipal(aTriggeringPrincipal)
+  , mReferrerPolicy(aReferrerPolicy)
+  , mCORSMode(aCORSMode)
+  , mTitle(aTitle)
+  , mMedia(aMedia)
+  , mHasAlternateRel(aHasAlternateRel == HasAlternateRel::Yes)
+  , mIsInline(aIsInline == IsInline::Yes)
+{
+  MOZ_ASSERT(!mIsInline || aContent);
+  MOZ_ASSERT_IF(aContent, aContent->OwnerDoc() == &aDocument);
+
+  if (mReferrerPolicy == net::ReferrerPolicy::RP_Unset) {
+    mReferrerPolicy = aDocument.GetReferrerPolicy();
+  }
+
+  if (!mIsInline && aContent && aContent->IsElement()) {
+    aContent->AsElement()->GetAttr(kNameSpaceID_None,
+                                   nsGkAtoms::integrity,
+                                   mIntegrity);
+  }
+}
+
+nsStyleLinkElement::SheetInfo::~SheetInfo() = default;
+
 nsStyleLinkElement::nsStyleLinkElement()
   : mDontLoadStyle(false)
   , mUpdatesEnabled(true)
   , mLineNumber(1)
 {
 }
 
 nsStyleLinkElement::~nsStyleLinkElement()
@@ -256,24 +294,25 @@ nsStyleLinkElement::DoUpdateStyleSheet(n
 
   nsCOMPtr<nsIDocument> doc = thisContent->IsInShadowTree() ?
     thisContent->OwnerDoc() : thisContent->GetUncomposedDoc();
   // Loader could be null during unlink, see bug 1425866.
   if (!doc || !doc->CSSLoader() || !doc->CSSLoader()->GetEnabled()) {
     return Update { };
   }
 
-  bool isInline;
-  nsCOMPtr<nsIPrincipal> triggeringPrincipal;
-  nsCOMPtr<nsIURI> uri = GetStyleSheetURL(&isInline, getter_AddRefs(triggeringPrincipal));
-
-  if (aForceUpdate == ForceUpdate::No && mStyleSheet && !isInline && uri) {
+  Maybe<SheetInfo> info = GetStyleSheetInfo();
+  if (aForceUpdate == ForceUpdate::No &&
+      mStyleSheet &&
+      info &&
+      !info->mIsInline &&
+      info->mURI) {
     if (nsIURI* oldURI = mStyleSheet->GetSheetURI()) {
       bool equal;
-      nsresult rv = oldURI->Equals(uri, &equal);
+      nsresult rv = oldURI->Equals(info->mURI, &equal);
       if (NS_SUCCEEDED(rv) && equal) {
         return Update { };
       }
     }
   }
 
   if (mStyleSheet) {
     if (thisContent->IsInShadowTree()) {
@@ -283,86 +322,63 @@ nsStyleLinkElement::DoUpdateStyleSheet(n
       doc->BeginUpdate(UPDATE_STYLE);
       doc->RemoveStyleSheet(mStyleSheet);
       doc->EndUpdate(UPDATE_STYLE);
     }
 
     nsStyleLinkElement::SetStyleSheet(nullptr);
   }
 
-  if (!uri && !isInline) {
+  if (!info) {
+    return Update { };
+  }
+
+  MOZ_ASSERT(info->mReferrerPolicy != net::RP_Unset ||
+             info->mReferrerPolicy == doc->GetReferrerPolicy());
+  if (!info->mURI && !info->mIsInline) {
     // If href is empty and this is not inline style then just bail
     return Update { };
   }
 
-  nsAutoString title, type, media;
-  bool hasAlternateRel;
-  GetStyleSheetInfo(title, type, media, &hasAlternateRel);
-  if (!type.LowerCaseEqualsLiteral("text/css")) {
-    return Update { };
-  }
-
-  // Load the link's referrerpolicy attribute. If the link does not provide a
-  // referrerpolicy attribute, ignore this and use the document's referrer
-  // policy
-
-  net::ReferrerPolicy referrerPolicy = GetLinkReferrerPolicy();
-  if (referrerPolicy == net::RP_Unset) {
-    referrerPolicy = doc->GetReferrerPolicy();
-  }
-
-  if (isInline) {
+  if (info->mIsInline) {
     nsAutoString text;
     if (!nsContentUtils::GetNodeTextContent(thisContent, false, text, fallible)) {
       return Err(NS_ERROR_OUT_OF_MEMORY);
     }
 
 
     MOZ_ASSERT(thisContent->NodeInfo()->NameAtom() != nsGkAtoms::link,
                "<link> is not 'inline', and needs different CSP checks");
     MOZ_ASSERT(thisContent->IsElement());
     nsresult rv = NS_OK;
     if (!nsStyleUtil::CSPAllowsInlineStyle(thisContent->AsElement(),
                                            thisContent->NodePrincipal(),
-                                           triggeringPrincipal,
+                                           info->mTriggeringPrincipal,
                                            doc->GetDocumentURI(),
                                            mLineNumber, text, &rv)) {
       if (NS_FAILED(rv)) {
         return Err(rv);
       }
       return Update { };
     }
 
     // Parse the style sheet.
-    return doc->CSSLoader()->
-      LoadInlineStyle(thisContent, text, triggeringPrincipal, mLineNumber,
-                      title, media, referrerPolicy,
-                      aObserver);
+    return doc->CSSLoader()->LoadInlineStyle(*info, text, mLineNumber, aObserver);
   }
   nsAutoString integrity;
   if (thisContent->IsElement()) {
     thisContent->AsElement()->GetAttr(kNameSpaceID_None, nsGkAtoms::integrity,
                                       integrity);
   }
   if (!integrity.IsEmpty()) {
     MOZ_LOG(SRILogHelper::GetSriLog(), mozilla::LogLevel::Debug,
             ("nsStyleLinkElement::DoUpdateStyleSheet, integrity=%s",
              NS_ConvertUTF16toUTF8(integrity).get()));
   }
-  auto resultOrError =
-    doc->CSSLoader()->LoadStyleLink(thisContent,
-                                    uri,
-                                    triggeringPrincipal,
-                                    title,
-                                    media,
-                                    hasAlternateRel,
-                                    GetCORSMode(),
-                                    referrerPolicy,
-                                    integrity,
-                                    aObserver);
+  auto resultOrError = doc->CSSLoader()->LoadStyleLink(*info, aObserver);
   if (resultOrError.isErr()) {
     // Don't propagate LoadStyleLink() errors further than this, since some
     // consumers (e.g. nsXMLContentSink) will completely abort on innocuous
     // things like a stylesheet load being blocked by the security system.
     return Update { };
   }
   return resultOrError;
 }
--- a/dom/base/nsStyleLinkElement.h
+++ b/dom/base/nsStyleLinkElement.h
@@ -88,32 +88,17 @@ protected:
    *
    * TODO(emilio): Should probably pass a single DocumentOrShadowRoot.
    */
   mozilla::Result<Update, nsresult> UpdateStyleSheetInternal(
       nsIDocument* aOldDocument,
       mozilla::dom::ShadowRoot* aOldShadowRoot,
       ForceUpdate = ForceUpdate::No);
 
-  virtual already_AddRefed<nsIURI> GetStyleSheetURL(bool* aIsInline, nsIPrincipal** aTriggeringPrincipal) = 0;
-  virtual void GetStyleSheetInfo(nsAString& aTitle,
-                                 nsAString& aType,
-                                 nsAString& aMedia,
-                                 bool* aIsAlternate) = 0;
-
-  virtual mozilla::CORSMode GetCORSMode() const
-  {
-    // Default to no CORS
-    return mozilla::CORS_NONE;
-  }
-
-  virtual mozilla::net::ReferrerPolicy GetLinkReferrerPolicy()
-  {
-    return mozilla::net::RP_Unset;
-  }
+  virtual mozilla::Maybe<SheetInfo> GetStyleSheetInfo() = 0;
 
   // CC methods
   void Unlink();
   void Traverse(nsCycleCollectionTraversalCallback &cb);
 
 private:
   /**
    * @param aOldDocument should be non-null only if we're updating because we
--- a/dom/base/nsSyncLoadService.cpp
+++ b/dom/base/nsSyncLoadService.cpp
@@ -284,17 +284,17 @@ nsSyncLoader::OnStopRequest(nsIRequest *
 }
 
 NS_IMETHODIMP
 nsSyncLoader::AsyncOnChannelRedirect(nsIChannel *aOldChannel,
                                      nsIChannel *aNewChannel,
                                      uint32_t aFlags,
                                      nsIAsyncVerifyRedirectCallback *callback)
 {
-    NS_PRECONDITION(aNewChannel, "Redirecting to null channel?");
+    MOZ_ASSERT(aNewChannel, "Redirecting to null channel?");
 
     mChannel = aNewChannel;
 
     callback->OnRedirectVerifyCallback(NS_OK);
     return NS_OK;
 }
 
 NS_IMETHODIMP
--- a/dom/base/nsTextNode.cpp
+++ b/dom/base/nsTextNode.cpp
@@ -210,19 +210,19 @@ nsTextNode::DumpContent(FILE* out, int32
 }
 #endif
 
 nsresult
 NS_NewAttributeContent(nsNodeInfoManager *aNodeInfoManager,
                        int32_t aNameSpaceID, nsAtom* aAttrName,
                        nsIContent** aResult)
 {
-  NS_PRECONDITION(aNodeInfoManager, "Missing nodeInfoManager");
-  NS_PRECONDITION(aAttrName, "Must have an attr name");
-  NS_PRECONDITION(aNameSpaceID != kNameSpaceID_Unknown, "Must know namespace");
+  MOZ_ASSERT(aNodeInfoManager, "Missing nodeInfoManager");
+  MOZ_ASSERT(aAttrName, "Must have an attr name");
+  MOZ_ASSERT(aNameSpaceID != kNameSpaceID_Unknown, "Must know namespace");
 
   *aResult = nullptr;
 
   already_AddRefed<mozilla::dom::NodeInfo> ni = aNodeInfoManager->GetTextNodeInfo();
 
   nsAttributeTextNode* textNode = new nsAttributeTextNode(ni,
                                                           aNameSpaceID,
                                                           aAttrName);
@@ -234,18 +234,18 @@ NS_NewAttributeContent(nsNodeInfoManager
 NS_IMPL_ISUPPORTS_INHERITED(nsAttributeTextNode, nsTextNode,
                             nsIMutationObserver)
 
 nsresult
 nsAttributeTextNode::BindToTree(nsIDocument* aDocument, nsIContent* aParent,
                                 nsIContent* aBindingParent,
                                 bool aCompileEventHandlers)
 {
-  NS_PRECONDITION(aParent && aParent->GetParent(),
-                  "This node can't be a child of the document or of the document root");
+  MOZ_ASSERT(aParent && aParent->GetParent(),
+             "This node can't be a child of the document or of the document root");
 
   nsresult rv = nsTextNode::BindToTree(aDocument, aParent,
                                        aBindingParent, aCompileEventHandlers);
   NS_ENSURE_SUCCESS(rv, rv);
 
   NS_ASSERTION(!mGrandparent, "We were already bound!");
   mGrandparent = aParent->GetParent()->AsElement();
   mGrandparent->AddMutationObserver(this);
@@ -300,9 +300,8 @@ void
 nsAttributeTextNode::UpdateText(bool aNotify)
 {
   if (mGrandparent) {
     nsAutoString attrValue;
     mGrandparent->GetAttr(mNameSpaceID, mAttrName, attrValue);
     SetText(attrValue, aNotify);
   }
 }
-
--- a/dom/base/nsTreeSanitizer.cpp
+++ b/dom/base/nsTreeSanitizer.cpp
@@ -1352,32 +1352,32 @@ nsTreeSanitizer::SanitizeURL(mozilla::do
 }
 
 void
 nsTreeSanitizer::Sanitize(DocumentFragment* aFragment)
 {
   // If you want to relax these preconditions, be sure to check the code in
   // here that notifies / does not notify or that fires mutation events if
   // in tree.
-  NS_PRECONDITION(!aFragment->IsInUncomposedDoc(), "The fragment is in doc?");
+  MOZ_ASSERT(!aFragment->IsInUncomposedDoc(), "The fragment is in doc?");
 
   mFullDocument = false;
   SanitizeChildren(aFragment);
 }
 
 void
 nsTreeSanitizer::Sanitize(nsIDocument* aDocument)
 {
   // If you want to relax these preconditions, be sure to check the code in
   // here that notifies / does not notify or that fires mutation events if
   // in tree.
 #ifdef DEBUG
-  NS_PRECONDITION(!aDocument->GetContainer(), "The document is in a shell.");
+  MOZ_ASSERT(!aDocument->GetContainer(), "The document is in a shell.");
   RefPtr<mozilla::dom::Element> root = aDocument->GetRootElement();
-  NS_PRECONDITION(root->IsHTMLElement(nsGkAtoms::html), "Not HTML root.");
+  MOZ_ASSERT(root->IsHTMLElement(nsGkAtoms::html), "Not HTML root.");
 #endif
 
   mFullDocument = true;
   SanitizeChildren(aDocument);
 }
 
 void
 nsTreeSanitizer::SanitizeChildren(nsINode* aRoot)
@@ -1537,17 +1537,17 @@ nsTreeSanitizer::LogMessage(const char* 
     nsContentUtils::ReportToConsoleNonLocalized(
         msg, nsIScriptError::warningFlag, NS_LITERAL_CSTRING("DOM"), aDoc);
   }
 }
 
 void
 nsTreeSanitizer::InitializeStatics()
 {
-  NS_PRECONDITION(!sElementsHTML, "Initializing a second time.");
+  MOZ_ASSERT(!sElementsHTML, "Initializing a second time.");
 
   sElementsHTML = new AtomsTable(ArrayLength(kElementsHTML));
   for (uint32_t i = 0; kElementsHTML[i]; i++) {
     sElementsHTML->PutEntry(kElementsHTML[i]);
   }
 
   sAttributesHTML = new AtomsTable(ArrayLength(kAttributesHTML));
   for (uint32_t i = 0; kAttributesHTML[i]; i++) {
--- a/dom/bindings/Bindings.conf
+++ b/dom/bindings/Bindings.conf
@@ -1702,19 +1702,16 @@ addExternalIface('HitRegionOptions', nat
 addExternalIface('imgINotificationObserver', nativeType='imgINotificationObserver')
 addExternalIface('imgIRequest', nativeType='imgIRequest', notflattened=True)
 addExternalIface('LoadContext', nativeType='nsILoadContext', notflattened=True)
 addExternalIface('LoadInfo', nativeType='nsILoadInfo',
                  headerFile='nsILoadInfo.h', notflattened=True)
 addExternalIface('MenuBuilder', nativeType='nsIMenuBuilder', notflattened=True)
 addExternalIface('XULControllers', nativeType='nsIControllers', notflattened=True)
 addExternalIface('MozObserver', nativeType='nsIObserver', notflattened=True)
-addExternalIface('MozRDFCompositeDataSource', nativeType='nsIRDFCompositeDataSource',
-                 notflattened=True)
-addExternalIface('MozRDFResource', nativeType='nsIRDFResource', notflattened=True)
 addExternalIface('MozTreeView', nativeType='nsITreeView',
                   headerFile='nsITreeView.h', notflattened=True)
 addExternalIface('MozWakeLockListener', headerFile='nsIDOMWakeLockListener.h')
 addExternalIface('nsIBrowserDOMWindow', nativeType='nsIBrowserDOMWindow',
                  notflattened=True)
 addExternalIface('nsIEventTarget', nativeType='nsIEventTarget', notflattened=True)
 addExternalIface('nsIFile', nativeType='nsIFile', notflattened=True)
 addExternalIface('nsILoadGroup', nativeType='nsILoadGroup',
--- a/dom/canvas/CanvasUtils.cpp
+++ b/dom/canvas/CanvasUtils.cpp
@@ -252,17 +252,17 @@ DoDrawImageSecurityCheck(dom::HTMLCanvas
         aCanvasElement->SetWriteOnly();
         return;
     }
 
     // No need to do a security check if the image used CORS for the load
     if (CORSUsed)
         return;
 
-    NS_PRECONDITION(aPrincipal, "Must have a principal here");
+    MOZ_ASSERT(aPrincipal, "Must have a principal here");
 
     if (aCanvasElement->NodePrincipal()->Subsumes(aPrincipal)) {
         // This canvas has access to that image anyway
         return;
     }
 
     aCanvasElement->SetWriteOnly();
 }
--- a/dom/commandhandler/nsControllerCommandTable.cpp
+++ b/dom/commandhandler/nsControllerCommandTable.cpp
@@ -192,17 +192,17 @@ nsControllerCommandTable::GetSupportedCo
     commands++;
   }
   return NS_OK;
 }
 
 nsresult
 NS_NewControllerCommandTable(nsIControllerCommandTable** aResult)
 {
-  NS_PRECONDITION(aResult != nullptr, "null ptr");
+  MOZ_ASSERT(aResult != nullptr, "null ptr");
   if (!aResult) {
     return NS_ERROR_NULL_POINTER;
   }
 
   nsControllerCommandTable* newCommandTable = new nsControllerCommandTable();
   NS_ADDREF(newCommandTable);
   *aResult = newCommandTable;
   return NS_OK;
--- a/dom/events/ContentEventHandler.cpp
+++ b/dom/events/ContentEventHandler.cpp
@@ -498,17 +498,17 @@ ContentEventHandler::IsPlugin(nsIContent
   return aContent &&
          aContent->GetDesiredIMEState().mEnabled == IMEState::PLUGIN;
 }
 
 nsresult
 ContentEventHandler::QueryContentRect(nsIContent* aContent,
                                       WidgetQueryContentEvent* aEvent)
 {
-  NS_PRECONDITION(aContent, "aContent must not be null");
+  MOZ_ASSERT(aContent, "aContent must not be null");
 
   nsIFrame* frame = aContent->GetPrimaryFrame();
   NS_ENSURE_TRUE(frame, NS_ERROR_FAILURE);
 
   // get rect for first frame
   nsRect resultRect(nsPoint(0, 0), frame->GetRect().Size());
   nsresult rv = ConvertToRootRelativeOffset(frame, resultRect);
   NS_ENSURE_SUCCESS(rv, rv);
@@ -2694,17 +2694,17 @@ ContentEventHandler::OnQueryCharacterAtP
   nsIFrame* rootFrame = shell->GetRootFrame();
   NS_ENSURE_TRUE(rootFrame, NS_ERROR_FAILURE);
   nsIWidget* rootWidget = rootFrame->GetNearestWidget();
   NS_ENSURE_TRUE(rootWidget, NS_ERROR_FAILURE);
 
   // The root frame's widget might be different, e.g., the event was fired on
   // a popup but the rootFrame is the document root.
   if (rootWidget != aEvent->mWidget) {
-    NS_PRECONDITION(aEvent->mWidget, "The event must have the widget");
+    MOZ_ASSERT(aEvent->mWidget, "The event must have the widget");
     nsView* view = nsView::GetViewFor(aEvent->mWidget);
     NS_ENSURE_TRUE(view, NS_ERROR_FAILURE);
     rootFrame = view->GetFrame();
     NS_ENSURE_TRUE(rootFrame, NS_ERROR_FAILURE);
     rootWidget = rootFrame->GetNearestWidget();
     NS_ENSURE_TRUE(rootWidget, NS_ERROR_FAILURE);
   }
 
--- a/dom/events/EventListenerService.cpp
+++ b/dom/events/EventListenerService.cpp
@@ -298,17 +298,17 @@ ToEventListener(JSContext* aCx, JS::Hand
 
 NS_IMETHODIMP
 EventListenerService::AddSystemEventListener(EventTarget *aTarget,
                                              const nsAString& aType,
                                              JS::Handle<JS::Value> aListener,
                                              bool aUseCapture,
                                              JSContext* aCx)
 {
-  NS_PRECONDITION(aTarget, "Missing target");
+  MOZ_ASSERT(aTarget, "Missing target");
 
   NS_ENSURE_TRUE(aTarget, NS_ERROR_UNEXPECTED);
 
   RefPtr<EventListener> listener = ToEventListener(aCx, aListener);
   if (!listener) {
     return NS_ERROR_UNEXPECTED;
   }
 
@@ -324,17 +324,17 @@ EventListenerService::AddSystemEventList
 
 NS_IMETHODIMP
 EventListenerService::RemoveSystemEventListener(EventTarget *aTarget,
                                                 const nsAString& aType,
                                                 JS::Handle<JS::Value> aListener,
                                                 bool aUseCapture,
                                                 JSContext* aCx)
 {
-  NS_PRECONDITION(aTarget, "Missing target");
+  MOZ_ASSERT(aTarget, "Missing target");
 
   NS_ENSURE_TRUE(aTarget, NS_ERROR_UNEXPECTED);
 
   RefPtr<EventListener> listener = ToEventListener(aCx, aListener);
   if (!listener) {
     return NS_ERROR_UNEXPECTED;
   }
 
--- a/dom/events/EventStateManager.cpp
+++ b/dom/events/EventStateManager.cpp
@@ -5283,21 +5283,21 @@ EventStateManager::UpdateAncestorState(n
   }
 }
 
 bool
 EventStateManager::SetContentState(nsIContent* aContent, EventStates aState)
 {
   // We manage 4 states here: ACTIVE, HOVER, DRAGOVER, URLTARGET
   // The input must be exactly one of them.
-  NS_PRECONDITION(aState == NS_EVENT_STATE_ACTIVE ||
-                  aState == NS_EVENT_STATE_HOVER ||
-                  aState == NS_EVENT_STATE_DRAGOVER ||
-                  aState == NS_EVENT_STATE_URLTARGET,
-                  "Unexpected state");
+  MOZ_ASSERT(aState == NS_EVENT_STATE_ACTIVE ||
+             aState == NS_EVENT_STATE_HOVER ||
+             aState == NS_EVENT_STATE_DRAGOVER ||
+             aState == NS_EVENT_STATE_URLTARGET,
+             "Unexpected state");
 
   nsCOMPtr<nsIContent> notifyContent1;
   nsCOMPtr<nsIContent> notifyContent2;
   bool updateAncestors;
 
   if (aState == NS_EVENT_STATE_HOVER || aState == NS_EVENT_STATE_ACTIVE) {
     // Hover and active are hierarchical
     updateAncestors = true;
@@ -5525,17 +5525,17 @@ EventStateManager::EnsureDocument(nsPres
 {
   if (!mDocument)
     mDocument = aPresContext->Document();
 }
 
 void
 EventStateManager::FlushPendingEvents(nsPresContext* aPresContext)
 {
-  NS_PRECONDITION(nullptr != aPresContext, "nullptr ptr");
+  MOZ_ASSERT(nullptr != aPresContext, "nullptr ptr");
   nsIPresShell *shell = aPresContext->GetPresShell();
   if (shell) {
     shell->FlushPendingNotifications(FlushType::InterruptibleLayout);
   }
 }
 
 nsIContent*
 EventStateManager::GetFocusedContent()
--- a/dom/events/WheelHandlingHelper.cpp
+++ b/dom/events/WheelHandlingHelper.cpp
@@ -305,17 +305,17 @@ WheelTransaction::OnEvent(WidgetEvent* a
 WheelTransaction::Shutdown()
 {
   NS_IF_RELEASE(sTimer);
 }
 
 /* static */ void
 WheelTransaction::OnFailToScrollTarget()
 {
-  NS_PRECONDITION(sTargetFrame, "We don't have mouse scrolling transaction");
+  MOZ_ASSERT(sTargetFrame, "We don't have mouse scrolling transaction");
 
   if (Prefs::sTestMouseScroll) {
     // This event is used for automated tests, see bug 442774.
     nsContentUtils::DispatchTrustedEvent(
                       sTargetFrame->GetContent()->OwnerDoc(),
                       sTargetFrame->GetContent(),
                       NS_LITERAL_STRING("MozMouseScrollFailed"),
                       true, true);
--- a/dom/html/HTMLFormElement.cpp
+++ b/dom/html/HTMLFormElement.cpp
@@ -1757,27 +1757,27 @@ HTMLFormElement::GetActionURL(nsIURI** a
   actionURL.forget(aActionURL);
 
   return rv;
 }
 
 NS_IMETHODIMP_(nsIFormControl*)
 HTMLFormElement::GetDefaultSubmitElement() const
 {
-  NS_PRECONDITION(mDefaultSubmitElement == mFirstSubmitInElements ||
-                  mDefaultSubmitElement == mFirstSubmitNotInElements,
-                  "What happened here?");
+  MOZ_ASSERT(mDefaultSubmitElement == mFirstSubmitInElements ||
+             mDefaultSubmitElement == mFirstSubmitNotInElements,
+             "What happened here?");
 
   return mDefaultSubmitElement;
 }
 
 bool
 HTMLFormElement::IsDefaultSubmitElement(const nsIFormControl* aControl) const
 {
-  NS_PRECONDITION(aControl, "Unexpected call");
+  MOZ_ASSERT(aControl, "Unexpected call");
 
   if (aControl == mDefaultSubmitElement) {
     // Yes, it is
     return true;
   }
 
   if (mDefaultSubmitElement ||
       (aControl != mFirstSubmitInElements &&
@@ -1816,17 +1816,17 @@ HTMLFormElement::ImplicitSubmissionIsDis
     }
   }
   return numDisablingControlsFound != 1;
 }
 
 bool
 HTMLFormElement::IsLastActiveElement(const nsIFormControl* aControl) const
 {
-  NS_PRECONDITION(aControl, "Unexpected call");
+  MOZ_ASSERT(aControl, "Unexpected call");
 
   for (auto* element : Reversed(mControls->mElements)) {
     if (element->IsSingleLineTextOrNumberControl(false) &&
         !element->IsDisabled()) {
       return element == aControl;
     }
   }
   return false;
--- a/dom/html/HTMLFrameSetElement.cpp
+++ b/dom/html/HTMLFrameSetElement.cpp
@@ -69,18 +69,18 @@ HTMLFrameSetElement::BeforeSetAttr(int32
 
   return nsGenericHTMLElement::BeforeSetAttr(aNamespaceID, aName, aValue, aNotify);
 }
 
 nsresult
 HTMLFrameSetElement::GetRowSpec(int32_t *aNumValues,
                                 const nsFramesetSpec** aSpecs)
 {
-  NS_PRECONDITION(aNumValues, "Must have a pointer to an integer here!");
-  NS_PRECONDITION(aSpecs, "Must have a pointer to an array of nsFramesetSpecs");
+  MOZ_ASSERT(aNumValues, "Must have a pointer to an integer here!");
+  MOZ_ASSERT(aSpecs, "Must have a pointer to an array of nsFramesetSpecs");
   *aNumValues = 0;
   *aSpecs = nullptr;
 
   if (!mRowSpecs) {
     const nsAttrValue* value = GetParsedAttr(nsGkAtoms::rows);
     if (value && value->Type() == nsAttrValue::eString) {
       nsresult rv = ParseRowCol(value->GetStringValue(), mNumRows,
                                 &mRowSpecs);
@@ -99,18 +99,18 @@ HTMLFrameSetElement::GetRowSpec(int32_t 
   *aNumValues = mNumRows;
   return NS_OK;
 }
 
 nsresult
 HTMLFrameSetElement::GetColSpec(int32_t *aNumValues,
                                 const nsFramesetSpec** aSpecs)
 {
-  NS_PRECONDITION(aNumValues, "Must have a pointer to an integer here!");
-  NS_PRECONDITION(aSpecs, "Must have a pointer to an array of nsFramesetSpecs");
+  MOZ_ASSERT(aNumValues, "Must have a pointer to an integer here!");
+  MOZ_ASSERT(aSpecs, "Must have a pointer to an array of nsFramesetSpecs");
   *aNumValues = 0;
   *aSpecs = nullptr;
 
   if (!mColSpecs) {
     const nsAttrValue* value = GetParsedAttr(nsGkAtoms::cols);
     if (value && value->Type() == nsAttrValue::eString) {
       nsresult rv = ParseRowCol(value->GetStringValue(), mNumCols,
                                 &mColSpecs);
--- a/dom/html/HTMLImageElement.cpp
+++ b/dom/html/HTMLImageElement.cpp
@@ -860,17 +860,17 @@ HTMLImageElement::GetForm() const
 {
   return mForm;
 }
 #endif
 
 void
 HTMLImageElement::SetForm(HTMLFormElement* aForm)
 {
-  NS_PRECONDITION(aForm, "Don't pass null here");
+  MOZ_ASSERT(aForm, "Don't pass null here");
   NS_ASSERTION(!mForm,
                "We don't support switching from one non-null form to another.");
 
   mForm = aForm;
 }
 
 void
 HTMLImageElement::ClearForm(bool aRemoveFromForm)
--- a/dom/html/HTMLInputElement.cpp
+++ b/dom/html/HTMLInputElement.cpp
@@ -871,22 +871,22 @@ HTMLInputElement::DestroyUploadLastDir()
   NS_IF_RELEASE(gUploadLastDir);
 }
 
 nsresult
 UploadLastDir::FetchDirectoryAndDisplayPicker(nsIDocument* aDoc,
                                               nsIFilePicker* aFilePicker,
                                               nsIFilePickerShownCallback* aFpCallback)
 {
-  NS_PRECONDITION(aDoc, "aDoc is null");
-  NS_PRECONDITION(aFilePicker, "aFilePicker is null");
-  NS_PRECONDITION(aFpCallback, "aFpCallback is null");
+  MOZ_ASSERT(aDoc, "aDoc is null");
+  MOZ_ASSERT(aFilePicker, "aFilePicker is null");
+  MOZ_ASSERT(aFpCallback, "aFpCallback is null");
 
   nsIURI* docURI = aDoc->GetDocumentURI();
-  NS_PRECONDITION(docURI, "docURI is null");
+  MOZ_ASSERT(docURI, "docURI is null");
 
   nsCOMPtr<nsILoadContext> loadContext = aDoc->GetLoadContext();
   nsCOMPtr<nsIContentPrefCallback2> prefCallback =
     new UploadLastDir::ContentPrefCallback(aFilePicker, aFpCallback);
 
   // Attempt to get the CPS, if it's not present we'll fallback to use the Desktop folder
   nsCOMPtr<nsIContentPrefService2> contentPrefService =
     do_GetService(NS_CONTENT_PREF_SERVICE_CONTRACTID);
@@ -901,23 +901,23 @@ UploadLastDir::FetchDirectoryAndDisplayP
 
   contentPrefService->GetByDomainAndName(spec, CPS_PREF_NAME, loadContext, prefCallback);
   return NS_OK;
 }
 
 nsresult
 UploadLastDir::StoreLastUsedDirectory(nsIDocument* aDoc, nsIFile* aDir)
 {
-  NS_PRECONDITION(aDoc, "aDoc is null");
+  MOZ_ASSERT(aDoc, "aDoc is null");
   if (!aDir) {
     return NS_OK;
   }
 
   nsCOMPtr<nsIURI> docURI = aDoc->GetDocumentURI();
-  NS_PRECONDITION(docURI, "docURI is null");
+  MOZ_ASSERT(docURI, "docURI is null");
 
   // Attempt to get the CPS, if it's not present we'll just return
   nsCOMPtr<nsIContentPrefService2> contentPrefService =
     do_GetService(NS_CONTENT_PREF_SERVICE_CONTRACTID);
   if (!contentPrefService)
     return NS_ERROR_NOT_AVAILABLE;
 
   nsAutoCString cstrSpec;
@@ -2789,18 +2789,18 @@ HTMLInputElement::UpdateFileList()
   }
 }
 
 nsresult
 HTMLInputElement::SetValueInternal(const nsAString& aValue,
                                    const nsAString* aOldValue,
                                    uint32_t aFlags)
 {
-  NS_PRECONDITION(GetValueMode() != VALUE_MODE_FILENAME,
-                  "Don't call SetValueInternal for file inputs");
+  MOZ_ASSERT(GetValueMode() != VALUE_MODE_FILENAME,
+             "Don't call SetValueInternal for file inputs");
 
   // We want to remember if the SetValueInternal() call is being made for a XUL
   // element.  We do that by looking at the parent node here, and if that node
   // is a XUL node, we consider our control a XUL control.
   nsIContent* parent = GetParent();
   if (parent && parent->IsXULElement()) {
     aFlags |= nsTextEditorState::eSetValue_ForXUL;
   }
--- a/dom/html/HTMLLinkElement.cpp
+++ b/dom/html/HTMLLinkElement.cpp
@@ -415,90 +415,74 @@ HTMLLinkElement::RelList()
 }
 
 already_AddRefed<nsIURI>
 HTMLLinkElement::GetHrefURI() const
 {
   return GetHrefURIForAnchors();
 }
 
-already_AddRefed<nsIURI>
-HTMLLinkElement::GetStyleSheetURL(bool* aIsInline, nsIPrincipal** aTriggeringPrincipal)
+Maybe<nsStyleLinkElement::SheetInfo>
+HTMLLinkElement::GetStyleSheetInfo()
 {
-  *aIsInline = false;
-  *aTriggeringPrincipal = nullptr;
-
-  nsAutoString href;
-  GetAttr(kNameSpaceID_None, nsGkAtoms::href, href);
-  if (href.IsEmpty()) {
-    return nullptr;
-  }
-
-  nsCOMPtr<nsIPrincipal> prin = mTriggeringPrincipal;
-  prin.forget(aTriggeringPrincipal);
-
-  nsCOMPtr<nsIURI> uri = Link::GetURI();
-  return uri.forget();
-}
-
-void
-HTMLLinkElement::GetStyleSheetInfo(nsAString& aTitle,
-                                   nsAString& aType,
-                                   nsAString& aMedia,
-                                   bool* aIsAlternate)
-{
-  aTitle.Truncate();
-  aType.Truncate();
-  aMedia.Truncate();
-  *aIsAlternate = false;
-
   nsAutoString rel;
   GetAttr(kNameSpaceID_None, nsGkAtoms::rel, rel);
   uint32_t linkTypes = nsStyleLinkElement::ParseLinkTypes(rel);
-  // Is it a stylesheet link?
   if (!(linkTypes & nsStyleLinkElement::eSTYLESHEET)) {
-    return;
+    return Nothing();
   }
 
   nsAutoString title;
   GetAttr(kNameSpaceID_None, nsGkAtoms::title, title);
   title.CompressWhitespace();
-  aTitle.Assign(title);
 
-  // If alternate, does it have title?
-  if (linkTypes & nsStyleLinkElement::eALTERNATE) {
-    if (aTitle.IsEmpty()) { // alternates must have title
-      return;
-    } else {
-      *aIsAlternate = true;
-    }
+  bool alternate = linkTypes & nsStyleLinkElement::eALTERNATE;
+  if (alternate && title.IsEmpty()) {
+    // alternates must have title.
+    return Nothing();
   }
 
-  GetAttr(kNameSpaceID_None, nsGkAtoms::media, aMedia);
+  nsAutoString type;
+  nsAutoString mimeType;
+  nsAutoString notUsed;
+  GetAttr(kNameSpaceID_None, nsGkAtoms::type, type);
+  nsContentUtils::SplitMimeType(type, mimeType, notUsed);
+  if (!mimeType.IsEmpty() && !mimeType.LowerCaseEqualsLiteral("text/css")) {
+    return Nothing();
+  }
+
+  nsAutoString href;
+  GetAttr(kNameSpaceID_None, nsGkAtoms::href, href);
+  if (href.IsEmpty()) {
+    return Nothing();
+  }
+
+  nsAutoString media;
+  GetAttr(kNameSpaceID_None, nsGkAtoms::media, media);
   // The HTML5 spec is formulated in terms of the CSSOM spec, which specifies
   // that media queries should be ASCII lowercased during serialization.
-  nsContentUtils::ASCIIToLower(aMedia);
-
-  nsAutoString mimeType;
-  nsAutoString notUsed;
-  GetAttr(kNameSpaceID_None, nsGkAtoms::type, aType);
-  nsContentUtils::SplitMimeType(aType, mimeType, notUsed);
-  if (!mimeType.IsEmpty() && !mimeType.LowerCaseEqualsLiteral("text/css")) {
-    return;
-  }
+  //
+  // FIXME(emilio): How does it matter? This is going to be parsed anyway, CSS
+  // should take care of serializing it properly.
+  nsContentUtils::ASCIIToLower(media);
 
-  // If we get here we assume that we're loading a css file, so set the
-  // type to 'text/css'
-  aType.AssignLiteral("text/css");
-}
-
-CORSMode
-HTMLLinkElement::GetCORSMode() const
-{
-  return AttrValueToCORSMode(GetParsedAttr(nsGkAtoms::crossorigin));
+  nsCOMPtr<nsIURI> uri = Link::GetURI();
+  nsCOMPtr<nsIPrincipal> prin = mTriggeringPrincipal;
+  return Some(SheetInfo {
+    *OwnerDoc(),
+    this,
+    uri.forget(),
+    prin.forget(),
+    GetReferrerPolicyAsEnum(),
+    GetCORSMode(),
+    title,
+    media,
+    alternate ? HasAlternateRel::Yes : HasAlternateRel::No,
+    IsInline::No,
+  });
 }
 
 EventStates
 HTMLLinkElement::IntrinsicState() const
 {
   return Link::LinkState() | nsGenericHTMLElement::IntrinsicState();
 }
 
--- a/dom/html/HTMLLinkElement.h
+++ b/dom/html/HTMLLinkElement.h
@@ -184,42 +184,36 @@ public:
   void SetReferrerPolicy(const nsAString& aReferrer, ErrorResult& aError)
   {
     SetHTMLAttr(nsGkAtoms::referrerpolicy, aReferrer, aError);
   }
   void GetReferrerPolicy(nsAString& aReferrer)
   {
     GetEnumAttr(nsGkAtoms::referrerpolicy, EmptyCString().get(), aReferrer);
   }
-  mozilla::net::ReferrerPolicy GetLinkReferrerPolicy() override
+
+  CORSMode GetCORSMode() const
   {
-    return GetReferrerPolicyAsEnum();
+    return AttrValueToCORSMode(GetParsedAttr(nsGkAtoms::crossorigin));
   }
 
-  virtual CORSMode GetCORSMode() const override;
-
   void NodeInfoChanged(nsIDocument* aOldDoc) final
   {
     ClearHasPendingLinkUpdate();
     nsGenericHTMLElement::NodeInfoChanged(aOldDoc);
   }
 
   static bool CheckPreloadAttrs(const nsAttrValue& aAs, const nsAString& aType,
                                 const nsAString& aMedia, nsIDocument* aDocument);
 protected:
   virtual ~HTMLLinkElement();
 
   // nsStyleLinkElement
-  already_AddRefed<nsIURI>
-    GetStyleSheetURL(bool* aIsInline, nsIPrincipal** aTriggeringPrincipal) final;
+  Maybe<SheetInfo> GetStyleSheetInfo() final;
 
-  void GetStyleSheetInfo(nsAString& aTitle,
-                         nsAString& aType,
-                         nsAString& aMedia,
-                         bool* aIsAlternate) final;
 protected:
   RefPtr<nsDOMTokenList> mRelList;
 };
 
 } // namespace dom
 } // namespace mozilla
 
 #endif // mozilla_dom_HTMLLinkElement_h
--- a/dom/html/HTMLSharedElement.cpp
+++ b/dom/html/HTMLSharedElement.cpp
@@ -115,17 +115,17 @@ HTMLSharedElement::IsAttributeMapped(con
   }
 
   return nsGenericHTMLElement::IsAttributeMapped(aAttribute);
 }
 
 static void
 SetBaseURIUsingFirstBaseWithHref(nsIDocument* aDocument, nsIContent* aMustMatch)
 {
-  NS_PRECONDITION(aDocument, "Need a document!");
+  MOZ_ASSERT(aDocument, "Need a document!");
 
   for (nsIContent* child = aDocument->GetFirstChild(); child;
        child = child->GetNextNode()) {
     if (child->IsHTMLElement(nsGkAtoms::base) &&
         child->AsElement()->HasAttr(kNameSpaceID_None, nsGkAtoms::href)) {
       if (aMustMatch && child != aMustMatch) {
         return;
       }
@@ -168,17 +168,17 @@ SetBaseURIUsingFirstBaseWithHref(nsIDocu
 
   aDocument->SetBaseURI(nullptr);
 }
 
 static void
 SetBaseTargetUsingFirstBaseWithTarget(nsIDocument* aDocument,
                                       nsIContent* aMustMatch)
 {
-  NS_PRECONDITION(aDocument, "Need a document!");
+  MOZ_ASSERT(aDocument, "Need a document!");
 
   for (nsIContent* child = aDocument->GetFirstChild(); child;
        child = child->GetNextNode()) {
     if (child->IsHTMLElement(nsGkAtoms::base) &&
         child->AsElement()->HasAttr(kNameSpaceID_None, nsGkAtoms::target)) {
       if (aMustMatch && child != aMustMatch) {
         return;
       }
--- a/dom/html/HTMLStyleElement.cpp
+++ b/dom/html/HTMLStyleElement.cpp
@@ -189,57 +189,53 @@ HTMLStyleElement::SetTextContentInternal
 
   SetEnableUpdates(true);
 
   mTriggeringPrincipal = aScriptedPrincipal;
 
   Unused << UpdateStyleSheetInternal(nullptr, nullptr);
 }
 
-already_AddRefed<nsIURI>
-HTMLStyleElement::GetStyleSheetURL(bool* aIsInline, nsIPrincipal** aTriggeringPrincipal)
+Maybe<nsStyleLinkElement::SheetInfo>
+HTMLStyleElement::GetStyleSheetInfo()
 {
-  *aIsInline = true;
-  *aTriggeringPrincipal = do_AddRef(mTriggeringPrincipal).take();
-  return nullptr;
-}
-
-void
-HTMLStyleElement::GetStyleSheetInfo(nsAString& aTitle,
-                                    nsAString& aType,
-                                    nsAString& aMedia,
-                                    bool* aIsAlternate)
-{
-  aTitle.Truncate();
-  aType.Truncate();
-  aMedia.Truncate();
-  *aIsAlternate = false;
-
   nsAutoString title;
   GetAttr(kNameSpaceID_None, nsGkAtoms::title, title);
   title.CompressWhitespace();
-  aTitle.Assign(title);
 
-  GetAttr(kNameSpaceID_None, nsGkAtoms::media, aMedia);
+  nsAutoString media;
+  GetAttr(kNameSpaceID_None, nsGkAtoms::media, media);
   // The HTML5 spec is formulated in terms of the CSSOM spec, which specifies
   // that media queries should be ASCII lowercased during serialization.
-  nsContentUtils::ASCIIToLower(aMedia);
+  //
+  // FIXME(emilio): Doesn't matter I'd think, style should take care of that.
+  nsContentUtils::ASCIIToLower(media);
 
-  GetAttr(kNameSpaceID_None, nsGkAtoms::type, aType);
-
+  nsAutoString type;
   nsAutoString mimeType;
   nsAutoString notUsed;
-  nsContentUtils::SplitMimeType(aType, mimeType, notUsed);
+  GetAttr(kNameSpaceID_None, nsGkAtoms::type, type);
+  nsContentUtils::SplitMimeType(type, mimeType, notUsed);
   if (!mimeType.IsEmpty() && !mimeType.LowerCaseEqualsLiteral("text/css")) {
-    return;
+    return Nothing();
   }
 
-  // If we get here we assume that we're loading a css file, so set the
-  // type to 'text/css'
-  aType.AssignLiteral("text/css");
+  nsCOMPtr<nsIPrincipal> prin = mTriggeringPrincipal;
+  return Some(SheetInfo {
+    *OwnerDoc(),
+    this,
+    nullptr,
+    prin.forget(),
+    net::ReferrerPolicy::RP_Unset,
+    CORS_NONE,
+    title,
+    media,
+    HasAlternateRel::No,
+    IsInline::Yes,
+  });
 }
 
 JSObject*
 HTMLStyleElement::WrapNode(JSContext *aCx, JS::Handle<JSObject*> aGivenProto)
 {
   return HTMLStyleElementBinding::Wrap(aCx, this, aGivenProto);
 }
 
--- a/dom/html/HTMLStyleElement.h
+++ b/dom/html/HTMLStyleElement.h
@@ -79,22 +79,18 @@ public:
     SetHTMLAttr(nsGkAtoms::type, aType, aError);
   }
 
   virtual JSObject* WrapNode(JSContext *aCx, JS::Handle<JSObject*> aGivenProto) override;
 
 protected:
   virtual ~HTMLStyleElement();
 
-  already_AddRefed<nsIURI>
-    GetStyleSheetURL(bool* aIsInline, nsIPrincipal** aTriggeringPrincipal) final;
-  void GetStyleSheetInfo(nsAString& aTitle,
-                         nsAString& aType,
-                         nsAString& aMedia,
-                         bool* aIsAlternate) final;
+  Maybe<SheetInfo> GetStyleSheetInfo() final;
+
   /**
    * Common method to call from the various mutation observer methods.
    * aContent is a content node that's either the one that changed or its
    * parent; we should only respond to the change if aContent is non-anonymous.
    */
   void ContentChanged(nsIContent* aContent);
 };
 
--- a/dom/html/nsGenericHTMLElement.cpp
+++ b/dom/html/nsGenericHTMLElement.cpp
@@ -539,18 +539,18 @@ nsGenericHTMLElement::FindAncestorForm(H
 
   return nullptr;
 }
 
 bool
 nsGenericHTMLElement::CheckHandleEventForAnchorsPreconditions(
                         EventChainVisitor& aVisitor)
 {
-  NS_PRECONDITION(nsCOMPtr<Link>(do_QueryObject(this)),
-                  "should be called only when |this| implements |Link|");
+  MOZ_ASSERT(nsCOMPtr<Link>(do_QueryObject(this)),
+             "should be called only when |this| implements |Link|");
 
   if (!aVisitor.mPresContext) {
     // We need a pres context to do link stuff. Some events (e.g. mutation
     // events) don't have one.
     // XXX: ideally, shouldn't we be able to do what we need without one?
     return false;
   }
 
@@ -584,17 +584,17 @@ nsGenericHTMLElement::PostHandleEventFor
   }
 
   return PostHandleEventForLinks(aVisitor);
 }
 
 bool
 nsGenericHTMLElement::IsHTMLLink(nsIURI** aURI) const
 {
-  NS_PRECONDITION(aURI, "Must provide aURI out param");
+  MOZ_ASSERT(aURI, "Must provide aURI out param");
 
   *aURI = GetHrefURIForAnchors().take();
   // We promise out param is non-null if we return true, so base rv on it
   return *aURI != nullptr;
 }
 
 already_AddRefed<nsIURI>
 nsGenericHTMLElement::GetHrefURIForAnchors() const
@@ -1678,17 +1678,17 @@ nsGenericHTMLFormElement::SaveSubtreeSta
   SaveState();
 
   nsGenericHTMLElement::SaveSubtreeState();
 }
 
 void
 nsGenericHTMLFormElement::SetForm(HTMLFormElement* aForm)
 {
-  NS_PRECONDITION(aForm, "Don't pass null here");
+  MOZ_ASSERT(aForm, "Don't pass null here");
   NS_ASSERTION(!mForm,
                "We don't support switching from one non-null form to another.");
 
   SetForm(aForm, false);
 }
 
 void nsGenericHTMLFormElement::SetForm(HTMLFormElement* aForm, bool aBindToTree)
 {
@@ -2218,18 +2218,18 @@ nsGenericHTMLFormElement::IsElementDisab
 
   return IsDisabled();
 }
 
 void
 nsGenericHTMLFormElement::UpdateFormOwner(bool aBindToTree,
                                           Element* aFormIdElement)
 {
-  NS_PRECONDITION(!aBindToTree || !aFormIdElement,
-                  "aFormIdElement shouldn't be set if aBindToTree is true!");
+  MOZ_ASSERT(!aBindToTree || !aFormIdElement,
+             "aFormIdElement shouldn't be set if aBindToTree is true!");
 
   bool needStateUpdate = false;
   if (!aBindToTree) {
     needStateUpdate = mForm && mForm->IsDefaultSubmitElement(this);
     ClearForm(true, false);
   }
 
   HTMLFormElement *oldForm = mForm;
--- a/dom/html/nsGenericHTMLFrameElement.cpp
+++ b/dom/html/nsGenericHTMLFrameElement.cpp
@@ -79,17 +79,17 @@ nsGenericHTMLFrameElement::~nsGenericHTM
   if (mFrameLoader) {
     mFrameLoader->Destroy();
   }
 }
 
 nsresult
 nsGenericHTMLFrameElement::GetContentDocument(nsIDOMDocument** aContentDocument)
 {
-  NS_PRECONDITION(aContentDocument, "Null out param");
+  MOZ_ASSERT(aContentDocument, "Null out param");
   nsCOMPtr<nsIDOMDocument> document =
     do_QueryInterface(GetContentDocument(*nsContentUtils::SubjectPrincipal()));
   document.forget(aContentDocument);
   return NS_OK;
 }
 
 nsIDocument*
 nsGenericHTMLFrameElement::GetContentDocument(nsIPrincipal& aSubjectPrincipal)
--- a/dom/html/nsHTMLContentSink.cpp
+++ b/dom/html/nsHTMLContentSink.cpp
@@ -780,17 +780,17 @@ HTMLContentSink::DidBuildModel(bool aTer
   DropParserAndPerfHint();
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
 HTMLContentSink::SetParser(nsParserBase* aParser)
 {
-  NS_PRECONDITION(aParser, "Should have a parser here!");
+  MOZ_ASSERT(aParser, "Should have a parser here!");
   mParser = aParser;
   return NS_OK;
 }
 
 nsresult
 HTMLContentSink::CloseHTML()
 {
   if (mHeadContext) {
@@ -963,17 +963,17 @@ HTMLContentSink::NotifyInsert(nsIContent
   }
 
   mInNotification--;
 }
 
 void
 HTMLContentSink::NotifyRootInsertion()
 {
-  NS_PRECONDITION(!mNotifiedRootInsertion, "Double-notifying on root?");
+  MOZ_ASSERT(!mNotifiedRootInsertion, "Double-notifying on root?");
   NS_ASSERTION(!mLayoutStarted,
                "How did we start layout without notifying on root?");
   // Now make sure to notify that we have now inserted our root.  If
   // there has been no initial reflow yet it'll be a no-op, but if
   // there has been one we need this to get its frames constructed.
   // Note that if mNotifiedRootInsertion is true we don't notify here,
   // since that just means there are multiple <html> tags in the
   // document; in those cases we just want to put all the attrs on one
--- a/dom/jsurl/nsJSProtocolHandler.cpp
+++ b/dom/jsurl/nsJSProtocolHandler.cpp
@@ -1410,17 +1410,17 @@ nsJSURI::Mutate(nsIURIMutator** aMutator
 }
 
 /* virtual */ nsresult
 nsJSURI::EqualsInternal(nsIURI* aOther,
                         mozilla::net::nsSimpleURI::RefHandlingEnum aRefHandlingMode,
                         bool* aResult)
 {
     NS_ENSURE_ARG_POINTER(aOther);
-    NS_PRECONDITION(aResult, "null pointer for outparam");
+    MOZ_ASSERT(aResult, "null pointer for outparam");
 
     RefPtr<nsJSURI> otherJSURI;
     nsresult rv = aOther->QueryInterface(kJSURICID,
                                          getter_AddRefs(otherJSURI));
     if (NS_FAILED(rv)) {
         *aResult = false; // aOther is not a nsJSURI --> not equal.
         return NS_OK;
     }
--- a/dom/script/nsIScriptElement.h
+++ b/dom/script/nsIScriptElement.h
@@ -59,23 +59,23 @@ public:
   virtual bool GetScriptType(nsAString& type) = 0;
 
   /**
    * Location of script source text. Can return null, in which case
    * this is assumed to be an inline script element.
    */
   nsIURI* GetScriptURI()
   {
-    NS_PRECONDITION(mFrozen, "Not ready for this call yet!");
+    MOZ_ASSERT(mFrozen, "Not ready for this call yet!");
     return mUri;
   }
 
   nsIPrincipal* GetScriptURITriggeringPrincipal()
   {
-    NS_PRECONDITION(mFrozen, "Not ready for this call yet!");
+    MOZ_ASSERT(mFrozen, "Not ready for this call yet!");
     return mSrcTriggeringPrincipal;
   }
 
   /**
    * Script source text for inline script elements.
    */
   virtual void GetScriptText(nsAString& text) = 0;
 
@@ -92,44 +92,44 @@ public:
    */
   virtual void FreezeExecutionAttrs(nsIDocument* aOwnerDoc) = 0;
 
   /**
    * Is the script a module script. Currently only supported by HTML scripts.
    */
   bool GetScriptIsModule()
   {
-    NS_PRECONDITION(mFrozen, "Not ready for this call yet!");
+    MOZ_ASSERT(mFrozen, "Not ready for this call yet!");
     return mIsModule;
   }
 
   /**
    * Is the script deferred. Currently only supported by HTML scripts.
    */
   bool GetScriptDeferred()
   {
-    NS_PRECONDITION(mFrozen, "Not ready for this call yet!");
+    MOZ_ASSERT(mFrozen, "Not ready for this call yet!");
     return mDefer;
   }
 
   /**
    * Is the script async. Currently only supported by HTML scripts.
    */
   bool GetScriptAsync()
   {
-    NS_PRECONDITION(mFrozen, "Not ready for this call yet!");
+    MOZ_ASSERT(mFrozen, "Not ready for this call yet!");
     return mAsync;
   }
 
   /**
    * Is the script an external script?
    */
   bool GetScriptExternal()
   {
-    NS_PRECONDITION(mFrozen, "Not ready for this call yet!");
+    MOZ_ASSERT(mFrozen, "Not ready for this call yet!");
     return mExternal;
   }
 
   /**
    * Returns how the element was created.
    */
   mozilla::dom::FromParser GetParserCreated()
   {
--- a/dom/security/nsCSPContext.cpp
+++ b/dom/security/nsCSPContext.cpp
@@ -729,18 +729,18 @@ nsCSPContext::LogViolationDetails(uint16
 }
 
 #undef CASE_CHECK_AND_REPORT
 
 NS_IMETHODIMP
 nsCSPContext::SetRequestContext(nsIDOMDocument* aDOMDocument,
                                 nsIPrincipal* aPrincipal)
 {
-  NS_PRECONDITION(aDOMDocument || aPrincipal,
-                  "Can't set context without doc or principal");
+  MOZ_ASSERT(aDOMDocument || aPrincipal,
+             "Can't set context without doc or principal");
   NS_ENSURE_ARG(aDOMDocument || aPrincipal);
 
   if (aDOMDocument) {
     nsCOMPtr<nsIDocument> doc = do_QueryInterface(aDOMDocument);
     mLoadingContext = do_GetWeakReference(doc);
     mSelfURI = doc->GetDocumentURI();
     mLoadingPrincipal = doc->NodePrincipal();
     doc->GetReferrer(mReferrer);
--- a/dom/smil/SMILBoolType.cpp
+++ b/dom/smil/SMILBoolType.cpp
@@ -9,75 +9,74 @@
 #include "nsDebug.h"
 #include <math.h>
 
 namespace mozilla {
 
 void
 SMILBoolType::Init(nsSMILValue& aValue) const
 {
-  NS_PRECONDITION(aValue.IsNull(), "Unexpected value type");
+  MOZ_ASSERT(aValue.IsNull(), "Unexpected value type");
   aValue.mU.mBool = false;
   aValue.mType = this;
 }
 
 void
 SMILBoolType::Destroy(nsSMILValue& aValue) const
 {
-  NS_PRECONDITION(aValue.mType == this, "Unexpected SMIL value");
+  MOZ_ASSERT(aValue.mType == this, "Unexpected SMIL value");
   aValue.mU.mBool = false;
   aValue.mType = nsSMILNullType::Singleton();
 }
 
 nsresult
 SMILBoolType::Assign(nsSMILValue& aDest, const nsSMILValue& aSrc) const
 {
-  NS_PRECONDITION(aDest.mType == aSrc.mType, "Incompatible SMIL types");
-  NS_PRECONDITION(aDest.mType == this, "Unexpected SMIL value");
+  MOZ_ASSERT(aDest.mType == aSrc.mType, "Incompatible SMIL types");
+  MOZ_ASSERT(aDest.mType == this, "Unexpected SMIL value");
   aDest.mU.mBool = aSrc.mU.mBool;
   return NS_OK;
 }
 
 bool
 SMILBoolType::IsEqual(const nsSMILValue& aLeft,
                       const nsSMILValue& aRight) const
 {
-  NS_PRECONDITION(aLeft.mType == aRight.mType, "Incompatible SMIL types");
-  NS_PRECONDITION(aLeft.mType == this, "Unexpected type for SMIL value");
+  MOZ_ASSERT(aLeft.mType == aRight.mType, "Incompatible SMIL types");
+  MOZ_ASSERT(aLeft.mType == this, "Unexpected type for SMIL value");
 
   return aLeft.mU.mBool == aRight.mU.mBool;
 }
 
 nsresult
 SMILBoolType::Add(nsSMILValue& aDest, const nsSMILValue& aValueToAdd,
                   uint32_t aCount) const
 {
-  NS_PRECONDITION(aValueToAdd.mType == aDest.mType,
-                  "Trying to add invalid types");
-  NS_PRECONDITION(aValueToAdd.mType == this, "Unexpected source type");
+  MOZ_ASSERT(aValueToAdd.mType == aDest.mType, "Trying to add invalid types");
+  MOZ_ASSERT(aValueToAdd.mType == this, "Unexpected source type");
   return NS_ERROR_FAILURE; // bool values can't be added to each other
 }
 
 nsresult
 SMILBoolType::ComputeDistance(const nsSMILValue& aFrom,
                               const nsSMILValue& aTo,
                               double& aDistance) const
 {
-  NS_PRECONDITION(aFrom.mType == aTo.mType,"Trying to compare different types");
-  NS_PRECONDITION(aFrom.mType == this, "Unexpected source type");
+  MOZ_ASSERT(aFrom.mType == aTo.mType, "Trying to compare different types");
+  MOZ_ASSERT(aFrom.mType == this, "Unexpected source type");
   return NS_ERROR_FAILURE; // there is no concept of distance between bool values
 }
 
 nsresult
 SMILBoolType::Interpolate(const nsSMILValue& aStartVal,
                           const nsSMILValue& aEndVal,
                           double aUnitDistance,
                           nsSMILValue& aResult) const
 {
-  NS_PRECONDITION(aStartVal.mType == aEndVal.mType,
-      "Trying to interpolate different types");
-  NS_PRECONDITION(aStartVal.mType == this,
+  MOZ_ASSERT(aStartVal.mType == aEndVal.mType,
+             "Trying to interpolate different types");
+  MOZ_ASSERT(aStartVal.mType == this,
       "Unexpected types for interpolation");
-  NS_PRECONDITION(aResult.mType   == this, "Unexpected result type");
+  MOZ_ASSERT(aResult.mType   == this, "Unexpected result type");
   return NS_ERROR_FAILURE; // bool values do not interpolate
 }
 
 } // namespace mozilla
--- a/dom/smil/SMILEnumType.cpp
+++ b/dom/smil/SMILEnumType.cpp
@@ -9,75 +9,75 @@
 #include "nsDebug.h"
 #include <math.h>
 
 namespace mozilla {
 
 void
 SMILEnumType::Init(nsSMILValue& aValue) const
 {
-  NS_PRECONDITION(aValue.IsNull(), "Unexpected value type");
+  MOZ_ASSERT(aValue.IsNull(), "Unexpected value type");
   aValue.mU.mUint = 0;
   aValue.mType = this;
 }
 
 void
 SMILEnumType::Destroy(nsSMILValue& aValue) const
 {
-  NS_PRECONDITION(aValue.mType == this, "Unexpected SMIL value");
+  MOZ_ASSERT(aValue.mType == this, "Unexpected SMIL value");
   aValue.mU.mUint = 0;
   aValue.mType = nsSMILNullType::Singleton();
 }
 
 nsresult
 SMILEnumType::Assign(nsSMILValue& aDest, const nsSMILValue& aSrc) const
 {
-  NS_PRECONDITION(aDest.mType == aSrc.mType, "Incompatible SMIL types");
-  NS_PRECONDITION(aDest.mType == this, "Unexpected SMIL value");
+  MOZ_ASSERT(aDest.mType == aSrc.mType, "Incompatible SMIL types");
+  MOZ_ASSERT(aDest.mType == this, "Unexpected SMIL value");
   aDest.mU.mUint = aSrc.mU.mUint;
   return NS_OK;
 }
 
 bool
 SMILEnumType::IsEqual(const nsSMILValue& aLeft,
                       const nsSMILValue& aRight) const
 {
-  NS_PRECONDITION(aLeft.mType == aRight.mType, "Incompatible SMIL types");
-  NS_PRECONDITION(aLeft.mType == this, "Unexpected type for SMIL value");
+  MOZ_ASSERT(aLeft.mType == aRight.mType, "Incompatible SMIL types");
+  MOZ_ASSERT(aLeft.mType == this, "Unexpected type for SMIL value");
 
   return aLeft.mU.mUint == aRight.mU.mUint;
 }
 
 nsresult
 SMILEnumType::Add(nsSMILValue& aDest, const nsSMILValue& aValueToAdd,
                   uint32_t aCount) const
 {
-  NS_PRECONDITION(aValueToAdd.mType == aDest.mType,
+  MOZ_ASSERT(aValueToAdd.mType == aDest.mType,
                   "Trying to add invalid types");
-  NS_PRECONDITION(aValueToAdd.mType == this, "Unexpected source type");
+  MOZ_ASSERT(aValueToAdd.mType == this, "Unexpected source type");
   return NS_ERROR_FAILURE; // enum values can't be added to each other
 }
 
 nsresult
 SMILEnumType::ComputeDistance(const nsSMILValue& aFrom,
                               const nsSMILValue& aTo,
                               double& aDistance) const
 {
-  NS_PRECONDITION(aFrom.mType == aTo.mType,"Trying to compare different types");
-  NS_PRECONDITION(aFrom.mType == this, "Unexpected source type");
+  MOZ_ASSERT(aFrom.mType == aTo.mType,"Trying to compare different types");
+  MOZ_ASSERT(aFrom.mType == this, "Unexpected source type");
   return NS_ERROR_FAILURE; // there is no concept of distance between enum values
 }
 
 nsresult
 SMILEnumType::Interpolate(const nsSMILValue& aStartVal,
                           const nsSMILValue& aEndVal,
                           double aUnitDistance,
                           nsSMILValue& aResult) const
 {
-  NS_PRECONDITION(aStartVal.mType == aEndVal.mType,
+  MOZ_ASSERT(aStartVal.mType == aEndVal.mType,
       "Trying to interpolate different types");
-  NS_PRECONDITION(aStartVal.mType == this,
+  MOZ_ASSERT(aStartVal.mType == this,
       "Unexpected types for interpolation");
-  NS_PRECONDITION(aResult.mType   == this, "Unexpected result type");
+  MOZ_ASSERT(aResult.mType   == this, "Unexpected result type");
   return NS_ERROR_FAILURE; // enum values do not interpolate
 }
 
 } // namespace mozilla
--- a/dom/smil/SMILIntegerType.cpp
+++ b/dom/smil/SMILIntegerType.cpp
@@ -17,73 +17,72 @@ SMILIntegerType::Init(nsSMILValue& aValu
   MOZ_ASSERT(aValue.IsNull(), "Unexpected value type");
   aValue.mU.mInt = 0;
   aValue.mType = this;
 }
 
 void
 SMILIntegerType::Destroy(nsSMILValue& aValue) const
 {
-  NS_PRECONDITION(aValue.mType == this, "Unexpected SMIL value");
+  MOZ_ASSERT(aValue.mType == this, "Unexpected SMIL value");
   aValue.mU.mInt = 0;
   aValue.mType = nsSMILNullType::Singleton();
 }
 
 nsresult
 SMILIntegerType::Assign(nsSMILValue& aDest, const nsSMILValue& aSrc) const
 {
-  NS_PRECONDITION(aDest.mType == aSrc.mType, "Incompatible SMIL types");
-  NS_PRECONDITION(aDest.mType == this, "Unexpected SMIL value");
+  MOZ_ASSERT(aDest.mType == aSrc.mType, "Incompatible SMIL types");
+  MOZ_ASSERT(aDest.mType == this, "Unexpected SMIL value");
   aDest.mU.mInt = aSrc.mU.mInt;
   return NS_OK;
 }
 
 bool
 SMILIntegerType::IsEqual(const nsSMILValue& aLeft,
                          const nsSMILValue& aRight) const
 {
-  NS_PRECONDITION(aLeft.mType == aRight.mType, "Incompatible SMIL types");
-  NS_PRECONDITION(aLeft.mType == this, "Unexpected type for SMIL value");
+  MOZ_ASSERT(aLeft.mType == aRight.mType, "Incompatible SMIL types");
+  MOZ_ASSERT(aLeft.mType == this, "Unexpected type for SMIL value");
 
   return aLeft.mU.mInt == aRight.mU.mInt;
 }
 
 nsresult
 SMILIntegerType::Add(nsSMILValue& aDest, const nsSMILValue& aValueToAdd,
                      uint32_t aCount) const
 {
-  NS_PRECONDITION(aValueToAdd.mType == aDest.mType,
+  MOZ_ASSERT(aValueToAdd.mType == aDest.mType,
                   "Trying to add invalid types");
-  NS_PRECONDITION(aValueToAdd.mType == this, "Unexpected source type");
+  MOZ_ASSERT(aValueToAdd.mType == this, "Unexpected source type");
   aDest.mU.mInt += aValueToAdd.mU.mInt * aCount;
   return NS_OK;
 }
 
 nsresult
 SMILIntegerType::ComputeDistance(const nsSMILValue& aFrom,
                                  const nsSMILValue& aTo,
                                  double& aDistance) const
 {
-  NS_PRECONDITION(aFrom.mType == aTo.mType,"Trying to compare different types");
-  NS_PRECONDITION(aFrom.mType == this, "Unexpected source type");
+  MOZ_ASSERT(aFrom.mType == aTo.mType, "Trying to compare different types");
+  MOZ_ASSERT(aFrom.mType == this, "Unexpected source type");
   aDistance = fabs(double(aTo.mU.mInt - aFrom.mU.mInt));
   return NS_OK;
 }
 
 nsresult
 SMILIntegerType::Interpolate(const nsSMILValue& aStartVal,
                              const nsSMILValue& aEndVal,
                              double aUnitDistance,
                              nsSMILValue& aResult) const
 {
-  NS_PRECONDITION(aStartVal.mType == aEndVal.mType,
-                  "Trying to interpolate different types");
-  NS_PRECONDITION(aStartVal.mType == this,
-                  "Unexpected types for interpolation");
-  NS_PRECONDITION(aResult.mType   == this, "Unexpected result type");
+  MOZ_ASSERT(aStartVal.mType == aEndVal.mType,
+             "Trying to interpolate different types");
+  MOZ_ASSERT(aStartVal.mType == this, "Unexpected types for interpolation");
+  MOZ_ASSERT(aResult.mType   == this, "Unexpected result type");
 
   const double startVal   = double(aStartVal.mU.mInt);
   const double endVal     = double(aEndVal.mU.mInt);
   const double currentVal = startVal + (endVal - startVal) * aUnitDistance;
 
   // When currentVal is exactly midway between its two nearest integers, we
   // jump to the "next" integer to provide simple, easy to remember and
   // consistent behaviour (from the SMIL author's point of view).
--- a/dom/smil/SMILStringType.cpp
+++ b/dom/smil/SMILStringType.cpp
@@ -9,83 +9,82 @@
 #include "nsDebug.h"
 #include "nsString.h"
 
 namespace mozilla {
 
 void
 SMILStringType::Init(nsSMILValue& aValue) const
 {
-  NS_PRECONDITION(aValue.IsNull(), "Unexpected value type");
+  MOZ_ASSERT(aValue.IsNull(), "Unexpected value type");
   aValue.mU.mPtr = new nsString();
   aValue.mType = this;
 }
 
 void
 SMILStringType::Destroy(nsSMILValue& aValue) const
 {
-  NS_PRECONDITION(aValue.mType == this, "Unexpected SMIL value");
+  MOZ_ASSERT(aValue.mType == this, "Unexpected SMIL value");
   delete static_cast<nsAString*>(aValue.mU.mPtr);
   aValue.mU.mPtr = nullptr;
   aValue.mType = nsSMILNullType::Singleton();
 }
 
 nsresult
 SMILStringType::Assign(nsSMILValue& aDest, const nsSMILValue& aSrc) const
 {
-  NS_PRECONDITION(aDest.mType == aSrc.mType, "Incompatible SMIL types");
-  NS_PRECONDITION(aDest.mType == this, "Unexpected SMIL value");
+  MOZ_ASSERT(aDest.mType == aSrc.mType, "Incompatible SMIL types");
+  MOZ_ASSERT(aDest.mType == this, "Unexpected SMIL value");
 
   const nsAString* src = static_cast<const nsAString*>(aSrc.mU.mPtr);
   nsAString* dst = static_cast<nsAString*>(aDest.mU.mPtr);
   *dst = *src;
   return NS_OK;
 }
 
 bool
 SMILStringType::IsEqual(const nsSMILValue& aLeft,
                         const nsSMILValue& aRight) const
 {
-  NS_PRECONDITION(aLeft.mType == aRight.mType, "Incompatible SMIL types");
-  NS_PRECONDITION(aLeft.mType == this, "Unexpected type for SMIL value");
+  MOZ_ASSERT(aLeft.mType == aRight.mType, "Incompatible SMIL types");
+  MOZ_ASSERT(aLeft.mType == this, "Unexpected type for SMIL value");
 
   const nsAString* leftString =
     static_cast<const nsAString*>(aLeft.mU.mPtr);
   const nsAString* rightString =
     static_cast<nsAString*>(aRight.mU.mPtr);
   return *leftString == *rightString;
 }
 
 nsresult
 SMILStringType::Add(nsSMILValue& aDest, const nsSMILValue& aValueToAdd,
                     uint32_t aCount) const
 {
-  NS_PRECONDITION(aValueToAdd.mType == aDest.mType,
+  MOZ_ASSERT(aValueToAdd.mType == aDest.mType,
                   "Trying to add invalid types");
-  NS_PRECONDITION(aValueToAdd.mType == this, "Unexpected source type");
+  MOZ_ASSERT(aValueToAdd.mType == this, "Unexpected source type");
   return NS_ERROR_FAILURE; // string values can't be added to each other
 }
 
 nsresult
 SMILStringType::ComputeDistance(const nsSMILValue& aFrom,
                                 const nsSMILValue& aTo,
                                 double& aDistance) const
 {
-  NS_PRECONDITION(aFrom.mType == aTo.mType,"Trying to compare different types");
-  NS_PRECONDITION(aFrom.mType == this, "Unexpected source type");
+  MOZ_ASSERT(aFrom.mType == aTo.mType, "Trying to compare different types");
+  MOZ_ASSERT(aFrom.mType == this, "Unexpected source type");
   return NS_ERROR_FAILURE; // there is no concept of distance between string values
 }
 
 nsresult
 SMILStringType::Interpolate(const nsSMILValue& aStartVal,
                             const nsSMILValue& aEndVal,
                             double aUnitDistance,
                             nsSMILValue& aResult) const
 {
-  NS_PRECONDITION(aStartVal.mType == aEndVal.mType,
-      "Trying to interpolate different types");
-  NS_PRECONDITION(aStartVal.mType == this,
-      "Unexpected types for interpolation");
-  NS_PRECONDITION(aResult.mType   == this, "Unexpected result type");
+  MOZ_ASSERT(aStartVal.mType == aEndVal.mType,
+             "Trying to interpolate different types");
+  MOZ_ASSERT(aStartVal.mType == this, "Unexpected types for interpolation");
+  MOZ_ASSERT(aResult.mType   == this, "Unexpected result type");
   return NS_ERROR_FAILURE; // string values do not interpolate
 }
 
 } // namespace mozilla
--- a/dom/smil/nsSMILFloatType.cpp
+++ b/dom/smil/nsSMILFloatType.cpp
@@ -7,86 +7,86 @@
 #include "nsSMILFloatType.h"
 #include "nsSMILValue.h"
 #include "nsDebug.h"
 #include <math.h>
 
 void
 nsSMILFloatType::Init(nsSMILValue& aValue) const
 {
-  NS_PRECONDITION(aValue.IsNull(), "Unexpected value type");
+  MOZ_ASSERT(aValue.IsNull(), "Unexpected value type");
   aValue.mU.mDouble = 0.0;
   aValue.mType = this;
 }
 
 void
 nsSMILFloatType::Destroy(nsSMILValue& aValue) const
 {
-  NS_PRECONDITION(aValue.mType == this, "Unexpected SMIL value");
+  MOZ_ASSERT(aValue.mType == this, "Unexpected SMIL value");
   aValue.mU.mDouble = 0.0;
   aValue.mType      = nsSMILNullType::Singleton();
 }
 
 nsresult
 nsSMILFloatType::Assign(nsSMILValue& aDest, const nsSMILValue& aSrc) const
 {
-  NS_PRECONDITION(aDest.mType == aSrc.mType, "Incompatible SMIL types");
-  NS_PRECONDITION(aDest.mType == this, "Unexpected SMIL value");
+  MOZ_ASSERT(aDest.mType == aSrc.mType, "Incompatible SMIL types");
+  MOZ_ASSERT(aDest.mType == this, "Unexpected SMIL value");
   aDest.mU.mDouble = aSrc.mU.mDouble;
   return NS_OK;
 }
 
 bool
 nsSMILFloatType::IsEqual(const nsSMILValue& aLeft,
                          const nsSMILValue& aRight) const
 {
-  NS_PRECONDITION(aLeft.mType == aRight.mType, "Incompatible SMIL types");
-  NS_PRECONDITION(aLeft.mType == this, "Unexpected type for SMIL value");
+  MOZ_ASSERT(aLeft.mType == aRight.mType, "Incompatible SMIL types");
+  MOZ_ASSERT(aLeft.mType == this, "Unexpected type for SMIL value");
 
   return aLeft.mU.mDouble == aRight.mU.mDouble;
 }
 
 nsresult
 nsSMILFloatType::Add(nsSMILValue& aDest, const nsSMILValue& aValueToAdd,
                      uint32_t aCount) const
 {
-  NS_PRECONDITION(aValueToAdd.mType == aDest.mType,
+  MOZ_ASSERT(aValueToAdd.mType == aDest.mType,
                   "Trying to add invalid types");
-  NS_PRECONDITION(aValueToAdd.mType == this, "Unexpected source type");
+  MOZ_ASSERT(aValueToAdd.mType == this, "Unexpected source type");
   aDest.mU.mDouble += aValueToAdd.mU.mDouble * aCount;
   return NS_OK;
 }
 
 nsresult
 nsSMILFloatType::ComputeDistance(const nsSMILValue& aFrom,
                                  const nsSMILValue& aTo,
                                  double& aDistance) const
 {
-  NS_PRECONDITION(aFrom.mType == aTo.mType,"Trying to compare different types");
-  NS_PRECONDITION(aFrom.mType == this, "Unexpected source type");
+  MOZ_ASSERT(aFrom.mType == aTo.mType, "Trying to compare different types");
+  MOZ_ASSERT(aFrom.mType == this, "Unexpected source type");
 
   const double &from = aFrom.mU.mDouble;
   const double &to   = aTo.mU.mDouble;
 
   aDistance = fabs(to - from);
 
   return NS_OK;
 }
 
 nsresult
 nsSMILFloatType::Interpolate(const nsSMILValue& aStartVal,
                              const nsSMILValue& aEndVal,
                              double aUnitDistance,
                              nsSMILValue& aResult) const
 {
-  NS_PRECONDITION(aStartVal.mType == aEndVal.mType,
-      "Trying to interpolate different types");
-  NS_PRECONDITION(aStartVal.mType == this,
+  MOZ_ASSERT(aStartVal.mType == aEndVal.mType,
+             "Trying to interpolate different types");
+  MOZ_ASSERT(aStartVal.mType == this,
       "Unexpected types for interpolation");
-  NS_PRECONDITION(aResult.mType   == this, "Unexpected result type");
+  MOZ_ASSERT(aResult.mType   == this, "Unexpected result type");
 
   const double &startVal = aStartVal.mU.mDouble;
   const double &endVal   = aEndVal.mU.mDouble;
 
   aResult.mU.mDouble = (startVal + (endVal - startVal) * aUnitDistance);
 
   return NS_OK;
 }
--- a/dom/smil/nsSMILNullType.cpp
+++ b/dom/smil/nsSMILNullType.cpp
@@ -13,29 +13,29 @@ nsSMILNullType::Singleton()
 {
   static nsSMILNullType sSingleton;
   return &sSingleton;
 }
 
 nsresult
 nsSMILNullType::Assign(nsSMILValue& aDest, const nsSMILValue& aSrc) const
 {
-  NS_PRECONDITION(aDest.mType == aSrc.mType, "Incompatible SMIL types");
-  NS_PRECONDITION(aSrc.mType == this, "Unexpected source type");
+  MOZ_ASSERT(aDest.mType == aSrc.mType, "Incompatible SMIL types");
+  MOZ_ASSERT(aSrc.mType == this, "Unexpected source type");
   aDest.mU    = aSrc.mU;
   aDest.mType = Singleton();
   return NS_OK;
 }
 
 bool
 nsSMILNullType::IsEqual(const nsSMILValue& aLeft,
                         const nsSMILValue& aRight) const
 {
-  NS_PRECONDITION(aLeft.mType == aRight.mType, "Incompatible SMIL types");
-  NS_PRECONDITION(aLeft.mType == this, "Unexpected type for SMIL value");
+  MOZ_ASSERT(aLeft.mType == aRight.mType, "Incompatible SMIL types");
+  MOZ_ASSERT(aLeft.mType == this, "Unexpected type for SMIL value");
 
   return true;  // All null-typed values are equivalent.
 }
 
 nsresult
 nsSMILNullType::Add(nsSMILValue& aDest, const nsSMILValue& aValueToAdd,
                     uint32_t aCount) const
 {
--- a/dom/svg/SVGIntegerPairSMILType.cpp
+++ b/dom/svg/SVGIntegerPairSMILType.cpp
@@ -19,85 +19,84 @@ SVGIntegerPairSMILType::Init(nsSMILValue
   aValue.mU.mIntPair[0] = 0;
   aValue.mU.mIntPair[1] = 0;
   aValue.mType = this;
 }
 
 void
 SVGIntegerPairSMILType::Destroy(nsSMILValue& aValue) const
 {
-  NS_PRECONDITION(aValue.mType == this, "Unexpected SMIL value");
+  MOZ_ASSERT(aValue.mType == this, "Unexpected SMIL value");
   aValue.mU.mIntPair[0] = 0;
   aValue.mU.mIntPair[1] = 0;
   aValue.mType = nsSMILNullType::Singleton();
 }
 
 nsresult
 SVGIntegerPairSMILType::Assign(nsSMILValue& aDest, const nsSMILValue& aSrc) const
 {
-  NS_PRECONDITION(aDest.mType == aSrc.mType, "Incompatible SMIL types");
-  NS_PRECONDITION(aDest.mType == this, "Unexpected SMIL value");
+  MOZ_ASSERT(aDest.mType == aSrc.mType, "Incompatible SMIL types");
+  MOZ_ASSERT(aDest.mType == this, "Unexpected SMIL value");
 
   aDest.mU.mIntPair[0] = aSrc.mU.mIntPair[0];
   aDest.mU.mIntPair[1] = aSrc.mU.mIntPair[1];
   return NS_OK;
 }
 
 bool
 SVGIntegerPairSMILType::IsEqual(const nsSMILValue& aLeft,
                                 const nsSMILValue& aRight) const
 {
-  NS_PRECONDITION(aLeft.mType == aRight.mType, "Incompatible SMIL types");
-  NS_PRECONDITION(aLeft.mType == this, "Unexpected type for SMIL value");
+  MOZ_ASSERT(aLeft.mType == aRight.mType, "Incompatible SMIL types");
+  MOZ_ASSERT(aLeft.mType == this, "Unexpected type for SMIL value");
 
   return aLeft.mU.mIntPair[0] == aRight.mU.mIntPair[0] &&
          aLeft.mU.mIntPair[1] == aRight.mU.mIntPair[1];
 }
 
 nsresult
 SVGIntegerPairSMILType::Add(nsSMILValue& aDest, const nsSMILValue& aValueToAdd,
                             uint32_t aCount) const
 {
-  NS_PRECONDITION(aValueToAdd.mType == aDest.mType,
+  MOZ_ASSERT(aValueToAdd.mType == aDest.mType,
                   "Trying to add invalid types");
-  NS_PRECONDITION(aValueToAdd.mType == this, "Unexpected source type");
+  MOZ_ASSERT(aValueToAdd.mType == this, "Unexpected source type");
 
   aDest.mU.mIntPair[0] += aValueToAdd.mU.mIntPair[0] * aCount;
   aDest.mU.mIntPair[1] += aValueToAdd.mU.mIntPair[1] * aCount;
 
   return NS_OK;
 }
 
 nsresult
 SVGIntegerPairSMILType::ComputeDistance(const nsSMILValue& aFrom,
                                         const nsSMILValue& aTo,
                                         double& aDistance) const
 {
-  NS_PRECONDITION(aFrom.mType == aTo.mType,"Trying to compare different types");
-  NS_PRECONDITION(aFrom.mType == this, "Unexpected source type");
+  MOZ_ASSERT(aFrom.mType == aTo.mType,"Trying to compare different types");
+  MOZ_ASSERT(aFrom.mType == this, "Unexpected source type");
 
   double delta[2];
   delta[0] = aTo.mU.mIntPair[0] - aFrom.mU.mIntPair[0];
   delta[1] = aTo.mU.mIntPair[1] - aFrom.mU.mIntPair[1];
 
   aDistance = NS_hypot(delta[0], delta[1]);
   return NS_OK;
 }
 
 nsresult
 SVGIntegerPairSMILType::Interpolate(const nsSMILValue& aStartVal,
                                     const nsSMILValue& aEndVal,
                                     double aUnitDistance,
                                     nsSMILValue& aResult) const
 {
-  NS_PRECONDITION(aStartVal.mType == aEndVal.mType,
-                  "Trying to interpolate different types");
-  NS_PRECONDITION(aStartVal.mType == this,
-                  "Unexpected types for interpolation");
-  NS_PRECONDITION(aResult.mType == this, "Unexpected result type");
+  MOZ_ASSERT(aStartVal.mType == aEndVal.mType,
+             "Trying to interpolate different types");
+  MOZ_ASSERT(aStartVal.mType == this, "Unexpected types for interpolation");
+  MOZ_ASSERT(aResult.mType == this, "Unexpected result type");
 
   double currentVal[2];
   currentVal[0] = aStartVal.mU.mIntPair[0] +
                   (aEndVal.mU.mIntPair[0] - aStartVal.mU.mIntPair[0]) * aUnitDistance;
   currentVal[1] = aStartVal.mU.mIntPair[1] +
                   (aEndVal.mU.mIntPair[1] - aStartVal.mU.mIntPair[1]) * aUnitDistance;
 
   aResult.mU.mIntPair[0] = NS_lround(currentVal[0]);
--- a/dom/svg/SVGLengthListSMILType.cpp
+++ b/dom/svg/SVGLengthListSMILType.cpp
@@ -31,55 +31,55 @@ SVGLengthListSMILType::Init(nsSMILValue 
 
   aValue.mU.mPtr = lengthList;
   aValue.mType = this;
 }
 
 void
 SVGLengthListSMILType::Destroy(nsSMILValue& aValue) const
 {
-  NS_PRECONDITION(aValue.mType == this, "Unexpected SMIL value type");
+  MOZ_ASSERT(aValue.mType == this, "Unexpected SMIL value type");
   delete static_cast<SVGLengthListAndInfo*>(aValue.mU.mPtr);
   aValue.mU.mPtr = nullptr;
   aValue.mType = nsSMILNullType::Singleton();
 }
 
 nsresult
 SVGLengthListSMILType::Assign(nsSMILValue& aDest,
                               const nsSMILValue& aSrc) const
 {
-  NS_PRECONDITION(aDest.mType == aSrc.mType, "Incompatible SMIL types");
-  NS_PRECONDITION(aDest.mType == this, "Unexpected SMIL value");
+  MOZ_ASSERT(aDest.mType == aSrc.mType, "Incompatible SMIL types");
+  MOZ_ASSERT(aDest.mType == this, "Unexpected SMIL value");
 
   const SVGLengthListAndInfo* src =
     static_cast<const SVGLengthListAndInfo*>(aSrc.mU.mPtr);
   SVGLengthListAndInfo* dest =
     static_cast<SVGLengthListAndInfo*>(aDest.mU.mPtr);
 
   return dest->CopyFrom(*src);
 }
 
 bool
 SVGLengthListSMILType::IsEqual(const nsSMILValue& aLeft,
                                const nsSMILValue& aRight) const
 {
-  NS_PRECONDITION(aLeft.mType == aRight.mType, "Incompatible SMIL types");
-  NS_PRECONDITION(aLeft.mType == this, "Unexpected type for SMIL value");
+  MOZ_ASSERT(aLeft.mType == aRight.mType, "Incompatible SMIL types");
+  MOZ_ASSERT(aLeft.mType == this, "Unexpected type for SMIL value");
 
   return *static_cast<const SVGLengthListAndInfo*>(aLeft.mU.mPtr) ==
          *static_cast<const SVGLengthListAndInfo*>(aRight.mU.mPtr);
 }
 
 nsresult
 SVGLengthListSMILType::Add(nsSMILValue& aDest,
                            const nsSMILValue& aValueToAdd,
                            uint32_t aCount) const
 {
-  NS_PRECONDITION(aDest.mType == this, "Unexpected SMIL type");
-  NS_PRECONDITION(aValueToAdd.mType == this, "Incompatible SMIL type");
+  MOZ_ASSERT(aDest.mType == this, "Unexpected SMIL type");
+  MOZ_ASSERT(aValueToAdd.mType == this, "Incompatible SMIL type");
 
   SVGLengthListAndInfo& dest =
     *static_cast<SVGLengthListAndInfo*>(aDest.mU.mPtr);
   const SVGLengthListAndInfo& valueToAdd =
     *static_cast<const SVGLengthListAndInfo*>(aValueToAdd.mU.mPtr);
 
   // To understand this code, see the comments documenting our Init() method,
   // and documenting SVGLengthListAndInfo::CanZeroPadList().
@@ -156,18 +156,18 @@ SVGLengthListSMILType::Add(nsSMILValue& 
   return NS_OK;
 }
 
 nsresult
 SVGLengthListSMILType::ComputeDistance(const nsSMILValue& aFrom,
                                        const nsSMILValue& aTo,
                                        double& aDistance) const
 {
-  NS_PRECONDITION(aFrom.mType == this, "Unexpected SMIL type");
-  NS_PRECONDITION(aTo.mType == this, "Incompatible SMIL type");
+  MOZ_ASSERT(aFrom.mType == this, "Unexpected SMIL type");
+  MOZ_ASSERT(aTo.mType == this, "Incompatible SMIL type");
 
   const SVGLengthListAndInfo& from =
     *static_cast<const SVGLengthListAndInfo*>(aFrom.mU.mPtr);
   const SVGLengthListAndInfo& to =
     *static_cast<const SVGLengthListAndInfo*>(aTo.mU.mPtr);
 
   // To understand this code, see the comments documenting our Init() method,
   // and documenting SVGLengthListAndInfo::CanZeroPadList().
@@ -226,21 +226,20 @@ SVGLengthListSMILType::ComputeDistance(c
 }
 
 nsresult
 SVGLengthListSMILType::Interpolate(const nsSMILValue& aStartVal,
                                    const nsSMILValue& aEndVal,
                                    double aUnitDistance,
                                    nsSMILValue& aResult) const
 {
-  NS_PRECONDITION(aStartVal.mType == aEndVal.mType,
-                  "Trying to interpolate different types");
-  NS_PRECONDITION(aStartVal.mType == this,
-                  "Unexpected types for interpolation");
-  NS_PRECONDITION(aResult.mType == this, "Unexpected result type");
+  MOZ_ASSERT(aStartVal.mType == aEndVal.mType,
+             "Trying to interpolate different types");
+  MOZ_ASSERT(aStartVal.mType == this, "Unexpected types for interpolation");
+  MOZ_ASSERT(aResult.mType == this, "Unexpected result type");
 
   const SVGLengthListAndInfo& start =
     *static_cast<const SVGLengthListAndInfo*>(aStartVal.mU.mPtr);
   const SVGLengthListAndInfo& end =
     *static_cast<const SVGLengthListAndInfo*>(aEndVal.mU.mPtr);
   SVGLengthListAndInfo& result =
     *static_cast<SVGLengthListAndInfo*>(aResult.mU.mPtr);
 
--- a/dom/svg/SVGNumberListSMILType.cpp
+++ b/dom/svg/SVGNumberListSMILType.cpp
@@ -44,55 +44,55 @@ SVGNumberListSMILType::Init(nsSMILValue 
 
   aValue.mU.mPtr = numberList;
   aValue.mType = this;
 }
 
 void
 SVGNumberListSMILType::Destroy(nsSMILValue& aValue) const
 {
-  NS_PRECONDITION(aValue.mType == this, "Unexpected SMIL value type");
+  MOZ_ASSERT(aValue.mType == this, "Unexpected SMIL value type");
   delete static_cast<SVGNumberListAndInfo*>(aValue.mU.mPtr);
   aValue.mU.mPtr = nullptr;
   aValue.mType = nsSMILNullType::Singleton();
 }
 
 nsresult
 SVGNumberListSMILType::Assign(nsSMILValue& aDest,
                               const nsSMILValue& aSrc) const
 {
-  NS_PRECONDITION(aDest.mType == aSrc.mType, "Incompatible SMIL types");
-  NS_PRECONDITION(aDest.mType == this, "Unexpected SMIL value");
+  MOZ_ASSERT(aDest.mType == aSrc.mType, "Incompatible SMIL types");
+  MOZ_ASSERT(aDest.mType == this, "Unexpected SMIL value");
 
   const SVGNumberListAndInfo* src =
     static_cast<const SVGNumberListAndInfo*>(aSrc.mU.mPtr);
   SVGNumberListAndInfo* dest =
     static_cast<SVGNumberListAndInfo*>(aDest.mU.mPtr);
 
   return dest->CopyFrom(*src);
 }
 
 bool
 SVGNumberListSMILType::IsEqual(const nsSMILValue& aLeft,
                                const nsSMILValue& aRight) const
 {
-  NS_PRECONDITION(aLeft.mType == aRight.mType, "Incompatible SMIL types");
-  NS_PRECONDITION(aLeft.mType == this, "Unexpected type for SMIL value");
+  MOZ_ASSERT(aLeft.mType == aRight.mType, "Incompatible SMIL types");
+  MOZ_ASSERT(aLeft.mType == this, "Unexpected type for SMIL value");
 
   return *static_cast<const SVGNumberListAndInfo*>(aLeft.mU.mPtr) ==
          *static_cast<const SVGNumberListAndInfo*>(aRight.mU.mPtr);
 }
 
 nsresult
 SVGNumberListSMILType::Add(nsSMILValue& aDest,
                            const nsSMILValue& aValueToAdd,
                            uint32_t aCount) const
 {
-  NS_PRECONDITION(aDest.mType == this, "Unexpected SMIL type");
-  NS_PRECONDITION(aValueToAdd.mType == this, "Incompatible SMIL type");
+  MOZ_ASSERT(aDest.mType == this, "Unexpected SMIL type");
+  MOZ_ASSERT(aValueToAdd.mType == this, "Incompatible SMIL type");
 
   SVGNumberListAndInfo& dest =
     *static_cast<SVGNumberListAndInfo*>(aDest.mU.mPtr);
   const SVGNumberListAndInfo& valueToAdd =
     *static_cast<const SVGNumberListAndInfo*>(aValueToAdd.mU.mPtr);
 
   MOZ_ASSERT(dest.Element() || valueToAdd.Element(),
              "Target element propagation failure");
@@ -128,18 +128,18 @@ SVGNumberListSMILType::Add(nsSMILValue& 
   return NS_OK;
 }
 
 nsresult
 SVGNumberListSMILType::ComputeDistance(const nsSMILValue& aFrom,
                                        const nsSMILValue& aTo,
                                        double& aDistance) const
 {
-  NS_PRECONDITION(aFrom.mType == this, "Unexpected SMIL type");
-  NS_PRECONDITION(aTo.mType == this, "Incompatible SMIL type");
+  MOZ_ASSERT(aFrom.mType == this, "Unexpected SMIL type");
+  MOZ_ASSERT(aTo.mType == this, "Incompatible SMIL type");
 
   const SVGNumberListAndInfo& from =
     *static_cast<const SVGNumberListAndInfo*>(aFrom.mU.mPtr);
   const SVGNumberListAndInfo& to =
     *static_cast<const SVGNumberListAndInfo*>(aTo.mU.mPtr);
 
   if (from.Length() != to.Length()) {
     // Lists in the 'values' attribute must have the same length.
@@ -166,21 +166,20 @@ SVGNumberListSMILType::ComputeDistance(c
 }
 
 nsresult
 SVGNumberListSMILType::Interpolate(const nsSMILValue& aStartVal,
                                    const nsSMILValue& aEndVal,
                                    double aUnitDistance,
                                    nsSMILValue& aResult) const
 {
-  NS_PRECONDITION(aStartVal.mType == aEndVal.mType,
-                  "Trying to interpolate different types");
-  NS_PRECONDITION(aStartVal.mType == this,
-                  "Unexpected types for interpolation");
-  NS_PRECONDITION(aResult.mType == this, "Unexpected result type");
+  MOZ_ASSERT(aStartVal.mType == aEndVal.mType,
+             "Trying to interpolate different types");
+  MOZ_ASSERT(aStartVal.mType == this, "Unexpected types for interpolation");
+  MOZ_ASSERT(aResult.mType == this, "Unexpected result type");
 
   const SVGNumberListAndInfo& start =
     *static_cast<const SVGNumberListAndInfo*>(aStartVal.mU.mPtr);
   const SVGNumberListAndInfo& end =
     *static_cast<const SVGNumberListAndInfo*>(aEndVal.mU.mPtr);
   SVGNumberListAndInfo& result =
     *static_cast<SVGNumberListAndInfo*>(aResult.mU.mPtr);
 
--- a/dom/svg/SVGNumberPairSMILType.cpp
+++ b/dom/svg/SVGNumberPairSMILType.cpp
@@ -21,85 +21,84 @@ SVGNumberPairSMILType::Init(nsSMILValue&
   aValue.mU.mNumberPair[0] = 0;
   aValue.mU.mNumberPair[1] = 0;
   aValue.mType = this;
 }
 
 void
 SVGNumberPairSMILType::Destroy(nsSMILValue& aValue) const
 {
-  NS_PRECONDITION(aValue.mType == this, "Unexpected SMIL value");
+  MOZ_ASSERT(aValue.mType == this, "Unexpected SMIL value");
   aValue.mU.mNumberPair[0] = 0;
   aValue.mU.mNumberPair[1] = 0;
   aValue.mType = nsSMILNullType::Singleton();
 }
 
 nsresult
 SVGNumberPairSMILType::Assign(nsSMILValue& aDest, const nsSMILValue& aSrc) const
 {
-  NS_PRECONDITION(aDest.mType == aSrc.mType, "Incompatible SMIL types");
-  NS_PRECONDITION(aDest.mType == this, "Unexpected SMIL value");
+  MOZ_ASSERT(aDest.mType == aSrc.mType, "Incompatible SMIL types");
+  MOZ_ASSERT(aDest.mType == this, "Unexpected SMIL value");
 
   aDest.mU.mNumberPair[0] = aSrc.mU.mNumberPair[0];
   aDest.mU.mNumberPair[1] = aSrc.mU.mNumberPair[1];
   return NS_OK;
 }
 
 bool
 SVGNumberPairSMILType::IsEqual(const nsSMILValue& aLeft,
                                const nsSMILValue& aRight) const
 {
-  NS_PRECONDITION(aLeft.mType == aRight.mType, "Incompatible SMIL types");
-  NS_PRECONDITION(aLeft.mType == this, "Unexpected type for SMIL value");
+  MOZ_ASSERT(aLeft.mType == aRight.mType, "Incompatible SMIL types");
+  MOZ_ASSERT(aLeft.mType == this, "Unexpected type for SMIL value");
 
   return aLeft.mU.mNumberPair[0] == aRight.mU.mNumberPair[0] &&
          aLeft.mU.mNumberPair[1] == aRight.mU.mNumberPair[1];
 }
 
 nsresult
 SVGNumberPairSMILType::Add(nsSMILValue& aDest, const nsSMILValue& aValueToAdd,
                            uint32_t aCount) const
 {
-  NS_PRECONDITION(aValueToAdd.mType == aDest.mType,
+  MOZ_ASSERT(aValueToAdd.mType == aDest.mType,
                   "Trying to add invalid types");
-  NS_PRECONDITION(aValueToAdd.mType == this, "Unexpected source type");
+  MOZ_ASSERT(aValueToAdd.mType == this, "Unexpected source type");
 
   aDest.mU.mNumberPair[0] += aValueToAdd.mU.mNumberPair[0] * aCount;
   aDest.mU.mNumberPair[1] += aValueToAdd.mU.mNumberPair[1] * aCount;
 
   return NS_OK;
 }
 
 nsresult
 SVGNumberPairSMILType::ComputeDistance(const nsSMILValue& aFrom,
                                        const nsSMILValue& aTo,
                                        double& aDistance) const
 {
-  NS_PRECONDITION(aFrom.mType == aTo.mType,"Trying to compare different types");
-  NS_PRECONDITION(aFrom.mType == this, "Unexpected source type");
+  MOZ_ASSERT(aFrom.mType == aTo.mType,"Trying to compare different types");
+  MOZ_ASSERT(aFrom.mType == this, "Unexpected source type");
 
   double delta[2];
   delta[0] = aTo.mU.mNumberPair[0] - aFrom.mU.mNumberPair[0];
   delta[1] = aTo.mU.mNumberPair[1] - aFrom.mU.mNumberPair[1];
 
   aDistance = NS_hypot(delta[0], delta[1]);
   return NS_OK;
 }
 
 nsresult
 SVGNumberPairSMILType::Interpolate(const nsSMILValue& aStartVal,
                                    const nsSMILValue& aEndVal,
                                    double aUnitDistance,
                                    nsSMILValue& aResult) const
 {
-  NS_PRECONDITION(aStartVal.mType == aEndVal.mType,
-                  "Trying to interpolate different types");
-  NS_PRECONDITION(aStartVal.mType == this,
-                  "Unexpected types for interpolation");
-  NS_PRECONDITION(aResult.mType == this, "Unexpected result type");
+  MOZ_ASSERT(aStartVal.mType == aEndVal.mType,
+             "Trying to interpolate different types");
+  MOZ_ASSERT(aStartVal.mType == this, "Unexpected types for interpolation");
+  MOZ_ASSERT(aResult.mType == this, "Unexpected result type");
 
   aResult.mU.mNumberPair[0] =
     float(aStartVal.mU.mNumberPair[0] +
           (aEndVal.mU.mNumberPair[0] - aStartVal.mU.mNumberPair[0]) * aUnitDistance);
   aResult.mU.mNumberPair[1] =
     float(aStartVal.mU.mNumberPair[1] +
           (aEndVal.mU.mNumberPair[1] - aStartVal.mU.mNumberPair[1]) * aUnitDistance);
   return NS_OK;
--- a/dom/svg/SVGOrientSMILType.cpp
+++ b/dom/svg/SVGOrientSMILType.cpp
@@ -27,53 +27,53 @@ SVGOrientSMILType::Init(nsSMILValue& aVa
   aValue.mU.mOrient.mUnit = SVG_ANGLETYPE_UNSPECIFIED;
   aValue.mU.mOrient.mOrientType = SVG_MARKER_ORIENT_ANGLE;
   aValue.mType = this;
 }
 
 void
 SVGOrientSMILType::Destroy(nsSMILValue& aValue) const
 {
-  NS_PRECONDITION(aValue.mType == this, "Unexpected SMIL value.");
+  MOZ_ASSERT(aValue.mType == this, "Unexpected SMIL value.");
   aValue.mU.mPtr = nullptr;
   aValue.mType = nsSMILNullType::Singleton();
 }
 
 nsresult
 SVGOrientSMILType::Assign(nsSMILValue& aDest, const nsSMILValue& aSrc) const
 {
-  NS_PRECONDITION(aDest.mType == aSrc.mType, "Incompatible SMIL types.");
-  NS_PRECONDITION(aDest.mType == this, "Unexpected SMIL value.");
+  MOZ_ASSERT(aDest.mType == aSrc.mType, "Incompatible SMIL types.");
+  MOZ_ASSERT(aDest.mType == this, "Unexpected SMIL value.");
 
   aDest.mU.mOrient.mAngle = aSrc.mU.mOrient.mAngle;
   aDest.mU.mOrient.mUnit = aSrc.mU.mOrient.mUnit;
   aDest.mU.mOrient.mOrientType = aSrc.mU.mOrient.mOrientType;
   return NS_OK;
 }
 
 bool
 SVGOrientSMILType::IsEqual(const nsSMILValue& aLeft,
                            const nsSMILValue& aRight) const
 {
-  NS_PRECONDITION(aLeft.mType == aRight.mType, "Incompatible SMIL types");
-  NS_PRECONDITION(aLeft.mType == this, "Unexpected type for SMIL value");
+  MOZ_ASSERT(aLeft.mType == aRight.mType, "Incompatible SMIL types");
+  MOZ_ASSERT(aLeft.mType == this, "Unexpected type for SMIL value");
 
   return
     aLeft.mU.mOrient.mAngle == aRight.mU.mOrient.mAngle &&
     aLeft.mU.mOrient.mUnit == aRight.mU.mOrient.mUnit &&
     aLeft.mU.mOrient.mOrientType == aRight.mU.mOrient.mOrientType;
 }
 
 nsresult
 SVGOrientSMILType::Add(nsSMILValue& aDest, const nsSMILValue& aValueToAdd,
                        uint32_t aCount) const
 {
-  NS_PRECONDITION(aValueToAdd.mType == aDest.mType,
+  MOZ_ASSERT(aValueToAdd.mType == aDest.mType,
                   "Trying to add invalid types");
-  NS_PRECONDITION(aValueToAdd.mType == this, "Unexpected source type");
+  MOZ_ASSERT(aValueToAdd.mType == this, "Unexpected source type");
 
   if (aDest.mU.mOrient.mOrientType != SVG_MARKER_ORIENT_ANGLE ||
       aValueToAdd.mU.mOrient.mOrientType != SVG_MARKER_ORIENT_ANGLE) {
     // TODO: it would be nice to be able to add to auto angles
     return NS_ERROR_FAILURE;
   }
 
   // We may be dealing with two different angle units, so we normalize to
@@ -93,18 +93,18 @@ SVGOrientSMILType::Add(nsSMILValue& aDes
   return NS_OK;
 }
 
 nsresult
 SVGOrientSMILType::ComputeDistance(const nsSMILValue& aFrom,
                                    const nsSMILValue& aTo,
                                    double& aDistance) const
 {
-  NS_PRECONDITION(aFrom.mType == aTo.mType,"Trying to compare different types");
-  NS_PRECONDITION(aFrom.mType == this, "Unexpected source type");
+  MOZ_ASSERT(aFrom.mType == aTo.mType,"Trying to compare different types");
+  MOZ_ASSERT(aFrom.mType == this, "Unexpected source type");
 
   if (aFrom.mU.mOrient.mOrientType != SVG_MARKER_ORIENT_ANGLE ||
       aTo.mU.mOrient.mOrientType != SVG_MARKER_ORIENT_ANGLE) {
     // TODO: it would be nice to be able to compute distance with auto angles
     return NS_ERROR_FAILURE;
   }
 
   // Normalize both to degrees in case they're different angle units:
@@ -119,21 +119,20 @@ SVGOrientSMILType::ComputeDistance(const
 }
 
 nsresult
 SVGOrientSMILType::Interpolate(const nsSMILValue& aStartVal,
                                const nsSMILValue& aEndVal,
                                double aUnitDistance,
                                nsSMILValue& aResult) const
 {
-  NS_PRECONDITION(aStartVal.mType == aEndVal.mType,
-                  "Trying to interpolate different types");
-  NS_PRECONDITION(aStartVal.mType == this,
-                  "Unexpected types for interpolation.");
-  NS_PRECONDITION(aResult.mType   == this, "Unexpected result type.");
+  MOZ_ASSERT(aStartVal.mType == aEndVal.mType,
+             "Trying to interpolate different types");
+  MOZ_ASSERT(aStartVal.mType == this, "Unexpected types for interpolation.");
+  MOZ_ASSERT(aResult.mType   == this, "Unexpected result type.");
 
   if (aStartVal.mU.mOrient.mOrientType != SVG_MARKER_ORIENT_ANGLE ||
       aEndVal.mU.mOrient.mOrientType != SVG_MARKER_ORIENT_ANGLE) {
     // TODO: it would be nice to be able to handle auto angles too.
     return NS_ERROR_FAILURE;
   }
 
   float start  = aStartVal.mU.mOrient.mAngle *
--- a/dom/svg/SVGPathSegListSMILType.cpp
+++ b/dom/svg/SVGPathSegListSMILType.cpp
@@ -27,43 +27,43 @@ SVGPathSegListSMILType::Init(nsSMILValue
   MOZ_ASSERT(aValue.IsNull(), "Unexpected value type");
   aValue.mU.mPtr = new SVGPathDataAndInfo();
   aValue.mType = this;
 }
 
 void
 SVGPathSegListSMILType::Destroy(nsSMILValue& aValue) const
 {
-  NS_PRECONDITION(aValue.mType == this, "Unexpected SMIL value type");
+  MOZ_ASSERT(aValue.mType == this, "Unexpected SMIL value type");
   delete static_cast<SVGPathDataAndInfo*>(aValue.mU.mPtr);
   aValue.mU.mPtr = nullptr;
   aValue.mType = nsSMILNullType::Singleton();
 }
 
 nsresult
 SVGPathSegListSMILType::Assign(nsSMILValue& aDest,
                                const nsSMILValue& aSrc) const
 {
-  NS_PRECONDITION(aDest.mType == aSrc.mType, "Incompatible SMIL types");
-  NS_PRECONDITION(aDest.mType == this, "Unexpected SMIL value");
+  MOZ_ASSERT(aDest.mType == aSrc.mType, "Incompatible SMIL types");
+  MOZ_ASSERT(aDest.mType == this, "Unexpected SMIL value");
 
   const SVGPathDataAndInfo* src =
     static_cast<const SVGPathDataAndInfo*>(aSrc.mU.mPtr);
   SVGPathDataAndInfo* dest =
     static_cast<SVGPathDataAndInfo*>(aDest.mU.mPtr);
 
   return dest->CopyFrom(*src);
 }
 
 bool
 SVGPathSegListSMILType::IsEqual(const nsSMILValue& aLeft,
                                 const nsSMILValue& aRight) const
 {
-  NS_PRECONDITION(aLeft.mType == aRight.mType, "Incompatible SMIL types");
-  NS_PRECONDITION(aLeft.mType == this, "Unexpected type for SMIL value");
+  MOZ_ASSERT(aLeft.mType == aRight.mType, "Incompatible SMIL types");
+  MOZ_ASSERT(aLeft.mType == this, "Unexpected type for SMIL value");
 
   return *static_cast<const SVGPathDataAndInfo*>(aLeft.mU.mPtr) ==
          *static_cast<const SVGPathDataAndInfo*>(aRight.mU.mPtr);
 }
 
 static bool
 ArcFlagsDiffer(SVGPathDataAndInfo::const_iterator aPathData1,
                SVGPathDataAndInfo::const_iterator aPathData2)
@@ -395,18 +395,18 @@ ConvertAllPathSegmentData(SVGPathDataAnd
              "Failed to convert all path segment data! (Corrupt?)");
 }
 
 nsresult
 SVGPathSegListSMILType::Add(nsSMILValue& aDest,
                             const nsSMILValue& aValueToAdd,
                             uint32_t aCount) const
 {
-  NS_PRECONDITION(aDest.mType == this, "Unexpected SMIL type");
-  NS_PRECONDITION(aValueToAdd.mType == this, "Incompatible SMIL type");
+  MOZ_ASSERT(aDest.mType == this, "Unexpected SMIL type");
+  MOZ_ASSERT(aValueToAdd.mType == this, "Incompatible SMIL type");
 
   SVGPathDataAndInfo& dest =
     *static_cast<SVGPathDataAndInfo*>(aDest.mU.mPtr);
   const SVGPathDataAndInfo& valueToAdd =
     *static_cast<const SVGPathDataAndInfo*>(aValueToAdd.mU.mPtr);
 
   if (valueToAdd.IsIdentity()) { // Adding identity value - no-op
     return NS_OK;
@@ -435,36 +435,35 @@ SVGPathSegListSMILType::Add(nsSMILValue&
   return AddWeightedPathSegLists(1.0, dest, aCount, valueToAdd, dest);
 }
 
 nsresult
 SVGPathSegListSMILType::ComputeDistance(const nsSMILValue& aFrom,
                                         const nsSMILValue& aTo,
                                         double& aDistance) const
 {
-  NS_PRECONDITION(aFrom.mType == this, "Unexpected SMIL type");
-  NS_PRECONDITION(aTo.mType == this, "Incompatible SMIL type");
+  MOZ_ASSERT(aFrom.mType == this, "Unexpected SMIL type");
+  MOZ_ASSERT(aTo.mType == this, "Incompatible SMIL type");
 
   // See https://bugzilla.mozilla.org/show_bug.cgi?id=522306#c18
 
   // SVGContentUtils::ReportToConsole
   return NS_ERROR_NOT_IMPLEMENTED;
 }
 
 nsresult
 SVGPathSegListSMILType::Interpolate(const nsSMILValue& aStartVal,
                                     const nsSMILValue& aEndVal,
                                     double aUnitDistance,
                                     nsSMILValue& aResult) const
 {
-  NS_PRECONDITION(aStartVal.mType == aEndVal.mType,
-                  "Trying to interpolate different types");
-  NS_PRECONDITION(aStartVal.mType == this,
-                  "Unexpected types for interpolation");
-  NS_PRECONDITION(aResult.mType == this, "Unexpected result type");
+  MOZ_ASSERT(aStartVal.mType == aEndVal.mType,
+             "Trying to interpolate different types");
+  MOZ_ASSERT(aStartVal.mType == this, "Unexpected types for interpolation");
+  MOZ_ASSERT(aResult.mType == this, "Unexpected result type");
 
   const SVGPathDataAndInfo& start =
     *static_cast<const SVGPathDataAndInfo*>(aStartVal.mU.mPtr);
   const SVGPathDataAndInfo& end =
     *static_cast<const SVGPathDataAndInfo*>(aEndVal.mU.mPtr);
   SVGPathDataAndInfo& result =
     *static_cast<SVGPathDataAndInfo*>(aResult.mU.mPtr);
   MOZ_ASSERT(result.IsIdentity(),
--- a/dom/svg/SVGPointListSMILType.cpp
+++ b/dom/svg/SVGPointListSMILType.cpp
@@ -27,55 +27,55 @@ SVGPointListSMILType::Init(nsSMILValue &
 
   aValue.mU.mPtr = pointList;
   aValue.mType = this;
 }
 
 void
 SVGPointListSMILType::Destroy(nsSMILValue& aValue) const
 {
-  NS_PRECONDITION(aValue.mType == this, "Unexpected SMIL value type");
+  MOZ_ASSERT(aValue.mType == this, "Unexpected SMIL value type");
   delete static_cast<SVGPointListAndInfo*>(aValue.mU.mPtr);
   aValue.mU.mPtr = nullptr;
   aValue.mType = nsSMILNullType::Singleton();
 }
 
 nsresult
 SVGPointListSMILType::Assign(nsSMILValue& aDest,
                               const nsSMILValue& aSrc) const
 {
-  NS_PRECONDITION(aDest.mType == aSrc.mType, "Incompatible SMIL types");
-  NS_PRECONDITION(aDest.mType == this, "Unexpected SMIL value");
+  MOZ_ASSERT(aDest.mType == aSrc.mType, "Incompatible SMIL types");
+  MOZ_ASSERT(aDest.mType == this, "Unexpected SMIL value");
 
   const SVGPointListAndInfo* src =
     static_cast<const SVGPointListAndInfo*>(aSrc.mU.mPtr);
   SVGPointListAndInfo* dest =
     static_cast<SVGPointListAndInfo*>(aDest.mU.mPtr);
 
   return dest->CopyFrom(*src);
 }
 
 bool
 SVGPointListSMILType::IsEqual(const nsSMILValue& aLeft,
                                const nsSMILValue& aRight) const
 {
-  NS_PRECONDITION(aLeft.mType == aRight.mType, "Incompatible SMIL types");
-  NS_PRECONDITION(aLeft.mType == this, "Unexpected type for SMIL value");
+  MOZ_ASSERT(aLeft.mType == aRight.mType, "Incompatible SMIL types");
+  MOZ_ASSERT(aLeft.mType == this, "Unexpected type for SMIL value");
 
   return *static_cast<const SVGPointListAndInfo*>(aLeft.mU.mPtr) ==
          *static_cast<const SVGPointListAndInfo*>(aRight.mU.mPtr);
 }
 
 nsresult
 SVGPointListSMILType::Add(nsSMILValue& aDest,
                           const nsSMILValue& aValueToAdd,
                           uint32_t aCount) const
 {
-  NS_PRECONDITION(aDest.mType == this, "Unexpected SMIL type");
-  NS_PRECONDITION(aValueToAdd.mType == this, "Incompatible SMIL type");
+  MOZ_ASSERT(aDest.mType == this, "Unexpected SMIL type");
+  MOZ_ASSERT(aValueToAdd.mType == this, "Incompatible SMIL type");
 
   SVGPointListAndInfo& dest =
     *static_cast<SVGPointListAndInfo*>(aDest.mU.mPtr);
   const SVGPointListAndInfo& valueToAdd =
     *static_cast<const SVGPointListAndInfo*>(aValueToAdd.mU.mPtr);
 
   MOZ_ASSERT(dest.Element() || valueToAdd.Element(),
              "Target element propagation failure");
@@ -107,18 +107,18 @@ SVGPointListSMILType::Add(nsSMILValue& a
   return NS_OK;
 }
 
 nsresult
 SVGPointListSMILType::ComputeDistance(const nsSMILValue& aFrom,
                                       const nsSMILValue& aTo,
                                       double& aDistance) const
 {
-  NS_PRECONDITION(aFrom.mType == this, "Unexpected SMIL type");
-  NS_PRECONDITION(aTo.mType == this, "Incompatible SMIL type");
+  MOZ_ASSERT(aFrom.mType == this, "Unexpected SMIL type");
+  MOZ_ASSERT(aTo.mType == this, "Incompatible SMIL type");
 
   const SVGPointListAndInfo& from =
     *static_cast<const SVGPointListAndInfo*>(aFrom.mU.mPtr);
   const SVGPointListAndInfo& to =
     *static_cast<const SVGPointListAndInfo*>(aTo.mU.mPtr);
 
   if (from.Length() != to.Length()) {
     // Lists in the 'values' attribute must have the same length.
@@ -146,21 +146,20 @@ SVGPointListSMILType::ComputeDistance(co
 }
 
 nsresult
 SVGPointListSMILType::Interpolate(const nsSMILValue& aStartVal,
                                   const nsSMILValue& aEndVal,
                                   double aUnitDistance,
                                   nsSMILValue& aResult) const
 {
-  NS_PRECONDITION(aStartVal.mType == aEndVal.mType,
-                  "Trying to interpolate different types");
-  NS_PRECONDITION(aStartVal.mType == this,
-                  "Unexpected types for interpolation");
-  NS_PRECONDITION(aResult.mType == this, "Unexpected result type");
+  MOZ_ASSERT(aStartVal.mType == aEndVal.mType,
+             "Trying to interpolate different types");
+  MOZ_ASSERT(aStartVal.mType == this, "Unexpected types for interpolation");
+  MOZ_ASSERT(aResult.mType == this, "Unexpected result type");
 
   const SVGPointListAndInfo& start =
     *static_cast<const SVGPointListAndInfo*>(aStartVal.mU.mPtr);
   const SVGPointListAndInfo& end =
     *static_cast<const SVGPointListAndInfo*>(aEndVal.mU.mPtr);
   SVGPointListAndInfo& result =
     *static_cast<SVGPointListAndInfo*>(aResult.mU.mPtr);
 
--- a/dom/svg/SVGStyleElement.cpp
+++ b/dom/svg/SVGStyleElement.cpp
@@ -211,49 +211,45 @@ void
 SVGStyleElement::SetTitle(const nsAString& aTitle, ErrorResult& rv)
 {
   SetAttr(nsGkAtoms::title, aTitle, rv);
 }
 
 //----------------------------------------------------------------------
 // nsStyleLinkElement methods
 
-already_AddRefed<nsIURI>
-SVGStyleElement::GetStyleSheetURL(bool* aIsInline, nsIPrincipal** aTriggeringPrincipal)
+Maybe<nsStyleLinkElement::SheetInfo>
+SVGStyleElement::GetStyleSheetInfo()
 {
-  *aIsInline = true;
-  *aTriggeringPrincipal = nullptr;
-  return nullptr;
-}
-
-void
-SVGStyleElement::GetStyleSheetInfo(nsAString& aTitle,
-                                   nsAString& aType,
-                                   nsAString& aMedia,
-                                   bool* aIsAlternate)
-{
-  *aIsAlternate = false;
-
   nsAutoString title;
   GetAttr(kNameSpaceID_None, nsGkAtoms::title, title);
   title.CompressWhitespace();
-  aTitle.Assign(title);
 
-  GetAttr(kNameSpaceID_None, nsGkAtoms::media, aMedia);
+  nsAutoString media;
+  GetAttr(kNameSpaceID_None, nsGkAtoms::media, media);
   // The SVG spec is formulated in terms of the CSS2 spec,
   // which specifies that media queries are case insensitive.
-  nsContentUtils::ASCIIToLower(aMedia);
+  nsContentUtils::ASCIIToLower(media);
 
-  GetAttr(kNameSpaceID_None, nsGkAtoms::type, aType);
-  if (aType.IsEmpty()) {
-    aType.AssignLiteral("text/css");
+  // FIXME(emilio): Why doesn't this do the same as HTMLStyleElement?
+  nsAutoString type;
+  GetAttr(kNameSpaceID_None, nsGkAtoms::type, type);
+  if (!type.IsEmpty() && !type.LowerCaseEqualsLiteral("text/css")) {
+    return Nothing();
   }
-}
 
-CORSMode
-SVGStyleElement::GetCORSMode() const
-{
-  return AttrValueToCORSMode(GetParsedAttr(nsGkAtoms::crossorigin));
+  return Some(SheetInfo {
+    *OwnerDoc(),
+    this,
+    nullptr,
+    nullptr,
+    net::ReferrerPolicy::RP_Unset,
+    AttrValueToCORSMode(GetParsedAttr(nsGkAtoms::crossorigin)),
+    title,
+    media,
+    HasAlternateRel::No,
+    IsInline::Yes,
+  });
 }
 
 } // namespace dom
 } // namespace mozilla
 
--- a/dom/svg/SVGStyleElement.h
+++ b/dom/svg/SVGStyleElement.h
@@ -79,25 +79,17 @@ protected:
   // NS_IMPL_ELEMENT_CLONE_WITH_INIT usable with this class. This should be
   // completely optimized away.
   inline nsresult Init()
   {
     return NS_OK;
   }
 
   // nsStyleLinkElement overrides
-  already_AddRefed<nsIURI>
-    GetStyleSheetURL(bool* aIsInline, nsIPrincipal** aTriggeringPrincipal) final;
-
-  void GetStyleSheetInfo(nsAString& aTitle,
-                         nsAString& aType,
-                         nsAString& aMedia,
-                         bool* aIsAlternate) final;
-
-  CORSMode GetCORSMode() const final;
+  Maybe<SheetInfo> GetStyleSheetInfo() final;
 
   /**
    * Common method to call from the various mutation observer methods.
    * aContent is a content node that's either the one that changed or its
    * parent; we should only respond to the change if aContent is non-anonymous.
    */
   void ContentChanged(nsIContent* aContent);
 };
--- a/dom/svg/SVGTransformListSMILType.cpp
+++ b/dom/svg/SVGTransformListSMILType.cpp
@@ -17,56 +17,56 @@ using namespace dom::SVGTransformBinding
 typedef FallibleTArray<SVGTransformSMILData> TransformArray;
 
 //----------------------------------------------------------------------
 // nsISMILType implementation
 
 void
 SVGTransformListSMILType::Init(nsSMILValue &aValue) const
 {
-  NS_PRECONDITION(aValue.IsNull(), "Unexpected value type");
+  MOZ_ASSERT(aValue.IsNull(), "Unexpected value type");
 
   TransformArray* transforms = new TransformArray(1);
   aValue.mU.mPtr = transforms;
   aValue.mType = this;
 }
 
 void
 SVGTransformListSMILType::Destroy(nsSMILValue& aValue) const
 {
-  NS_PRECONDITION(aValue.mType == this, "Unexpected SMIL value type");
+  MOZ_ASSERT(aValue.mType == this, "Unexpected SMIL value type");
   TransformArray* params = static_cast<TransformArray*>(aValue.mU.mPtr);
   delete params;
   aValue.mU.mPtr = nullptr;
   aValue.mType = nsSMILNullType::Singleton();
 }
 
 nsresult
 SVGTransformListSMILType::Assign(nsSMILValue& aDest,
                                const nsSMILValue& aSrc) const
 {
-  NS_PRECONDITION(aDest.mType == aSrc.mType, "Incompatible SMIL types");
-  NS_PRECONDITION(aDest.mType == this, "Unexpected SMIL value");
+  MOZ_ASSERT(aDest.mType == aSrc.mType, "Incompatible SMIL types");
+  MOZ_ASSERT(aDest.mType == this, "Unexpected SMIL value");
 
   const TransformArray* srcTransforms =
     static_cast<const TransformArray*>(aSrc.mU.mPtr);
   TransformArray* dstTransforms = static_cast<TransformArray*>(aDest.mU.mPtr);
   if (!dstTransforms->Assign(*srcTransforms, fallible)) {
     return NS_ERROR_OUT_OF_MEMORY;
   }
 
   return NS_OK;
 }
 
 bool
 SVGTransformListSMILType::IsEqual(const nsSMILValue& aLeft,
                                   const nsSMILValue& aRight) const
 {
-  NS_PRECONDITION(aLeft.mType == aRight.mType, "Incompatible SMIL types");
-  NS_PRECONDITION(aLeft.mType == this, "Unexpected SMIL type");
+  MOZ_ASSERT(aLeft.mType == aRight.mType, "Incompatible SMIL types");
+  MOZ_ASSERT(aLeft.mType == this, "Unexpected SMIL type");
 
   const TransformArray& leftArr
     (*static_cast<const TransformArray*>(aLeft.mU.mPtr));
   const TransformArray& rightArr
     (*static_cast<const TransformArray*>(aRight.mU.mPtr));
 
   // If array-lengths don't match, we're trivially non-equal.
   if (leftArr.Length() != rightArr.Length()) {
@@ -85,18 +85,18 @@ SVGTransformListSMILType::IsEqual(const 
   return true;
 }
 
 nsresult
 SVGTransformListSMILType::Add(nsSMILValue& aDest,
                               const nsSMILValue& aValueToAdd,
                               uint32_t aCount) const
 {
-  NS_PRECONDITION(aDest.mType == this, "Unexpected SMIL type");
-  NS_PRECONDITION(aDest.mType == aValueToAdd.mType, "Incompatible SMIL types");
+  MOZ_ASSERT(aDest.mType == this, "Unexpected SMIL type");
+  MOZ_ASSERT(aDest.mType == aValueToAdd.mType, "Incompatible SMIL types");
 
   TransformArray& dstTransforms(*static_cast<TransformArray*>(aDest.mU.mPtr));
   const TransformArray& srcTransforms
     (*static_cast<const TransformArray*>(aValueToAdd.mU.mPtr));
 
   // We're doing a simple add here (as opposed to a sandwich add below).
   // We only do this when we're accumulating a repeat result or calculating
   // a by-animation value.
@@ -137,18 +137,18 @@ SVGTransformListSMILType::Add(nsSMILValu
 
   return NS_OK;
 }
 
 nsresult
 SVGTransformListSMILType::SandwichAdd(nsSMILValue& aDest,
                                       const nsSMILValue& aValueToAdd) const
 {
-  NS_PRECONDITION(aDest.mType == this, "Unexpected SMIL type");
-  NS_PRECONDITION(aDest.mType == aValueToAdd.mType, "Incompatible SMIL types");
+  MOZ_ASSERT(aDest.mType == this, "Unexpected SMIL type");
+  MOZ_ASSERT(aDest.mType == aValueToAdd.mType, "Incompatible SMIL types");
 
   // For <animateTransform> a sandwich add means a matrix post-multiplication
   // which just means to put the additional transform on the end of the array
 
   TransformArray& dstTransforms(*static_cast<TransformArray*>(aDest.mU.mPtr));
   const TransformArray& srcTransforms
     (*static_cast<const TransformArray*>(aValueToAdd.mU.mPtr));
 
@@ -175,19 +175,19 @@ SVGTransformListSMILType::SandwichAdd(ns
   return NS_OK;
 }
 
 nsresult
 SVGTransformListSMILType::ComputeDistance(const nsSMILValue& aFrom,
                                           const nsSMILValue& aTo,
                                           double& aDistance) const
 {
-  NS_PRECONDITION(aFrom.mType == aTo.mType,
+  MOZ_ASSERT(aFrom.mType == aTo.mType,
       "Can't compute difference between different SMIL types");
-  NS_PRECONDITION(aFrom.mType == this, "Unexpected SMIL type");
+  MOZ_ASSERT(aFrom.mType == this, "Unexpected SMIL type");
 
   const TransformArray* fromTransforms =
     static_cast<const TransformArray*>(aFrom.mU.mPtr);
   const TransformArray* toTransforms =
     static_cast<const TransformArray*>(aTo.mU.mPtr);
 
   // ComputeDistance is only used for calculating distances between single
   // values in a values array which necessarily have the same type
@@ -240,21 +240,20 @@ SVGTransformListSMILType::ComputeDistanc
 }
 
 nsresult
 SVGTransformListSMILType::Interpolate(const nsSMILValue& aStartVal,
                                       const nsSMILValue& aEndVal,
                                       double aUnitDistance,
                                       nsSMILValue& aResult) const
 {
-  NS_PRECONDITION(aStartVal.mType == aEndVal.mType,
-      "Can't interpolate between different SMIL types");
-  NS_PRECONDITION(aStartVal.mType == this,
-      "Unexpected type for interpolation");
-  NS_PRECONDITION(aResult.mType == this, "Unexpected result type");
+  MOZ_ASSERT(aStartVal.mType == aEndVal.mType,
+             "Can't interpolate between different SMIL types");
+  MOZ_ASSERT(aStartVal.mType == this, "Unexpected type for interpolation");
+  MOZ_ASSERT(aResult.mType == this, "Unexpected result type");
 
   const TransformArray& startTransforms =
     (*static_cast<const TransformArray*>(aStartVal.mU.mPtr));
   const TransformArray& endTransforms
     (*static_cast<const TransformArray*>(aEndVal.mU.mPtr));
 
   // We may have 0..n transforms in the start transform array (the base
   // value) but we should only have 1 transform in the end transform array
@@ -314,29 +313,29 @@ SVGTransformListSMILType::Interpolate(co
 // Transform array accessors
 
 // static
 nsresult
 SVGTransformListSMILType::AppendTransform(
   const SVGTransformSMILData& aTransform,
   nsSMILValue& aValue)
 {
-  NS_PRECONDITION(aValue.mType == Singleton(), "Unexpected SMIL value type");
+  MOZ_ASSERT(aValue.mType == Singleton(), "Unexpected SMIL value type");
 
   TransformArray& transforms = *static_cast<TransformArray*>(aValue.mU.mPtr);
   return transforms.AppendElement(aTransform, fallible) ?
     NS_OK : NS_ERROR_OUT_OF_MEMORY;
 }
 
 // static
 bool
 SVGTransformListSMILType::AppendTransforms(const SVGTransformList& aList,
                                            nsSMILValue& aValue)
 {
-  NS_PRECONDITION(aValue.mType == Singleton(), "Unexpected SMIL value type");
+  MOZ_ASSERT(aValue.mType == Singleton(), "Unexpected SMIL value type");
 
   TransformArray& transforms = *static_cast<TransformArray*>(aValue.mU.mPtr);
 
   if (!transforms.SetCapacity(transforms.Length() + aList.Length(), fallible))
     return false;
 
   for (uint32_t i = 0; i < aList.Length(); ++i) {
     // No need to check the return value below since we have already allocated
@@ -347,17 +346,17 @@ SVGTransformListSMILType::AppendTransfor
   return true;
 }
 
 // static
 bool
 SVGTransformListSMILType::GetTransforms(const nsSMILValue& aValue,
                                         FallibleTArray<nsSVGTransform>& aTransforms)
 {
-  NS_PRECONDITION(aValue.mType == Singleton(), "Unexpected SMIL value type");
+  MOZ_ASSERT(aValue.mType == Singleton(), "Unexpected SMIL value type");
 
   const TransformArray& smilTransforms =
     *static_cast<const TransformArray*>(aValue.mU.mPtr);
 
   aTransforms.Clear();
   if (!aTransforms.SetCapacity(smilTransforms.Length(), fallible))
       return false;
 
--- a/dom/svg/SVGViewBoxSMILType.cpp
+++ b/dom/svg/SVGViewBoxSMILType.cpp
@@ -21,70 +21,70 @@ SVGViewBoxSMILType::Init(nsSMILValue& aV
 
   aValue.mU.mPtr = new nsSVGViewBoxRect();
   aValue.mType = this;
 }
 
 void
 SVGViewBoxSMILType::Destroy(nsSMILValue& aValue) const
 {
-  NS_PRECONDITION(aValue.mType == this, "Unexpected SMIL value");
+  MOZ_ASSERT(aValue.mType == this, "Unexpected SMIL value");
   delete static_cast<nsSVGViewBoxRect*>(aValue.mU.mPtr);
   aValue.mU.mPtr = nullptr;
   aValue.mType = nsSMILNullType::Singleton();
 }
 
 nsresult
 SVGViewBoxSMILType::Assign(nsSMILValue& aDest, const nsSMILValue& aSrc) const
 {
-  NS_PRECONDITION(aDest.mType == aSrc.mType, "Incompatible SMIL types");
-  NS_PRECONDITION(aDest.mType == this, "Unexpected SMIL value");
+  MOZ_ASSERT(aDest.mType == aSrc.mType, "Incompatible SMIL types");
+  MOZ_ASSERT(aDest.mType == this, "Unexpected SMIL value");
 
   const nsSVGViewBoxRect* src = static_cast<const nsSVGViewBoxRect*>(aSrc.mU.mPtr);
   nsSVGViewBoxRect* dst = static_cast<nsSVGViewBoxRect*>(aDest.mU.mPtr);
   *dst = *src;
   return NS_OK;
 }
 
 bool
 SVGViewBoxSMILType::IsEqual(const nsSMILValue& aLeft,
                             const nsSMILValue& aRight) const
 {
-  NS_PRECONDITION(aLeft.mType == aRight.mType, "Incompatible SMIL types");
-  NS_PRECONDITION(aLeft.mType == this, "Unexpected type for SMIL value");
+  MOZ_ASSERT(aLeft.mType == aRight.mType, "Incompatible SMIL types");
+  MOZ_ASSERT(aLeft.mType == this, "Unexpected type for SMIL value");
 
   const nsSVGViewBoxRect* leftBox =
     static_cast<const nsSVGViewBoxRect*>(aLeft.mU.mPtr);
   const nsSVGViewBoxRect* rightBox =
     static_cast<nsSVGViewBoxRect*>(aRight.mU.mPtr);
   return *leftBox == *rightBox;
 }
 
 nsresult
 SVGViewBoxSMILType::Add(nsSMILValue& aDest, const nsSMILValue& aValueToAdd,
                         uint32_t aCount) const
 {
-  NS_PRECONDITION(aValueToAdd.mType == aDest.mType,
+  MOZ_ASSERT(aValueToAdd.mType == aDest.mType,
                   "Trying to add invalid types");
-  NS_PRECONDITION(aValueToAdd.mType == this, "Unexpected source type");
+  MOZ_ASSERT(aValueToAdd.mType == this, "Unexpected source type");
 
   // See https://bugzilla.mozilla.org/show_bug.cgi?id=541884#c3 and the two
   // comments that follow that one for arguments for and against allowing
   // viewBox to be additive.
 
   return NS_ERROR_FAILURE;
 }
 
 nsresult
 SVGViewBoxSMILType::ComputeDistance(const nsSMILValue& aFrom,
                                     const nsSMILValue& aTo,
                                     double& aDistance) const
 {
-  NS_PRECONDITION(aFrom.mType == aTo.mType,"Trying to compare different types");
-  NS_PRECONDITION(aFrom.mType == this, "Unexpected source type");
+  MOZ_ASSERT(aFrom.mType == aTo.mType,"Trying to compare different types");
+  MOZ_ASSERT(aFrom.mType == this, "Unexpected source type");
 
   const nsSVGViewBoxRect* from = static_cast<const nsSVGViewBoxRect*>(aFrom.mU.mPtr);
   const nsSVGViewBoxRect* to = static_cast<const nsSVGViewBoxRect*>(aTo.mU.mPtr);
 
   if (from->none || to->none) {
     return NS_ERROR_FAILURE;
   }
 
@@ -105,21 +105,20 @@ SVGViewBoxSMILType::ComputeDistance(cons
 }
 
 nsresult
 SVGViewBoxSMILType::Interpolate(const nsSMILValue& aStartVal,
                                 const nsSMILValue& aEndVal,
                                 double aUnitDistance,
                                 nsSMILValue& aResult) const
 {
-  NS_PRECONDITION(aStartVal.mType == aEndVal.mType,
-                  "Trying to interpolate different types");
-  NS_PRECONDITION(aStartVal.mType == this,
-                  "Unexpected types for interpolation");
-  NS_PRECONDITION(aResult.mType == this, "Unexpected result type");
+  MOZ_ASSERT(aStartVal.mType == aEndVal.mType,
+             "Trying to interpolate different types");
+  MOZ_ASSERT(aStartVal.mType == this, "Unexpected types for interpolation");
+  MOZ_ASSERT(aResult.mType == this, "Unexpected result type");
 
   const nsSVGViewBoxRect* start = static_cast<const nsSVGViewBoxRect*>(aStartVal.mU.mPtr);
   const nsSVGViewBoxRect* end = static_cast<const nsSVGViewBoxRect*>(aEndVal.mU.mPtr);
 
   if (start->none || end->none) {
     return NS_ERROR_FAILURE;
   }
 
--- a/dom/webauthn/u2f-hid-rs/Cargo.toml
+++ b/dom/webauthn/u2f-hid-rs/Cargo.toml
@@ -2,17 +2,18 @@
 name = "u2fhid"
 version = "0.1.0"
 authors = ["Kyle Machulis <kyle@nonpolynomial.com>", "J.C. Jones <jc@mozilla.com>", "Tim Taubert <ttaubert@mozilla.com>"]
 
 [target.'cfg(target_os = "linux")'.dependencies]
 libudev = "^0.2"
 
 [target.'cfg(target_os = "macos")'.dependencies]
-core-foundation-sys = "0.5.1"
+core-foundation-sys = "0.6.0"
+core-foundation = "0.6.0"
 
 [target.'cfg(target_os = "windows")'.dependencies]
 winapi = "0.2.8"
 
 [dependencies]
 rand = "0.3"
 log = "0.4"
 libc = "^0.2"
--- a/dom/webauthn/u2f-hid-rs/src/lib.rs
+++ b/dom/webauthn/u2f-hid-rs/src/lib.rs
@@ -11,16 +11,19 @@ extern crate libudev;
 #[cfg(any(target_os = "linux"))]
 #[path = "linux/mod.rs"]
 pub mod platform;
 
 #[cfg(any(target_os = "macos"))]
 extern crate core_foundation_sys;
 
 #[cfg(any(target_os = "macos"))]
+extern crate core_foundation;
+
+#[cfg(any(target_os = "macos"))]
 #[path = "macos/mod.rs"]
 pub mod platform;
 
 #[cfg(any(target_os = "windows"))]
 #[path = "windows/mod.rs"]
 pub mod platform;
 
 #[cfg(not(any(target_os = "linux", target_os = "macos", target_os = "windows")))]
--- a/dom/webauthn/u2f-hid-rs/src/macos/iokit.rs
+++ b/dom/webauthn/u2f-hid-rs/src/macos/iokit.rs
@@ -5,20 +5,22 @@
 #![allow(non_snake_case, non_camel_case_types, non_upper_case_globals)]
 
 extern crate core_foundation_sys;
 extern crate libc;
 
 use consts::{FIDO_USAGE_U2FHID, FIDO_USAGE_PAGE};
 use core_foundation_sys::base::*;
 use core_foundation_sys::dictionary::*;
-use core_foundation_sys::number::*;
 use core_foundation_sys::runloop::*;
 use core_foundation_sys::string::*;
-use libc::c_void;
+use core_foundation::dictionary::*;
+use core_foundation::string::*;
+use core_foundation::number::*;
+use std::os::raw::c_void;
 use std::ops::Deref;
 
 type IOOptionBits = u32;
 
 pub type IOReturn = libc::c_int;
 
 pub type IOHIDManagerRef = *mut __IOHIDManager;
 pub type IOHIDManagerOptions = IOOptionBits;
@@ -147,86 +149,32 @@ impl Drop for CFRunLoopEntryObserver {
 
             // Drop the CFRunLoopObserverContext.
             let _ = Box::from_raw(self.context_ptr);
         };
     }
 }
 
 pub struct IOHIDDeviceMatcher {
-    dict: CFDictionaryRef,
-    keys: Vec<CFStringRef>,
-    values: Vec<CFNumberRef>,
+    pub dict: CFDictionary<CFString, CFNumber>,
 }
 
 impl IOHIDDeviceMatcher {
     pub fn new() -> Self {
-        let keys = vec![
-            IOHIDDeviceMatcher::cf_string("DeviceUsage"),
-            IOHIDDeviceMatcher::cf_string("DeviceUsagePage"),
-        ];
-
-        let values = vec![
-            IOHIDDeviceMatcher::cf_number(FIDO_USAGE_U2FHID as i32),
-            IOHIDDeviceMatcher::cf_number(FIDO_USAGE_PAGE as i32),
-        ];
-
-        let dict = unsafe {
-            CFDictionaryCreate(
-                kCFAllocatorDefault,
-                keys.as_ptr() as *const *const libc::c_void,
-                values.as_ptr() as *const *const libc::c_void,
-                keys.len() as CFIndex,
-                &kCFTypeDictionaryKeyCallBacks,
-                &kCFTypeDictionaryValueCallBacks,
-            )
-        };
-
-        Self { dict, keys, values }
-    }
-
-    fn cf_number(number: i32) -> CFNumberRef {
-        let nbox = Box::new(number);
-        let nptr = Box::into_raw(nbox) as *mut libc::c_void;
-
-        unsafe {
-            // Drop when out of scope.
-            let _num = Box::from_raw(nptr as *mut i32);
-            CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, nptr)
-        }
-    }
-
-    fn cf_string(string: &str) -> CFStringRef {
-        unsafe {
-            CFStringCreateWithBytes(
-                kCFAllocatorDefault,
-                string.as_ptr(),
-                string.len() as CFIndex,
-                kCFStringEncodingUTF8,
-                false as Boolean,
-            )
-        }
-    }
-
-    pub fn get(&self) -> CFDictionaryRef {
-        self.dict
-    }
-}
-
-impl Drop for IOHIDDeviceMatcher {
-    fn drop(&mut self) {
-        unsafe { CFRelease(self.dict as *mut libc::c_void) };
-
-        for key in &self.keys {
-            unsafe { CFRelease(*key as *mut libc::c_void) };
-        }
-
-        for value in &self.values {
-            unsafe { CFRelease(*value as *mut libc::c_void) };
-        }
+        let dict = CFDictionary::<CFString, CFNumber>::from_CFType_pairs(&[
+            (
+                CFString::from_static_string("DeviceUsage"),
+                CFNumber::from(FIDO_USAGE_U2FHID as i32),
+            ),
+            (
+                CFString::from_static_string("DeviceUsagePage"),
+                CFNumber::from(FIDO_USAGE_PAGE as i32),
+            ),
+            ]);
+        Self { dict }
     }
 }
 
 #[link(name = "IOKit", kind = "framework")]
 extern "C" {
     // CFRunLoop
     pub fn CFRunLoopObserverCreate(
         allocator: CFAllocatorRef,
@@ -278,19 +226,17 @@ extern "C" {
 
 ////////////////////////////////////////////////////////////////////////
 // Tests
 ////////////////////////////////////////////////////////////////////////
 
 #[cfg(test)]
 mod tests {
     use super::*;
-    use core_foundation_sys::base::*;
-    use core_foundation_sys::runloop::*;
-    use libc::c_void;
+    use std::os::raw::c_void;
     use std::ptr;
     use std::sync::mpsc::{channel, Sender};
     use std::thread;
 
     extern "C" fn observe(_: CFRunLoopObserverRef, _: CFRunLoopActivity, context: *mut c_void) {
         let tx: &Sender<SendableRunLoop> = unsafe { &*(context as *mut _) };
 
         // Send the current runloop to the receiver to unblock it.
--- a/dom/webauthn/u2f-hid-rs/src/macos/monitor.rs
+++ b/dom/webauthn/u2f-hid-rs/src/macos/monitor.rs
@@ -2,17 +2,18 @@
  * 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/. */
 
 extern crate libc;
 extern crate log;
 
 use core_foundation_sys::base::*;
 use core_foundation_sys::runloop::*;
-use libc::c_void;
+use core_foundation::base::TCFType;
+use std::os::raw::c_void;
 use platform::iokit::*;
 use runloop::RunLoop;
 use std::collections::HashMap;
 use std::sync::mpsc::{channel, Receiver, Sender};
 use std::{io, slice};
 use util::io_err;
 
 struct DeviceData {
@@ -35,17 +36,17 @@ impl<F> Monitor<F>
 where
     F: Fn((IOHIDDeviceRef, Receiver<Vec<u8>>), &Fn() -> bool) + Sync + 'static,
 {
     pub fn new(new_device_cb: F) -> Self {
         let manager = unsafe { IOHIDManagerCreate(kCFAllocatorDefault, kIOHIDManagerOptionNone) };
 
         // Match FIDO devices only.
         let _matcher = IOHIDDeviceMatcher::new();
-        unsafe { IOHIDManagerSetDeviceMatching(manager, _matcher.get()) };
+        unsafe { IOHIDManagerSetDeviceMatching(manager, _matcher.dict.as_concrete_TypeRef()) };
 
         Self {
             manager,
             _matcher,
             new_device_cb,
             map: HashMap::new(),
         }
     }
@@ -165,11 +166,11 @@ where
     }
 }
 
 impl<F> Drop for Monitor<F>
 where
     F: Fn((IOHIDDeviceRef, Receiver<Vec<u8>>), &Fn() -> bool) + Sync,
 {
     fn drop(&mut self) {
-        unsafe { CFRelease(self.manager as *mut libc::c_void) };
+        unsafe { CFRelease(self.manager as *mut c_void) };
     }
 }
--- a/dom/webauthn/u2f-hid-rs/src/macos/transaction.rs
+++ b/dom/webauthn/u2f-hid-rs/src/macos/transaction.rs
@@ -1,16 +1,16 @@
 /* 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/. */
 
 extern crate libc;
 
 use core_foundation_sys::runloop::*;
-use libc::c_void;
+use std::os::raw::c_void;
 use platform::iokit::{CFRunLoopEntryObserver, IOHIDDeviceRef, SendableRunLoop};
 use platform::monitor::Monitor;
 use std::sync::mpsc::{channel, Receiver, Sender};
 use std::thread;
 use util::OnceCallback;
 
 // A transaction will run the given closure in a new thread, thereby using a
 // separate per-thread state machine for each HID. It will either complete or
--- a/dom/xbl/nsBindingManager.cpp
+++ b/dom/xbl/nsBindingManager.cpp
@@ -197,17 +197,17 @@ nsBindingManager::SetWrappedJS(nsIConten
   return NS_OK;
 }
 
 void
 nsBindingManager::RemovedFromDocumentInternal(nsIContent* aContent,
                                               nsIDocument* aOldDocument,
                                               DestructorHandling aDestructorHandling)
 {
-  NS_PRECONDITION(aOldDocument != nullptr, "no old document");
+  MOZ_ASSERT(aOldDocument != nullptr, "no old document");
 
   RefPtr<nsXBLBinding> binding = aContent->GetXBLBinding();
   if (binding) {
     // The binding manager may have been destroyed before a runnable
     // has had a chance to reach this point. If so, we bail out on calling
     // BindingDetached (which may invoke a XBL destructor) and
     // ChangeDocument, but we still want to clear out the binding
     // and insertion parent that may hold references.
@@ -293,17 +293,17 @@ nsBindingManager::ClearBinding(Element* 
   return NS_OK;
 }
 
 nsresult
 nsBindingManager::LoadBindingDocument(nsIDocument* aBoundDoc,
                                       nsIURI* aURL,
                                       nsIPrincipal* aOriginPrincipal)
 {
-  NS_PRECONDITION(aURL, "Must have a URI to load!");
+  MOZ_ASSERT(aURL, "Must have a URI to load!");
 
   // First we need to load our binding.
   nsXBLService* xblService = nsXBLService::GetInstance();
   if (!xblService)
     return NS_ERROR_FAILURE;
 
   // Load the binding doc.
   RefPtr<nsXBLDocumentInfo> info;
@@ -466,17 +466,17 @@ nsBindingManager::ExecuteDetachedHandler
   for (i = 0; i < count; ++i) {
     bindings[i]->ExecuteDetachedHandler();
   }
 }
 
 nsresult
 nsBindingManager::PutXBLDocumentInfo(nsXBLDocumentInfo* aDocumentInfo)
 {
-  NS_PRECONDITION(aDocumentInfo, "Must have a non-null documentinfo!");
+  MOZ_ASSERT(aDocumentInfo, "Must have a non-null documentinfo!");
 
   if (!mDocumentTable) {
     mDocumentTable = new nsRefPtrHashtable<nsURIHashKey,nsXBLDocumentInfo>();
   }
 
   mDocumentTable->Put(aDocumentInfo->DocumentURI(), aDocumentInfo);
 
   return NS_OK;
@@ -497,17 +497,17 @@ nsBindingManager::GetXBLDocumentInfo(nsI
     return nullptr;
 
   return mDocumentTable->GetWeak(aURL);
 }
 
 nsresult
 nsBindingManager::PutLoadingDocListener(nsIURI* aURL, nsIStreamListener* aListener)
 {
-  NS_PRECONDITION(aListener, "Must have a non-null listener!");
+  MOZ_ASSERT(aListener, "Must have a non-null listener!");
 
   if (!mLoadingDocTable) {
     mLoadingDocTable =
       new nsInterfaceHashtable<nsURIHashKey,nsIStreamListener>();
   }
   mLoadingDocTable->Put(aURL, aListener);
 
   return NS_OK;
--- a/dom/xbl/nsXBLContentSink.cpp
+++ b/dom/xbl/nsXBLContentSink.cpp
@@ -165,17 +165,17 @@ nsXBLContentSink::FlushText(bool aReleas
 }
 
 NS_IMETHODIMP
 nsXBLContentSink::ReportError(const char16_t* aErrorText,
                               const char16_t* aSourceText,
                               nsIScriptError *aError,
                               bool *_retval)
 {
-  NS_PRECONDITION(aError && aSourceText && aErrorText, "Check arguments!!!");
+  MOZ_ASSERT(aError && aSourceText && aErrorText, "Check arguments!!!");
 
   // XXX FIXME This function overrides and calls on
   // nsXMLContentSink::ReportError, and probably should die.  See bug 347826.
 
   // XXX We should make sure the binding has no effect, but that it also
   // gets destroyed properly without leaking.  Perhaps we should even
   // ensure that the content that was bound is displayed with no
   // binding.
--- a/dom/xbl/nsXBLProtoImplField.cpp
+++ b/dom/xbl/nsXBLProtoImplField.cpp
@@ -370,19 +370,18 @@ nsXBLProtoImplField::InstallAccessors(JS
   return NS_OK;
 }
 
 nsresult
 nsXBLProtoImplField::InstallField(JS::Handle<JSObject*> aBoundNode,
                                   const nsXBLPrototypeBinding& aProtoBinding,
                                   bool* aDidInstall) const
 {
-  NS_PRECONDITION(aBoundNode,
-                  "uh-oh, bound node should NOT be null or bad things will "
-                  "happen");
+  MOZ_ASSERT(aBoundNode,
+             "uh-oh, bound node should NOT be null or bad things will happen");
 
   *aDidInstall = false;
 
   // Empty fields are treated as not actually present.
   if (IsEmpty()) {
     return NS_OK;
   }
 
--- a/dom/xbl/nsXBLProtoImplMethod.cpp
+++ b/dom/xbl/nsXBLProtoImplMethod.cpp
@@ -39,33 +39,33 @@ nsXBLProtoImplMethod::~nsXBLProtoImplMet
   if (!IsCompiled()) {
     delete GetUncompiledMethod();
   }
 }
 
 void
 nsXBLProtoImplMethod::AppendBodyText(const nsAString& aText)
 {
-  NS_PRECONDITION(!IsCompiled(),
-                  "Must not be compiled when accessing uncompiled method");
+  MOZ_ASSERT(!IsCompiled(),
+             "Must not be compiled when accessing uncompiled method");
 
   nsXBLUncompiledMethod* uncompiledMethod = GetUncompiledMethod();
   if (!uncompiledMethod) {
     uncompiledMethod = new nsXBLUncompiledMethod();
     SetUncompiledMethod(uncompiledMethod);
   }
 
   uncompiledMethod->AppendBodyText(aText);
 }
 
 void
 nsXBLProtoImplMethod::AddParameter(const nsAString& aText)
 {
-  NS_PRECONDITION(!IsCompiled(),
-                  "Must not be compiled when accessing uncompiled method");
+  MOZ_ASSERT(!IsCompiled(),
+             "Must not be compiled when accessing uncompiled method");
 
   if (aText.IsEmpty()) {
     NS_WARNING("Empty name attribute in xbl:parameter!");
     return;
   }
 
   nsXBLUncompiledMethod* uncompiledMethod = GetUncompiledMethod();
   if (!uncompiledMethod) {
@@ -74,33 +74,33 @@ nsXBLProtoImplMethod::AddParameter(const
   }
 
   uncompiledMethod->AddParameter(aText);
 }
 
 void
 nsXBLProtoImplMethod::SetLineNumber(uint32_t aLineNumber)
 {
-  NS_PRECONDITION(!IsCompiled(),
-                  "Must not be compiled when accessing uncompiled method");
+  MOZ_ASSERT(!IsCompiled(),
+             "Must not be compiled when accessing uncompiled method");
 
   nsXBLUncompiledMethod* uncompiledMethod = GetUncompiledMethod();
   if (!uncompiledMethod) {
     uncompiledMethod = new nsXBLUncompiledMethod();
     SetUncompiledMethod(uncompiledMethod);
   }
 
   uncompiledMethod->SetLineNumber(aLineNumber);
 }
 
 nsresult
 nsXBLProtoImplMethod::InstallMember(JSContext* aCx,
                                     JS::Handle<JSObject*> aTargetClassObject)
 {
-  NS_PRECONDITION(IsCompiled(),
+  MOZ_ASSERT(IsCompiled(),
                   "Should not be installing an uncompiled method");
   MOZ_ASSERT(js::IsObjectInContextCompartment(aTargetClassObject, aCx));
 
 #ifdef DEBUG
   {
     JS::Rooted<JSObject*> globalObject(aCx, JS_GetGlobalForObject(aCx, aTargetClassObject));
     MOZ_ASSERT(xpc::IsInContentXBLScope(globalObject) ||
                globalObject == xpc::GetXBLScope(aCx, globalObject));
@@ -125,19 +125,19 @@ nsXBLProtoImplMethod::InstallMember(JSCo
   return NS_OK;
 }
 
 nsresult
 nsXBLProtoImplMethod::CompileMember(AutoJSAPI& jsapi, const nsString& aClassStr,
                                     JS::Handle<JSObject*> aClassObject)
 {
   AssertInCompilationScope();
-  NS_PRECONDITION(!IsCompiled(),
+  MOZ_ASSERT(!IsCompiled(),
                   "Trying to compile an already-compiled method");
-  NS_PRECONDITION(aClassObject,
+  MOZ_ASSERT(aClassObject,
                   "Must have class object to compile");
 
   nsXBLUncompiledMethod* uncompiledMethod = GetUncompiledMethod();
 
   // No parameters or body was supplied, so don't install method.
   if (!uncompiledMethod) {
     // Early return after which we consider ourselves compiled.
     SetCompiledMethod(nullptr);
@@ -258,17 +258,17 @@ nsXBLProtoImplMethod::Write(nsIObjectOut
   return NS_OK;
 }
 
 nsresult
 nsXBLProtoImplAnonymousMethod::Execute(nsIContent* aBoundElement,
                                        const nsXBLPrototypeBinding& aProtoBinding)
 {
   MOZ_ASSERT(aBoundElement->IsElement());
-  NS_PRECONDITION(IsCompiled(), "Can't execute uncompiled method");
+  MOZ_ASSERT(IsCompiled(), "Can't execute uncompiled method");
 
   if (!GetCompiledMethod()) {
     // Nothing to do here
     return NS_OK;
   }
 
   // Get the script context the same way
   // nsXBLProtoImpl::InstallImplementation does.
--- a/dom/xbl/nsXBLProtoImplProperty.cpp
+++ b/dom/xbl/nsXBLProtoImplProperty.cpp
@@ -81,57 +81,52 @@ void nsXBLProtoImplProperty::EnsureUncom
     nsXBLTextWithLineNumber* text = new nsXBLTextWithLineNumber();
     aPropertyOp.SetUncompiled(text);
   }
 }
 
 void
 nsXBLProtoImplProperty::AppendGetterText(const nsAString& aText)
 {
-  NS_PRECONDITION(!mIsCompiled,
-                  "Must not be compiled when accessing getter text");
+  MOZ_ASSERT(!mIsCompiled, "Must not be compiled when accessing getter text");
   EnsureUncompiledText(mGetter);
   mGetter.GetUncompiled()->AppendText(aText);
 }
 
 void
 nsXBLProtoImplProperty::AppendSetterText(const nsAString& aText)
 {
-  NS_PRECONDITION(!mIsCompiled,
-                  "Must not be compiled when accessing setter text");
+  MOZ_ASSERT(!mIsCompiled, "Must not be compiled when accessing setter text");
   EnsureUncompiledText(mSetter);
   mSetter.GetUncompiled()->AppendText(aText);
 }
 
 void
 nsXBLProtoImplProperty::SetGetterLineNumber(uint32_t aLineNumber)
 {
-  NS_PRECONDITION(!mIsCompiled,
-                  "Must not be compiled when accessing getter text");
+  MOZ_ASSERT(!mIsCompiled, "Must not be compiled when accessing getter text");
   EnsureUncompiledText(mGetter);
   mGetter.GetUncompiled()->SetLineNumber(aLineNumber);
 }
 
 void
 nsXBLProtoImplProperty::SetSetterLineNumber(uint32_t aLineNumber)
 {
-  NS_PRECONDITION(!mIsCompiled,
-                  "Must not be compiled when accessing setter text");
+  MOZ_ASSERT(!mIsCompiled, "Must not be compiled when accessing setter text");
   EnsureUncompiledText(mSetter);
   mSetter.GetUncompiled()->SetLineNumber(aLineNumber);
 }
 
 const char* gPropertyArgs[] = { "val" };
 
 nsresult
 nsXBLProtoImplProperty::InstallMember(JSContext *aCx,
                                       JS::Handle<JSObject*> aTargetClassObject)
 {
-  NS_PRECONDITION(mIsCompiled,
-                  "Should not be installing an uncompiled property");
+  MOZ_ASSERT(mIsCompiled, "Should not be installing an uncompiled property");
   MOZ_ASSERT(mGetter.IsCompiled() && mSetter.IsCompiled());
   MOZ_ASSERT(js::IsObjectInContextCompartment(aTargetClassObject, aCx));
 
 #ifdef DEBUG
   {
     JS::Rooted<JSObject*> globalObject(aCx, JS_GetGlobalForObject(aCx, aTargetClassObject));
     MOZ_ASSERT(xpc::IsInContentXBLScope(globalObject) ||
                globalObject == xpc::GetXBLScope(aCx, globalObject));
@@ -164,20 +159,18 @@ nsXBLProtoImplProperty::InstallMember(JS
   return NS_OK;
 }
 
 nsresult
 nsXBLProtoImplProperty::CompileMember(AutoJSAPI& jsapi, const nsString& aClassStr,
                                       JS::Handle<JSObject*> aClassObject)
 {
   AssertInCompilationScope();
-  NS_PRECONDITION(!mIsCompiled,
-                  "Trying to compile an already-compiled property");
-  NS_PRECONDITION(aClassObject,
-                  "Must have class object to compile");
+  MOZ_ASSERT(!mIsCompiled, "Trying to compile an already-compiled property");
+  MOZ_ASSERT(aClassObject, "Must have class object to compile");
   MOZ_ASSERT(!mGetter.IsCompiled() && !mSetter.IsCompiled());
   JSContext *cx = jsapi.cx();
 
   if (!mName)
     return NS_ERROR_FAILURE; // Without a valid name, we can't install the member.
 
   // We have a property.
   nsresult rv = NS_OK;
--- a/dom/xbl/nsXBLService.cpp
+++ b/dom/xbl/nsXBLService.cpp
@@ -475,17 +475,17 @@ private:
 
 // This function loads a particular XBL file and installs all of the bindings
 // onto the element.
 nsresult
 nsXBLService::LoadBindings(Element* aElement, nsIURI* aURL,
                            nsIPrincipal* aOriginPrincipal,
                            nsXBLBinding** aBinding, bool* aResolveStyle)
 {
-  NS_PRECONDITION(aOriginPrincipal, "Must have an origin principal");
+  MOZ_ASSERT(aOriginPrincipal, "Must have an origin principal");
 
   *aBinding = nullptr;
   *aResolveStyle = false;
 
   AutoEnsureSubtreeStyled subtreeStyled(aElement);
 
   if (MOZ_UNLIKELY(!aURL)) {
     return NS_OK;
@@ -895,19 +895,19 @@ IsSystemOrChromeURLPrincipal(nsIPrincipa
 nsresult
 nsXBLService::LoadBindingDocumentInfo(nsIContent* aBoundElement,
                                       nsIDocument* aBoundDocument,
                                       nsIURI* aBindingURI,
                                       nsIPrincipal* aOriginPrincipal,
                                       bool aForceSyncLoad,
                                       nsXBLDocumentInfo** aResult)
 {
-  NS_PRECONDITION(aBindingURI, "Must have a binding URI");
-  NS_PRECONDITION(!aOriginPrincipal || aBoundDocument,
-                  "If we're doing a security check, we better have a document!");
+  MOZ_ASSERT(aBindingURI, "Must have a binding URI");
+  MOZ_ASSERT(!aOriginPrincipal || aBoundDocument,
+             "If we're doing a security check, we better have a document!");
 
   *aResult = nullptr;
   // Allow XBL in unprivileged documents if it's specified in a privileged or
   // chrome: stylesheet. This allows themes to specify XBL bindings.
   if (aOriginPrincipal && !IsSystemOrChromeURLPrincipal(aOriginPrincipal)) {
     NS_ENSURE_TRUE(!aBoundDocument || aBoundDocument->AllowXULXBL(),
                    NS_ERROR_XBL_BLOCKED);
   }
--- a/dom/xhr/XMLHttpRequestMainThread.cpp
+++ b/dom/xhr/XMLHttpRequestMainThread.cpp
@@ -3212,17 +3212,17 @@ XMLHttpRequestMainThread::ChangeState(ui
 // nsIChannelEventSink methods:
 //
 NS_IMETHODIMP
 XMLHttpRequestMainThread::AsyncOnChannelRedirect(nsIChannel *aOldChannel,
                                                  nsIChannel *aNewChannel,
                                                  uint32_t    aFlags,
                                                  nsIAsyncVerifyRedirectCallback *callback)
 {
-  NS_PRECONDITION(aNewChannel, "Redirect without a channel?");
+  MOZ_ASSERT(aNewChannel, "Redirect without a channel?");
 
   // Prepare to receive callback
   mRedirectCallback = callback;
   mNewRedirectChannel = aNewChannel;
 
   if (mChannelEventSink) {
     nsCOMPtr<nsIAsyncVerifyRedirectCallback> fwd =
       EnsureXPCOMifier();
--- a/dom/xml/ProcessingInstruction.cpp
+++ b/dom/xml/ProcessingInstruction.cpp
@@ -15,17 +15,17 @@
 already_AddRefed<mozilla::dom::ProcessingInstruction>
 NS_NewXMLProcessingInstruction(nsNodeInfoManager *aNodeInfoManager,
                                const nsAString& aTarget,
                                const nsAString& aData)
 {
   using mozilla::dom::ProcessingInstruction;
   using mozilla::dom::XMLStylesheetProcessingInstruction;
 
-  NS_PRECONDITION(aNodeInfoManager, "Missing nodeinfo manager");
+  MOZ_ASSERT(aNodeInfoManager, "Missing nodeinfo manager");
 
   RefPtr<nsAtom> target = NS_Atomize(aTarget);
   MOZ_ASSERT(target);
 
   if (target == nsGkAtoms::xml_stylesheet) {
     RefPtr<XMLStylesheetProcessingInstruction> pi =
       new XMLStylesheetProcessingInstruction(aNodeInfoManager, aData);
     return pi.forget();
--- a/dom/xml/XMLStylesheetProcessingInstruction.cpp
+++ b/dom/xml/XMLStylesheetProcessingInstruction.cpp
@@ -95,91 +95,78 @@ XMLStylesheetProcessingInstruction::GetC
 }
 
 /* virtual */ void
 XMLStylesheetProcessingInstruction::OverrideBaseURI(nsIURI* aNewBaseURI)
 {
   mOverriddenBaseURI = aNewBaseURI;
 }
 
-already_AddRefed<nsIURI>
-XMLStylesheetProcessingInstruction::GetStyleSheetURL(bool* aIsInline, nsIPrincipal** aTriggeringPrincipal)
+Maybe<nsStyleLinkElement::SheetInfo>
+XMLStylesheetProcessingInstruction::GetStyleSheetInfo()
 {
-  *aIsInline = false;
-  *aTriggeringPrincipal = nullptr;
+  // xml-stylesheet PI is special only in prolog
+  if (!nsContentUtils::InProlog(this)) {
+    return Nothing();
+  }
 
   nsAutoString href;
   if (!GetAttrValue(nsGkAtoms::href, href)) {
-    return nullptr;
-  }
-
-  nsIURI *baseURL;
-  nsIDocument *document = OwnerDoc();
-  baseURL = mOverriddenBaseURI ?
-            mOverriddenBaseURI.get() :
-            document->GetDocBaseURI();
-  auto encoding = document->GetDocumentCharacterSet();
-
-  nsCOMPtr<nsIURI> aURI;
-  NS_NewURI(getter_AddRefs(aURI), href, encoding, baseURL);
-  return aURI.forget();
-}
-
-void
-XMLStylesheetProcessingInstruction::GetStyleSheetInfo(nsAString& aTitle,
-                                                      nsAString& aType,
-                                                      nsAString& aMedia,
-                                                      bool* aIsAlternate)
-{
-  aTitle.Truncate();
-  aType.Truncate();
-  aMedia.Truncate();
-  *aIsAlternate = false;
-
-  // xml-stylesheet PI is special only in prolog
-  if (!nsContentUtils::InProlog(this)) {
-    return;
+    return Nothing();
   }
 
   nsAutoString data;
   GetData(data);
 
-  nsContentUtils::GetPseudoAttributeValue(data, nsGkAtoms::title, aTitle);
+  nsAutoString title;
+  nsContentUtils::GetPseudoAttributeValue(data, nsGkAtoms::title, title);
 
-  nsAutoString alternate;
+  nsAutoString alternateAttr;
   nsContentUtils::GetPseudoAttributeValue(data,
                                           nsGkAtoms::alternate,
-                                          alternate);
+                                          alternateAttr);
 
-  // if alternate, does it have title?
-  if (alternate.EqualsLiteral("yes")) {
-    if (aTitle.IsEmpty()) { // alternates must have title
-      return;
-    }
-
-    *aIsAlternate = true;
+  bool alternate = alternateAttr.EqualsLiteral("yes");
+  if (alternate && title.IsEmpty()) {
+    // alternates must have title
+    return Nothing();
   }
 
-  nsContentUtils::GetPseudoAttributeValue(data, nsGkAtoms::media, aMedia);
+  nsAutoString media;
+  nsContentUtils::GetPseudoAttributeValue(data, nsGkAtoms::media, media);
 
   // Make sure the type handling here matches
   // nsXMLContentSink::HandleProcessingInstruction
   nsAutoString type;
   nsContentUtils::GetPseudoAttributeValue(data, nsGkAtoms::type, type);
 
   nsAutoString mimeType, notUsed;
   nsContentUtils::SplitMimeType(type, mimeType, notUsed);
   if (!mimeType.IsEmpty() && !mimeType.LowerCaseEqualsLiteral("text/css")) {
-    aType.Assign(type);
-    return;
+    return Nothing();
   }
 
-  // If we get here we assume that we're loading a css file, so set the
-  // type to 'text/css'
-  aType.AssignLiteral("text/css");
+  nsIDocument* doc = OwnerDoc();
+  nsIURI* baseURL =
+    mOverriddenBaseURI ? mOverriddenBaseURI.get() : doc->GetDocBaseURI();
+  auto encoding = doc->GetDocumentCharacterSet();
+  nsCOMPtr<nsIURI> uri;
+  NS_NewURI(getter_AddRefs(uri), href, encoding, baseURL);
+  return Some(SheetInfo {
+    *doc,
+    this,
+    uri.forget(),
+    nullptr,
+    net::RP_Unset,
+    CORS_NONE,
+    title,
+    media,
+    alternate ? HasAlternateRel::Yes : HasAlternateRel::No,
+    IsInline::No,
+  });
 }
 
 already_AddRefed<CharacterData>
 XMLStylesheetProcessingInstruction::CloneDataNode(mozilla::dom::NodeInfo *aNodeInfo,
                                                   bool aCloneText) const
 {
   nsAutoString data;
   GetData(data);
--- a/dom/xml/XMLStylesheetProcessingInstruction.h
+++ b/dom/xml/XMLStylesheetProcessingInstruction.h
@@ -72,22 +72,18 @@ public:
     Unused << UpdateStyleSheetInternal(nullptr, nullptr, ForceUpdate::Yes);
   }
 
 protected:
   virtual ~XMLStylesheetProcessingInstruction();
 
   nsCOMPtr<nsIURI> mOverriddenBaseURI;
 
-  already_AddRefed<nsIURI>
-    GetStyleSheetURL(bool* aIsInline, nsIPrincipal** aTriggeringPrincipal) final;
-  void GetStyleSheetInfo(nsAString& aTitle,
-                         nsAString& aType,
-                         nsAString& aMedia,
-                         bool* aIsAlternate) final;
+  Maybe<SheetInfo> GetStyleSheetInfo() final;
+
   already_AddRefed<CharacterData>
     CloneDataNode(mozilla::dom::NodeInfo* aNodeInfo,
                   bool aCloneText) const final;
 };
 
 } // namespace dom
 } // namespace mozilla
 
--- a/dom/xml/nsXMLContentSink.cpp
+++ b/dom/xml/nsXMLContentSink.cpp
@@ -74,17 +74,17 @@ using namespace mozilla::dom;
 
 nsresult
 NS_NewXMLContentSink(nsIXMLContentSink** aResult,
                      nsIDocument* aDoc,
                      nsIURI* aURI,
                      nsISupports* aContainer,
                      nsIChannel* aChannel)
 {
-  NS_PRECONDITION(nullptr != aResult, "null ptr");
+  MOZ_ASSERT(nullptr != aResult, "null ptr");
   if (nullptr == aResult) {
     return NS_ERROR_NULL_POINTER;
   }
   RefPtr<nsXMLContentSink> it = new nsXMLContentSink();
 
   nsresult rv = it->Init(aDoc, aURI, aContainer, aChannel);
   NS_ENSURE_SUCCESS(rv, rv);
 
@@ -451,17 +451,17 @@ NS_IMETHODIMP
 nsXMLContentSink::WillResume(void)
 {
   return WillResumeImpl();
 }
 
 NS_IMETHODIMP
 nsXMLContentSink::SetParser(nsParserBase* aParser)
 {
-  NS_PRECONDITION(aParser, "Should have a parser here!");
+  MOZ_ASSERT(aParser, "Should have a parser here!");
   mParser = aParser;
   return NS_OK;
 }
 
 nsresult
 nsXMLContentSink::CreateElement(const char16_t** aAtts, uint32_t aAttsCount,
                                 mozilla::dom::NodeInfo* aNodeInfo, uint32_t aLineNumber,
                                 nsIContent** aResult, bool* aAppendContent,
@@ -839,17 +839,17 @@ nsXMLContentSink::GetCurrentStackNode()
   int32_t count = mContentStack.Length();
   return count != 0 ? &mContentStack[count-1] : nullptr;
 }
 
 
 nsresult
 nsXMLContentSink::PushContent(nsIContent *aContent)
 {
-  NS_PRECONDITION(aContent, "Null content being pushed!");
+  MOZ_ASSERT(aContent, "Null content being pushed!");
   StackNode *sn = mContentStack.AppendElement();
   NS_ENSURE_TRUE(sn, NS_ERROR_OUT_OF_MEMORY);
 
   nsIContent* contentToPush = aContent;
 
   // When an XML parser would append a node to a template element, it
   // must instead append it to the template element's template contents.
   if (contentToPush->IsHTMLElement(nsGkAtoms::_template)) {
@@ -968,17 +968,17 @@ nsXMLContentSink::HandleStartElement(con
 
 nsresult
 nsXMLContentSink::HandleStartElement(const char16_t *aName,
                                      const char16_t **aAtts,
                                      uint32_t aAttsCount,
                                      uint32_t aLineNumber,
                                      bool aInterruptable)
 {
-  NS_PRECONDITION(aAttsCount % 2 == 0, "incorrect aAttsCount");
+  MOZ_ASSERT(aAttsCount % 2 == 0, "incorrect aAttsCount");
   // Adjust aAttsCount so it's the actual number of attributes
   aAttsCount /= 2;
 
   nsresult result = NS_OK;
   bool appendContent = true;
   nsCOMPtr<nsIContent> content;
 
   // XXX Hopefully the parser will flag this before we get
@@ -1353,17 +1353,17 @@ nsXMLContentSink::HandleXMLDeclaration(c
 }
 
 NS_IMETHODIMP
 nsXMLContentSink::ReportError(const char16_t* aErrorText,
                               const char16_t* aSourceText,
                               nsIScriptError *aError,
                               bool *_retval)
 {
-  NS_PRECONDITION(aError && aSourceText && aErrorText, "Check arguments!!!");
+  MOZ_ASSERT(aError && aSourceText && aErrorText, "Check arguments!!!");
   nsresult rv = NS_OK;
 
   // The expat driver should report the error.  We're just cleaning up the mess.
   *_retval = true;
 
   mPrettyPrintXML = false;
 
   mState = eXMLContentSinkState_InProlog;
--- a/dom/xml/nsXMLFragmentContentSink.cpp
+++ b/dom/xml/nsXMLFragmentContentSink.cpp
@@ -291,17 +291,17 @@ nsXMLFragmentContentSink::HandleXMLDecla
 }
 
 NS_IMETHODIMP
 nsXMLFragmentContentSink::ReportError(const char16_t* aErrorText,
                                       const char16_t* aSourceText,
                                       nsIScriptError *aError,
                                       bool *_retval)
 {
-  NS_PRECONDITION(aError && aSourceText && aErrorText, "Check arguments!!!");
+  MOZ_ASSERT(aError && aSourceText && aErrorText, "Check arguments!!!");
 
   // The expat driver should report the error.
   *_retval = true;
 
   mParseError = true;
 
 #ifdef DEBUG
   // Report the error to stderr.
--- a/dom/xslt/xpath/txXPathTreeWalker.h
+++ b/dom/xslt/xpath/txXPathTreeWalker.h
@@ -172,18 +172,17 @@ txXPathTreeWalker::isOnNode(const txXPat
 {
     return (mPosition == aNode);
 }
 
 /* static */
 inline int32_t
 txXPathNodeUtils::getUniqueIdentifier(const txXPathNode& aNode)
 {
-    NS_PRECONDITION(!aNode.isAttribute(),
-                    "Not implemented for attributes.");
+    MOZ_ASSERT(!aNode.isAttribute(), "Not implemented for attributes.");
     return NS_PTR_TO_INT32(aNode.mNode);
 }
 
 /* static */
 inline void
 txXPathNodeUtils::release(txXPathNode* aNode)
 {
     NS_RELEASE(aNode->mNode);
--- a/dom/xslt/xslt/txExecutionState.cpp
+++ b/dom/xslt/xslt/txExecutionState.cpp
@@ -390,17 +390,17 @@ txExecutionState::pushTemplateRule(txSty
     rule->mModeNsId = aMode.mNamespaceID;
     rule->mModeLocalName = aMode.mLocalName;
     rule->mParams = aParams;
 }
 
 void
 txExecutionState::popTemplateRule()
 {
-    NS_PRECONDITION(!mTemplateRules.IsEmpty(), "No rules to pop");
+    MOZ_ASSERT(!mTemplateRules.IsEmpty(), "No rules to pop");
     mTemplateRules.RemoveLastElement();
 }
 
 txIEvalContext*
 txExecutionState::getEvalContext()
 {
     return mEvalContext;
 }
@@ -452,17 +452,17 @@ txExecutionState::getKeyNodes(const txEx
 {
     return mKeyHash.getKeyNodes(aKeyName, aRoot, aKeyValue,
                                 aIndexIfNotFound, *this, aResult);
 }
 
 txExecutionState::TemplateRule*
 txExecutionState::getCurrentTemplateRule()
 {
-    NS_PRECONDITION(!mTemplateRules.IsEmpty(), "No current rule!");
+    MOZ_ASSERT(!mTemplateRules.IsEmpty(), "No current rule!");
     return &mTemplateRules[mTemplateRules.Length() - 1];
 }
 
 txInstruction*
 txExecutionState::getNextInstruction()
 {
     txInstruction* instr = mNextInstruction;
     if (instr) {
--- a/dom/xslt/xslt/txMozillaStylesheetCompiler.cpp
+++ b/dom/xslt/xslt/txMozillaStylesheetCompiler.cpp
@@ -120,17 +120,17 @@ NS_IMPL_ISUPPORTS(txStylesheetSink,
                   nsIInterfaceRequestor)
 
 NS_IMETHODIMP
 txStylesheetSink::HandleStartElement(const char16_t *aName,
                                      const char16_t **aAtts,
                                      uint32_t aAttsCount,
                                      uint32_t aLineNumber)
 {
-    NS_PRECONDITION(aAttsCount % 2 == 0, "incorrect aAttsCount");
+    MOZ_ASSERT(aAttsCount % 2 == 0, "incorrect aAttsCount");
 
     nsresult rv =
         mCompiler->startElement(aName, aAtts, aAttsCount / 2);
     if (NS_FAILED(rv)) {
         mCompiler->cancel(rv);
 
         return rv;
     }
@@ -203,17 +203,17 @@ txStylesheetSink::HandleXMLDeclaration(c
 }
 
 NS_IMETHODIMP
 txStylesheetSink::ReportError(const char16_t *aErrorText,
                               const char16_t *aSourceText,
                               nsIScriptError *aError,
                               bool *_retval)
 {
-    NS_PRECONDITION(aError && aSourceText && aErrorText, "Check arguments!!!");
+    MOZ_ASSERT(aError && aSourceText && aErrorText, "Check arguments!!!");
 
     // The expat driver should report the error.
     *_retval = true;
 
     mCompiler->cancel(NS_ERROR_FAILURE, aErrorText, aSourceText);
 
     return NS_OK;
 }
--- a/dom/xslt/xslt/txMozillaXMLOutput.cpp
+++ b/dom/xslt/xslt/txMozillaXMLOutput.cpp
@@ -427,18 +427,18 @@ txMozillaXMLOutput::startDocument()
     return NS_OK;
 }
 
 nsresult
 txMozillaXMLOutput::startElement(nsAtom* aPrefix, nsAtom* aLocalName,
                                  nsAtom* aLowercaseLocalName,
                                  const int32_t aNsID)
 {
-    NS_PRECONDITION(aNsID != kNameSpaceID_None || !aPrefix,
-                    "Can't have prefix without namespace");
+    MOZ_ASSERT(aNsID != kNameSpaceID_None || !aPrefix,
+               "Can't have prefix without namespace");
 
     if (mOutputFormat.mMethod == eHTMLOutput && aNsID == kNameSpaceID_None) {
         RefPtr<nsAtom> owner;
         if (!aLowercaseLocalName) {
             owner = TX_ToLowerCaseAtom(aLocalName);
             NS_ENSURE_TRUE(owner, NS_ERROR_OUT_OF_MEMORY);
 
             aLowercaseLocalName = owner;
--- a/dom/xslt/xslt/txStylesheetCompiler.cpp
+++ b/dom/xslt/xslt/txStylesheetCompiler.cpp
@@ -698,34 +698,34 @@ nsresult
 txStylesheetCompilerState::addToplevelItem(txToplevelItem* aItem)
 {
     return mToplevelIterator.addBefore(aItem);
 }
 
 nsresult
 txStylesheetCompilerState::openInstructionContainer(txInstructionContainer* aContainer)
 {
-    NS_PRECONDITION(!mNextInstrPtr, "can't nest instruction-containers");
+    MOZ_ASSERT(!mNextInstrPtr, "can't nest instruction-containers");
 
     mNextInstrPtr = aContainer->mFirstInstruction.StartAssignment();
     return NS_OK;
 }
 
 void
 txStylesheetCompilerState::closeInstructionContainer()
 {
     NS_ASSERTION(mGotoTargetPointers.IsEmpty(),
                  "GotoTargets still exists, did you forget to add txReturn?");
     mNextInstrPtr = 0;
 }
 
 nsresult
 txStylesheetCompilerState::addInstruction(nsAutoPtr<txInstruction>&& aInstruction)
 {
-    NS_PRECONDITION(mNextInstrPtr, "adding instruction outside container");
+    MOZ_ASSERT(mNextInstrPtr, "adding instruction outside container");
 
     txInstruction* newInstr = aInstruction;
 
     *mNextInstrPtr = aInstruction.forget();
     mNextInstrPtr = newInstr->mNext.StartAssignment();
 
     uint32_t i, count = mGotoTargetPointers.Length();
     for (i = 0; i < count; ++i) {
--- a/dom/xul/XULDocument.cpp
+++ b/dom/xul/XULDocument.cpp
@@ -214,17 +214,17 @@ XULDocument::~XULDocument()
 }
 
 } // namespace dom
 } // namespace mozilla
 
 nsresult
 NS_NewXULDocument(nsIDocument** result)
 {
-    NS_PRECONDITION(result != nullptr, "null ptr");
+    MOZ_ASSERT(result != nullptr, "null ptr");
     if (! result)
         return NS_ERROR_NULL_POINTER;
 
     RefPtr<XULDocument> doc = new XULDocument();
 
     nsresult rv;
     if (NS_FAILED(rv = doc->Init())) {
         return rv;
@@ -1617,17 +1617,17 @@ XULDocument::StartLayout(void)
 
 /* static */
 bool
 XULDocument::MatchAttribute(Element* aElement,
                             int32_t aNamespaceID,
                             nsAtom* aAttrName,
                             void* aData)
 {
-    NS_PRECONDITION(aElement, "Must have content node to work with!");
+    MOZ_ASSERT(aElement, "Must have content node to work with!");
     nsString* attrValue = static_cast<nsString*>(aData);
     if (aNamespaceID != kNameSpaceID_Unknown &&
         aNamespaceID != kNameSpaceID_Wildcard) {
         return attrValue->EqualsLiteral("*") ?
             aElement->HasAttr(aNamespaceID, aAttrName) :
             aElement->AttrValueIs(aNamespaceID, aAttrName, *attrValue,
                                   eCaseMatters);
     }
@@ -2043,18 +2043,18 @@ XULDocument::PrepareToWalk()
 
     return NS_OK;
 }
 
 nsresult
 XULDocument::CreateAndInsertPI(const nsXULPrototypePI* aProtoPI,
                                nsINode* aParent, nsINode* aBeforeThis)
 {
-    NS_PRECONDITION(aProtoPI, "null ptr");
-    NS_PRECONDITION(aParent, "null ptr");
+    MOZ_ASSERT(aProtoPI, "null ptr");
+    MOZ_ASSERT(aParent, "null ptr");
 
     RefPtr<ProcessingInstruction> node =
         NS_NewXMLProcessingInstruction(mNodeInfoManager, aProtoPI->mTarget,
                                        aProtoPI->mData);
 
     nsresult rv;
     if (aProtoPI->mTarget.EqualsLiteral("xml-stylesheet")) {
         rv = InsertXMLStylesheetPI(aProtoPI, aParent, aBeforeThis, node);
@@ -2734,18 +2734,18 @@ XULDocument::GetXULWindowIfToplevelChrom
         return nullptr;
     }
     return xulWin.forget();
 }
 
 nsresult
 XULDocument::DoneWalking()
 {
-    NS_PRECONDITION(mPendingSheets == 0, "there are sheets to be loaded");
-    NS_PRECONDITION(!mStillWalking, "walk not done");
+    MOZ_ASSERT(mPendingSheets == 0, "there are sheets to be loaded");
+    MOZ_ASSERT(!mStillWalking, "walk not done");
 
     // XXXldb This is where we should really be setting the chromehidden
     // attribute.
 
     {
         mozAutoDocUpdate updateBatch(this, UPDATE_STYLE, true);
         uint32_t count = mOverlaySheets.Length();
         for (uint32_t i = 0; i < count; ++i) {
@@ -2954,17 +2954,17 @@ XULDocument::EndUpdate(nsUpdateType aUpd
     XMLDocument::EndUpdate(aUpdateType);
 
     MaybeBroadcast();
 }
 
 void
 XULDocument::ReportMissingOverlay(nsIURI* aURI)
 {
-    NS_PRECONDITION(aURI, "Must have a URI");
+    MOZ_ASSERT(aURI, "Must have a URI");
 
     NS_ConvertUTF8toUTF16 utfSpec(aURI->GetSpecOrDefault());
     const char16_t* params[] = { utfSpec.get() };
     nsContentUtils::ReportToConsole(nsIScriptError::warningFlag,
                                     NS_LITERAL_CSTRING("XUL Document"), this,
                                     nsContentUtils::eXUL_PROPERTIES,
                                     "MissingOverlay",
                                     params, ArrayLength(params));
@@ -3260,17 +3260,17 @@ XULDocument::OnScriptCompileComplete(JSS
     }
 
     return rv;
 }
 
 nsresult
 XULDocument::ExecuteScript(nsXULPrototypeScript *aScript)
 {
-    NS_PRECONDITION(aScript != nullptr, "null ptr");
+    MOZ_ASSERT(aScript != nullptr, "null ptr");
     NS_ENSURE_TRUE(aScript, NS_ERROR_NULL_POINTER);
     NS_ENSURE_TRUE(mScriptGlobalObject, NS_ERROR_NOT_INITIALIZED);
 
     nsresult rv;
     rv = mScriptGlobalObject->EnsureScriptEnvironment();
     NS_ENSURE_SUCCESS(rv, rv);
 
     // Execute the precompiled script with the given version
@@ -3301,17 +3301,17 @@ XULDocument::ExecuteScript(nsXULPrototyp
 
 
 nsresult
 XULDocument::CreateElementFromPrototype(nsXULPrototypeElement* aPrototype,
                                         Element** aResult,
                                         bool aIsRoot)
 {
     // Create a content model element from a prototype element.
-    NS_PRECONDITION(aPrototype != nullptr, "null ptr");
+    MOZ_ASSERT(aPrototype != nullptr, "null ptr");
     if (! aPrototype)
         return NS_ERROR_NULL_POINTER;
 
     *aResult = nullptr;
     nsresult rv = NS_OK;
 
     if (MOZ_LOG_TEST(gXULLog, LogLevel::Debug)) {
         MOZ_LOG(gXULLog, LogLevel::Debug,
--- a/dom/xul/XULDocument.h
+++ b/dom/xul/XULDocument.h
@@ -24,18 +24,16 @@
 #include "nsIXULStore.h"
 
 #include "mozilla/Attributes.h"
 #include "mozilla/dom/ScriptLoader.h"
 
 #include "js/TracingAPI.h"
 #include "js/TypeDecls.h"
 
-class nsIRDFResource;
-class nsIRDFService;
 class nsPIWindowRoot;
 class nsXULPrototypeElement;
 #if 0 // XXXbe save me, scc (need NSCAP_FORWARD_DECL(nsXULPrototypeScript))
 class nsIObjectInputStream;
 class nsIObjectOutputStream;
 #else
 #include "nsIObjectInputStream.h"
 #include "nsIObjectOutputStream.h"
@@ -249,21 +247,16 @@ protected:
 
     already_AddRefed<nsPIWindowRoot> GetWindowRoot();
 
     static void DirectionChanged(const char* aPrefName, void* aData);
 
     // pseudo constants
     static int32_t gRefCnt;
 
-    static nsIRDFService* gRDFService;
-    static nsIRDFResource* kNC_persist;
-    static nsIRDFResource* kNC_attribute;
-    static nsIRDFResource* kNC_value;
-
     static LazyLogModule gXULLog;
 
     nsresult
     Persist(mozilla::dom::Element* aElement,
             int32_t aNameSpaceID,
             nsAtom* aAttribute);
     // Just like Persist but ignores the return value so we can use it
     // as a runnable method.
--- a/dom/xul/nsXULCommandDispatcher.cpp
+++ b/dom/xul/nsXULCommandDispatcher.cpp
@@ -16,17 +16,16 @@
 #include "nsIDOMDocument.h"
 #include "nsIDOMWindow.h"
 #include "nsIDocument.h"
 #include "nsPresContext.h"
 #include "nsIPresShell.h"
 #include "nsIScriptGlobalObject.h"
 #include "nsPIDOMWindow.h"
 #include "nsPIWindowRoot.h"
-#include "nsRDFCID.h"
 #include "nsXULCommandDispatcher.h"
 #include "mozilla/Logging.h"
 #include "nsContentUtils.h"
 #include "nsReadableUtils.h"
 #include "nsCRT.h"
 #include "nsError.h"
 #include "mozilla/BasicEvents.h"
 #include "mozilla/EventDispatcher.h"
@@ -238,17 +237,17 @@ nsXULCommandDispatcher::AdvanceFocusInto
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsXULCommandDispatcher::AddCommandUpdater(Element* aElement,
                                           const nsAString& aEvents,
                                           const nsAString& aTargets)
 {
-  NS_PRECONDITION(aElement != nullptr, "null ptr");
+  MOZ_ASSERT(aElement != nullptr, "null ptr");
   if (! aElement)
     return NS_ERROR_NULL_POINTER;
 
   NS_ENSURE_TRUE(mDocument, NS_ERROR_UNEXPECTED);
 
   nsresult rv = nsContentUtils::CheckSameOrigin(mDocument, aElement);
 
   if (NS_FAILED(rv)) {
@@ -306,17 +305,17 @@ nsXULCommandDispatcher::AddCommandUpdate
   // If we get here, this is a new updater. Append it to the list.
   *link = new Updater(aElement, aEvents, aTargets);
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsXULCommandDispatcher::RemoveCommandUpdater(Element* aElement)
 {
-  NS_PRECONDITION(aElement != nullptr, "null ptr");
+  MOZ_ASSERT(aElement != nullptr, "null ptr");
   if (! aElement)
     return NS_ERROR_NULL_POINTER;
 
   Updater* updater = mUpdaters;
   Updater** link = &mUpdaters;
 
   while (updater) {
     if (updater->mElement == aElement) {
--- a/dom/xul/nsXULContentSink.cpp
+++ b/dom/xul/nsXULContentSink.cpp
@@ -29,17 +29,16 @@
 #include "nsIServiceManager.h"
 #include "nsIURL.h"
 #include "nsNameSpaceManager.h"
 #include "nsParserBase.h"
 #include "nsViewManager.h"
 #include "nsIScriptSecurityManager.h"
 #include "nsLayoutCID.h"
 #include "nsNetUtil.h"
-#include "nsRDFCID.h"
 #include "nsString.h"
 #include "nsReadableUtils.h"
 #include "nsXULElement.h"
 #include "mozilla/Logging.h"
 #include "nsCRT.h"
 
 #include "nsXULPrototypeDocument.h"     // XXXbe temporary
 #include "mozilla/css/Loader.h"
@@ -270,17 +269,17 @@ XULContentSinkImpl::GetTarget()
 }
 
 //----------------------------------------------------------------------
 
 nsresult
 XULContentSinkImpl::Init(nsIDocument* aDocument,
                          nsXULPrototypeDocument* aPrototype)
 {
-    NS_PRECONDITION(aDocument != nullptr, "null ptr");
+    MOZ_ASSERT(aDocument != nullptr, "null ptr");
     if (! aDocument)
         return NS_ERROR_NULL_POINTER;
 
     mDocument    = do_GetWeakReference(aDocument);
     mPrototype   = aPrototype;
 
     mDocumentURL = mPrototype->GetURI();
     mNodeInfoManager = aPrototype->GetNodeInfoManager();
@@ -402,27 +401,27 @@ XULContentSinkImpl::CreateElement(mozill
     element->mNodeInfo    = aNodeInfo;
 
     *aResult = element;
     return NS_OK;
 }
 
 /**** BEGIN NEW APIs ****/
 
-
 NS_IMETHODIMP
 XULContentSinkImpl::HandleStartElement(const char16_t *aName,
                                        const char16_t **aAtts,
                                        uint32_t aAttsCount,
                                        uint32_t aLineNumber)
 {
   // XXX Hopefully the parser will flag this before we get here. If
   // we're in the epilog, there should be no new elements
-  NS_PRECONDITION(mState != eInEpilog, "tag in XUL doc epilog");
-  NS_PRECONDITION(aAttsCount % 2 == 0, "incorrect aAttsCount");
+  MOZ_ASSERT(mState != eInEpilog, "tag in XUL doc epilog");
+  MOZ_ASSERT(aAttsCount % 2 == 0, "incorrect aAttsCount");
+
   // Adjust aAttsCount so it's the actual number of attributes
   aAttsCount /= 2;
 
   if (mState == eInEpilog)
       return NS_ERROR_UNEXPECTED;
 
   if (mState != eInScript) {
       FlushText();
@@ -625,17 +624,17 @@ XULContentSinkImpl::HandleXMLDeclaration
 
 
 NS_IMETHODIMP
 XULContentSinkImpl::ReportError(const char16_t* aErrorText,
                                 const char16_t* aSourceText,
                                 nsIScriptError *aError,
                                 bool *_retval)
 {
-  NS_PRECONDITION(aError && aSourceText && aErrorText, "Check arguments!!!");
+  MOZ_ASSERT(aError && aSourceText && aErrorText, "Check arguments!!!");
 
   // The expat driver should report the error.
   *_retval = true;
 
   nsresult rv = NS_OK;
 
   // make sure to empty the context stack so that
   // <parsererror> could become the root element.
--- a/dom/xul/nsXULContentUtils.cpp
+++ b/dom/xul/nsXULContentUtils.cpp
@@ -14,54 +14,37 @@
 #include "mozilla/ArrayUtils.h"
 
 #include "nsCollationCID.h"
 #include "nsCOMPtr.h"
 #include "nsIContent.h"
 #include "nsICollation.h"
 #include "nsIDocument.h"
 #include "nsIDOMXULCommandDispatcher.h"
-#include "nsIRDFService.h"
 #include "nsIServiceManager.h"
 #include "nsXULContentUtils.h"
 #include "nsLayoutCID.h"
-#include "nsRDFCID.h"
 #include "nsString.h"
 #include "nsGkAtoms.h"
 #include "XULDocument.h"
 
 using namespace mozilla;
 using dom::XULDocument;
 
 //------------------------------------------------------------------------
 
-nsIRDFService* nsXULContentUtils::gRDF;
 nsICollation *nsXULContentUtils::gCollation;
 
 //------------------------------------------------------------------------
 // Constructors n' stuff
 //
 
 nsresult
-nsXULContentUtils::Init()
-{
-    static NS_DEFINE_CID(kRDFServiceCID, NS_RDFSERVICE_CID);
-    nsresult rv = CallGetService(kRDFServiceCID, &gRDF);
-    if (NS_FAILED(rv)) {
-        return rv;
-    }
-
-    return NS_OK;
-}
-
-
-nsresult
 nsXULContentUtils::Finish()
 {
-    NS_IF_RELEASE(gRDF);
     NS_IF_RELEASE(gCollation);
 
     return NS_OK;
 }
 
 nsICollation*
 nsXULContentUtils::GetCollation()
 {
@@ -105,21 +88,21 @@ nsXULContentUtils::FindChildByTag(nsICon
 }
 
 nsresult
 nsXULContentUtils::SetCommandUpdater(nsIDocument* aDocument, Element* aElement)
 {
     // Deal with setting up a 'commandupdater'. Pulls the 'events' and
     // 'targets' attributes off of aElement, and adds it to the
     // document's command dispatcher.
-    NS_PRECONDITION(aDocument != nullptr, "null ptr");
+    MOZ_ASSERT(aDocument != nullptr, "null ptr");
     if (! aDocument)
         return NS_ERROR_NULL_POINTER;
 
-    NS_PRECONDITION(aElement != nullptr, "null ptr");
+    MOZ_ASSERT(aElement != nullptr, "null ptr");
     if (! aElement)
         return NS_ERROR_NULL_POINTER;
 
     nsresult rv;
 
     NS_ASSERTION(aDocument->IsXULDocument(), "not a xul document");
     if (! aDocument->IsXULDocument())
         return NS_ERROR_UNEXPECTED;
--- a/dom/xul/nsXULContentUtils.h
+++ b/dom/xul/nsXULContentUtils.h
@@ -13,54 +13,43 @@
 #define nsXULContentUtils_h__
 
 #include "nsISupports.h"
 
 class nsAtom;
 class nsICollation;
 class nsIContent;
 class nsIDocument;
-class nsIRDFService;
 
 namespace mozilla {
 namespace dom {
 class Element;
 }
 }
 
 class nsXULContentUtils
 {
 protected:
-    static nsIRDFService* gRDF;
     static nsICollation *gCollation;
 
     static bool gDisableXULCache;
 
     static int
     DisableXULCacheChangedCallback(const char* aPrefName, void* aClosure);
 
 public:
     static nsresult
-    Init();
-
-    static nsresult
     Finish();
 
     static nsresult
     FindChildByTag(nsIContent *aElement,
                    int32_t aNameSpaceID,
                    nsAtom* aTag,
                    mozilla::dom::Element** aResult);
 
     static nsresult
     SetCommandUpdater(nsIDocument* aDocument, mozilla::dom::Element* aElement);
 
-    static nsIRDFService*
-    RDFService()
-    {
-        return gRDF;
-    }
-
     static nsICollation*
     GetCollation();
 };
 
 #endif // nsXULContentUtils_h__
--- a/dom/xul/nsXULControllers.cpp
+++ b/dom/xul/nsXULControllers.cpp
@@ -40,17 +40,17 @@ nsXULControllers::DeleteControllers()
 
   mControllers.Clear();
 }
 
 
 nsresult
 NS_NewXULControllers(nsISupports* aOuter, REFNSIID aIID, void** aResult)
 {
-  NS_PRECONDITION(aOuter == nullptr, "no aggregation");
+  MOZ_ASSERT(aOuter == nullptr, "no aggregation");
   if (aOuter)
     return NS_ERROR_NO_AGGREGATION;
 
   nsXULControllers* controllers = new nsXULControllers();
   nsresult rv;
   NS_ADDREF(controllers);
   rv = controllers->QueryInterface(aIID, aResult);
   NS_RELEASE(controllers);
--- a/dom/xul/nsXULElement.cpp
+++ b/dom/xul/nsXULElement.cpp
@@ -234,21 +234,21 @@ nsXULElement::CreateFromPrototype(nsXULP
 nsresult
 nsXULElement::CreateFromPrototype(nsXULPrototypeElement* aPrototype,
                                   nsIDocument* aDocument,
                                   bool aIsScriptable,
                                   bool aIsRoot,
                                   Element** aResult)
 {
     // Create an nsXULElement from a prototype
-    NS_PRECONDITION(aPrototype != nullptr, "null ptr");
+    MOZ_ASSERT(aPrototype != nullptr, "null ptr");
     if (! aPrototype)
         return NS_ERROR_NULL_POINTER;
 
-    NS_PRECONDITION(aResult != nullptr, "null ptr");
+    MOZ_ASSERT(aResult != nullptr, "null ptr");
     if (! aResult)
         return NS_ERROR_NULL_POINTER;
 
     RefPtr<mozilla::dom::NodeInfo> nodeInfo;
     if (aDocument) {
         mozilla::dom::NodeInfo* ni = aPrototype->mNodeInfo;
         nodeInfo = aDocument->NodeInfoManager()->
           GetNodeInfo(ni->NameAtom(), ni->GetPrefixAtom(), ni->NamespaceID(),
@@ -265,17 +265,17 @@ nsXULElement::CreateFromPrototype(nsXULP
 }
 
 nsresult
 NS_NewXULElement(Element** aResult, already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo,
                  FromParser aFromParser)
 {
     RefPtr<mozilla::dom::NodeInfo> nodeInfo = aNodeInfo;
 
-    NS_PRECONDITION(nodeInfo, "need nodeinfo for non-proto Create");
+    MOZ_ASSERT(nodeInfo, "need nodeinfo for non-proto Create");
 
     NS_ASSERTION(nodeInfo->NamespaceEquals(kNameSpaceID_XUL),
                  "Trying to create XUL elements that don't have the XUL namespace");
 
     nsIDocument* doc = nodeInfo->GetDocument();
     if (doc && !doc->AllowXULXBL()) {
         return NS_ERROR_NOT_AVAILABLE;
     }
@@ -283,17 +283,17 @@ NS_NewXULElement(Element** aResult, alre
     return nsContentUtils::NewXULOrHTMLElement(aResult, nodeInfo, aFromParser, nullptr, nullptr);
 }
 
 void
 NS_TrustedNewXULElement(Element** aResult,
                         already_AddRefed<mozilla::dom::NodeInfo>&& aNodeInfo)
 {
     RefPtr<mozilla::dom::NodeInfo> ni = aNodeInfo;
-    NS_PRECONDITION(ni, "need nodeinfo for non-proto Create");
+    MOZ_ASSERT(ni, "need nodeinfo for non-proto Create");
 
     // Create an nsXULElement with the specified namespace and tag.
     NS_ADDREF(*aResult = nsXULElement::Construct(ni.forget()));
 }
 
 //----------------------------------------------------------------------
 // nsISupports interface
 
@@ -2140,17 +2140,17 @@ nsXULPrototypeElement::Serialize(nsIObje
 }
 
 nsresult
 nsXULPrototypeElement::Deserialize(nsIObjectInputStream* aStream,
                                    nsXULPrototypeDocument* aProtoDoc,
                                    nsIURI* aDocumentURI,
                                    const nsTArray<RefPtr<mozilla::dom::NodeInfo>> *aNodeInfos)
 {
-    NS_PRECONDITION(aNodeInfos, "missing nodeinfo array");
+    MOZ_ASSERT(aNodeInfos, "missing nodeinfo array");
 
     // Read Node Info
     uint32_t number = 0;
     nsresult rv = aStream->Read32(&number);
     if (NS_WARN_IF(NS_FAILED(rv))) return rv;
     mNodeInfo = aNodeInfos->SafeElementAt(number, nullptr);
     if (!mNodeInfo) {
         return NS_ERROR_UNEXPECTED;
@@ -2267,17 +2267,17 @@ nsXULPrototypeElement::Deserialize(nsIOb
 
     return rv;
 }
 
 nsresult
 nsXULPrototypeElement::SetAttrAt(uint32_t aPos, const nsAString& aValue,
                                  nsIURI* aDocumentURI)
 {
-    NS_PRECONDITION(aPos < mNumAttributes, "out-of-bounds");
+    MOZ_ASSERT(aPos < mNumAttributes, "out-of-bounds");
 
     // WARNING!!
     // This code is largely duplicated in nsXULElement::SetAttr.
     // Any changes should be made to both functions.
 
     if (!mNodeInfo->NamespaceEquals(kNameSpaceID_XUL)) {
         mAttributes[aPos].mValue.ParseStringOrAtom(aValue);
 
--- a/dom/xul/nsXULPrototypeDocument.cpp
+++ b/dom/xul/nsXULPrototypeDocument.cpp
@@ -404,49 +404,49 @@ void
 nsXULPrototypeDocument::SetRootElement(nsXULPrototypeElement* aElement)
 {
     mRoot = aElement;
 }
 
 nsresult
 nsXULPrototypeDocument::AddProcessingInstruction(nsXULPrototypePI* aPI)
 {
-    NS_PRECONDITION(aPI, "null ptr");
+    MOZ_ASSERT(aPI, "null ptr");
     if (!mProcessingInstructions.AppendElement(aPI)) {
         return NS_ERROR_OUT_OF_MEMORY;
     }
     return NS_OK;
 }
 
 const nsTArray<RefPtr<nsXULPrototypePI> >&
 nsXULPrototypeDocument::GetProcessingInstructions() const
 {
     return mProcessingInstructions;
 }
 
 void
 nsXULPrototypeDocument::AddStyleSheetReference(nsIURI* aURI)
 {
-    NS_PRECONDITION(aURI, "null ptr");
+    MOZ_ASSERT(aURI, "null ptr");
     if (!mStyleSheetReferences.AppendObject(aURI)) {
         NS_WARNING("mStyleSheetReferences->AppendElement() failed."
                    "Stylesheet overlay dropped.");
     }
 }
 
 const nsCOMArray<nsIURI>&
 nsXULPrototypeDocument::GetStyleSheetReferences() const
 {
     return mStyleSheetReferences;
 }
 
 nsIPrincipal*
 nsXULPrototypeDocument::DocumentPrincipal()
 {
-    NS_PRECONDITION(mNodeInfoManager, "missing nodeInfoManager");
+    MOZ_ASSERT(mNodeInfoManager, "missing nodeInfoManager");
     return mNodeInfoManager->DocumentPrincipal();
 }
 
 void
 nsXULPrototypeDocument::SetDocumentPrincipal(nsIPrincipal* aPrincipal)
 {
     mNodeInfoManager->SetDocumentPrincipal(aPrincipal);
 }
--- a/editor/libeditor/EditorBase.cpp
+++ b/editor/libeditor/EditorBase.cpp
@@ -3544,19 +3544,19 @@ EditorBase::GetNextNodeInternal(const Ed
 }
 
 nsIContent*
 EditorBase::FindNextLeafNode(nsINode* aCurrentNode,
                              bool aGoForward,
                              bool bNoBlockCrossing)
 {
   // called only by GetPriorNode so we don't need to check params.
-  NS_PRECONDITION(IsDescendantOfEditorRoot(aCurrentNode) &&
-                  !IsEditorRoot(aCurrentNode),
-                  "Bogus arguments");
+  MOZ_ASSERT(IsDescendantOfEditorRoot(aCurrentNode) &&
+             !IsEditorRoot(aCurrentNode),
+             "Bogus arguments");
 
   nsINode* cur = aCurrentNode;
   for (;;) {
     // if aCurrentNode has a sibling in the right direction, return
     // that sibling's closest child (or itself if it has no children)
     nsIContent* sibling =
       aGoForward ? cur->GetNextSibling() : cur->GetPreviousSibling();
     if (sibling) {
@@ -4141,33 +4141,33 @@ EditorBase::JoinNodesDeepWithTransaction
   }
 
   return ret;
 }
 
 void
 EditorBase::BeginUpdateViewBatch()
 {
-  NS_PRECONDITION(mUpdateCount >= 0, "bad state");
+  MOZ_ASSERT(mUpdateCount >= 0, "bad state");
 
   if (!mUpdateCount) {
     // Turn off selection updates and notifications.
     RefPtr<Selection> selection = GetSelection();
     if (selection) {
       selection->StartBatchChanges();
     }
   }
 
   mUpdateCount++;
 }
 
 nsresult
 EditorBase::EndUpdateViewBatch()
 {
-  NS_PRECONDITION(mUpdateCount > 0, "bad state");
+  MOZ_ASSERT(mUpdateCount > 0, "bad state");
 
   if (mUpdateCount <= 0) {
     mUpdateCount = 0;
     return NS_ERROR_FAILURE;
   }
 
   mUpdateCount--;
 
--- a/editor/libeditor/EditorEventListener.cpp
+++ b/editor/libeditor/EditorEventListener.cpp
@@ -133,17 +133,17 @@ EditorEventListener::Connect(EditorBase*
     Disconnect();
   }
   return rv;
 }
 
 nsresult
 EditorEventListener::InstallToEditor()
 {
-  NS_PRECONDITION(mEditorBase, "The caller must set mEditorBase");
+  MOZ_ASSERT(mEditorBase, "The caller must set mEditorBase");
 
   EventTarget* piTarget = mEditorBase->GetDOMEventTarget();
   NS_ENSURE_TRUE(piTarget, NS_ERROR_FAILURE);
 
   // register the event listeners with the listener manager
   EventListenerManager* elmP = piTarget->GetOrCreateListenerManager();
   NS_ENSURE_STATE(elmP);
 
--- a/editor/libeditor/HTMLEditor.cpp
+++ b/editor/libeditor/HTMLEditor.cpp
@@ -386,18 +386,18 @@ HTMLEditor::UpdateRootElement()
 
 already_AddRefed<nsIContent>
 HTMLEditor::FindSelectionRoot(nsINode* aNode)
 {
   if (NS_WARN_IF(!aNode)) {
     return nullptr;
   }
 
-  NS_PRECONDITION(aNode->IsDocument() || aNode->IsContent(),
-                  "aNode must be content or document node");
+  MOZ_ASSERT(aNode->IsDocument() || aNode->IsContent(),
+             "aNode must be content or document node");
 
   nsCOMPtr<nsIDocument> doc = aNode->GetComposedDoc();
   if (!doc) {
     return nullptr;
   }
 
   nsCOMPtr<nsIContent> content;
   if (aNode->IsInUncomposedDoc() &&
@@ -3644,17 +3644,17 @@ HTMLEditor::GetEnclosingTable(nsINode* a
     }
   }
   return nullptr;
 }
 
 nsIDOMNode*
 HTMLEditor::GetEnclosingTable(nsIDOMNode* aNode)
 {
-  NS_PRECONDITION(aNode, "null node passed to HTMLEditor::GetEnclosingTable");
+  MOZ_ASSERT(aNode, "null node passed to HTMLEditor::GetEnclosingTable");
   nsCOMPtr<nsINode> node = do_QueryInterface(aNode);
   NS_ENSURE_TRUE(node, nullptr);
   nsCOMPtr<Element> table = GetEnclosingTable(node);
   nsCOMPtr<nsIDOMNode> ret = do_QueryInterface(table);
   return ret;
 }
 
 
--- a/editor/libeditor/TextEditRules.cpp
+++ b/editor/libeditor/TextEditRules.cpp
@@ -225,17 +225,17 @@ TextEditRules::AfterEdit(EditAction aAct
                          nsIEditor::EDirection aDirection)
 {
   if (mLockRulesSniffing) {
     return NS_OK;
   }
 
   AutoLockRulesSniffing lockIt(this);
 
-  NS_PRECONDITION(mActionNesting>0, "bad action nesting!");
+  MOZ_ASSERT(mActionNesting>0, "bad action nesting!");
   if (!--mActionNesting) {
     NS_ENSURE_STATE(mTextEditor);
     RefPtr<Selection> selection = mTextEditor->GetSelection();
     NS_ENSURE_STATE(selection);
 
     NS_ENSURE_STATE(mTextEditor);
     nsresult rv =
       mTextEditor->HandleInlineSpellCheck(aAction, *selection,
--- a/editor/libeditor/TextEditor.cpp
+++ b/editor/libeditor/TextEditor.cpp
@@ -202,17 +202,17 @@ void
 TextEditor::BeginEditorInit()
 {
   mInitTriggerCounter++;
 }
 
 nsresult
 TextEditor::EndEditorInit()
 {
-  NS_PRECONDITION(mInitTriggerCounter > 0, "ended editor init before we began?");
+  MOZ_ASSERT(mInitTriggerCounter > 0, "ended editor init before we began?");
   mInitTriggerCounter--;
   if (mInitTriggerCounter) {
     return NS_OK;
   }
 
   nsresult rv = InitRules();
   if (NS_FAILED(rv)) {
     return rv;
--- a/extensions/spellcheck/src/mozInlineSpellChecker.cpp
+++ b/extensions/spellcheck/src/mozInlineSpellChecker.cpp
@@ -1753,18 +1753,18 @@ mozInlineSpellChecker::SaveCurrentSelect
 }
 
 // This is a copy of nsContentUtils::ContentIsDescendantOf. Another crime
 // for XPCOM's rap sheet
 bool // static
 ContentIsDescendantOf(nsINode* aPossibleDescendant,
                       nsINode* aPossibleAncestor)
 {
-  NS_PRECONDITION(aPossibleDescendant, "The possible descendant is null!");
-  NS_PRECONDITION(aPossibleAncestor, "The possible ancestor is null!");
+  MOZ_ASSERT(aPossibleDescendant, "The possible descendant is null!");
+  MOZ_ASSERT(aPossibleAncestor, "The possible ancestor is null!");
 
   do {
     if (aPossibleDescendant == aPossibleAncestor)
       return true;
     aPossibleDescendant = aPossibleDescendant->GetParentNode();
   } while (aPossibleDescendant);
 
   return false;
--- a/extensions/spellcheck/src/mozInlineSpellWordUtil.cpp
+++ b/extensions/spellcheck/src/mozInlineSpellWordUtil.cpp
@@ -82,17 +82,17 @@ typedef void (* OnLeaveNodeFunPtr)(nsINo
 
 // Find the next node in the DOM tree in preorder.
 // Calls OnLeaveNodeFunPtr when the traversal leaves a node, which is
 // why we can't just use GetNextNode here, sadly.
 static nsINode*
 FindNextNode(nsINode* aNode, nsINode* aRoot,
              OnLeaveNodeFunPtr aOnLeaveNode, void* aClosure)
 {
-  NS_PRECONDITION(aNode, "Null starting node?");
+  MOZ_ASSERT(aNode, "Null starting node?");
 
   nsINode* next = aNode->GetFirstChild();
   if (next)
     return next;
 
   // Don't look at siblings or otherwise outside of aRoot
   if (aNode == aRoot)
     return nullptr;
@@ -118,17 +118,17 @@ FindNextNode(nsINode* aNode, nsINode* aR
   }
 }
 
 // aNode is not a text node. Find the first text node starting at aNode/aOffset
 // in a preorder DOM traversal.
 static nsINode*
 FindNextTextNode(nsINode* aNode, int32_t aOffset, nsINode* aRoot)
 {
-  NS_PRECONDITION(aNode, "Null starting node?");
+  MOZ_ASSERT(aNode, "Null starting node?");
   NS_ASSERTION(!IsSpellCheckingTextNode(aNode), "FindNextTextNode should start with a non-text node");
 
   nsINode* checkNode;
   // Need to start at the aOffset'th child
   nsIContent* child = aNode->GetChildAt_Deprecated(aOffset);
 
   if (child) {
     checkNode = child;
@@ -160,17 +160,17 @@ FindNextTextNode(nsINode* aNode, int32_t
 //    There is no beginning soft boundary. This is because we only go to the
 //    previous node once, when finding the previous word boundary in
 //    SetPosition(). You might think of the soft boundary as being this initial
 //    position.
 
 nsresult
 mozInlineSpellWordUtil::SetEnd(nsINode* aEndNode, int32_t aEndOffset)
 {
-  NS_PRECONDITION(aEndNode, "Null end node?");
+  MOZ_ASSERT(aEndNode, "Null end node?");
 
   NS_ASSERTION(mRootNode, "Not initialized");
 
   InvalidateWords();
 
   if (!IsSpellCheckingTextNode(aEndNode)) {
     // End at the start of the first text node after aEndNode/aEndOffset.
     aEndNode = FindNextTextNode(aEndNode, aEndOffset, mRootNode);
--- a/gfx/thebes/gfxDWriteCommon.cpp
+++ b/gfx/thebes/gfxDWriteCommon.cpp
@@ -46,24 +46,24 @@ public:
     }
     else {
       return E_NOINTERFACE;
     }
   }
 
   IFACEMETHOD_(ULONG, AddRef)()
   {
-    NS_PRECONDITION(int32_t(mRefCnt) >= 0, "illegal refcnt");
+    MOZ_ASSERT(int32_t(mRefCnt) >= 0, "illegal refcnt");
     ++mRefCnt;
     return mRefCnt;
   }
 
   IFACEMETHOD_(ULONG, Release)()
   {
-    NS_PRECONDITION(0 != mRefCnt, "dup release");
+    MOZ_ASSERT(0 != mRefCnt, "dup release");
     --mRefCnt;
     if (mRefCnt == 0) {
       delete this;
       return 0;
     }
     return mRefCnt;
   }
 
--- a/gfx/thebes/gfxFT2FontBase.cpp
+++ b/gfx/thebes/gfxFT2FontBase.cpp
@@ -102,17 +102,17 @@ gfxFT2FontBase::GetGlyph(uint32_t aCharC
     }
 
     return slot->mGlyphIndex;
 }
 
 void
 gfxFT2FontBase::GetGlyphExtents(uint32_t aGlyph, cairo_text_extents_t* aExtents)
 {
-    NS_PRECONDITION(aExtents != nullptr, "aExtents must not be NULL");
+    MOZ_ASSERT(aExtents != nullptr, "aExtents must not be NULL");
 
     cairo_glyph_t glyphs[1];
     glyphs[0].index = aGlyph;
     glyphs[0].x = 0.0;
     glyphs[0].y = 0.0;
     // cairo does some caching for us here but perhaps a small gain could be
     // made by caching more.  It is usually only the advance that is needed,
     // so caching only the advance could allow many requests to be cached with
--- a/gfx/thebes/gfxFT2Utils.cpp
+++ b/gfx/thebes/gfxFT2Utils.cpp
@@ -42,17 +42,17 @@ gfxFT2LockedFace::GetGlyph(uint32_t aCha
 
 typedef FT_UInt (*GetCharVariantFunction)(FT_Face  face,
                                           FT_ULong charcode,
                                           FT_ULong variantSelector);
 
 uint32_t
 gfxFT2LockedFace::GetUVSGlyph(uint32_t aCharCode, uint32_t aVariantSelector)
 {
-    NS_PRECONDITION(aVariantSelector, "aVariantSelector should not be NULL");
+    MOZ_ASSERT(aVariantSelector, "aVariantSelector should not be NULL");
 
     if (MOZ_UNLIKELY(!mFace))
         return 0;
 
     // This function is available from FreeType 2.3.6 (June 2008).
     static CharVariantFunction sGetCharVariantPtr = FindCharVariantFunction();
     if (!sGetCharVariantPtr)
         return 0;
--- a/gfx/thebes/gfxFont.cpp
+++ b/gfx/thebes/gfxFont.cpp
@@ -4186,19 +4186,19 @@ gfxFontStyle::Hash() const
             uint32_t(size*1000) + int32_t(sizeAdjust*1000)) ^
             nsRefPtrHashKey<nsAtom>::HashKey(language);
     */
 }
 
 void
 gfxFontStyle::AdjustForSubSuperscript(int32_t aAppUnitsPerDevPixel)
 {
-    NS_PRECONDITION(variantSubSuper != NS_FONT_VARIANT_POSITION_NORMAL &&
-                    baselineOffset == 0,
-                    "can't adjust this style for sub/superscript");
+    MOZ_ASSERT(variantSubSuper != NS_FONT_VARIANT_POSITION_NORMAL &&
+               baselineOffset == 0,
+               "can't adjust this style for sub/superscript");
 
     // calculate the baseline offset (before changing the size)
     if (variantSubSuper == NS_FONT_VARIANT_POSITION_SUPER) {
         baselineOffset = size * -NS_FONT_SUPERSCRIPT_OFFSET_RATIO;
     } else {
         baselineOffset = size * NS_FONT_SUBSCRIPT_OFFSET_RATIO;
     }
 
--- a/gfx/thebes/gfxFont.h
+++ b/gfx/thebes/gfxFont.h
@@ -1460,26 +1460,26 @@ protected:
     typedef mozilla::SVGContextPaint SVGContextPaint;
 
     typedef gfxFontShaper::RoundingFlags RoundingFlags;
 
 public:
     typedef mozilla::FontSlantStyle FontSlantStyle;
 
     nsrefcnt AddRef(void) {
-        NS_PRECONDITION(int32_t(mRefCnt) >= 0, "illegal refcnt");
+        MOZ_ASSERT(int32_t(mRefCnt) >= 0, "illegal refcnt");
         if (mExpirationState.IsTracked()) {
             gfxFontCache::GetCache()->RemoveObject(this);
         }
         ++mRefCnt;
         NS_LOG_ADDREF(this, mRefCnt, "gfxFont", sizeof(*this));
         return mRefCnt;
     }
     nsrefcnt Release(void) {
-        NS_PRECONDITION(0 != mRefCnt, "dup release");
+        MOZ_ASSERT(0 != mRefCnt, "dup release");
         --mRefCnt;
         NS_LOG_RELEASE(this, mRefCnt, "gfxFont");
         if (mRefCnt == 0) {
             NotifyReleased();
             // |this| may have been deleted.
             return 0;
         }
         return mRefCnt;
--- a/gfx/thebes/gfxFontEntry.h
+++ b/gfx/thebes/gfxFontEntry.h
@@ -45,24 +45,24 @@ namespace mozilla {
 class SVGContextPaint;
 };
 
 #define NO_FONT_LANGUAGE_OVERRIDE      0
 
 class gfxCharacterMap : public gfxSparseBitSet {
 public:
     nsrefcnt AddRef() {
-        NS_PRECONDITION(int32_t(mRefCnt) >= 0, "illegal refcnt");
+        MOZ_ASSERT(int32_t(mRefCnt) >= 0, "illegal refcnt");
         ++mRefCnt;
         NS_LOG_ADDREF(this, mRefCnt, "gfxCharacterMap", sizeof(*this));
         return mRefCnt;
     }
 
     nsrefcnt Release() {
-        NS_PRECONDITION(0 != mRefCnt, "dup release");
+        MOZ_ASSERT(0 != mRefCnt, "dup release");
         --mRefCnt;
         NS_LOG_RELEASE(this, mRefCnt, "gfxCharacterMap");
         if (mRefCnt == 0) {
             NotifyReleased();
             // |this| has been deleted.
             return 0;
         }
         return mRefCnt;
--- a/gfx/thebes/gfxTextRun.cpp
+++ b/gfx/thebes/gfxTextRun.cpp
@@ -848,18 +848,18 @@ gfxTextRun::MeasureText(Range aRange,
 
 #define MEASUREMENT_BUFFER_SIZE 100
 
 void
 gfxTextRun::ClassifyAutoHyphenations(uint32_t aStart, Range aRange,
                                      nsTArray<HyphenType>& aHyphenBuffer,
                                      HyphenationState* aWordState)
 {
-  NS_PRECONDITION(aRange.end - aStart <= aHyphenBuffer.Length() &&
-                  aRange.start >= aStart, "Range out of bounds");
+  MOZ_ASSERT(aRange.end - aStart <= aHyphenBuffer.Length() &&
+             aRange.start >= aStart, "Range out of bounds");
   MOZ_ASSERT(aWordState->mostRecentBoundary >= aStart,
              "Unexpected aMostRecentWordBoundary!!");
 
   uint32_t start = std::min<uint32_t>(aRange.start, aWordState->mostRecentBoundary);
 
   for (uint32_t i = start; i < aRange.end; ++i) {
     if (aHyphenBuffer[i - aStart] == HyphenType::Explicit &&
         !aWordState->hasExplicitHyphen) {
--- a/gfx/thebes/gfxXlibSurface.cpp
+++ b/gfx/thebes/gfxXlibSurface.cpp
@@ -66,18 +66,18 @@ gfxXlibSurface::gfxXlibSurface(Screen *s
 }
 
 gfxXlibSurface::gfxXlibSurface(cairo_surface_t *csurf)
     : mPixmapTaken(false)
 #if defined(GL_PROVIDER_GLX)
       , mGLXPixmap(X11None)
 #endif
 {
-    NS_PRECONDITION(cairo_surface_status(csurf) == 0,
-                    "Not expecting an error surface");
+    MOZ_ASSERT(cairo_surface_status(csurf) == 0,
+               "Not expecting an error surface");
 
     mDrawable = cairo_xlib_surface_get_drawable(csurf);
     mDisplay = cairo_xlib_surface_get_display(csurf);
 
     Init(csurf, true);
 }
 
 gfxXlibSurface::~gfxXlibSurface()
--- a/image/ImageURL.h
+++ b/image/ImageURL.h
@@ -79,18 +79,18 @@ public:
   nsresult GetScheme(nsACString& result)
   {
     result = mScheme;
     return NS_OK;
   }
 
   nsresult SchemeIs(const char* scheme, bool* result)
   {
-    NS_PRECONDITION(scheme, "scheme is null");
-    NS_PRECONDITION(result, "result is null");
+    MOZ_ASSERT(scheme, "scheme is null");
+    MOZ_ASSERT(result, "result is null");
 
     *result = mScheme.Equals(scheme);
     return NS_OK;
   }
 
   nsresult GetRef(nsACString& result)
   {
     result = mRef;
--- a/image/decoders/icon/nsIconURI.cpp
+++ b/image/decoders/icon/nsIconURI.cpp
@@ -466,17 +466,17 @@ nsMozIconURI::SetRef(const nsACString& a
   return NS_ERROR_FAILURE;
 }
 
 NS_IMETHODIMP
 nsMozIconURI::Equals(nsIURI* other, bool* result)
 {
   *result = false;
   NS_ENSURE_ARG_POINTER(other);
-  NS_PRECONDITION(result, "null pointer");
+  MOZ_ASSERT(result, "null pointer");
 
   nsAutoCString spec1;
   nsAutoCString spec2;
 
   nsresult rv = GetSpec(spec1);
   NS_ENSURE_SUCCESS(rv, rv);
   rv = other->GetSpec(spec2);
   NS_ENSURE_SUCCESS(rv, rv);
--- a/image/imgLoader.h
+++ b/image/imgLoader.h
@@ -44,26 +44,26 @@ public:
   static uint32_t SecondsFromPRTime(PRTime prTime);
 
   imgCacheEntry(imgLoader* loader, imgRequest* request,
                 bool aForcePrincipalCheck);
   ~imgCacheEntry();
 
   nsrefcnt AddRef()
   {
-    NS_PRECONDITION(int32_t(mRefCnt) >= 0, "illegal refcnt");
+    MOZ_ASSERT(int32_t(mRefCnt) >= 0, "illegal refcnt");
     NS_ASSERT_OWNINGTHREAD(imgCacheEntry);
     ++mRefCnt;
     NS_LOG_ADDREF(this, mRefCnt, "imgCacheEntry", sizeof(*this));
     return mRefCnt;
   }
 
   nsrefcnt Release()
   {
-    NS_PRECONDITION(0 != mRefCnt, "dup release");
+    MOZ_ASSERT(0 != mRefCnt, "dup release");
     NS_ASSERT_OWNINGTHREAD(imgCacheEntry);
     --mRefCnt;
     NS_LOG_RELEASE(this, mRefCnt, "imgCacheEntry");
     if (mRefCnt == 0) {
       mRefCnt = 1; /* stabilize */
       delete this;
       return 0;
     }
--- a/image/imgRequest.cpp
+++ b/image/imgRequest.cpp
@@ -209,17 +209,17 @@ imgRequest::ResetCacheEntry()
   if (HasCacheEntry()) {
     mCacheEntry->SetDataSize(0);
   }
 }
 
 void
 imgRequest::AddProxy(imgRequestProxy* proxy)
 {
-  NS_PRECONDITION(proxy, "null imgRequestProxy passed in");
+  MOZ_ASSERT(proxy, "null imgRequestProxy passed in");
   LOG_SCOPE_WITH_PARAM(gImgLog, "imgRequest::AddProxy", "proxy", proxy);
 
   if (!mFirstProxy) {
     // Save a raw pointer to the first proxy we see, for use in the network
     // priority logic.
     mFirstProxy = proxy;
   }
 
--- a/image/imgRequestProxy.cpp
+++ b/image/imgRequestProxy.cpp
@@ -128,17 +128,17 @@ imgRequestProxy::imgRequestProxy() :
 {
   /* member initializers and constructor code */
   LOG_FUNC(gImgLog, "imgRequestProxy::imgRequestProxy");
 }
 
 imgRequestProxy::~imgRequestProxy()
 {
   /* destructor code */
-  NS_PRECONDITION(!mListener,
+  MOZ_ASSERT(!mListener,
                   "Someone forgot to properly cancel this request!");
 
   // If we had a listener, that means we would have issued notifications. With
   // bug 1359833, we added support for main thread scheduler groups. Each
   // imgRequestProxy may have its own associated listener, document and/or
   // scheduler group. Typically most imgRequestProxy belong to the same
   // document, or have no listener, which means we will want to execute all main
   // thread code in that shared scheduler group. Less frequently, there may be
@@ -179,18 +179,18 @@ imgRequestProxy::~imgRequestProxy()
 
 nsresult
 imgRequestProxy::Init(imgRequest* aOwner,
                       nsILoadGroup* aLoadGroup,
                       nsIDocument* aLoadingDocument,
                       ImageURL* aURI,
                       imgINotificationObserver* aObserver)
 {
-  NS_PRECONDITION(!GetOwner() && !mListener,
-                  "imgRequestProxy is already initialized");
+  MOZ_ASSERT(!GetOwner() && !mListener,
+             "imgRequestProxy is already initialized");
 
   LOG_SCOPE_WITH_PARAM(gImgLog, "imgRequestProxy::Init", "request",
                        aOwner);
 
   MOZ_ASSERT(mAnimationConsumers == 0, "Cannot have animation before Init");
 
   mBehaviour->SetOwner(aOwner);
   mListener = aObserver;
@@ -209,17 +209,17 @@ imgRequestProxy::Init(imgRequest* aOwner
   AddToOwner(aLoadingDocument);
 
   return NS_OK;
 }
 
 nsresult
 imgRequestProxy::ChangeOwner(imgRequest* aNewOwner)
 {
-  NS_PRECONDITION(GetOwner(),
+  MOZ_ASSERT(GetOwner(),
                   "Cannot ChangeOwner on a proxy without an owner!");
 
   if (mCanceled) {
     // Ensure that this proxy has received all notifications to date
     // before we clean it up when removing it from the old owner below.
     SyncNotifyListener();
   }
 
@@ -858,17 +858,17 @@ nsresult imgRequestProxy::Clone(imgINoti
 }
 
 nsresult
 imgRequestProxy::PerformClone(imgINotificationObserver* aObserver,
                               nsIDocument* aLoadingDocument,
                               bool aSyncNotify,
                               imgRequestProxy** aClone)
 {
-  NS_PRECONDITION(aClone, "Null out param");
+  MOZ_ASSERT(aClone, "Null out param");
 
   LOG_SCOPE(gImgLog, "imgRequestProxy::Clone");
 
   *aClone = nullptr;
   RefPtr<imgRequestProxy> clone = NewClonedProxy();
 
   nsCOMPtr<nsILoadGroup> loadGroup;
   if (aLoadingDocument) {
@@ -1132,17 +1132,17 @@ imgRequestProxy::OnLoadComplete(bool aLa
     } else {
       // More data is coming, so change the request to be a background request
       // and put it back in the loadgroup.
       MoveToBackgroundInLoadGroup();
     }
   }
 
   if (mListenerIsStrongRef && aLastPart) {
-    NS_PRECONDITION(mListener, "How did that happen?");
+    MOZ_ASSERT(mListener, "How did that happen?");
     // Drop our strong ref to the listener now that we're done with
     // everything.  Note that this can cancel us and other fun things
     // like that.  Don't add anything in this method after this point.
     imgINotificationObserver* obs = mListener;
     mListenerIsStrongRef = false;
     NS_RELEASE(obs);
   }
 }
--- a/intl/lwbrk/WordBreaker.cpp
+++ b/intl/lwbrk/WordBreaker.cpp
@@ -12,31 +12,29 @@ using mozilla::intl::WordRange;
 
 /*static*/
 already_AddRefed<WordBreaker>
 WordBreaker::Create()
 {
   return RefPtr<WordBreaker>(new WordBreaker()).forget();
 }
 
-
 bool WordBreaker::BreakInBetween(
   const char16_t* aText1 , uint32_t aTextLen1,
   const char16_t* aText2 , uint32_t aTextLen2)
 {
-  NS_PRECONDITION( nullptr != aText1, "null ptr");
-  NS_PRECONDITION( nullptr != aText2, "null ptr");
+  MOZ_ASSERT(nullptr != aText1, "null ptr");
+  MOZ_ASSERT(nullptr != aText2, "null ptr");
 
   if(!aText1 || !aText2 || (0 == aTextLen1) || (0 == aTextLen2))
     return false;
 
   return GetClass(aText1[aTextLen1-1]) != GetClass(aText2[0]);
 }
 
-
 #define IS_ASCII(c)            (0 == ( 0xFF80 & (c)))
 #define ASCII_IS_ALPHA(c)         ((( 'a' <= (c)) && ((c) <= 'z')) || (( 'A' <= (c)) && ((c) <= 'Z')))
 #define ASCII_IS_DIGIT(c)         (( '0' <= (c)) && ((c) <= '9'))
 #define ASCII_IS_SPACE(c)         (( ' ' == (c)) || ( '\t' == (c)) || ( '\r' == (c)) || ( '\n' == (c)))
 #define IS_ALPHABETICAL_SCRIPT(c) ((c) < 0x2E80)
 
 // we change the beginning of IS_HAN from 0x4e00 to 0x3400 to relfect Unicode 3.0
 #define IS_HAN(c)              (( 0x3400 <= (c)) && ((c) <= 0x9fff))||(( 0xf900 <= (c)) && ((c) <= 0xfaff))
@@ -87,19 +85,19 @@ WordBreaker::GetClass(char16_t c)
   return static_cast<WordBreakClass>(0);
 }
 
 WordRange WordBreaker::FindWord(
   const char16_t* aText , uint32_t aTextLen,
   uint32_t aOffset)
 {
   WordRange range;
-  NS_PRECONDITION( nullptr != aText, "null ptr");
-  NS_PRECONDITION( 0 != aTextLen, "len = 0");
-  NS_PRECONDITION( aOffset <= aTextLen, "aOffset > aTextLen");
+  MOZ_ASSERT(nullptr != aText, "null ptr");
+  MOZ_ASSERT(0 != aTextLen, "len = 0");
+  MOZ_ASSERT(aOffset <= aTextLen, "aOffset > aTextLen");
 
   range.mBegin = aTextLen + 1;
   range.mEnd = aTextLen + 1;
 
   if(!aText || aOffset > aTextLen)
     return range;
 
   WordBreakClass c = GetClass(aText[aOffset]);
--- a/intl/uconv/nsConverterOutputStream.cpp
+++ b/intl/uconv/nsConverterOutputStream.cpp
@@ -22,17 +22,17 @@ nsConverterOutputStream::~nsConverterOut
 {
     Close();
 }
 
 NS_IMETHODIMP
 nsConverterOutputStream::Init(nsIOutputStream* aOutStream,
                               const char* aCharset)
 {
-    NS_PRECONDITION(aOutStream, "Null output stream!");
+    MOZ_ASSERT(aOutStream, "Null output stream!");
 
     const Encoding* encoding;
     if (!aCharset) {
       encoding = UTF_8_ENCODING;
     } else {
       encoding = Encoding::ForLabelNoReplacement(MakeStringSpan(aCharset));
       if (!encoding || encoding == UTF_16LE_ENCODING ||
           encoding == UTF_16BE_ENCODING) {
@@ -127,9 +127,8 @@ nsConverterOutputStream::Close()
 
     nsresult rv1 = Flush();
 
     nsresult rv2 = mOutStream->Close();
     mOutStream = nullptr;
     mConverter = nullptr;
     return NS_FAILED(rv1) ? rv1 : rv2;
 }
-
--- a/ipc/glue/MessageChannel.cpp
+++ b/ipc/glue/MessageChannel.cpp
@@ -771,17 +771,17 @@ MessageChannel::Clear()
     while (!mDeferred.empty()) {
         mDeferred.pop();
     }
 }
 
 bool
 MessageChannel::Open(Transport* aTransport, MessageLoop* aIOLoop, Side aSide)
 {
-    NS_PRECONDITION(!mLink, "Open() called > once");
+    MOZ_ASSERT(!mLink, "Open() called > once");
 
     mMonitor = new RefCountedMonitor();
     mWorkerLoop = MessageLoop::current();
     mWorkerThread = GetCurrentVirtualThread();
     mWorkerLoop->AddDestructionObserver(this);
     mListener->SetIsMainThreadProtocol();
 
     ProcessLink *link = new ProcessLink(this);
@@ -803,18 +803,18 @@ MessageChannel::Open(MessageChannel *aTa
     //    Let PA be the one appropriate to A and PB the side for B.
     //  - A invokes PA->Open(PB, ...):
     //    - set state to mChannelOpening
     //    - this will place a work item in B's worker loop (see next bullet)
     //      and then spins until PB->mChannelState becomes mChannelConnected
     //    - meanwhile, on PB's worker loop, the work item is removed and:
     //      - invokes PB->SlaveOpen(PA, ...):
     //        - sets its state and that of PA to Connected
-    NS_PRECONDITION(aTargetChan, "Need a target channel");
-    NS_PRECONDITION(ChannelClosed == mChannelState, "Not currently closed");
+    MOZ_ASSERT(aTargetChan, "Need a target channel");
+    MOZ_ASSERT(ChannelClosed == mChannelState, "Not currently closed");
 
     CommonThreadOpenInit(aTargetChan, aSide);
 
     Side oppSide = UnknownSide;
     switch(aSide) {
       case ChildSide: oppSide = ParentSide; break;
       case ParentSide: oppSide = ChildSide; break;
       case UnknownSide: break;
@@ -836,20 +836,19 @@ MessageChannel::Open(MessageChannel *aTa
     MOZ_RELEASE_ASSERT(ChannelConnected == mChannelState, "not connected when awoken");
     return (ChannelConnected == mChannelState);
 }
 
 void
 MessageChannel::OnOpenAsSlave(MessageChannel *aTargetChan, Side aSide)
 {
     // Invoked when the other side has begun the open.
-    NS_PRECONDITION(ChannelClosed == mChannelState,
-                    "Not currently closed");
-    NS_PRECONDITION(ChannelOpening == aTargetChan->mChannelState,
-                    "Target channel not in the process of opening");
+    MOZ_ASSERT(ChannelClosed == mChannelState, "Not currently closed");
+    MOZ_ASSERT(ChannelOpening == aTargetChan->mChannelState,
+               "Target channel not in the process of opening");
 
     CommonThreadOpenInit(aTargetChan, aSide);
     mMonitor = aTargetChan->mMonitor;
 
     MonitorAutoLock lock(*mMonitor);
     MOZ_RELEASE_ASSERT(ChannelOpening == aTargetChan->mChannelState,
                           "Target channel not in the process of opening");
     mChannelState = ChannelConnected;
--- a/ipc/glue/MessageLink.cpp
+++ b/ipc/glue/MessageLink.cpp
@@ -67,32 +67,32 @@ ProcessLink::~ProcessLink()
 #endif
 }
 
 void
 ProcessLink::Open(mozilla::ipc::Transport* aTransport, MessageLoop *aIOLoop, Side aSide)
 {
     mChan->AssertWorkerThread();
 
-    NS_PRECONDITION(aTransport, "need transport layer");
+    MOZ_ASSERT(aTransport, "need transport layer");
 
     // FIXME need to check for valid channel
 
     mTransport = aTransport;
 
     // FIXME figure out whether we're in parent or child, grab IO loop
     // appropriately
     bool needOpen = true;
     if(aIOLoop) {
         // We're a child or using the new arguments.  Either way, we
         // need an open.
         needOpen = true;
         mChan->mSide = (aSide == UnknownSide) ? ChildSide : aSide;
     } else {
-        NS_PRECONDITION(aSide == UnknownSide, "expected default side arg");
+        MOZ_ASSERT(aSide == UnknownSide, "expected default side arg");
 
         // parent
         mChan->mSide = ParentSide;
         needOpen = false;
         aIOLoop = XRE_GetIOMessageLoop();
     }
 
     mIOLoop = aIOLoop;
--- a/js/public/AllocPolicy.h
+++ b/js/public/AllocPolicy.h
@@ -12,17 +12,17 @@
  */
 
 #ifndef js_AllocPolicy_h
 #define js_AllocPolicy_h
 
 #include "js/TypeDecls.h"
 #include "js/Utility.h"
 
-extern JS_PUBLIC_API(void) JS_ReportOutOfMemory(JSContext* cx);
+extern MOZ_COLD JS_PUBLIC_API(void) JS_ReportOutOfMemory(JSContext* cx);
 
 namespace js {
 
 enum class AllocFunction {
     Malloc,
     Calloc,
     Realloc
 };
@@ -42,17 +42,17 @@ class SystemAllocPolicy
     }
     void free_(void* p) { js_free(p); }
     void reportAllocOverflow() const {}
     bool checkSimulatedOOM() const {
         return !js::oom::ShouldFailWithOOM();
     }
 };
 
-JS_FRIEND_API(void) ReportOutOfMemory(JSContext* cx);
+MOZ_COLD JS_FRIEND_API(void) ReportOutOfMemory(JSContext* cx);
 
 /*
  * Allocation policy that calls the system memory functions and reports errors
  * to the context. Since the JSContext given on construction is stored for
  * the lifetime of the container, this policy may only be used for containers
  * whose lifetime is a shorter than the given JSContext.
  *
  * FIXME bug 647103 - rewrite this in terms of temporary allocation functions,
--- a/js/src/ds/InlineTable.h
+++ b/js/src/ds/InlineTable.h
@@ -17,17 +17,17 @@ namespace js {
 namespace detail {
 
 template <typename InlineEntry,
           typename Entry,
           typename Table,
           typename HashPolicy,
           typename AllocPolicy,
           size_t InlineEntries>
-class InlineTable
+class InlineTable : private AllocPolicy
 {
   private:
     using TablePtr    = typename Table::Ptr;
     using TableAddPtr = typename Table::AddPtr;
     using TableRange  = typename Table::Range;
     using Lookup      = typename HashPolicy::Lookup;
 
     size_t      inlNext_;
@@ -97,17 +97,18 @@ class InlineTable
 
         return entry.putNew(table_);
     }
 
   public:
     static const size_t SizeOfInlineEntries = sizeof(InlineEntry) * InlineEntries;
 
     explicit InlineTable(AllocPolicy a = AllocPolicy())
-      : inlNext_(0),
+      : AllocPolicy(a),
+        inlNext_(0),
         inlCount_(0),
         table_(a)
     { }
 
     class Ptr
     {
         friend class InlineTable;
 
@@ -298,16 +299,20 @@ class InlineTable
                 if (!switchToTable())
                     return false;
                 return table_.putNew(mozilla::Forward<KeyInput>(key),
                                      mozilla::Forward<Args>(args)...);
             }
 
             MOZ_ASSERT(!p.found());
             MOZ_ASSERT(uintptr_t(inlineEnd()) == uintptr_t(p.inlAddPtr_));
+
+            if (!this->checkSimulatedOOM())
+                return false;
+
             addPtr->update(mozilla::Forward<KeyInput>(key),
                            mozilla::Forward<Args>(args)...);
             ++inlCount_;
             ++inlNext_;
             return true;
         }
 
         return table_.add(p.tableAddPtr_,
--- a/js/src/frontend/BytecodeCompiler.cpp
+++ b/js/src/frontend/BytecodeCompiler.cpp
@@ -78,17 +78,17 @@ class MOZ_STACK_CLASS BytecodeCompiler
 
     JSContext* cx;
     LifoAlloc& alloc;
     const ReadOnlyCompileOptions& options;
     SourceBufferHolder& sourceBuffer;
 
     RootedScope enclosingScope;
 
-    RootedScriptSource sourceObject;
+    RootedScriptSourceObject sourceObject;
     ScriptSource* scriptSource;
 
     Maybe<UsedNameTracker> usedNames;
     Maybe<Parser<SyntaxParseHandler, char16_t>> syntaxParser;
     Maybe<Parser<FullParseHandler, char16_t>> parser;
 
     Directives directives;
 
@@ -506,17 +506,17 @@ frontend::CreateScriptSourceObject(JSCon
     ScriptSource* ss = cx->new_<ScriptSource>();
     if (!ss)
         return nullptr;
     ScriptSourceHolder ssHolder(ss);
 
     if (!ss->initFromOptions(cx, options, parameterListEnd))
         return nullptr;
 
-    RootedScriptSource sso(cx, ScriptSourceObject::create(cx, ss));
+    RootedScriptSourceObject sso(cx, ScriptSourceObject::create(cx, ss));
     if (!sso)
         return nullptr;
 
     // Off-thread compilations do all their GC heap allocation, including the
     // SSO, in a temporary compartment. Hence, for the SSO to refer to the
     // gc-heap-allocated values in |options|, it would need cross-compartment
     // wrappers from the temporary compartment to the real compartment --- which
     // would then be inappropriate once we merged the temporary and real
@@ -778,17 +778,17 @@ frontend::CompileLazyFunction(JSContext*
 
     Rooted<JSFunction*> fun(cx, lazy->functionNonDelazifying());
     ParseNode* pn = parser.standaloneLazyFunction(fun, lazy->toStringStart(),
                                                   lazy->strict(), lazy->generatorKind(),
                                                   lazy->asyncKind());
     if (!pn)
         return false;
 
-    RootedScriptSource sourceObject(cx, lazy->sourceObject());
+    RootedScriptSourceObject sourceObject(cx, lazy->sourceObject());
     MOZ_ASSERT(sourceObject);
 
     Rooted<JSScript*> script(cx, JSScript::Create(cx, options, sourceObject,
                                                   lazy->sourceStart(), lazy->sourceEnd(),
                                                   lazy->toStringStart(), lazy->toStringEnd()));
     if (!script)
         return false;
 
--- a/js/src/frontend/BytecodeEmitter.cpp
+++ b/js/src/frontend/BytecodeEmitter.cpp
@@ -1491,18 +1491,20 @@ BytecodeEmitter::TDZCheckCache::noteTDZC
     if (!ensureCache(bce))
         return false;
 
     CheckTDZMap::AddPtr p = cache_->lookupForAdd(name);
     if (p) {
         MOZ_ASSERT(!check, "TDZ only needs to be checked once per binding per basic block.");
         p->value() = check;
     } else {
-        if (!cache_->add(p, name, check))
-            return false;
+        if (!cache_->add(p, name, check)) {
+            ReportOutOfMemory(bce->cx);
+            return false;
+        }
     }
 
     return true;
 }
 
 // Class for emitting bytecode for blocks like try-catch-finally.
 //
 // Usage: (check for the return value is omitted for simplicity)
--- a/js/src/frontend/BytecodeEmitter.h
+++ b/js/src/frontend/BytecodeEmitter.h
@@ -396,18 +396,20 @@ struct MOZ_STACK_CLASS BytecodeEmitter
         MOZ_ASSERT(atomIndices);
         AtomIndexMap::AddPtr p = atomIndices->lookupForAdd(atom);
         if (p) {
             *indexp = p->value();
             return true;
         }
 
         uint32_t index = atomIndices->count();
-        if (!atomIndices->add(p, atom, index))
+        if (!atomIndices->add(p, atom, index)) {
+            ReportOutOfMemory(cx);
             return false;
+        }
 
         *indexp = index;
         return true;
     }
 
     bool isInLoop();
     MOZ_MUST_USE bool checkSingletonContext();
 
--- a/js/src/gc/Rooting.h
+++ b/js/src/gc/Rooting.h
@@ -36,17 +36,17 @@ typedef JS::Handle<NativeObject*>       
 typedef JS::Handle<Shape*>                  HandleShape;
 typedef JS::Handle<ObjectGroup*>            HandleObjectGroup;
 typedef JS::Handle<JSAtom*>                 HandleAtom;
 typedef JS::Handle<JSLinearString*>         HandleLinearString;
 typedef JS::Handle<PropertyName*>           HandlePropertyName;
 typedef JS::Handle<ArrayObject*>            HandleArrayObject;
 typedef JS::Handle<PlainObject*>            HandlePlainObject;
 typedef JS::Handle<SavedFrame*>             HandleSavedFrame;
-typedef JS::Handle<ScriptSourceObject*>     HandleScriptSource;
+typedef JS::Handle<ScriptSourceObject*>     HandleScriptSourceObject;
 typedef JS::Handle<DebuggerArguments*>      HandleDebuggerArguments;
 typedef JS::Handle<DebuggerEnvironment*>    HandleDebuggerEnvironment;
 typedef JS::Handle<DebuggerFrame*>          HandleDebuggerFrame;
 typedef JS::Handle<DebuggerObject*>         HandleDebuggerObject;
 typedef JS::Handle<Scope*>                  HandleScope;
 
 typedef JS::MutableHandle<Shape*>               MutableHandleShape;
 typedef JS::MutableHandle<JSAtom*>              MutableHandleAtom;
@@ -64,17 +64,17 @@ typedef JS::Rooted<Shape*>              
 typedef JS::Rooted<ObjectGroup*>            RootedObjectGroup;
 typedef JS::Rooted<JSAtom*>                 RootedAtom;
 typedef JS::Rooted<JSLinearString*>         RootedLinearString;
 typedef JS::Rooted<PropertyName*>           RootedPropertyName;
 typedef JS::Rooted<ArrayObject*>            RootedArrayObject;
 typedef JS::Rooted<GlobalObject*>           RootedGlobalObject;
 typedef JS::Rooted<PlainObject*>            RootedPlainObject;
 typedef JS::Rooted<SavedFrame*>             RootedSavedFrame;
-typedef JS::Rooted<ScriptSourceObject*>     RootedScriptSource;
+typedef JS::Rooted<ScriptSourceObject*>     RootedScriptSourceObject;
 typedef JS::Rooted<DebuggerArguments*>      RootedDebuggerArguments;
 typedef JS::Rooted<DebuggerEnvironment*>    RootedDebuggerEnvironment;
 typedef JS::Rooted<DebuggerFrame*>          RootedDebuggerFrame;
 typedef JS::Rooted<DebuggerObject*>         RootedDebuggerObject;
 typedef JS::Rooted<Scope*>                  RootedScope;
 
 typedef JS::GCVector<JSFunction*>   FunctionVector;
 typedef JS::GCVector<PropertyName*> PropertyNameVector;
new file mode 100644
--- /dev/null
+++ b/js/src/jit-test/tests/basic/bug1459258.js
@@ -0,0 +1,8 @@
+if (!('oomTest' in this))
+    quit();
+oomTest(function() {
+    return [0, Math.PI, NaN, Infinity, true, false, Symbol(), Math.tan,
+            Reflect, Proxy, print, assertEq, Array, String, Boolean, Number, parseInt,
+            parseFloat, Math.sin, Math.cos, Math.abs, Math.pow, Math.sqrt,
+            Uint8Array, Int8Array, Int32Array, Int16Array, Uint16Array];
+});
--- a/js/src/jit-test/tests/wasm/atomic.js
+++ b/js/src/jit-test/tests/wasm/atomic.js
@@ -508,16 +508,19 @@ var BoundsAndAlignment =
 		    addrs.push([65520, i, unaligned]);
 
 		// Both out-of-bounds and unaligned.  The spec leaves it unspecified
 		// whether we see the OOB message or the unaligned message (they are
 		// both "traps").  In Firefox, the unaligned check comes first.
 		for ( let i=1 ; i < size ; i++ )
 		    addrs.push([65536, i, unaligned]);
 
+		// GC to prevent TSan builds from running out of memory.
+		gc();
+
 		for ( let [ base, offset, re ] of addrs )
 		{
 		    assertErrorMessage(() => this.loadModule(type, ext, offset)(base), RuntimeError, re);
 		    assertErrorMessage(() => this.loadModuleIgnored(type, ext, offset)(base), RuntimeError, re);
 		    assertErrorMessage(() => this.storeModule(type, ext, offset)(base), RuntimeError, re);
 		    for ( let op of [ "add", "sub", "and", "or", "xor", "xchg" ]) {
 			assertErrorMessage(() => this.opModule(type, ext, offset, op)(base), RuntimeError, re);
 			assertErrorMessage(() => this.opModuleForEffect(type, ext, offset, op)(base), RuntimeError, re);
--- a/js/src/jsapi.cpp
+++ b/js/src/jsapi.cpp
@@ -4662,17 +4662,17 @@ JS::CompileFunction(JSContext* cx, AutoO
 
 JS_PUBLIC_API(bool)
 JS::InitScriptSourceElement(JSContext* cx, HandleScript script,
                             HandleObject element, HandleString elementAttrName)
 {
     MOZ_ASSERT(cx);
     MOZ_ASSERT(CurrentThreadCanAccessRuntime(cx->runtime()));
 
-    RootedScriptSource sso(cx, &script->sourceObject()->as<ScriptSourceObject>());
+    RootedScriptSourceObject sso(cx, &script->sourceObject()->as<ScriptSourceObject>());
     return ScriptSourceObject::initElementProperties(cx, sso, element, elementAttrName);
 }
 
 JS_PUBLIC_API(void)
 JS::ExposeScriptToDebugger(JSContext* cx, HandleScript script)
 {
     MOZ_ASSERT(cx);
     MOZ_ASSERT(CurrentThreadCanAccessRuntime(cx->runtime()));
--- a/js/src/jsapi.h
+++ b/js/src/jsapi.h
@@ -5316,17 +5316,17 @@ JS_ReportErrorFlagsAndNumberUTF8(JSConte
 extern JS_PUBLIC_API(bool)
 JS_ReportErrorFlagsAndNumberUC(JSContext* cx, unsigned flags,
                                JSErrorCallback errorCallback, void* userRef,
                                const unsigned errorNumber, ...);
 
 /**
  * Complain when out of memory.
  */
-extern JS_PUBLIC_API(void)
+extern MOZ_COLD JS_PUBLIC_API(void)
 JS_ReportOutOfMemory(JSContext* cx);
 
 /**
  * Complain when an allocation size overflows the maximum supported limit.
  */
 extern JS_PUBLIC_API(void)
 JS_ReportAllocationOverflow(JSContext* cx);
 
--- a/js/src/vm/Debugger.cpp
+++ b/js/src/vm/Debugger.cpp
@@ -5464,17 +5464,17 @@ class DebuggerScriptGetSourceMatcher
   public:
     DebuggerScriptGetSourceMatcher(JSContext* cx, Debugger* dbg)
       : cx_(cx), dbg_(dbg)
     { }
 
     using ReturnType = JSObject*;
 
     ReturnType match(HandleScript script) {
-        RootedScriptSource source(cx_,
+        RootedScriptSourceObject source(cx_,
             &UncheckedUnwrap(script->sourceObject())->as<ScriptSourceObject>());
         return dbg_->wrapSource(cx_, source);
     }
 
     ReturnType match(Handle<WasmInstanceObject*> wasmInstance) {
         return dbg_->wrapWasmSource(cx_, wasmInstance);
     }
 };
@@ -6866,17 +6866,17 @@ DebuggerSource_trace(JSTracer* trc, JSOb
 }
 
 class SetDebuggerSourcePrivateMatcher
 {
     NativeObject* obj_;
   public:
     explicit SetDebuggerSourcePrivateMatcher(NativeObject* obj) : obj_(obj) { }
     using ReturnType = void;
-    ReturnType match(HandleScriptSource source) { obj_->setPrivateGCThing(source); }
+    ReturnType match(HandleScriptSourceObject source) { obj_->setPrivateGCThing(source); }
     ReturnType match(Handle<WasmInstanceObject*> instance) { obj_->setPrivateGCThing(instance); }
 };
 
 NativeObject*
 Debugger::newDebuggerSource(JSContext* cx, Handle<DebuggerSourceReferent> referent)
 {
     assertSameCompartment(cx, object.get());
 
@@ -6910,17 +6910,17 @@ Debugger::wrapVariantReferent(JSContext*
         obj = wrapVariantReferent<DebuggerSourceReferent, WasmInstanceObject*, WasmInstanceWeakMap>(
             cx, wasmInstanceSources, key, referent);
     }
     MOZ_ASSERT_IF(obj, GetSourceReferent(obj) == referent);
     return obj;
 }
 
 JSObject*
-Debugger::wrapSource(JSContext* cx, HandleScriptSource source)
+Debugger::wrapSource(JSContext* cx, HandleScriptSourceObject source)
 {
     Rooted<DebuggerSourceReferent> referent(cx, source.get());
     return wrapVariantReferent(cx, referent);
 }
 
 JSObject*
 Debugger::wrapWasmSource(JSContext* cx, Handle<WasmInstanceObject*> wasmInstance)
 {
@@ -6987,28 +6987,28 @@ DebuggerSource_checkThis(JSContext* cx, 
 
 #define THIS_DEBUGSOURCE_SOURCE(cx, argc, vp, fnname, args, obj, sourceObject)      \
     CallArgs args = CallArgsFromVp(argc, vp);                                       \
     RootedNativeObject obj(cx,                                                      \
         DebuggerSource_checkThis<ScriptSourceObject*>(cx, args, fnname,             \
                                                       "a JS source"));              \
     if (!obj)                                                                       \
         return false;                                                               \
-    RootedScriptSource sourceObject(cx, GetSourceReferent(obj).as<ScriptSourceObject*>())
+    RootedScriptSourceObject sourceObject(cx, GetSourceReferent(obj).as<ScriptSourceObject*>())
 
 class DebuggerSourceGetTextMatcher
 {
     JSContext* cx_;
 
   public:
     explicit DebuggerSourceGetTextMatcher(JSContext* cx) : cx_(cx) { }
 
     using ReturnType = JSString*;
 
-    ReturnType match(HandleScriptSource sourceObject) {
+    ReturnType match(HandleScriptSourceObject sourceObject) {
         ScriptSource* ss = sourceObject->source();
         bool hasSourceData = ss->hasSourceData();
         if (!ss->hasSourceData() && !JSScript::loadSource(cx_, ss, &hasSourceData))
             return nullptr;
         if (!hasSourceData)
             return NewStringCopyZ<CanGC>(cx_, "[no source]");
 
         if (ss->isFunctionBody())
@@ -7083,17 +7083,17 @@ class DebuggerSourceGetURLMatcher
 {
     JSContext* cx_;
 
   public:
     explicit DebuggerSourceGetURLMatcher(JSContext* cx) : cx_(cx) { }
 
     using ReturnType = Maybe<JSString*>;
 
-    ReturnType match(HandleScriptSource sourceObject) {
+    ReturnType match(HandleScriptSourceObject sourceObject) {
         ScriptSource* ss = sourceObject->source();
         MOZ_ASSERT(ss);
         if (ss->filename()) {
             JSString* str = NewStringCopyZ<CanGC>(cx_, ss->filename());
             return Some(str);
         }
         return Nothing();
     }
@@ -7125,17 +7125,17 @@ DebuggerSource_getURL(JSContext* cx, uns
         args.rval().setNull();
     }
     return true;
 }
 
 struct DebuggerSourceGetDisplayURLMatcher
 {
     using ReturnType = const char16_t*;
-    ReturnType match(HandleScriptSource sourceObject) {
+    ReturnType match(HandleScriptSourceObject sourceObject) {
         ScriptSource* ss = sourceObject->source();
         MOZ_ASSERT(ss);
         return ss->hasDisplayURL() ? ss->displayURL() : nullptr;
     }
     ReturnType match(Handle<WasmInstanceObject*> wasmInstance) {
         return wasmInstance->instance().metadata().displayURL();
     }
 };
@@ -7155,17 +7155,17 @@ DebuggerSource_getDisplayURL(JSContext* 
         args.rval().setNull();
     }
     return true;
 }
 
 struct DebuggerSourceGetElementMatcher
 {
     using ReturnType = JSObject*;
-    ReturnType match(HandleScriptSource sourceObject) {
+    ReturnType match(HandleScriptSourceObject sourceObject) {
         return sourceObject->element();
     }
     ReturnType match(Handle<WasmInstanceObject*> wasmInstance) {
         return nullptr;
     }
 };
 
 static bool
@@ -7182,17 +7182,17 @@ DebuggerSource_getElement(JSContext* cx,
         args.rval().setUndefined();
     }
     return true;
 }
 
 struct DebuggerSourceGetElementPropertyMatcher
 {
     using ReturnType = Value;
-    ReturnType match(HandleScriptSource sourceObject) {
+    ReturnType match(HandleScriptSourceObject sourceObject) {
         return sourceObject->elementAttributeName();
     }
     ReturnType match(Handle<WasmInstanceObject*> wasmInstance) {
         return UndefinedValue();
     }
 };
 
 static bool
@@ -7215,17 +7215,17 @@ class DebuggerSourceGetIntroductionScrip
                                                MutableHandleValue rval)
       : cx_(cx),
         dbg_(dbg),
         rval_(rval)
     { }
 
     using ReturnType = bool;
 
-    ReturnType match(HandleScriptSource sourceObject) {
+    ReturnType match(HandleScriptSourceObject sourceObject) {
         RootedScript script(cx_, sourceObject->introductionScript());
         if (script) {
             RootedObject scriptDO(cx_, dbg_->wrapScript(cx_, script));
             if (!scriptDO)
                 return false;
             rval_.setObject(*scriptDO);
         } else {
             rval_.setUndefined();
@@ -7249,17 +7249,17 @@ DebuggerSource_getIntroductionScript(JSC
     Debugger* dbg = Debugger::fromChildJSObject(obj);
     DebuggerSourceGetIntroductionScriptMatcher matcher(cx, dbg, args.rval());
     return referent.match(matcher);
 }
 
 struct DebuggerGetIntroductionOffsetMatcher
 {
     using ReturnType = Value;
-    ReturnType match(HandleScriptSource sourceObject) {
+    ReturnType match(HandleScriptSourceObject sourceObject) {
         // Regardless of what's recorded in the ScriptSourceObject and
         // ScriptSource, only hand out the introduction offset if we also have
         // the script within which it applies.
         ScriptSource* ss = sourceObject->source();
         if (ss->hasIntroductionOffset() && sourceObject->introductionScript())
             return Int32Value(ss->introductionOffset());
         return UndefinedValue();
     }
@@ -7275,17 +7275,17 @@ DebuggerSource_getIntroductionOffset(JSC
     DebuggerGetIntroductionOffsetMatcher matcher;
     args.rval().set(referent.match(matcher));
     return true;
 }
 
 struct DebuggerSourceGetIntroductionTypeMatcher
 {
     using ReturnType = const char*;
-    ReturnType match(HandleScriptSource sourceObject) {
+    ReturnType match(HandleScriptSourceObject sourceObject) {
         ScriptSource* ss = sourceObject->source();
         MOZ_ASSERT(ss);
         return ss->hasIntroductionType() ? ss->introductionType() : nullptr;
     }
     ReturnType match(Handle<WasmInstanceObject*> wasmInstance) {
         return "wasm";
     }
 };
@@ -7339,17 +7339,17 @@ class DebuggerSourceGetSourceMapURLMatch
 
   public:
     explicit DebuggerSourceGetSourceMapURLMatcher(JSContext* cx, MutableHandleString result)
       : cx_(cx),
         result_(result)
     { }
 
     using ReturnType = bool;
-    ReturnType match(HandleScriptSource sourceObject) {
+    ReturnType match(HandleScriptSourceObject sourceObject) {
         ScriptSource* ss = sourceObject->source();
         MOZ_ASSERT(ss);
         if (!ss->hasSourceMapURL()) {
             result_.set(nullptr);
             return true;
         }
         JSString* str = JS_NewUCStringCopyZ(cx_, ss->sourceMapURL());
         if (!str)
--- a/js/src/vm/Debugger.h
+++ b/js/src/vm/Debugger.h
@@ -1099,17 +1099,17 @@ class Debugger : private mozilla::Linked
      */
     JSObject* wrapWasmScript(JSContext* cx, Handle<WasmInstanceObject*> wasmInstance);
 
     /*
      * Return the Debugger.Source object for |source|, or create a new one if
      * needed. The context |cx| must be in the debugger compartment; |source|
      * must be a script source object in a debuggee compartment.
      */
-    JSObject* wrapSource(JSContext* cx, js::HandleScriptSource source);
+    JSObject* wrapSource(JSContext* cx, js::HandleScriptSourceObject source);
 
     /*
      * Return the Debugger.Source object for |wasmInstance| (the entire module),
      * synthesizing a new one if needed. The context |cx| must be in the
      * debugger compartment; |wasmInstance| must be a WasmInstanceObject in the
      * debuggee compartment.
      */
     JSObject* wrapWasmSource(JSContext* cx, Handle<WasmInstanceObject*> wasmInstance);
--- a/js/src/vm/HelperThreads.cpp
+++ b/js/src/vm/HelperThreads.cpp
@@ -422,17 +422,17 @@ ParseTask::activate(JSRuntime* rt)
 {
     rt->setUsedByHelperThread(parseGlobal->zone());
 }
 
 bool
 ParseTask::finish(JSContext* cx)
 {
     for (auto& sourceObject : sourceObjects) {
-        RootedScriptSource sso(cx, sourceObject);
+        RootedScriptSourceObject sso(cx, sourceObject);
         if (!ScriptSourceObject::initFromOptions(cx, sso, options))
             return false;
         if (!sso->source()->tryCompressOffThread(cx))
             return false;
     }
 
     return true;
 }
--- a/js/src/vm/JSFunction-inl.h
+++ b/js/src/vm/JSFunction-inl.h
@@ -4,18 +4,22 @@
  * 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 vm_JSFunction_inl_h
 #define vm_JSFunction_inl_h
 
 #include "vm/JSFunction.h"
 
+#include "gc/Allocator.h"
+#include "gc/GCTrace.h"
 #include "vm/EnvironmentObject.h"
 
+#include "vm/JSObject-inl.h"
+
 namespace js {
 
 inline const char*
 GetFunctionNameBytes(JSContext* cx, JSFunction* fun, JSAutoByteString* bytes)
 {
     if (JSAtom* name = fun->explicitName())
         return bytes->encodeLatin1(cx, name);
     return js_anonymous_str;
@@ -81,9 +85,68 @@ CloneFunctionObjectIfNotSingleton(JSCont
     if (!script)
         return nullptr;
     RootedScope enclosingScope(cx, script->enclosingScope());
     return CloneFunctionAndScript(cx, fun, parent, enclosingScope, kind, proto);
 }
 
 } /* namespace js */
 
+/* static */ inline JS::Result<JSFunction*, JS::OOM&>
+JSFunction::create(JSContext* cx, js::gc::AllocKind kind, js::gc::InitialHeap heap,
+                   js::HandleShape shape, js::HandleObjectGroup group)
+{
+    MOZ_ASSERT(kind == js::gc::AllocKind::FUNCTION ||
+               kind == js::gc::AllocKind::FUNCTION_EXTENDED);
+
+    debugCheckNewObject(group, shape, kind, heap);
+
+    const js::Class* clasp = group->clasp();
+    MOZ_ASSERT(clasp->isJSFunction());
+
+    static constexpr size_t NumDynamicSlots = 0;
+    MOZ_ASSERT(dynamicSlotsCount(shape->numFixedSlots(), shape->slotSpan(), clasp) ==
+               NumDynamicSlots);
+
+    JSObject* obj = js::Allocate<JSObject>(cx, kind, NumDynamicSlots, heap, clasp);
+    if (!obj)
+        return cx->alreadyReportedOOM();
+
+    NativeObject* nobj = static_cast<NativeObject*>(obj);
+    nobj->initGroup(group);
+    nobj->initShape(shape);
+
+    nobj->initSlots(nullptr);
+    nobj->setEmptyElements();
+
+    MOZ_ASSERT(!clasp->hasPrivate());
+    MOZ_ASSERT(shape->slotSpan() == 0);
+
+    JSFunction* fun = static_cast<JSFunction*>(nobj);
+    fun->nargs_ = 0;
+
+    // This must be overwritten by some ultimate caller: there's no default
+    // value to which we could sensibly initialize this.
+    MOZ_MAKE_MEM_UNDEFINED(&fun->u, sizeof(u));
+
+    // Safe: we're initializing for the very first time.
+    fun->atom_.unsafeSet(nullptr);
+
+    if (kind == js::gc::AllocKind::FUNCTION_EXTENDED) {
+        fun->setFlags(JSFunction::EXTENDED);
+        for (js::GCPtrValue& extendedSlot : fun->toExtended()->extendedSlots)
+            extendedSlot.unsafeSet(JS::DoubleValue(+0.0));
+    } else {
+        fun->setFlags(0);
+    }
+
+    MOZ_ASSERT(!clasp->shouldDelayMetadataBuilder(),
+               "Function has no extra data hanging off it, that wouldn't be "
+               "allocated at this point, that would require delaying the "
+               "building of metadata for it");
+    fun = SetNewObjectMetadata(cx, fun);
+
+    js::gc::TraceCreateObject(fun);
+
+    return fun;
+}
+
 #endif /* vm_JSFunction_inl_h */
--- a/js/src/vm/JSFunction.cpp
+++ b/js/src/vm/JSFunction.cpp
@@ -562,17 +562,17 @@ fun_resolve(JSContext* cx, HandleObject 
     }
 
     return true;
 }
 
 template<XDRMode mode>
 XDRResult
 js::XDRInterpretedFunction(XDRState<mode>* xdr, HandleScope enclosingScope,
-                           HandleScriptSource sourceObject, MutableHandleFunction objp)
+                           HandleScriptSourceObject sourceObject, MutableHandleFunction objp)
 {
     enum FirstWordFlag {
         HasAtom             = 0x1,
         HasGeneratorProto   = 0x2,
         IsLazy              = 0x4,
         HasSingletonType    = 0x8
     };
 
@@ -679,21 +679,21 @@ js::XDRInterpretedFunction(XDRState<mode
     // Required by AutoXDRTree to copy & paste snipet of sub-trees while keeping
     // the alignment.
     MOZ_TRY(xdr->codeAlign(sizeof(js::XDRAlignment)));
 
     return Ok();
 }
 
 template XDRResult
-js::XDRInterpretedFunction(XDRState<XDR_ENCODE>*, HandleScope, HandleScriptSource,
+js::XDRInterpretedFunction(XDRState<XDR_ENCODE>*, HandleScope, HandleScriptSourceObject,
                            MutableHandleFunction);
 
 template XDRResult
-js::XDRInterpretedFunction(XDRState<XDR_DECODE>*, HandleScope, HandleScriptSource,
+js::XDRInterpretedFunction(XDRState<XDR_DECODE>*, HandleScope, HandleScriptSourceObject,
                            MutableHandleFunction);
 
 /* ES6 (04-25-16) 19.2.3.6 Function.prototype [ @@hasInstance ] */
 bool
 js::fun_symbolHasInstance(JSContext* cx, unsigned argc, Value* vp)
 {
     CallArgs args = CallArgsFromVp(argc, vp);
 
@@ -859,17 +859,17 @@ CreateFunctionPrototype(JSContext* cx, J
     if (!ss->setSource(cx, mozilla::Move(source), sourceLen))
         return nullptr;
 
     CompileOptions options(cx);
     options.setIntroductionType("Function.prototype")
            .setNoScriptRval(true);
     if (!ss->initFromOptions(cx, options))
         return nullptr;
-    RootedScriptSource sourceObject(cx, ScriptSourceObject::create(cx, ss));
+    RootedScriptSourceObject sourceObject(cx, ScriptSourceObject::create(cx, ss));
     if (!sourceObject || !ScriptSourceObject::initFromOptions(cx, sourceObject, options))
         return nullptr;
 
     RootedScript script(cx, JSScript::Create(cx,
                                              options,
                                              sourceObject,
                                              begin,
                                              ss->length(),
@@ -1650,17 +1650,17 @@ JSFunction::createScriptForLazilyInterpr
             // Remember the lazy script on the compiled script, so it can be
             // stored on the function again in case of re-lazification.
             // Only functions without inner functions are re-lazified.
             script->setLazyScript(lazy);
         }
 
         // XDR the newly delazified function.
         if (script->scriptSource()->hasEncoder()) {
-            RootedScriptSource sourceObject(cx, lazy->sourceObject());
+            RootedScriptSourceObject sourceObject(cx, lazy->sourceObject());
             if (!script->scriptSource()->xdrEncodeFunction(cx, fun, sourceObject))
                 return false;
         }
 
         return true;
     }
 
     /* Lazily cloned self-hosted script. */
--- a/js/src/vm/JSFunction.h
+++ b/js/src/vm/JSFunction.h
@@ -179,16 +179,20 @@ class JSFunction : public js::NativeObje
     //   b. If HAS_BOUND_FUNCTION_NAME_PREFIX is not set, |atom_| doesn't
     //      contain the "bound " prefix which is prepended to the "name"
     //      property of bound functions per ECMAScript.
     //   c. Bound functions can never have an inferred or guessed name.
     //   d. |atom_| is never null for bound functions.
     js::GCPtrAtom atom_;
 
   public:
+    static inline JS::Result<JSFunction*, JS::OOM&>
+    create(JSContext* cx, js::gc::AllocKind kind, js::gc::InitialHeap heap,
+           js::HandleShape shape, js::HandleObjectGroup group);
+
     /* Call objects must be created for each invocation of this function. */
     bool needsCallObject() const {
         MOZ_ASSERT(!isInterpretedLazy());
 
         if (isNative())
             return false;
 
         // Note: this should be kept in sync with
@@ -999,17 +1003,17 @@ JSFunction::getExtendedSlot(size_t which
 
 namespace js {
 
 JSString* FunctionToString(JSContext* cx, HandleFunction fun, bool isToSource);
 
 template<XDRMode mode>
 XDRResult
 XDRInterpretedFunction(XDRState<mode>* xdr, HandleScope enclosingScope,
-                       HandleScriptSource sourceObject, MutableHandleFunction objp);
+                       HandleScriptSourceObject sourceObject, MutableHandleFunction objp);
 
 /*
  * Report an error that call.thisv is not compatible with the specified class,
  * assuming that the method (clasp->name).prototype.<name of callee function>
  * is what was called.
  */
 extern void
 ReportIncompatibleMethod(JSContext* cx, const CallArgs& args, const Class* clasp);
--- a/js/src/vm/JSObject.cpp
+++ b/js/src/vm/JSObject.cpp
@@ -57,16 +57,17 @@
 #include "gc/Marking-inl.h"
 #include "vm/ArrayObject-inl.h"
 #include "vm/BooleanObject-inl.h"
 #include "vm/Caches-inl.h"
 #include "vm/Interpreter-inl.h"
 #include "vm/JSAtom-inl.h"
 #include "vm/JSCompartment-inl.h"
 #include "vm/JSContext-inl.h"
+#include "vm/JSFunction-inl.h"
 #include "vm/NativeObject-inl.h"
 #include "vm/NumberObject-inl.h"
 #include "vm/Shape-inl.h"
 #include "vm/StringObject-inl.h"
 #include "vm/TypedArrayObject-inl.h"
 #include "vm/UnboxedObject-inl.h"
 
 using namespace js;
@@ -722,17 +723,19 @@ NewObject(JSContext* cx, HandleObjectGro
     RootedShape shape(cx, EmptyShape::getInitialShape(cx, clasp, group->proto(), nfixed,
                                                       initialShapeFlags));
     if (!shape)
         return nullptr;
 
     gc::InitialHeap heap = GetInitialHeap(newKind, clasp);
 
     JSObject* obj;
-    if (MOZ_LIKELY(clasp->isNative())) {
+    if (clasp->isJSFunction()) {
+        JS_TRY_VAR_OR_RETURN_NULL(cx, obj, JSFunction::create(cx, kind, heap, shape, group));
+    } else if (MOZ_LIKELY(clasp->isNative())) {
         JS_TRY_VAR_OR_RETURN_NULL(cx, obj, NativeObject::create(cx, kind, heap, shape, group));
     } else {
         MOZ_ASSERT(IsTypedObjectClass(clasp));
         JS_TRY_VAR_OR_RETURN_NULL(cx, obj, TypedObject::create(cx, kind, heap, shape, group));
     }
 
     if (newKind == SingletonObject) {
         RootedObject nobj(cx, obj);
--- a/js/src/vm/JSScript.cpp
+++ b/js/src/vm/JSScript.cpp
@@ -263,17 +263,17 @@ XDRRelazificationInfo(XDRState<mode>* xd
             // relazify scripts with inner functions.  See
             // JSFunction::createScriptForLazilyInterpretedFunction.
             MOZ_ASSERT(lazy->numInnerFunctions() == 0);
         }
 
         MOZ_TRY(xdr->codeUint64(&packedFields));
 
         if (mode == XDR_DECODE) {
-            RootedScriptSource sourceObject(cx, &script->scriptSourceUnwrap());
+            RootedScriptSourceObject sourceObject(cx, &script->scriptSourceUnwrap());
             lazy.set(LazyScript::Create(cx, fun, script, enclosingScope, sourceObject,
                                         packedFields, sourceStart, sourceEnd, toStringStart,
                                         lineno, column));
             if (!lazy)
                 return xdr->fail(JS::TranscodeResult_Throw);
 
             lazy->setToStringEnd(toStringEnd);
 
@@ -311,17 +311,17 @@ enum XDRClassKind {
     CK_RegexpObject,
     CK_JSFunction,
     CK_JSObject
 };
 
 template<XDRMode mode>
 XDRResult
 js::XDRScript(XDRState<mode>* xdr, HandleScope scriptEnclosingScope,
-              HandleScriptSource sourceObjectArg, HandleFunction fun,
+              HandleScriptSourceObject sourceObjectArg, HandleFunction fun,
               MutableHandleScript scriptp)
 {
     /* NB: Keep this in sync with CopyScript. */
 
     enum ScriptBits {
         NoScriptRval,
         Strict,
         ContainsDynamicNameAccess,
@@ -476,17 +476,17 @@ js::XDRScript(XDRState<mode>* xdr, Handl
     MOZ_TRY(xdr->codeUint32(&ntrynotes));
     MOZ_TRY(xdr->codeUint32(&nscopenotes));
     MOZ_TRY(xdr->codeUint32(&nyieldoffsets));
     MOZ_TRY(xdr->codeUint32(&nTypeSets));
     MOZ_TRY(xdr->codeUint32(&funLength));
     MOZ_TRY(xdr->codeUint32(&scriptBits));
 
     MOZ_ASSERT(!!(scriptBits & (1 << OwnSource)) == !sourceObjectArg);
-    RootedScriptSource sourceObject(cx, sourceObjectArg);
+    RootedScriptSourceObject sourceObject(cx, sourceObjectArg);
 
     if (mode == XDR_DECODE) {
         // When loading from the bytecode cache, we get the CompileOptions from
         // the document. If the noScriptRval or selfHostingMode flag doesn't
         // match, we should fail. This only applies to the top-level and not
         // its inner functions.
         mozilla::Maybe<CompileOptions> options;
         if (xdr->hasOptions() && (scriptBits & (1 << OwnSource))) {
@@ -891,27 +891,27 @@ js::XDRScript(XDRState<mode>* xdr, Handl
         if (!fun && !cx->helperThread())
             Debugger::onNewScript(cx, script);
     }
 
     return Ok();